Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  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
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
/*	$NetBSD: cissreg.h,v 1.11 2022/11/01 19:24:30 andvar Exp $	*/
/*	$OpenBSD: cissreg.h,v 1.11 2010/06/03 01:02:13 dlg 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_INTR_OPQ_SA5	(1<<3)
#define	CISS_INTR_OPQ_SA5B	(1<<2)
#define	CISS_INTR_OPQ	(CISS_INTR_OPQ_SA5|CISS_INTR_OPQ_SA5B)
#define	CISS_INTR_MSI		(1<<0)
#define	CISS_INQ	0x40
#define	CISS_OUTQ	0x44
#define CISS_OSR	0x9c    /* outbound status register */
#define CISS_ODC	0xa0    /* outbound doorbell clear register */
#define CISS_ODC_CLEAR		(0x1)
#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	(*(const 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;
/*
 * these fields appear in OpenCISS Spec 1.06
 * http://cciss.sourceforge.net/#docs
 */
	u_int32_t	max_logical_supported;
	u_int32_t	max_physical_supported;
	u_int32_t	max_physical_per_logical;
	u_int32_t	max_perfomant_mode_cmds;
	u_int32_t	max_block_fetch_count;
} __packed;

/*
 * Configuration table for the Performant transport.  Only 4 request queues
 * are mentioned in this table, though apparently up to 256 can exist.
 */
struct ciss_perf_config {
	uint32_t	fetch_count[8];
#define CISS_SG_FETCH_MAX	0
#define CISS_SG_FETCH_1		1
#define CISS_SG_FETCH_2		2
#define CISS_SG_FETCH_4		3
#define CISS_SG_FETCH_8		4
#define CISS_SG_FETCH_16	5
#define CISS_SG_FETCH_32	6
#define CISS_SG_FETCH_NONE	7
	uint32_t	rq_size;
	uint32_t	rq_count;
	uint32_t	rq_bank_lo;
	uint32_t	rq_bank_hi;
	struct {
		uint32_t	rq_addr_lo;
		uint32_t	rq_addr_hi;
	} __packed rq[4];
} __packed;
#define	CISS_CYCLE_MASK	0x00000001

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 remapped 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 failed */
#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_sg_entry {
	u_int32_t	addr_lo;
	u_int32_t	addr_hi;
	u_int32_t	len;
	u_int32_t	flags;
#define	CISS_SG_EXT	0x0001
} __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[16];/* 18 */

	u_int64_t	err_pa;	/* 28: pa(struct ciss_error *) */
	u_int32_t	err_len;/* 30 */

	struct ciss_sg_entry sgl[1];		/* 34 */
} __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;
	paddr_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 scsipi_xfer	*ccb_xs;
	size_t			ccb_len;
	void			*ccb_data;
	bus_dmamap_t		ccb_dmamap;
	uint8_t			ccb_sg_tag;

	struct ciss_error	ccb_err;
	struct ciss_cmd		ccb_cmd __aligned(16);	/* followed by sgl */
};
CTASSERT((offsetof(struct ciss_ccb, ccb_cmd) & 0xf) == 0);

typedef TAILQ_HEAD(ciss_queue_head, ciss_ccb)     ciss_queue_head;