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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
/* $OpenBSD: cissreg.h,v 1.10 2009/04/29 08:24:26 reyk Exp $ */
/*
* Copyright (c) 2005,2006 Michael Shalayeff
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define CISS_BIGBIT 0x80 /* texas radio and the big beat! */
#define CISS_IDB 0x20
#define CISS_IDB_CFG 0x01
#define CISS_ISR 0x30
#define CISS_IMR 0x34
#define CISS_READYENAB 4
#define CISS_READYENA 8
#define CISS_INQ 0x40
#define CISS_OUTQ 0x44
#define CISS_CFG_BAR 0xb4
#define CISS_CFG_OFF 0xb8
/* 64bit FIFO mode input/output post queues */
#define CISS_INQ64_LO 0xc0
#define CISS_INQ64_HI 0xc4
#define CISS_OUTQ64_LO 0xc8
#define CISS_OUTQ64_HI 0xcc
#define CISS_DRVMAP_SIZE (128 / 8)
#define CISS_CMD_CTRL_GET 0x26
#define CISS_CMD_CTRL_SET 0x27
/* sub-commands for GET/SET */
#define CISS_CMS_CTRL_LDID 0x10
#define CISS_CMS_CTRL_CTRL 0x11
#define CISS_CMS_CTRL_LDSTAT 0x12
#define CISS_CMS_CTRL_PDID 0x15
#define CISS_CMS_CTRL_PDBLINK 0x16
#define CISS_CMS_CTRL_PDBLSENS 0x17
#define CISS_CMS_CTRL_LDIDEXT 0x18
#define CISS_CMS_CTRL_REDSTAT 0x82
#define CISS_CMS_CTRL_FLUSH 0xc2
#define CISS_CMS_CTRL_ACCEPT 0xe0
#define CISS_CMD_READ 0xc0
#define CISS_CMD_READ_EVENT 0xd0
#define CISS_EVENT_RECENT 0x08 /* ignore previous events */
#define CISS_EVENT_RSTOLD 0x04 /* start w/ the oldest one */
#define CISS_EVENT_ORDER 0x02 /* keep the order */
#define CISS_EVENT_SYNC 0x01 /* sync mode: wait till new come */
#define CISS_CMD_LDMAP 0xc2
#define CISS_CMD_PDMAP 0xc3
#define ciss_bitset(d, v) ((v)[(d) >> 3] & (1 << ((d) & 7)))
struct ciss_softc;
struct ciss_config {
u_int32_t signature;
#define CISS_SIGNATURE (*(u_int32_t *)"CISS")
u_int32_t version;
u_int32_t methods;
#define CISS_METH_READY 0x00000001 /* indicate to accept commands */
#define CISS_METH_SIMPL 0x00000002 /* simple mode */
#define CISS_METH_PERF 0x00000004 /* performant mode */
#define CISS_METH_EMQ 0x00000008 /* MEMQ method */
#define CISS_METH_BIT63 0x08000000 /* address bit 63 is valid */
#define CISS_METH_FIFO64_RRO 0x10000000 /* 64bit FIFO reverse read order */
#define CISS_METH_SHORT_TAG 0x20000000 /* short 4 byte tag support */
#define CISS_METH_MSIX 0x40000000 /* directed MSI-X support */
#define CISS_METH_FIFO64 0x80000000 /* 64bit FIFO support */
u_int32_t amethod;
u_int32_t rmethod;
u_int32_t paddr_lim;
u_int32_t int_delay;
u_int32_t int_count;
u_int32_t maxcmd;
u_int32_t scsibus;
#define CISS_BUS_U2 0x0001
#define CISS_BUS_U3 0x0002
#define CISS_BUS_FC1 0x0100
#define CISS_BUS_FC2 0x0200
u_int32_t troff;
u_int8_t hostname[16];
u_int32_t heartbeat;
u_int32_t driverf;
#define CISS_DRV_UATT 0x0001
#define CISS_DRV_QINI 0x0002
#define CISS_DRV_LCKINT 0x0004
#define CISS_DRV_QTAGS 0x0008
#define CISS_DRV_ALPHA 0x0010
#define CISS_DRV_LUNS 0x0020
#define CISS_DRV_MSGRQ 0x0080
#define CISS_DRV_DBRD 0x0100
#define CISS_DRV_PRF 0x0200
u_int32_t maxsg;
} __packed;
struct ciss_inquiry {
u_int8_t numld;
u_int8_t sign[4];
u_int8_t fw_running[4];
u_int8_t fw_stored[4];
u_int8_t hw_rev;
u_int8_t resv0[12];
u_int16_t pci_vendor;
u_int16_t pci_product;
u_int8_t resv1[10];
u_int8_t market_rev;
u_int8_t flags;
#define CISS_INQ_WIDE 0x08
#define CISS_INQ_BIGMAP 0x80
#define CISS_INQ_BITS "\020\04WIDE\010BIGMAP"
u_int8_t resv2[2];
u_int8_t nscsi_bus;
u_int8_t resv3[4];
u_int8_t clk[4]; /* unaligned dumbness */
u_int8_t buswidth;
u_int8_t disks[CISS_DRVMAP_SIZE];
u_int8_t extdisks[CISS_DRVMAP_SIZE];
u_int8_t nondisks[CISS_DRVMAP_SIZE];
} __packed;
struct ciss_ldmap {
u_int32_t size;
u_int32_t resv;
struct {
u_int32_t tgt;
u_int32_t tgt2;
} map[1];
} __packed;
struct ciss_flush {
u_int16_t flush;
#define CISS_FLUSH_ENABLE 0
#define CISS_FLUSH_DISABLE 1
u_int16_t resv[255];
} __packed;
struct ciss_blink {
u_int32_t duration; /* x100ms */
u_int32_t elapsed; /* only for sense */
u_int8_t pdtab[256];
#define CISS_BLINK_ALL 1
#define CISS_BLINK_TIMED 2
u_int8_t res[248];
} __packed;
struct ciss_ldid {
u_int16_t blksize;
u_int16_t nblocks[2]; /* UNALIGNED! */
u_int8_t params[16];
u_int8_t type;
#define CISS_LD_RAID0 0
#define CISS_LD_RAID4 1
#define CISS_LD_RAID1 2
#define CISS_LD_RAID5 3
#define CISS_LD_RAID51 4
#define CISS_LD_RAIDADG 5
u_int8_t res0;
u_int8_t bios_dis;
u_int8_t res1;
u_int32_t id;
u_int8_t label[64];
u_int64_t nbigblocks;
u_int8_t res2[410];
} __packed;
struct ciss_ldstat {
u_int8_t stat;
#define CISS_LD_OK 0
#define CISS_LD_FAILED 1
#define CISS_LD_UNCONF 2
#define CISS_LD_DEGRAD 3
#define CISS_LD_RBLDRD 4 /* ready for rebuild */
#define CISS_LD_REBLD 5
#define CISS_LD_PDINV 6 /* wrong phys drive replaced */
#define CISS_LD_PDUNC 7 /* phys drive is not connected proper */
#define CISS_LD_EXPND 10 /* expanding */
#define CISS_LD_NORDY 11 /* volume is not ready */
#define CISS_LD_QEXPND 12 /* queued for expansion */
u_int8_t failed[4]; /* failed map */
u_int8_t res0[416];
u_int8_t prog[4]; /* blocks left to rebuild/expand */
u_int8_t rebuild; /* drive that is rebuilding */
u_int16_t remapcnt[32]; /* count of re3mapped blocks for pds */
u_int8_t replaced[4]; /* replaced drives map */
u_int8_t spare[4]; /* used spares map */
u_int8_t sparestat; /* spare status */
#define CISS_LD_CONF 0x01 /* spare configured */
#define CISS_LD_RBLD 0x02 /* spare is used and rebuilding */
#define CISS_LD_DONE 0x04 /* spare rebuild done */
#define CISS_LD_FAIL 0x08 /* at least one spare drive has failed */
#define CISS_LD_USED 0x10 /* at least one spare drive is used */
#define CISS_LD_AVAIL 0x20 /* at least one spare is available */
u_int8_t sparemap[32]; /* spare->pd replacement map */
u_int8_t replok[4]; /* replaced failed map */
u_int8_t readyok; /* ready to become ok */
u_int8_t memfail; /* cache mem failure */
u_int8_t expfail; /* expansion failure */
u_int8_t rebldfail; /* rebuild failure */
#define CISS_LD_RBLD_READ 0x01 /* read faild */
#define CISS_LD_RBLD_WRITE 0x02 /* write fail */
u_int8_t bigfailed[16]; /* bigmap vers of same of the above */
u_int8_t bigremapcnt[256];
u_int8_t bigreplaced[16];
u_int8_t bigspare[16];
u_int8_t bigsparemap[128];
u_int8_t bigreplok[16];
u_int8_t bigrebuild; /* big-number rebuilding driveno */
} __packed;
struct ciss_pdid {
u_int8_t bus;
u_int8_t target;
u_int16_t blksz;
u_int32_t nblocks;
u_int32_t resblks;
u_int8_t model[40];
u_int8_t serial[40];
u_int8_t revision[8];
u_int8_t bits;
u_int8_t res0[2];
u_int8_t present;
#define CISS_PD_PRESENT 0x01
#define CISS_PD_NONDSK 0x02
#define CISS_PD_WIDE 0x04
#define CISS_PD_SYNC 0x08
#define CISS_PD_NARROW 0x10
#define CISS_PD_W2NARR 0x20 /* wide downgrade to narrow */
#define CISS_PD_ULTRA 0x40
#define CISS_PD_ULTRA2 0x80
u_int8_t config;
#define CISS_PD_SMART 0x01
#define CISS_PD_SMERRR 0x02
#define CISS_PD_SMERRE 0x04
#define CISS_PD_SMERRD 0x08
#define CISS_PD_EXT 0x10
#define CISS_PD_CONF 0x20
#define CISS_PD_SPARE 0x40
#define CISS_PD_CASAVE 0x80
u_int8_t res1;
u_int8_t cache;
#define CISS_PD_CACHE 0x01
#define CISS_PD_CASAFE 0x01
u_int8_t res2[5];
u_int8_t connector[2];
u_int8_t res3;
u_int8_t bay;
u_int16_t rpm;
u_int8_t type;
u_int8_t res4[393];
} __packed;
struct ciss_event {
u_int32_t reltime; /* time since controller boot */
u_int16_t event;
#define CISS_EVCLS_PROTO 0
#define CISS_EVCLS_PLUG 1
#define CISS_EVCLS_HW 2
#define CISS_EVCLS_ENV 3
#define CISS_EVCLS_PD 4 /* ciss_evpdchg in details */
#define CISS_EVCLS_LD 5
#define CISS_EVCLS_CTRL 6
#define CISS_EVCLS_CISS 8 /* funky errors */
#define CISS_EVCLS_RESV 9
u_int16_t subevent;
#define CISS_EVPROTO_STAT 0
#define CISS_EVPROTO_ERR 1
#define CISS_EVPLUG_PDCHG 0 /* ciss_evpdchg */
#define CISS_EVPLUG_POWER 1 /* ciss_evpschg */
#define CISS_EVPLUG_FAN 2 /* ciss_evfanchg */
#define CISS_EVPLUG_UPS 3 /* ciss_evupschg */
#define CISS_EVPLUG_CTRL 4 /* ciss_evctrlchg: ctrl removed? (; */
#define CISS_EVHW_CABLES 0
#define CISS_EVHW_MEMORY 1
#define CISS_EVHW_FAN 2 /* detail as in CISS_EVPLUG_FAN */
#define CISS_EVHW_VRM 3
#define CISS_EVENV_TEMP 0 /* ciss_evtempchg */
#define CISS_EVENV_PS 1
#define CISS_EVENV_CHASSIS 2
#define CISS_EVENV_AC 3
#define CISS_EVPD_STAT 0
#define CISS_EVLD_STAT 0
#define CISS_EVLD_ERR 1
#define CISS_EVLD_CHECK 2 /* surface check */
#define CISS_EVCTRL_STAT 0
u_int16_t detail;
#define CISS_EVSTAT_NONE 0
#define CISS_EVSTAT_DISABLE 1
#define CISS_EVSTAT_TMO 2 /* async event poll timeout */
#define CISS_EVERR_OVERFLOW 0 /* event queue overflow */
#define CISS_EVPLUG_REMOVE 0
#define CISS_EVPLUG_INSERT 1
#define CISS_EVFAN_FAULT 0
#define CISS_EVFAN_DEGRADED 1
#define CISS_EVFAN_OK 2
#define CISS_EVVRM_REMOVE 0
#define CISS_EVVRM_INSERT 1
#define CISS_EVVRM_FAILED 2
#define CISS_EVVRM_OK 3
#define CISS_EVTEMP_LIMEX 0 /* limit exceeded */
#define CISS_EVTEMP_WARN 1
#define CISS_EVTEMP_OK 2
#define CISS_EVPS_FAIL 0
#define CISS_EVPS_OK 2
#define CISS_EVCHAS_OPEN 0
#define CISS_EVCHAS_CLOSE 2
#define CISS_EVAC_FAIL 0
#define CISS_EVAC_BATTLOW 1
#define CISS_EVPDSTAT_FAIL 0
#define CISS_EVLDSTAT_CHG 0 /* ciss_evldchg */
#define CISS_EVLDSTAT_EXMEDIA 1 /* untolerant cfg got drive replaced */
#define CISS_EVLDSTAT_RERDERR 2 /* ciss_evldrblderr */
#define CISS_EVLDSTAT_REWRERR 3 /* ciss_evldrblderr */
#define CISS_EVLDERR_FATAL 0 /* ciss_evlderr */
#define CISS_EVCHECK_DONE 0 /* details have onle 16bit ld num */
#define CISS_EVCTRLSTAT_CHG 0 /* ciss_evctrlstat */
u_int8_t data[64];
u_int8_t msg[80];
u_int32_t tag;
u_int16_t monday;
u_int16_t year;
u_int32_t time;
u_int16_t presec; /* time for events before boot */
u_int8_t device[8];
u_int8_t resv[336];
} __packed;
struct ciss_evpdchg { /* details pointer */
u_int16_t pd;
u_int8_t flag; /* 1 for configured */
u_int8_t spare;
u_int8_t bigpd; /* big number of the pd */
u_int8_t baynum;
} __packed;
struct ciss_evpschg { /* details pointer */
u_int16_t port;
u_int16_t psid;
u_int16_t box;
} __packed;
struct ciss_evfanchg { /* details pointer */
u_int16_t port;
u_int16_t fanid;
u_int16_t box;
} __packed;
struct ciss_evupschg { /* details pointer */
u_int16_t port;
u_int16_t upsid;
} __packed;
struct ciss_evctrlchg { /* details pointer */
u_int16_t slot;
} __packed;
struct ciss_evtempchg { /* details pointer */
u_int16_t port;
u_int16_t sensid;
u_int16_t box;
} __packed;
struct ciss_evldchg { /* details pointer */
u_int16_t ld;
u_int8_t prevstat; /* same as ldstat->state */
u_int8_t newstat; /* same as ldstat->state */
u_int8_t sparestat;
} __packed;
struct ciss_evldrblderr { /* details pointer */
u_int16_t ld;
u_int8_t replace;
u_int8_t errpd;
u_int8_t bigreplace;
u_int8_t bigerrpd;
} __packed;
struct ciss_evlderr { /* details pointer */
u_int16_t ld;
u_int16_t blkno[2]; /* unaligned; if >2tb see big later */
u_int16_t count;
u_int8_t ldcmd;
u_int8_t bus;
u_int8_t target;
u_int8_t bigblkno[8]; /* unaligned */
} __packed;
struct ciss_evctrlstat { /* details pointer */
u_int8_t prefctrl;
u_int8_t currmode;
u_int8_t redctrl;
u_int8_t redfail;
u_int8_t prevctrl;
u_int8_t prevmode;
u_int8_t prevred;
u_int8_t prevfail;
} __packed;
struct ciss_cmd {
u_int8_t resv0; /* 00 */
u_int8_t sgin; /* 01: #sg in the cmd */
u_int16_t sglen; /* 02: #sg total */
u_int32_t id; /* 04: cmd id << 2 and status bits */
#define CISS_CMD_ERR 0x02
u_int32_t id_hi; /* 08: not used */
u_int32_t tgt; /* 0c: tgt:bus:mode or lun:mode */
#define CISS_CMD_MODE_PERIPH 0x00000000
#define CISS_CMD_MODE_LD 0x40000000
#define CISS_CMD_TGT_MASK 0x40ffffff
#define CISS_CMD_BUS_MASK 0x3f000000
#define CISS_CMD_BUS_SHIFT 24
u_int32_t tgt2; /* 10: scsi-3 address bytes */
u_int8_t cdblen; /* 14: valid length of cdb */
u_int8_t flags; /* 15 */
#define CISS_CDB_CMD 0x00
#define CISS_CDB_MSG 0x01
#define CISS_CDB_NOTAG 0x00
#define CISS_CDB_SIMPL 0x20
#define CISS_CDB_QHEAD 0x28
#define CISS_CDB_ORDR 0x30
#define CISS_CDB_AUTO 0x38
#define CISS_CDB_IN 0x80
#define CISS_CDB_OUT 0x40
u_int16_t tmo; /* 16: timeout in seconds */
#define CISS_MAX_CDB 16
u_int8_t cdb[CISS_MAX_CDB]; /* 18 */
u_int64_t err_pa; /* 28: pa(struct ciss_error *) */
u_int32_t err_len;/* 30 */
struct { /* 34 */
u_int32_t addr_lo;
u_int32_t addr_hi;
u_int32_t len;
u_int32_t flags;
#define CISS_SG_EXT 0x0001
} sgl[1];
} __packed;
struct ciss_error {
u_int8_t scsi_stat; /* SCSI_OK etc */
u_int8_t senselen;
u_int16_t cmd_stat;
#define CISS_ERR_OK 0
#define CISS_ERR_TGTST 1 /* target status */
#define CISS_ERR_UNRUN 2
#define CISS_ERR_OVRUN 3
#define CISS_ERR_INVCMD 4
#define CISS_ERR_PROTE 5
#define CISS_ERR_HWERR 6
#define CISS_ERR_CLOSS 7
#define CISS_ERR_ABRT 8
#define CISS_ERR_FABRT 9
#define CISS_ERR_UABRT 10
#define CISS_ERR_TMO 11
#define CISS_ERR_NABRT 12
u_int32_t resid;
u_int8_t err_type[4];
u_int32_t err_info;
u_int8_t sense[32];
} __packed;
struct ciss_ccb {
TAILQ_ENTRY(ciss_ccb) ccb_link;
struct ciss_softc *ccb_sc;
u_int64_t ccb_cmdpa;
enum {
CISS_CCB_FREE = 0x01,
CISS_CCB_READY = 0x02,
CISS_CCB_ONQ = 0x04,
CISS_CCB_PREQ = 0x08,
CISS_CCB_POLL = 0x10,
CISS_CCB_FAIL = 0x80
#define CISS_CCB_BITS "\020\01FREE\02READY\03ONQ\04PREQ\05POLL\010FAIL"
} ccb_state;
struct scsi_xfer *ccb_xs;
size_t ccb_len;
void *ccb_data;
bus_dmamap_t ccb_dmamap;
struct ciss_error ccb_err;
struct ciss_cmd ccb_cmd; /* followed by sgl */
};
typedef TAILQ_HEAD(ciss_queue_head, ciss_ccb) ciss_queue_head;
|