cissreg.h revision 1.10 1 /* $NetBSD: cissreg.h,v 1.10 2020/07/16 14:41:04 jdolecek Exp $ */
2 /* $OpenBSD: cissreg.h,v 1.11 2010/06/03 01:02:13 dlg Exp $ */
3
4 /*
5 * Copyright (c) 2005,2006 Michael Shalayeff
6 * All rights reserved.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
17 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
18 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21 #define CISS_BIGBIT 0x80 /* texas radio and the big beat! */
22
23 #define CISS_IDB 0x20
24 #define CISS_IDB_CFG 0x01
25 #define CISS_ISR 0x30
26 #define CISS_IMR 0x34
27 #define CISS_INTR_OPQ_SA5 (1<<3)
28 #define CISS_INTR_OPQ_SA5B (1<<2)
29 #define CISS_INTR_OPQ (CISS_INTR_OPQ_SA5|CISS_INTR_OPQ_SA5B)
30 #define CISS_INTR_MSI (1<<0)
31 #define CISS_INQ 0x40
32 #define CISS_OUTQ 0x44
33 #define CISS_OSR 0x9c /* outbound status register */
34 #define CISS_ODC 0xa0 /* outbound doorbell clear register */
35 #define CISS_ODC_CLEAR (0x1)
36 #define CISS_CFG_BAR 0xb4
37 #define CISS_CFG_OFF 0xb8
38
39 /* 64bit FIFO mode input/output post queues */
40 #define CISS_INQ64_LO 0xc0
41 #define CISS_INQ64_HI 0xc4
42 #define CISS_OUTQ64_LO 0xc8
43 #define CISS_OUTQ64_HI 0xcc
44
45 #define CISS_DRVMAP_SIZE (128 / 8)
46
47 #define CISS_CMD_CTRL_GET 0x26
48 #define CISS_CMD_CTRL_SET 0x27
49 /* sub-commands for GET/SET */
50 #define CISS_CMS_CTRL_LDID 0x10
51 #define CISS_CMS_CTRL_CTRL 0x11
52 #define CISS_CMS_CTRL_LDSTAT 0x12
53 #define CISS_CMS_CTRL_PDID 0x15
54 #define CISS_CMS_CTRL_PDBLINK 0x16
55 #define CISS_CMS_CTRL_PDBLSENS 0x17
56 #define CISS_CMS_CTRL_LDIDEXT 0x18
57 #define CISS_CMS_CTRL_REDSTAT 0x82
58 #define CISS_CMS_CTRL_FLUSH 0xc2
59 #define CISS_CMS_CTRL_ACCEPT 0xe0
60
61 #define CISS_CMD_READ 0xc0
62 #define CISS_CMD_READ_EVENT 0xd0
63 #define CISS_EVENT_RECENT 0x08 /* ignore previous events */
64 #define CISS_EVENT_RSTOLD 0x04 /* start w/ the oldest one */
65 #define CISS_EVENT_ORDER 0x02 /* keep the order */
66 #define CISS_EVENT_SYNC 0x01 /* sync mode: wait till new come */
67 #define CISS_CMD_LDMAP 0xc2
68 #define CISS_CMD_PDMAP 0xc3
69
70 #define ciss_bitset(d, v) ((v)[(d) >> 3] & (1 << ((d) & 7)))
71
72 struct ciss_softc;
73
74 struct ciss_config {
75 u_int32_t signature;
76 #define CISS_SIGNATURE (*(const u_int32_t *)"CISS")
77 u_int32_t version;
78 u_int32_t methods;
79 #define CISS_METH_READY 0x00000001 /* indicate to accept commands */
80 #define CISS_METH_SIMPL 0x00000002 /* simple mode */
81 #define CISS_METH_PERF 0x00000004 /* performant mode */
82 #define CISS_METH_EMQ 0x00000008 /* MEMQ method */
83 #define CISS_METH_BIT63 0x08000000 /* address bit 63 is valid */
84 #define CISS_METH_FIFO64_RRO 0x10000000 /* 64bit FIFO reverse read order */
85 #define CISS_METH_SHORT_TAG 0x20000000 /* short 4 byte tag support */
86 #define CISS_METH_MSIX 0x40000000 /* directed MSI-X support */
87 #define CISS_METH_FIFO64 0x80000000 /* 64bit FIFO support */
88 u_int32_t amethod;
89 u_int32_t rmethod;
90 u_int32_t paddr_lim;
91 u_int32_t int_delay;
92 u_int32_t int_count;
93 u_int32_t maxcmd;
94 u_int32_t scsibus;
95 #define CISS_BUS_U2 0x0001
96 #define CISS_BUS_U3 0x0002
97 #define CISS_BUS_FC1 0x0100
98 #define CISS_BUS_FC2 0x0200
99 u_int32_t troff;
100 u_int8_t hostname[16];
101 u_int32_t heartbeat;
102 u_int32_t driverf;
103 #define CISS_DRV_UATT 0x0001
104 #define CISS_DRV_QINI 0x0002
105 #define CISS_DRV_LCKINT 0x0004
106 #define CISS_DRV_QTAGS 0x0008
107 #define CISS_DRV_ALPHA 0x0010
108 #define CISS_DRV_LUNS 0x0020
109 #define CISS_DRV_MSGRQ 0x0080
110 #define CISS_DRV_DBRD 0x0100
111 #define CISS_DRV_PRF 0x0200
112 u_int32_t maxsg;
113 /*
114 * these fields appear in OpenCISS Spec 1.06
115 * http://cciss.sourceforge.net/#docs
116 */
117 u_int32_t max_logical_supported;
118 u_int32_t max_physical_supported;
119 u_int32_t max_physical_per_logical;
120 u_int32_t max_perfomant_mode_cmds;
121 u_int32_t max_block_fetch_count;
122 } __packed;
123
124 /*
125 * Configuration table for the Performant transport. Only 4 request queues
126 * are mentioned in this table, though apparently up to 256 can exist.
127 */
128 struct ciss_perf_config {
129 uint32_t fetch_count[8];
130 #define CISS_SG_FETCH_MAX 0
131 #define CISS_SG_FETCH_1 1
132 #define CISS_SG_FETCH_2 2
133 #define CISS_SG_FETCH_4 3
134 #define CISS_SG_FETCH_8 4
135 #define CISS_SG_FETCH_16 5
136 #define CISS_SG_FETCH_32 6
137 #define CISS_SG_FETCH_NONE 7
138 uint32_t rq_size;
139 uint32_t rq_count;
140 uint32_t rq_bank_lo;
141 uint32_t rq_bank_hi;
142 struct {
143 uint32_t rq_addr_lo;
144 uint32_t rq_addr_hi;
145 } __packed rq[4];
146 } __packed;
147 #define CISS_CYCLE_MASK 0x00000001
148
149 struct ciss_inquiry {
150 u_int8_t numld;
151 u_int8_t sign[4];
152 u_int8_t fw_running[4];
153 u_int8_t fw_stored[4];
154 u_int8_t hw_rev;
155 u_int8_t resv0[12];
156 u_int16_t pci_vendor;
157 u_int16_t pci_product;
158 u_int8_t resv1[10];
159 u_int8_t market_rev;
160 u_int8_t flags;
161 #define CISS_INQ_WIDE 0x08
162 #define CISS_INQ_BIGMAP 0x80
163 #define CISS_INQ_BITS "\020\04WIDE\010BIGMAP"
164 u_int8_t resv2[2];
165 u_int8_t nscsi_bus;
166 u_int8_t resv3[4];
167 u_int8_t clk[4]; /* unaligned dumbness */
168 u_int8_t buswidth;
169 u_int8_t disks[CISS_DRVMAP_SIZE];
170 u_int8_t extdisks[CISS_DRVMAP_SIZE];
171 u_int8_t nondisks[CISS_DRVMAP_SIZE];
172 } __packed;
173
174 struct ciss_ldmap {
175 u_int32_t size;
176 u_int32_t resv;
177 struct {
178 u_int32_t tgt;
179 u_int32_t tgt2;
180 } map[1];
181 } __packed;
182
183 struct ciss_flush {
184 u_int16_t flush;
185 #define CISS_FLUSH_ENABLE 0
186 #define CISS_FLUSH_DISABLE 1
187 u_int16_t resv[255];
188 } __packed;
189
190 struct ciss_blink {
191 u_int32_t duration; /* x100ms */
192 u_int32_t elapsed; /* only for sense */
193 u_int8_t pdtab[256];
194 #define CISS_BLINK_ALL 1
195 #define CISS_BLINK_TIMED 2
196 u_int8_t res[248];
197 } __packed;
198
199 struct ciss_ldid {
200 u_int16_t blksize;
201 u_int16_t nblocks[2]; /* UNALIGNED! */
202 u_int8_t params[16];
203 u_int8_t type;
204 #define CISS_LD_RAID0 0
205 #define CISS_LD_RAID4 1
206 #define CISS_LD_RAID1 2
207 #define CISS_LD_RAID5 3
208 #define CISS_LD_RAID51 4
209 #define CISS_LD_RAIDADG 5
210 u_int8_t res0;
211 u_int8_t bios_dis;
212 u_int8_t res1;
213 u_int32_t id;
214 u_int8_t label[64];
215 u_int64_t nbigblocks;
216 u_int8_t res2[410];
217 } __packed;
218
219 struct ciss_ldstat {
220 u_int8_t stat;
221 #define CISS_LD_OK 0
222 #define CISS_LD_FAILED 1
223 #define CISS_LD_UNCONF 2
224 #define CISS_LD_DEGRAD 3
225 #define CISS_LD_RBLDRD 4 /* ready for rebuild */
226 #define CISS_LD_REBLD 5
227 #define CISS_LD_PDINV 6 /* wrong phys drive replaced */
228 #define CISS_LD_PDUNC 7 /* phys drive is not connected proper */
229 #define CISS_LD_EXPND 10 /* expanding */
230 #define CISS_LD_NORDY 11 /* volume is not ready */
231 #define CISS_LD_QEXPND 12 /* queued for expansion */
232 u_int8_t failed[4]; /* failed map */
233 u_int8_t res0[416];
234 u_int8_t prog[4]; /* blocks left to rebuild/expand */
235 u_int8_t rebuild; /* drive that is rebuilding */
236 u_int16_t remapcnt[32]; /* count of remapped blocks for pds */
237 u_int8_t replaced[4]; /* replaced drives map */
238 u_int8_t spare[4]; /* used spares map */
239 u_int8_t sparestat; /* spare status */
240 #define CISS_LD_CONF 0x01 /* spare configured */
241 #define CISS_LD_RBLD 0x02 /* spare is used and rebuilding */
242 #define CISS_LD_DONE 0x04 /* spare rebuild done */
243 #define CISS_LD_FAIL 0x08 /* at least one spare drive has failed */
244 #define CISS_LD_USED 0x10 /* at least one spare drive is used */
245 #define CISS_LD_AVAIL 0x20 /* at least one spare is available */
246 u_int8_t sparemap[32]; /* spare->pd replacement map */
247 u_int8_t replok[4]; /* replaced failed map */
248 u_int8_t readyok; /* ready to become ok */
249 u_int8_t memfail; /* cache mem failure */
250 u_int8_t expfail; /* expansion failure */
251 u_int8_t rebldfail; /* rebuild failure */
252 #define CISS_LD_RBLD_READ 0x01 /* read faild */
253 #define CISS_LD_RBLD_WRITE 0x02 /* write fail */
254 u_int8_t bigfailed[16]; /* bigmap vers of same of the above */
255 u_int8_t bigremapcnt[256];
256 u_int8_t bigreplaced[16];
257 u_int8_t bigspare[16];
258 u_int8_t bigsparemap[128];
259 u_int8_t bigreplok[16];
260 u_int8_t bigrebuild; /* big-number rebuilding driveno */
261 } __packed;
262
263 struct ciss_pdid {
264 u_int8_t bus;
265 u_int8_t target;
266 u_int16_t blksz;
267 u_int32_t nblocks;
268 u_int32_t resblks;
269 u_int8_t model[40];
270 u_int8_t serial[40];
271 u_int8_t revision[8];
272 u_int8_t bits;
273 u_int8_t res0[2];
274 u_int8_t present;
275 #define CISS_PD_PRESENT 0x01
276 #define CISS_PD_NONDSK 0x02
277 #define CISS_PD_WIDE 0x04
278 #define CISS_PD_SYNC 0x08
279 #define CISS_PD_NARROW 0x10
280 #define CISS_PD_W2NARR 0x20 /* wide downgrade to narrow */
281 #define CISS_PD_ULTRA 0x40
282 #define CISS_PD_ULTRA2 0x80
283 u_int8_t config;
284 #define CISS_PD_SMART 0x01
285 #define CISS_PD_SMERRR 0x02
286 #define CISS_PD_SMERRE 0x04
287 #define CISS_PD_SMERRD 0x08
288 #define CISS_PD_EXT 0x10
289 #define CISS_PD_CONF 0x20
290 #define CISS_PD_SPARE 0x40
291 #define CISS_PD_CASAVE 0x80
292 u_int8_t res1;
293 u_int8_t cache;
294 #define CISS_PD_CACHE 0x01
295 #define CISS_PD_CASAFE 0x01
296 u_int8_t res2[5];
297 u_int8_t connector[2];
298 u_int8_t res3;
299 u_int8_t bay;
300 u_int16_t rpm;
301 u_int8_t type;
302 u_int8_t res4[393];
303 } __packed;
304
305 struct ciss_event {
306 u_int32_t reltime; /* time since controller boot */
307 u_int16_t event;
308 #define CISS_EVCLS_PROTO 0
309 #define CISS_EVCLS_PLUG 1
310 #define CISS_EVCLS_HW 2
311 #define CISS_EVCLS_ENV 3
312 #define CISS_EVCLS_PD 4 /* ciss_evpdchg in details */
313 #define CISS_EVCLS_LD 5
314 #define CISS_EVCLS_CTRL 6
315 #define CISS_EVCLS_CISS 8 /* funky errors */
316 #define CISS_EVCLS_RESV 9
317 u_int16_t subevent;
318 #define CISS_EVPROTO_STAT 0
319 #define CISS_EVPROTO_ERR 1
320 #define CISS_EVPLUG_PDCHG 0 /* ciss_evpdchg */
321 #define CISS_EVPLUG_POWER 1 /* ciss_evpschg */
322 #define CISS_EVPLUG_FAN 2 /* ciss_evfanchg */
323 #define CISS_EVPLUG_UPS 3 /* ciss_evupschg */
324 #define CISS_EVPLUG_CTRL 4 /* ciss_evctrlchg: ctrl removed? (; */
325 #define CISS_EVHW_CABLES 0
326 #define CISS_EVHW_MEMORY 1
327 #define CISS_EVHW_FAN 2 /* detail as in CISS_EVPLUG_FAN */
328 #define CISS_EVHW_VRM 3
329 #define CISS_EVENV_TEMP 0 /* ciss_evtempchg */
330 #define CISS_EVENV_PS 1
331 #define CISS_EVENV_CHASSIS 2
332 #define CISS_EVENV_AC 3
333 #define CISS_EVPD_STAT 0
334 #define CISS_EVLD_STAT 0
335 #define CISS_EVLD_ERR 1
336 #define CISS_EVLD_CHECK 2 /* surface check */
337 #define CISS_EVCTRL_STAT 0
338 u_int16_t detail;
339 #define CISS_EVSTAT_NONE 0
340 #define CISS_EVSTAT_DISABLE 1
341 #define CISS_EVSTAT_TMO 2 /* async event poll timeout */
342 #define CISS_EVERR_OVERFLOW 0 /* event queue overflow */
343 #define CISS_EVPLUG_REMOVE 0
344 #define CISS_EVPLUG_INSERT 1
345 #define CISS_EVFAN_FAULT 0
346 #define CISS_EVFAN_DEGRADED 1
347 #define CISS_EVFAN_OK 2
348 #define CISS_EVVRM_REMOVE 0
349 #define CISS_EVVRM_INSERT 1
350 #define CISS_EVVRM_FAILED 2
351 #define CISS_EVVRM_OK 3
352 #define CISS_EVTEMP_LIMEX 0 /* limit exceeded */
353 #define CISS_EVTEMP_WARN 1
354 #define CISS_EVTEMP_OK 2
355 #define CISS_EVPS_FAIL 0
356 #define CISS_EVPS_OK 2
357 #define CISS_EVCHAS_OPEN 0
358 #define CISS_EVCHAS_CLOSE 2
359 #define CISS_EVAC_FAIL 0
360 #define CISS_EVAC_BATTLOW 1
361 #define CISS_EVPDSTAT_FAIL 0
362 #define CISS_EVLDSTAT_CHG 0 /* ciss_evldchg */
363 #define CISS_EVLDSTAT_EXMEDIA 1 /* untolerant cfg got drive replaced */
364 #define CISS_EVLDSTAT_RERDERR 2 /* ciss_evldrblderr */
365 #define CISS_EVLDSTAT_REWRERR 3 /* ciss_evldrblderr */
366 #define CISS_EVLDERR_FATAL 0 /* ciss_evlderr */
367 #define CISS_EVCHECK_DONE 0 /* details have onle 16bit ld num */
368 #define CISS_EVCTRLSTAT_CHG 0 /* ciss_evctrlstat */
369 u_int8_t data[64];
370 u_int8_t msg[80];
371 u_int32_t tag;
372 u_int16_t monday;
373 u_int16_t year;
374 u_int32_t time;
375 u_int16_t presec; /* time for events before boot */
376 u_int8_t device[8];
377 u_int8_t resv[336];
378 } __packed;
379
380 struct ciss_evpdchg { /* details pointer */
381 u_int16_t pd;
382 u_int8_t flag; /* 1 for configured */
383 u_int8_t spare;
384 u_int8_t bigpd; /* big number of the pd */
385 u_int8_t baynum;
386 } __packed;
387
388 struct ciss_evpschg { /* details pointer */
389 u_int16_t port;
390 u_int16_t psid;
391 u_int16_t box;
392 } __packed;
393
394 struct ciss_evfanchg { /* details pointer */
395 u_int16_t port;
396 u_int16_t fanid;
397 u_int16_t box;
398 } __packed;
399
400 struct ciss_evupschg { /* details pointer */
401 u_int16_t port;
402 u_int16_t upsid;
403 } __packed;
404
405 struct ciss_evctrlchg { /* details pointer */
406 u_int16_t slot;
407 } __packed;
408
409 struct ciss_evtempchg { /* details pointer */
410 u_int16_t port;
411 u_int16_t sensid;
412 u_int16_t box;
413 } __packed;
414
415 struct ciss_evldchg { /* details pointer */
416 u_int16_t ld;
417 u_int8_t prevstat; /* same as ldstat->state */
418 u_int8_t newstat; /* same as ldstat->state */
419 u_int8_t sparestat;
420 } __packed;
421
422 struct ciss_evldrblderr { /* details pointer */
423 u_int16_t ld;
424 u_int8_t replace;
425 u_int8_t errpd;
426 u_int8_t bigreplace;
427 u_int8_t bigerrpd;
428 } __packed;
429
430 struct ciss_evlderr { /* details pointer */
431 u_int16_t ld;
432 u_int16_t blkno[2]; /* unaligned; if >2tb see big later */
433 u_int16_t count;
434 u_int8_t ldcmd;
435 u_int8_t bus;
436 u_int8_t target;
437 u_int8_t bigblkno[8]; /* unaligned */
438 } __packed;
439
440 struct ciss_evctrlstat { /* details pointer */
441 u_int8_t prefctrl;
442 u_int8_t currmode;
443 u_int8_t redctrl;
444 u_int8_t redfail;
445 u_int8_t prevctrl;
446 u_int8_t prevmode;
447 u_int8_t prevred;
448 u_int8_t prevfail;
449 } __packed;
450
451 struct ciss_sg_entry {
452 u_int32_t addr_lo;
453 u_int32_t addr_hi;
454 u_int32_t len;
455 u_int32_t flags;
456 #define CISS_SG_EXT 0x0001
457 } __packed;
458
459 struct ciss_cmd {
460 u_int8_t resv0; /* 00 */
461 u_int8_t sgin; /* 01: #sg in the cmd */
462 u_int16_t sglen; /* 02: #sg total */
463 u_int32_t id; /* 04: cmd id << 2 and status bits */
464 #define CISS_CMD_ERR 0x02
465 u_int32_t id_hi; /* 08: not used */
466 u_int32_t tgt; /* 0c: tgt:bus:mode or lun:mode */
467 #define CISS_CMD_MODE_PERIPH 0x00000000
468 #define CISS_CMD_MODE_LD 0x40000000
469 #define CISS_CMD_TGT_MASK 0x40ffffff
470 #define CISS_CMD_BUS_MASK 0x3f000000
471 #define CISS_CMD_BUS_SHIFT 24
472 u_int32_t tgt2; /* 10: scsi-3 address bytes */
473
474 u_int8_t cdblen; /* 14: valid length of cdb */
475 u_int8_t flags; /* 15 */
476 #define CISS_CDB_CMD 0x00
477 #define CISS_CDB_MSG 0x01
478 #define CISS_CDB_NOTAG 0x00
479 #define CISS_CDB_SIMPL 0x20
480 #define CISS_CDB_QHEAD 0x28
481 #define CISS_CDB_ORDR 0x30
482 #define CISS_CDB_AUTO 0x38
483 #define CISS_CDB_IN 0x80
484 #define CISS_CDB_OUT 0x40
485 u_int16_t tmo; /* 16: timeout in seconds */
486 #define CISS_MAX_CDB 16
487 u_int8_t cdb[16];/* 18 */
488
489 u_int64_t err_pa; /* 28: pa(struct ciss_error *) */
490 u_int32_t err_len;/* 30 */
491
492 struct ciss_sg_entry sgl[1]; /* 34 */
493 } __packed;
494
495 struct ciss_error {
496 u_int8_t scsi_stat; /* SCSI_OK etc */
497 u_int8_t senselen;
498 u_int16_t cmd_stat;
499 #define CISS_ERR_OK 0
500 #define CISS_ERR_TGTST 1 /* target status */
501 #define CISS_ERR_UNRUN 2
502 #define CISS_ERR_OVRUN 3
503 #define CISS_ERR_INVCMD 4
504 #define CISS_ERR_PROTE 5
505 #define CISS_ERR_HWERR 6
506 #define CISS_ERR_CLOSS 7
507 #define CISS_ERR_ABRT 8
508 #define CISS_ERR_FABRT 9
509 #define CISS_ERR_UABRT 10
510 #define CISS_ERR_TMO 11
511 #define CISS_ERR_NABRT 12
512 u_int32_t resid;
513 u_int8_t err_type[4];
514 u_int32_t err_info;
515 u_int8_t sense[32];
516 } __packed;
517
518 struct ciss_ccb {
519 TAILQ_ENTRY(ciss_ccb) ccb_link;
520 paddr_t ccb_cmdpa;
521 enum {
522 CISS_CCB_FREE = 0x01,
523 CISS_CCB_READY = 0x02,
524 CISS_CCB_ONQ = 0x04,
525 CISS_CCB_PREQ = 0x08,
526 CISS_CCB_POLL = 0x10,
527 CISS_CCB_FAIL = 0x80
528 #define CISS_CCB_BITS "\020\01FREE\02READY\03ONQ\04PREQ\05POLL\010FAIL"
529 } ccb_state;
530
531 struct scsipi_xfer *ccb_xs;
532 size_t ccb_len;
533 void *ccb_data;
534 bus_dmamap_t ccb_dmamap;
535 uint8_t ccb_sg_tag;
536
537 struct ciss_error ccb_err;
538 struct ciss_cmd ccb_cmd __aligned(16); /* followed by sgl */
539 };
540 CTASSERT((offsetof(struct ciss_ccb, ccb_cmd) & 0xf) == 0);
541
542 typedef TAILQ_HEAD(ciss_queue_head, ciss_ccb) ciss_queue_head;
543
544