summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid.h
blob: b020d1b7896e2e751ea45b0818ca81f3536ce396 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
#ifndef __MEGARAID_H__
#define __MEGARAID_H__

#include <linux/version.h>

#define IN_ISR                  0x80000000L
#define NO_INTR                 0x40000000L
#define IN_TIMEOUT              0x20000000L
#define PENDING                 0x10000000L
#define BOARD_QUARTZ            0x08000000L

#define SCB_ACTIVE 0x1
#define SCB_WAITQ  0x2
#define SCB_ISSUED 0x4

#define SCB_FREE                -1
#define SCB_RESET               -2
#define SCB_ABORT               -3
#define SCB_LOCKED              -4

#define MEGA_CMD_TIMEOUT        10

#define MAX_SGLIST              20
#define MAX_COMMANDS            254

#define MAX_LOGICAL_DRIVES      8
#define MAX_CHANNEL             5
#define MAX_TARGET              15
#define MAX_PHYSICAL_DRIVES     MAX_CHANNEL*MAX_TARGET

#define INQUIRY_DATA_SIZE       0x24
#define MAX_CDB_LEN             0x0A
#define MAX_REQ_SENSE_LEN       0x20

#define INTR_VALID              0x40

/* Mailbox commands */
#define MEGA_MBOXCMD_LREAD      0x01
#define MEGA_MBOXCMD_LWRITE     0x02
#define MEGA_MBOXCMD_PASSTHRU   0x03
#define MEGA_MBOXCMD_ADAPTERINQ 0x05

/* Offsets into Mailbox */
#define COMMAND_PORT       0x00
#define COMMAND_ID_PORT    0x01
#define SG_LIST_PORT0      0x08
#define SG_LIST_PORT1      0x09
#define SG_LIST_PORT2      0x0a
#define SG_LIST_PORT3      0x0b
#define SG_ELEMENT_PORT    0x0d
#define NO_FIRED_PORT      0x0f

/* I/O Port offsets */
#define I_CMD_PORT         0x00
#define I_ACK_PORT         0x00
#define I_TOGGLE_PORT      0x01
#define INTR_PORT          0x0a

#define MAILBOX_SIZE       70
#define MBOX_BUSY_PORT     0x00
#define MBOX_PORT0         0x04
#define MBOX_PORT1         0x05
#define MBOX_PORT2         0x06
#define MBOX_PORT3         0x07
#define ENABLE_MBOX_REGION 0x0B

/* I/O Port Values */
#define ISSUE_BYTE         0x10
#define ACK_BYTE           0x08
#define ENABLE_INTR_BYTE   0xc0
#define DISABLE_INTR_BYTE  0x00
#define VALID_INTR_BYTE    0x40
#define MBOX_BUSY_BYTE     0x10
#define ENABLE_MBOX_BYTE   0x00

/* Setup some port macros here */
#define WRITE_MAILBOX(base,offset,value)   *(base+offset)=value
#define READ_MAILBOX(base,offset)          *(base+offset)

#define WRITE_PORT(base,offset,value)      outb_p(value,base+offset)
#define READ_PORT(base,offset)             inb_p(base+offset)

#define ISSUE_COMMAND(base)   WRITE_PORT(base,I_CMD_PORT,ISSUE_BYTE)
#define CLEAR_INTR(base)      WRITE_PORT(base,I_ACK_PORT,ACK_BYTE)
#define ENABLE_INTR(base)     WRITE_PORT(base,I_TOGGLE_PORT,ENABLE_INTR_BYTE)
#define DISABLE_INTR(base)    WRITE_PORT(base,I_TOGGLE_PORT,DISABLE_INTR_BYTE)

/* Define AMI's PCI codes */
#undef PCI_VENDOR_ID_AMI
#undef PCI_DEVICE_ID_AMI_MEGARAID

#ifndef PCI_VENDOR_ID_AMI
#define PCI_VENDOR_ID_AMI          0x101E
#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010
#endif

#define PCI_CONF_BASE_ADDR_OFFSET  0x10
#define PCI_CONF_IRQ_OFFSET        0x3c

#if LINUX_VERSION_CODE < 0x20100
#define MEGARAID \
  { NULL,                               /* Next                      */\
    NULL,                               /* Usage Count Pointer       */\
    NULL,                               /* /proc Directory Entry     */\
    megaraid_proc_info,                 /* /proc Info Function       */\
    "MegaRAID",                         /* Driver Name               */\
    megaraid_detect,                    /* Detect Host Adapter       */\
    megaraid_release,                   /* Release Host Adapter      */\
    megaraid_info,                      /* Driver Info Function      */\
    megaraid_command,                   /* Command Function          */\
    megaraid_queue,                     /* Queue Command Function    */\
    megaraid_abort,                     /* Abort Command Function    */\
    megaraid_reset,                     /* Reset Command Function    */\
    NULL,                               /* Slave Attach Function     */\
    megaraid_biosparam,                 /* Disk BIOS Parameters      */\
    1,                                  /* # of cmds that can be\
                                           outstanding at any time */\
    7,                                  /* HBA Target ID             */\
    MAX_SGLIST,                         /* Scatter/Gather Table Size */\
    1,                                  /* SCSI Commands per LUN     */\
    0,                                  /* Present                   */\
    0,                                  /* Default Unchecked ISA DMA */\
    ENABLE_CLUSTERING }                 /* Enable Clustering         */
#else
#define MEGARAID \
  {\
    name:            "MegaRAID",               /* Driver Name               */\
    proc_info:        megaraid_proc_info,      /* /proc driver info         */\
    detect:           megaraid_detect,         /* Detect Host Adapter       */\
    release:          megaraid_release,        /* Release Host Adapter      */\
    info:             megaraid_info,           /* Driver Info Function      */\
    command:          megaraid_command,        /* Command Function          */\
    queuecommand:     megaraid_queue,          /* Queue Command Function    */\
    abort:            megaraid_abort,          /* Abort Command Function    */\
    reset:            megaraid_reset,          /* Reset Command Function    */\
    bios_param:       megaraid_biosparam,      /* Disk BIOS Parameters      */\
    can_queue:        255,                     /* Can Queue                 */\
    this_id:          7,                       /* HBA Target ID             */\
    sg_tablesize:     MAX_SGLIST,              /* Scatter/Gather Table Size */\
    cmd_per_lun:      1,                       /* SCSI Commands per LUN     */\
    present:          0,                       /* Present                   */\
    unchecked_isa_dma:0,                       /* Default Unchecked ISA DMA */\
    use_clustering:   ENABLE_CLUSTERING       /* Enable Clustering         */\
  }
#endif

/* Structures */
typedef struct _mega_ADP_INFO
{
  u_char    MaxConcCmds;
  u_char    RbldRate;
  u_char    MaxTargPerChan;
  u_char    ChanPresent;
  u_char    FwVer[4];
  u_short   AgeOfFlash;
  u_char    ChipSet;
  u_char    DRAMSize;
  u_char    CacheFlushInterval;
  u_char    BiosVer[4];
  u_char    resvd[7];
} mega_ADP_INFO;

typedef struct _mega_LDRV_INFO
{
  u_char   NumLDrv;
  u_char   resvd[3];
  u_long   LDrvSize[MAX_LOGICAL_DRIVES];
  u_char   LDrvProp[MAX_LOGICAL_DRIVES];
  u_char   LDrvState[MAX_LOGICAL_DRIVES];
} mega_LDRV_INFO;

typedef struct _mega_PDRV_INFO
{
  u_char   PDrvState[MAX_PHYSICAL_DRIVES];
  u_char   resvd;
} mega_PDRV_INFO;

// RAID inquiry: Mailbox command 0x5
typedef struct _mega_RAIDINQ
{
  mega_ADP_INFO    AdpInfo;
  mega_LDRV_INFO   LogdrvInfo;
  mega_PDRV_INFO   PhysdrvInfo;
} mega_RAIDINQ;

// Passthrough command: Mailbox command 0x3
typedef struct mega_passthru
{
  u_char            timeout:3;              /* 0=6sec/1=60sec/2=10min/3=3hrs */
  u_char            ars:1;
  u_char            reserved:3;
  u_char            islogical:1;
  u_char            logdrv;                 /* if islogical == 1 */
  u_char            channel;                /* if islogical == 0 */
  u_char            target;                 /* if islogical == 0 */
  u_char            queuetag;               /* unused */
  u_char            queueaction;            /* unused */
  u_char            cdb[MAX_CDB_LEN];
  u_char            cdblen;
  u_char            reqsenselen;
  u_char            reqsensearea[MAX_REQ_SENSE_LEN];
  u_char            numsgelements;
  u_char            scsistatus;
  u_long            dataxferaddr;
  u_long            dataxferlen;
} mega_passthru;

typedef struct _mega_mailbox
{
  /* 0x0 */ u_char    cmd;
  /* 0x1 */ u_char    cmdid;
  /* 0x2 */ u_short   numsectors;
  /* 0x4 */ u_long    lba;
  /* 0x8 */ u_long    xferaddr;
  /* 0xC */ u_char    logdrv;
  /* 0xD */ u_char    numsgelements;
  /* 0xE */ u_char    resvd;
  /* 0xF */ u_char    busy;
  /* 0x10*/ u_char    numstatus;
  /* 0x11*/ u_char    status;
  /* 0x12*/ u_char    completed[46];
            u_char    mraid_poll;
            u_char    mraid_ack;
            u_char    pad[16];
} mega_mailbox;

typedef struct _mega_sglist
{
  u_long     address;
  u_long     length;
} mega_sglist;

/* Queued command data */
typedef struct _mega_scb mega_scb;

struct _mega_scb
{
  int             idx;
  u_long          flag;
  Scsi_Cmnd      *SCpnt;
  u_char          mboxData[16];
  mega_passthru   pthru;
  mega_sglist    *sgList;
  mega_scb       *next;
};

/* Per-controller data */
typedef struct _mega_host_config
{
  u_char               numldrv;
  u_long               flag;
  u_long               base;

  struct tq_struct     megaTq;

  /* Host adapter parameters */
  u_char               fwVer[7];
  u_char               biosVer[7];

  struct Scsi_Host     *host;

  /* The following must be DMA-able!! */
  volatile mega_mailbox *mbox;
  volatile mega_mailbox mailbox;
  volatile u_char       mega_buffer[2*1024L];

  u_char                max_cmds;
  mega_scb              scbList[MAX_COMMANDS];
} mega_host_config;

extern struct proc_dir_entry proc_scsi_megaraid;

const char *megaraid_info( struct Scsi_Host * );
int        megaraid_detect( Scsi_Host_Template * );
int        megaraid_release(struct Scsi_Host *);
int        megaraid_command( Scsi_Cmnd * );
int        megaraid_abort( Scsi_Cmnd * );
int        megaraid_reset( Scsi_Cmnd *, unsigned int); 
int        megaraid_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
int        megaraid_biosparam( Disk *, kdev_t, int * );
int        megaraid_proc_info( char *buffer, char **start, off_t offset,
			       int length, int hostno, int inout );

#endif