scsi_all.h revision 268697
1104862Sru/*-
2151497Sru * Largely written by Julian Elischer (julian@tfs.com)
3151497Sru * for TRW Financial Systems.
4151497Sru *
5151497Sru * TRW Financial Systems, in accordance with their agreement with Carnegie
6151497Sru * Mellon University, makes this software available to CMU to distribute
7151497Sru * or use in any manner that they see fit as long as this message is kept with
8151497Sru * the software. For this reason TFS also grants any other persons or
9151497Sru * organisations permission to use or modify this software.
10151497Sru *
11151497Sru * TFS supplies this software to be publicly redistributed
12151497Sru * on the understanding that TFS is not responsible for the correct
13151497Sru * functioning of this software in any circumstances.
14151497Sru *
15151497Sru * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
16151497Sru *
17151497Sru * $FreeBSD: stable/10/sys/cam/scsi/scsi_all.h 268697 2014-07-15 17:18:50Z mav $
18151497Sru */
19151497Sru
20151497Sru/*
21151497Sru * SCSI general  interface description
22151497Sru */
23151497Sru
24151497Sru#ifndef	_SCSI_SCSI_ALL_H
25151497Sru#define	_SCSI_SCSI_ALL_H 1
26151497Sru
27151497Sru#include <sys/cdefs.h>
28151497Sru#include <machine/stdarg.h>
29151497Sru
30151497Sru#ifdef _KERNEL
31151497Sru/*
32151497Sru * This is the number of seconds we wait for devices to settle after a SCSI
33151497Sru * bus reset.
34151497Sru */
35151497Sruextern int scsi_delay;
36151497Sru#endif /* _KERNEL */
37151497Sru
38151497Sru/*
39151497Sru * SCSI command format
40151497Sru */
41151497Sru
42151497Sru/*
43151497Sru * Define dome bits that are in ALL (or a lot of) scsi commands
44151497Sru */
45104862Sru#define	SCSI_CTL_LINK		0x01
46151497Sru#define	SCSI_CTL_FLAG		0x02
47151497Sru#define	SCSI_CTL_VENDOR		0xC0
48151497Sru#define	SCSI_CMD_LUN		0xA0	/* these two should not be needed */
49104862Sru#define	SCSI_CMD_LUN_SHIFT	5	/* LUN in the cmd is no longer SCSI */
50151497Sru
51151497Sru#define	SCSI_MAX_CDBLEN		16	/*
52151497Sru					 * 16 byte commands are in the
53151497Sru					 * SCSI-3 spec
54151497Sru					 */
55151497Sru#if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN)
56151497Sru#error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN"
57151497Sru#endif
58151497Sru
59151497Sru/* 6byte CDBs special case 0 length to be 256 */
60151497Sru#define	SCSI_CDB6_LEN(len)	((len) == 0 ? 256 : len)
61151497Sru
62151497Sru/*
63151497Sru * This type defines actions to be taken when a particular sense code is
64151497Sru * received.  Right now, these flags are only defined to take up 16 bits,
65151497Sru * but can be expanded in the future if necessary.
66151497Sru */
67151497Srutypedef enum {
68151497Sru	SS_NOP      = 0x000000,	/* Do nothing */
69151497Sru	SS_RETRY    = 0x010000,	/* Retry the command */
70151497Sru	SS_FAIL     = 0x020000,	/* Bail out */
71151497Sru	SS_START    = 0x030000,	/* Send a Start Unit command to the device,
72151497Sru				 * then retry the original command.
73151497Sru				 */
74151497Sru	SS_TUR      = 0x040000,	/* Send a Test Unit Ready command to the
75151497Sru				 * device, then retry the original command.
76151497Sru				 */
77151497Sru	SS_MASK     = 0xff0000
78151497Sru} scsi_sense_action;
79151497Sru
80151497Srutypedef enum {
81151497Sru	SSQ_NONE		= 0x0000,
82151497Sru	SSQ_DECREMENT_COUNT	= 0x0100,  /* Decrement the retry count */
83151497Sru	SSQ_MANY		= 0x0200,  /* send lots of recovery commands */
84151497Sru	SSQ_RANGE		= 0x0400,  /*
85151497Sru					    * This table entry represents the
86151497Sru					    * end of a range of ASCQs that
87104862Sru					    * have identical error actions
88104862Sru					    * and text.
89104862Sru					    */
90104862Sru	SSQ_PRINT_SENSE		= 0x0800,
91104862Sru	SSQ_UA			= 0x1000,  /* Broadcast UA. */
92104862Sru	SSQ_RESCAN		= 0x2000,  /* Rescan target for LUNs. */
93104862Sru	SSQ_LOST		= 0x4000,  /* Destroy the LUNs. */
94104862Sru	SSQ_MASK		= 0xff00
95151497Sru} scsi_sense_action_qualifier;
96104862Sru
97151497Sru/* Mask for error status values */
98151497Sru#define	SS_ERRMASK	0xff
99151497Sru
100151497Sru/* The default, retyable, error action */
101151497Sru#define	SS_RDEF		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
102151497Sru
103151497Sru/* The retyable, error action, with table specified error code */
104104862Sru#define	SS_RET		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
105104862Sru
106104862Sru/* Fatal error action, with table specified error code */
107104862Sru#define	SS_FATAL	SS_FAIL|SSQ_PRINT_SENSE
108104862Sru
109151497Srustruct scsi_generic
110104862Sru{
111104862Sru	u_int8_t opcode;
112104862Sru	u_int8_t bytes[11];
113104862Sru};
114104862Sru
115104862Srustruct scsi_request_sense
116104862Sru{
117104862Sru	u_int8_t opcode;
118104862Sru	u_int8_t byte2;
119104862Sru#define	SRS_DESC	0x01
120104862Sru	u_int8_t unused[2];
121104862Sru	u_int8_t length;
122104862Sru	u_int8_t control;
123104862Sru};
124104862Sru
125104862Srustruct scsi_test_unit_ready
126104862Sru{
127104862Sru	u_int8_t opcode;
128151497Sru	u_int8_t byte2;
129151497Sru	u_int8_t unused[3];
130151497Sru	u_int8_t control;
131104862Sru};
132151497Sru
133151497Srustruct scsi_receive_diag {
134151497Sru	uint8_t opcode;
135151497Sru	uint8_t byte2;
136151497Sru#define SRD_PCV		0x01
137151497Sru	uint8_t page_code;
138151497Sru	uint8_t length[2];
139151497Sru	uint8_t control;
140151497Sru};
141151497Sru
142151497Srustruct scsi_send_diag {
143151497Sru	uint8_t opcode;
144151497Sru	uint8_t byte2;
145151497Sru#define SSD_UNITOFFL				0x01
146151497Sru#define SSD_DEVOFFL				0x02
147151497Sru#define SSD_SELFTEST				0x04
148151497Sru#define SSD_PF					0x10
149151497Sru#define SSD_SELF_TEST_CODE_MASK			0xE0
150151497Sru#define SSD_SELF_TEST_CODE_SHIFT		5
151151497Sru#define		SSD_SELF_TEST_CODE_NONE		0x00
152151497Sru#define		SSD_SELF_TEST_CODE_BG_SHORT	0x01
153151497Sru#define		SSD_SELF_TEST_CODE_BG_EXTENDED	0x02
154151497Sru#define		SSD_SELF_TEST_CODE_BG_ABORT	0x04
155151497Sru#define		SSD_SELF_TEST_CODE_FG_SHORT	0x05
156151497Sru#define		SSD_SELF_TEST_CODE_FG_EXTENDED	0x06
157104862Sru	uint8_t	reserved;
158104862Sru	uint8_t	length[2];
159104862Sru	uint8_t control;
160104862Sru};
161104862Sru
162104862Srustruct scsi_sense
163104862Sru{
164104862Sru	u_int8_t opcode;
165104862Sru	u_int8_t byte2;
166104862Sru	u_int8_t unused[2];
167151497Sru	u_int8_t length;
168104862Sru	u_int8_t control;
169104862Sru};
170104862Sru
171104862Srustruct scsi_inquiry
172104862Sru{
173104862Sru	u_int8_t opcode;
174104862Sru	u_int8_t byte2;
175104862Sru#define	SI_EVPD 	0x01
176104862Sru#define	SI_CMDDT	0x02
177104862Sru	u_int8_t page_code;
178104862Sru	u_int8_t length[2];
179104862Sru	u_int8_t control;
180104862Sru};
181104862Sru
182104862Srustruct scsi_mode_sense_6
183104862Sru{
184104862Sru	u_int8_t opcode;
185151497Sru	u_int8_t byte2;
186104862Sru#define	SMS_DBD				0x08
187104862Sru	u_int8_t page;
188104862Sru#define	SMS_PAGE_CODE 			0x3F
189104862Sru#define	SMS_VENDOR_SPECIFIC_PAGE	0x00
190104862Sru#define	SMS_DISCONNECT_RECONNECT_PAGE	0x02
191104862Sru#define	SMS_FORMAT_DEVICE_PAGE		0x03
192104862Sru#define	SMS_GEOMETRY_PAGE		0x04
193104862Sru#define	SMS_CACHE_PAGE			0x08
194104862Sru#define	SMS_PERIPHERAL_DEVICE_PAGE	0x09
195104862Sru#define	SMS_CONTROL_MODE_PAGE		0x0A
196104862Sru#define	SMS_PROTO_SPECIFIC_PAGE		0x19
197104862Sru#define	SMS_INFO_EXCEPTIONS_PAGE	0x1C
198104862Sru#define	SMS_ALL_PAGES_PAGE		0x3F
199104862Sru#define	SMS_PAGE_CTRL_MASK		0xC0
200104862Sru#define	SMS_PAGE_CTRL_CURRENT 		0x00
201104862Sru#define	SMS_PAGE_CTRL_CHANGEABLE 	0x40
202151497Sru#define	SMS_PAGE_CTRL_DEFAULT 		0x80
203104862Sru#define	SMS_PAGE_CTRL_SAVED 		0xC0
204104862Sru	u_int8_t subpage;
205104862Sru#define	SMS_SUBPAGE_PAGE_0		0x00
206104862Sru#define	SMS_SUBPAGE_ALL			0xff
207104862Sru	u_int8_t length;
208104862Sru	u_int8_t control;
209104862Sru};
210104862Sru
211104862Srustruct scsi_mode_sense_10
212104862Sru{
213104862Sru	u_int8_t opcode;
214104862Sru	u_int8_t byte2;		/* same bits as small version */
215104862Sru#define	SMS10_LLBAA			0x10
216104862Sru	u_int8_t page; 		/* same bits as small version */
217104862Sru	u_int8_t subpage;
218104862Sru	u_int8_t unused[3];
219104862Sru	u_int8_t length[2];
220104862Sru	u_int8_t control;
221104862Sru};
222104862Sru
223104862Srustruct scsi_mode_select_6
224104862Sru{
225104862Sru	u_int8_t opcode;
226151497Sru	u_int8_t byte2;
227104862Sru#define	SMS_SP	0x01
228104862Sru#define	SMS_PF	0x10
229104862Sru	u_int8_t unused[2];
230104862Sru	u_int8_t length;
231104862Sru	u_int8_t control;
232104862Sru};
233104862Sru
234104862Srustruct scsi_mode_select_10
235151497Sru{
236104862Sru	u_int8_t opcode;
237104862Sru	u_int8_t byte2;		/* same bits as small version */
238104862Sru	u_int8_t unused[5];
239104862Sru	u_int8_t length[2];
240104862Sru	u_int8_t control;
241104862Sru};
242104862Sru
243104862Sru/*
244104862Sru * When sending a mode select to a tape drive, the medium type must be 0.
245104862Sru */
246151497Srustruct scsi_mode_hdr_6
247104862Sru{
248104862Sru	u_int8_t datalen;
249104862Sru	u_int8_t medium_type;
250104862Sru	u_int8_t dev_specific;
251104862Sru	u_int8_t block_descr_len;
252104862Sru};
253104862Sru
254104862Srustruct scsi_mode_hdr_10
255151497Sru{
256151497Sru	u_int8_t datalen[2];
257104862Sru	u_int8_t medium_type;
258104862Sru	u_int8_t dev_specific;
259104862Sru	u_int8_t reserved[2];
260104862Sru	u_int8_t block_descr_len[2];
261104862Sru};
262104862Sru
263104862Srustruct scsi_mode_block_descr
264104862Sru{
265104862Sru	u_int8_t density_code;
266104862Sru	u_int8_t num_blocks[3];
267104862Sru	u_int8_t reserved;
268104862Sru	u_int8_t block_len[3];
269104862Sru};
270104862Sru
271104862Srustruct scsi_per_res_in
272104862Sru{
273104862Sru	u_int8_t opcode;
274104862Sru	u_int8_t action;
275104862Sru#define	SPRI_RK	0x00
276104862Sru#define	SPRI_RR	0x01
277151497Sru#define	SPRI_RC	0x02
278151497Sru#define	SPRI_RS	0x03
279151497Sru	u_int8_t reserved[5];
280151497Sru	u_int8_t length[2];
281151497Sru	u_int8_t control;
282151497Sru};
283151497Sru
284151497Srustruct scsi_per_res_in_header
285104862Sru{
286104862Sru	u_int8_t generation[4];
287104862Sru	u_int8_t length[4];
288104862Sru};
289104862Sru
290104862Srustruct scsi_per_res_key
291104862Sru{
292104862Sru	u_int8_t key[8];
293104862Sru};
294104862Sru
295104862Srustruct scsi_per_res_in_keys
296104862Sru{
297104862Sru	struct scsi_per_res_in_header header;
298151497Sru	struct scsi_per_res_key keys[0];
299104862Sru};
300151497Sru
301104862Srustruct scsi_per_res_cap
302104862Sru{
303151497Sru	uint8_t length[2];
304151497Sru	uint8_t flags1;
305104862Sru#define	SPRI_CRH	0x10
306104862Sru#define	SPRI_SIP_C	0x08
307151497Sru#define	SPRI_ATP_C	0x04
308104862Sru#define	SPRI_PTPL_C	0x01
309104862Sru	uint8_t flags2;
310104862Sru#define	SPRI_TMV	0x80
311104862Sru#define	SPRI_ALLOW_MASK	0x70
312104862Sru#define	SPRI_ALLOW_0	0x00
313104862Sru#define	SPRI_ALLOW_1	0x10
314104862Sru#define	SPRI_ALLOW_2	0x20
315104862Sru#define	SPRI_ALLOW_3	0x30
316151497Sru#define	SPRI_PTPL_A	0x01
317104862Sru	uint8_t type_mask[2];
318151497Sru#define	SPRI_TM_WR_EX_AR	0x8000
319104862Sru#define	SPRI_TM_EX_AC_RO	0x4000
320104862Sru#define	SPRI_TM_WR_EX_RO	0x2000
321151497Sru#define	SPRI_TM_EX_AC		0x0800
322151497Sru#define	SPRI_TM_WR_EX		0x0200
323104862Sru#define	SPRI_TM_EX_AC_AR	0x0001
324151497Sru	uint8_t reserved[2];
325104862Sru};
326104862Sru
327151497Srustruct scsi_per_res_in_rsrv_data
328151497Sru{
329151497Sru	uint8_t reservation[8];
330151497Sru	uint8_t obsolete1[4];
331151497Sru	uint8_t reserved;
332151497Sru	uint8_t scopetype;
333151497Sru#define	SPRT_WE    0x01
334151497Sru#define	SPRT_EA    0x03
335151497Sru#define	SPRT_WERO  0x05
336151497Sru#define	SPRT_EARO  0x06
337151497Sru#define	SPRT_WEAR  0x07
338151497Sru#define	SPRT_EAAR  0x08
339151497Sru	uint8_t obsolete2[2];
340151497Sru};
341151497Sru
342151497Srustruct scsi_per_res_in_rsrv
343151497Sru{
344151497Sru	struct scsi_per_res_in_header header;
345151497Sru	struct scsi_per_res_in_rsrv_data data;
346151497Sru};
347151497Sru
348151497Srustruct scsi_per_res_out
349151497Sru{
350151497Sru	u_int8_t opcode;
351151497Sru	u_int8_t action;
352151497Sru#define	SPRO_REGISTER		0x00
353151497Sru#define	SPRO_RESERVE		0x01
354151497Sru#define	SPRO_RELEASE		0x02
355151497Sru#define	SPRO_CLEAR		0x03
356151497Sru#define	SPRO_PREEMPT		0x04
357151497Sru#define	SPRO_PRE_ABO		0x05
358151497Sru#define	SPRO_REG_IGNO		0x06
359151497Sru#define	SPRO_REG_MOVE		0x07
360151497Sru#define	SPRO_ACTION_MASK	0x1f
361151497Sru	u_int8_t scope_type;
362151497Sru#define	SPR_SCOPE_MASK		0xf0
363151497Sru#define	SPR_LU_SCOPE		0x00
364104862Sru#define	SPR_TYPE_MASK		0x0f
365104862Sru#define	SPR_TYPE_WR_EX		0x01
366104862Sru#define	SPR_TYPE_EX_AC		0x03
367104862Sru#define	SPR_TYPE_WR_EX_RO	0x05
368104862Sru#define	SPR_TYPE_EX_AC_RO	0x06
369104862Sru#define	SPR_TYPE_WR_EX_AR	0x07
370104862Sru#define	SPR_TYPE_EX_AC_AR	0x08
371104862Sru	u_int8_t reserved[2];
372104862Sru	u_int8_t length[4];
373104862Sru	u_int8_t control;
374104862Sru};
375151497Sru
376104862Srustruct scsi_per_res_out_parms
377104862Sru{
378104862Sru	struct scsi_per_res_key res_key;
379104862Sru	u_int8_t serv_act_res_key[8];
380104862Sru	u_int8_t obsolete1[4];
381104862Sru	u_int8_t flags;
382104862Sru#define	SPR_SPEC_I_PT		0x08
383104862Sru#define	SPR_ALL_TG_PT		0x04
384151497Sru#define	SPR_APTPL		0x01
385151497Sru	u_int8_t reserved1;
386104862Sru	u_int8_t obsolete2[2];
387104862Sru};
388104862Sru
389104862Sru
390151497Srustruct scsi_log_sense
391151497Sru{
392151497Sru	u_int8_t opcode;
393151497Sru	u_int8_t byte2;
394151497Sru#define	SLS_SP				0x01
395151497Sru#define	SLS_PPC				0x02
396151497Sru	u_int8_t page;
397151497Sru#define	SLS_PAGE_CODE 			0x3F
398151497Sru#define	SLS_ALL_PAGES_PAGE		0x00
399151497Sru#define	SLS_OVERRUN_PAGE		0x01
400151497Sru#define	SLS_ERROR_WRITE_PAGE		0x02
401151497Sru#define	SLS_ERROR_READ_PAGE		0x03
402151497Sru#define	SLS_ERROR_READREVERSE_PAGE	0x04
403151497Sru#define	SLS_ERROR_VERIFY_PAGE		0x05
404151497Sru#define	SLS_ERROR_NONMEDIUM_PAGE	0x06
405151497Sru#define	SLS_ERROR_LASTN_PAGE		0x07
406151497Sru#define	SLS_SELF_TEST_PAGE		0x10
407151497Sru#define	SLS_IE_PAGE			0x2f
408151497Sru#define	SLS_PAGE_CTRL_MASK		0xC0
409151497Sru#define	SLS_PAGE_CTRL_THRESHOLD		0x00
410151497Sru#define	SLS_PAGE_CTRL_CUMULATIVE	0x40
411151497Sru#define	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80
412151497Sru#define	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0
413151497Sru	u_int8_t reserved[2];
414151497Sru	u_int8_t paramptr[2];
415151497Sru	u_int8_t length[2];
416151497Sru	u_int8_t control;
417151497Sru};
418151497Sru
419151497Srustruct scsi_log_select
420151497Sru{
421151497Sru	u_int8_t opcode;
422151497Sru	u_int8_t byte2;
423151497Sru/*	SLS_SP				0x01 */
424151497Sru#define	SLS_PCR				0x02
425151497Sru	u_int8_t page;
426151497Sru/*	SLS_PAGE_CTRL_MASK		0xC0 */
427151497Sru/*	SLS_PAGE_CTRL_THRESHOLD		0x00 */
428151497Sru/*	SLS_PAGE_CTRL_CUMULATIVE	0x40 */
429151497Sru/*	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80 */
430104862Sru/*	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0 */
431104862Sru	u_int8_t reserved[4];
432104862Sru	u_int8_t length[2];
433104862Sru	u_int8_t control;
434104862Sru};
435104862Sru
436104862Srustruct scsi_log_header
437104862Sru{
438104862Sru	u_int8_t page;
439151497Sru	u_int8_t reserved;
440151497Sru	u_int8_t datalen[2];
441151497Sru};
442151497Sru
443151497Srustruct scsi_log_param_header {
444151497Sru	u_int8_t param_code[2];
445151497Sru	u_int8_t param_control;
446151497Sru#define	SLP_LP				0x01
447151497Sru#define	SLP_LBIN			0x02
448151497Sru#define	SLP_TMC_MASK			0x0C
449151497Sru#define	SLP_TMC_ALWAYS			0x00
450104862Sru#define	SLP_TMC_EQUAL			0x04
451151497Sru#define	SLP_TMC_NOTEQUAL		0x08
452104862Sru#define	SLP_TMC_GREATER			0x0C
453151497Sru#define	SLP_ETC				0x10
454151497Sru#define	SLP_TSD				0x20
455151497Sru#define	SLP_DS				0x40
456151497Sru#define	SLP_DU				0x80
457151497Sru	u_int8_t param_len;
458151497Sru};
459151497Sru
460151497Srustruct scsi_control_page {
461151497Sru	u_int8_t page_code;
462104862Sru	u_int8_t page_length;
463104862Sru	u_int8_t rlec;
464104862Sru#define	SCP_RLEC			0x01	/*Report Log Exception Cond*/
465104862Sru#define	SCP_GLTSD			0x02	/*Global Logging target
466104862Sru						  save disable */
467104862Sru#define	SCP_DSENSE			0x04	/*Descriptor Sense */
468151497Sru#define	SCP_DPICZ			0x08	/*Disable Prot. Info Check
469104862Sru						  if Prot. Field is Zero */
470104862Sru#define	SCP_TMF_ONLY			0x10	/*TM Functions Only*/
471104862Sru#define	SCP_TST_MASK			0xE0	/*Task Set Type Mask*/
472104862Sru#define	SCP_TST_ONE			0x00	/*One Task Set*/
473104862Sru#define	SCP_TST_SEPARATE		0x20	/*Separate Task Sets*/
474104862Sru	u_int8_t queue_flags;
475104862Sru#define	SCP_QUEUE_ALG_MASK		0xF0
476104862Sru#define	SCP_QUEUE_ALG_RESTRICTED	0x00
477104862Sru#define	SCP_QUEUE_ALG_UNRESTRICTED	0x10
478104862Sru#define	SCP_NUAR			0x08	/*No UA on release*/
479104862Sru#define	SCP_QUEUE_ERR			0x02	/*Queued I/O aborted for CACs*/
480104862Sru#define	SCP_QUEUE_DQUE			0x01	/*Queued I/O disabled*/
481104862Sru	u_int8_t eca_and_aen;
482104862Sru#define	SCP_EECA			0x80	/*Enable Extended CA*/
483104862Sru#define	SCP_RAC				0x40	/*Report a check*/
484104862Sru#define	SCP_SWP				0x08	/*Software Write Protect*/
485104862Sru#define	SCP_RAENP			0x04	/*Ready AEN Permission*/
486104862Sru#define	SCP_UAAENP			0x02	/*UA AEN Permission*/
487104862Sru#define	SCP_EAENP			0x01	/*Error AEN Permission*/
488104862Sru	u_int8_t flags4;
489151497Sru#define	SCP_ATO				0x80	/*Application tag owner*/
490104862Sru#define	SCP_TAS				0x40	/*Task aborted status*/
491151497Sru#define	SCP_ATMPE			0x20	/*Application tag mode page*/
492151497Sru#define	SCP_RWWP			0x10	/*Reject write without prot*/
493151497Sru	u_int8_t aen_holdoff_period[2];
494151497Sru	u_int8_t busy_timeout_period[2];
495151497Sru	u_int8_t extended_selftest_completion_time[2];
496151497Sru};
497151497Sru
498151497Srustruct scsi_cache_page {
499151497Sru	u_int8_t page_code;
500151497Sru#define	SCHP_PAGE_SAVABLE		0x80	/* Page is savable */
501151497Sru	u_int8_t page_length;
502151497Sru	u_int8_t cache_flags;
503151497Sru#define	SCHP_FLAGS_WCE			0x04	/* Write Cache Enable */
504151497Sru#define	SCHP_FLAGS_MF			0x02	/* Multiplication factor */
505151497Sru#define	SCHP_FLAGS_RCD			0x01	/* Read Cache Disable */
506151497Sru	u_int8_t rw_cache_policy;
507151497Sru	u_int8_t dis_prefetch[2];
508151497Sru	u_int8_t min_prefetch[2];
509151497Sru	u_int8_t max_prefetch[2];
510151497Sru	u_int8_t max_prefetch_ceil[2];
511151497Sru};
512104862Sru
513104862Sru/*
514104862Sru * XXX KDM
515104862Sru * Updated version of the cache page, as of SBC.  Update this to SBC-3 and
516104862Sru * rationalize the two.
517104862Sru */
518104862Srustruct scsi_caching_page {
519104862Sru	uint8_t page_code;
520104862Sru#define	SMS_CACHING_PAGE		0x08
521104862Sru	uint8_t page_length;
522104862Sru	uint8_t flags1;
523104862Sru#define	SCP_IC		0x80
524104862Sru#define	SCP_ABPF	0x40
525104862Sru#define	SCP_CAP		0x20
526104862Sru#define	SCP_DISC	0x10
527104862Sru#define	SCP_SIZE	0x08
528104862Sru#define	SCP_WCE		0x04
529104862Sru#define	SCP_MF		0x02
530104862Sru#define	SCP_RCD		0x01
531104862Sru	uint8_t ret_priority;
532104862Sru	uint8_t disable_pf_transfer_len[2];
533104862Sru	uint8_t min_prefetch[2];
534104862Sru	uint8_t max_prefetch[2];
535104862Sru	uint8_t max_pf_ceiling[2];
536104862Sru	uint8_t flags2;
537104862Sru#define	SCP_FSW		0x80
538151497Sru#define	SCP_LBCSS	0x40
539151497Sru#define	SCP_DRA		0x20
540151497Sru#define	SCP_VS1		0x10
541151497Sru#define	SCP_VS2		0x08
542151497Sru	uint8_t cache_segments;
543151497Sru	uint8_t cache_seg_size[2];
544151497Sru	uint8_t reserved;
545151497Sru	uint8_t non_cache_seg_size[3];
546151497Sru};
547151497Sru
548151497Sru/*
549151497Sru * XXX KDM move this off to a vendor shim.
550151497Sru */
551151497Srustruct copan_power_subpage {
552151497Sru	uint8_t page_code;
553151497Sru#define	PWR_PAGE_CODE		0x00
554104862Sru	uint8_t subpage;
555104862Sru#define	PWR_SUBPAGE_CODE	0x02
556104862Sru	uint8_t page_length[2];
557104862Sru	uint8_t page_version;
558104862Sru#define	PWR_VERSION		    0x01
559151497Sru	uint8_t total_luns;
560104862Sru	uint8_t max_active_luns;
561104862Sru#define	PWR_DFLT_MAX_LUNS	    0x07
562151497Sru	uint8_t reserved[25];
563104862Sru};
564104862Sru
565151497Sru/*
566151497Sru * XXX KDM move this off to a vendor shim.
567104862Sru */
568104862Srustruct copan_aps_subpage {
569104862Sru	uint8_t page_code;
570104862Sru#define	APS_PAGE_CODE		0x00
571104862Sru	uint8_t subpage;
572104862Sru#define	APS_SUBPAGE_CODE	0x03
573104862Sru	uint8_t page_length[2];
574151497Sru	uint8_t page_version;
575151497Sru#define	APS_VERSION		    0x00
576151497Sru	uint8_t lock_active;
577151497Sru#define	APS_LOCK_ACTIVE	    0x01
578151497Sru#define	APS_LOCK_INACTIVE	0x00
579104862Sru	uint8_t reserved[26];
580104862Sru};
581104862Sru
582151497Sru/*
583151497Sru * XXX KDM move this off to a vendor shim.
584151497Sru */
585151497Srustruct copan_debugconf_subpage {
586104862Sru	uint8_t page_code;
587151497Sru#define DBGCNF_PAGE_CODE		0x00
588104862Sru	uint8_t subpage;
589104862Sru#define DBGCNF_SUBPAGE_CODE	0xF0
590104862Sru	uint8_t page_length[2];
591104862Sru	uint8_t page_version;
592104862Sru#define DBGCNF_VERSION			0x00
593104862Sru	uint8_t ctl_time_io_secs[2];
594104862Sru};
595104862Sru
596104862Sru
597104862Srustruct scsi_info_exceptions_page {
598104862Sru	u_int8_t page_code;
599104862Sru#define	SIEP_PAGE_SAVABLE		0x80	/* Page is savable */
600104862Sru	u_int8_t page_length;
601104862Sru	u_int8_t info_flags;
602104862Sru#define	SIEP_FLAGS_PERF			0x80
603104862Sru#define	SIEP_FLAGS_EBF			0x20
604104862Sru#define	SIEP_FLAGS_EWASC		0x10
605104862Sru#define	SIEP_FLAGS_DEXCPT		0x08
606151497Sru#define	SIEP_FLAGS_TEST			0x04
607104862Sru#define	SIEP_FLAGS_EBACKERR		0x02
608104862Sru#define	SIEP_FLAGS_LOGERR		0x01
609104862Sru	u_int8_t mrie;
610104862Sru	u_int8_t interval_timer[4];
611104862Sru	u_int8_t report_count[4];
612104862Sru};
613104862Sru
614104862Srustruct scsi_proto_specific_page {
615104862Sru	u_int8_t page_code;
616104862Sru#define	SPSP_PAGE_SAVABLE		0x80	/* Page is savable */
617151497Sru	u_int8_t page_length;
618151497Sru	u_int8_t protocol;
619151497Sru#define	SPSP_PROTO_FC			0x00
620151497Sru#define	SPSP_PROTO_SPI			0x01
621151497Sru#define	SPSP_PROTO_SSA			0x02
622104862Sru#define	SPSP_PROTO_1394			0x03
623104862Sru#define	SPSP_PROTO_RDMA			0x04
624104862Sru#define	SPSP_PROTO_ISCSI		0x05
625104862Sru#define	SPSP_PROTO_SAS			0x06
626104862Sru#define	SPSP_PROTO_ADT			0x07
627104862Sru#define	SPSP_PROTO_ATA			0x08
628104862Sru#define	SPSP_PROTO_NONE			0x0f
629104862Sru};
630104862Sru
631104862Srustruct scsi_reserve
632104862Sru{
633104862Sru	u_int8_t opcode;
634104862Sru	u_int8_t byte2;
635104862Sru#define	SR_EXTENT	0x01
636104862Sru#define	SR_ID_MASK	0x0e
637104862Sru#define	SR_3RDPTY	0x10
638104862Sru#define	SR_LUN_MASK	0xe0
639104862Sru	u_int8_t resv_id;
640104862Sru	u_int8_t length[2];
641104862Sru	u_int8_t control;
642104862Sru};
643104862Sru
644104862Srustruct scsi_reserve_10 {
645104862Sru	uint8_t	opcode;
646104862Sru	uint8_t	byte2;
647104862Sru#define	SR10_3RDPTY	0x10
648104862Sru#define	SR10_LONGID	0x02
649104862Sru#define	SR10_EXTENT	0x01
650104862Sru	uint8_t resv_id;
651104862Sru	uint8_t thirdparty_id;
652151497Sru	uint8_t reserved[3];
653151497Sru	uint8_t length[2];
654104862Sru	uint8_t control;
655104862Sru};
656104862Sru
657104862Sru
658151497Srustruct scsi_release
659151497Sru{
660151497Sru	u_int8_t opcode;
661151497Sru	u_int8_t byte2;
662151497Sru	u_int8_t resv_id;
663151497Sru	u_int8_t unused[1];
664151497Sru	u_int8_t length;
665151497Sru	u_int8_t control;
666151497Sru};
667151497Sru
668151497Srustruct scsi_release_10 {
669151497Sru	uint8_t opcode;
670151497Sru	uint8_t byte2;
671151497Sru	uint8_t resv_id;
672151497Sru	uint8_t thirdparty_id;
673151497Sru	uint8_t reserved[3];
674151497Sru	uint8_t length[2];
675151497Sru	uint8_t control;
676151497Sru};
677151497Sru
678151497Srustruct scsi_prevent
679151497Sru{
680151497Sru	u_int8_t opcode;
681151497Sru	u_int8_t byte2;
682151497Sru	u_int8_t unused[2];
683151497Sru	u_int8_t how;
684151497Sru	u_int8_t control;
685151497Sru};
686151497Sru#define	PR_PREVENT 0x01
687104862Sru#define	PR_ALLOW   0x00
688104862Sru
689104862Srustruct scsi_sync_cache
690104862Sru{
691104862Sru	u_int8_t opcode;
692151497Sru	u_int8_t byte2;
693104862Sru#define	SSC_IMMED	0x02
694151497Sru#define	SSC_RELADR	0x01
695151497Sru	u_int8_t begin_lba[4];
696151497Sru	u_int8_t reserved;
697151497Sru	u_int8_t lb_count[2];
698104862Sru	u_int8_t control;
699151497Sru};
700151497Sru
701151497Srustruct scsi_sync_cache_16
702151497Sru{
703151497Sru	uint8_t opcode;
704104862Sru	uint8_t byte2;
705151497Sru	uint8_t begin_lba[8];
706151497Sru	uint8_t lb_count[4];
707151497Sru	uint8_t reserved;
708151497Sru	uint8_t control;
709151497Sru};
710151497Sru
711151497Srustruct scsi_format {
712151497Sru	uint8_t opcode;
713151497Sru	uint8_t byte2;
714104862Sru#define	SF_LONGLIST		0x20
715151497Sru#define	SF_FMTDATA		0x10
716151497Sru#define	SF_CMPLIST		0x08
717104862Sru#define	SF_FORMAT_MASK		0x07
718104862Sru#define	SF_FORMAT_BLOCK		0x00
719104862Sru#define	SF_FORMAT_LONG_BLOCK	0x03
720104862Sru#define	SF_FORMAT_BFI		0x04
721104862Sru#define	SF_FORMAT_PHYS		0x05
722104862Sru	uint8_t vendor;
723104862Sru	uint8_t interleave[2];
724104862Sru	uint8_t control;
725104862Sru};
726104862Sru
727104862Srustruct scsi_format_header_short {
728104862Sru	uint8_t reserved;
729104862Sru#define	SF_DATA_FOV	0x80
730104862Sru#define	SF_DATA_DPRY	0x40
731104862Sru#define	SF_DATA_DCRT	0x20
732104862Sru#define	SF_DATA_STPF	0x10
733104862Sru#define	SF_DATA_IP	0x08
734104862Sru#define	SF_DATA_DSP	0x04
735104862Sru#define	SF_DATA_IMMED	0x02
736104862Sru#define	SF_DATA_VS	0x01
737104862Sru	uint8_t byte2;
738104862Sru	uint8_t defect_list_len[2];
739104862Sru};
740104862Sru
741104862Srustruct scsi_format_header_long {
742104862Sru	uint8_t reserved;
743104862Sru	uint8_t byte2;
744104862Sru	uint8_t reserved2[2];
745104862Sru	uint8_t defect_list_len[4];
746104862Sru};
747104862Sru
748104862Srustruct scsi_changedef
749104862Sru{
750104862Sru	u_int8_t opcode;
751104862Sru	u_int8_t byte2;
752104862Sru	u_int8_t unused1;
753104862Sru	u_int8_t how;
754104862Sru	u_int8_t unused[4];
755104862Sru	u_int8_t datalen;
756104862Sru	u_int8_t control;
757104862Sru};
758104862Sru
759104862Srustruct scsi_read_buffer
760104862Sru{
761104862Sru	u_int8_t opcode;
762104862Sru	u_int8_t byte2;
763104862Sru#define	RWB_MODE		0x1F
764104862Sru#define	RWB_MODE_HDR_DATA	0x00
765104862Sru#define	RWB_MODE_VENDOR		0x01
766104862Sru#define	RWB_MODE_DATA		0x02
767104862Sru#define	RWB_MODE_DESCR		0x03
768104862Sru#define	RWB_MODE_DOWNLOAD	0x04
769104862Sru#define	RWB_MODE_DOWNLOAD_SAVE	0x05
770104862Sru#define	RWB_MODE_ECHO		0x0A
771104862Sru#define	RWB_MODE_ECHO_DESCR	0x0B
772104862Sru#define	RWB_MODE_ERROR_HISTORY	0x1C
773104862Sru        u_int8_t buffer_id;
774104862Sru        u_int8_t offset[3];
775104862Sru        u_int8_t length[3];
776104862Sru        u_int8_t control;
777104862Sru};
778104862Sru
779104862Srustruct scsi_write_buffer
780104862Sru{
781104862Sru	u_int8_t opcode;
782104862Sru	u_int8_t byte2;
783104862Sru	u_int8_t buffer_id;
784104862Sru	u_int8_t offset[3];
785104862Sru	u_int8_t length[3];
786104862Sru	u_int8_t control;
787104862Sru};
788104862Sru
789104862Srustruct scsi_rw_6
790104862Sru{
791104862Sru	u_int8_t opcode;
792104862Sru	u_int8_t addr[3];
793104862Sru/* only 5 bits are valid in the MSB address byte */
794104862Sru#define	SRW_TOPADDR	0x1F
795104862Sru	u_int8_t length;
796104862Sru	u_int8_t control;
797104862Sru};
798104862Sru
799104862Srustruct scsi_rw_10
800104862Sru{
801104862Sru	u_int8_t opcode;
802104862Sru#define	SRW10_RELADDR	0x01
803104862Sru/* EBP defined for WRITE(10) only */
804104862Sru#define	SRW10_EBP	0x04
805104862Sru#define	SRW10_FUA	0x08
806104862Sru#define	SRW10_DPO	0x10
807104862Sru	u_int8_t byte2;
808104862Sru	u_int8_t addr[4];
809104862Sru	u_int8_t reserved;
810104862Sru	u_int8_t length[2];
811104862Sru	u_int8_t control;
812104862Sru};
813104862Sru
814104862Srustruct scsi_rw_12
815104862Sru{
816104862Sru	u_int8_t opcode;
817104862Sru#define	SRW12_RELADDR	0x01
818104862Sru#define	SRW12_FUA	0x08
819104862Sru#define	SRW12_DPO	0x10
820104862Sru	u_int8_t byte2;
821104862Sru	u_int8_t addr[4];
822104862Sru	u_int8_t length[4];
823104862Sru	u_int8_t reserved;
824104862Sru	u_int8_t control;
825104862Sru};
826151497Sru
827151497Srustruct scsi_rw_16
828151497Sru{
829151497Sru	u_int8_t opcode;
830151497Sru#define	SRW16_RELADDR	0x01
831151497Sru#define	SRW16_FUA	0x08
832151497Sru#define	SRW16_DPO	0x10
833104862Sru	u_int8_t byte2;
834104862Sru	u_int8_t addr[8];
835104862Sru	u_int8_t length[4];
836104862Sru	u_int8_t reserved;
837104862Sru	u_int8_t control;
838104862Sru};
839104862Sru
840104862Srustruct scsi_write_same_10
841104862Sru{
842104862Sru	uint8_t	opcode;
843104862Sru	uint8_t	byte2;
844104862Sru#define	SWS_LBDATA	0x02
845151497Sru#define	SWS_PBDATA	0x04
846151497Sru#define	SWS_UNMAP	0x08
847151497Sru#define	SWS_ANCHOR	0x10
848151497Sru	uint8_t	addr[4];
849151497Sru	uint8_t	group;
850151497Sru	uint8_t	length[2];
851151497Sru	uint8_t	control;
852151497Sru};
853151497Sru
854151497Srustruct scsi_write_same_16
855151497Sru{
856151497Sru	uint8_t	opcode;
857151497Sru	uint8_t	byte2;
858151497Sru	uint8_t	addr[8];
859151497Sru	uint8_t	length[4];
860151497Sru	uint8_t	group;
861151497Sru	uint8_t	control;
862151497Sru};
863104862Sru
864104862Srustruct scsi_unmap
865151497Sru{
866151497Sru	uint8_t	opcode;
867151497Sru	uint8_t	byte2;
868151497Sru#define	SU_ANCHOR	0x01
869151497Sru	uint8_t	reserved[4];
870104862Sru	uint8_t	group;
871104862Sru	uint8_t	length[2];
872104862Sru	uint8_t	control;
873104862Sru};
874151497Sru
875151497Srustruct scsi_unmap_header
876151497Sru{
877151497Sru	uint8_t	length[2];
878151497Sru	uint8_t	desc_length[2];
879104862Sru	uint8_t	reserved[4];
880104862Sru};
881104862Sru
882104862Srustruct scsi_unmap_desc
883104862Sru{
884104862Sru	uint8_t	lba[8];
885104862Sru	uint8_t	length[4];
886104862Sru	uint8_t	reserved[4];
887104862Sru};
888104862Sru
889104862Srustruct scsi_write_verify_10
890104862Sru{
891104862Sru	uint8_t	opcode;
892104862Sru	uint8_t	byte2;
893104862Sru#define	SWV_BYTCHK		0x02
894104862Sru#define	SWV_DPO			0x10
895104862Sru#define	SWV_WRPROECT_MASK	0xe0
896104862Sru	uint8_t	addr[4];
897104862Sru	uint8_t	group;
898104862Sru	uint8_t length[2];
899104862Sru	uint8_t	control;
900104862Sru};
901104862Sru
902104862Srustruct scsi_write_verify_12
903104862Sru{
904104862Sru	uint8_t	opcode;
905104862Sru	uint8_t	byte2;
906104862Sru	uint8_t	addr[4];
907151497Sru	uint8_t	length[4];
908104862Sru	uint8_t	group;
909104862Sru	uint8_t	control;
910104862Sru};
911104862Sru
912104862Srustruct scsi_write_verify_16
913151497Sru{
914151497Sru	uint8_t	opcode;
915151497Sru	uint8_t	byte2;
916151497Sru	uint8_t	addr[8];
917104862Sru	uint8_t	length[4];
918104862Sru	uint8_t	group;
919104862Sru	uint8_t	control;
920104862Sru};
921104862Sru
922151497Sru
923104862Srustruct scsi_start_stop_unit
924151497Sru{
925104862Sru	u_int8_t opcode;
926104862Sru	u_int8_t byte2;
927104862Sru#define	SSS_IMMED		0x01
928104862Sru	u_int8_t reserved[2];
929104862Sru	u_int8_t how;
930104862Sru#define	SSS_START		0x01
931104862Sru#define	SSS_LOEJ		0x02
932104862Sru#define	SSS_PC_MASK		0xf0
933104862Sru#define	SSS_PC_START_VALID	0x00
934104862Sru#define	SSS_PC_ACTIVE		0x10
935104862Sru#define	SSS_PC_IDLE		0x20
936104862Sru#define	SSS_PC_STANDBY		0x30
937104862Sru#define	SSS_PC_LU_CONTROL	0x70
938104862Sru#define	SSS_PC_FORCE_IDLE_0	0xa0
939104862Sru#define	SSS_PC_FORCE_STANDBY_0	0xb0
940104862Sru	u_int8_t control;
941104862Sru};
942104862Sru
943104862Srustruct ata_pass_12 {
944104862Sru	u_int8_t opcode;
945104862Sru	u_int8_t protocol;
946104862Sru#define	AP_PROTO_HARD_RESET	(0x00 << 1)
947104862Sru#define	AP_PROTO_SRST		(0x01 << 1)
948104862Sru#define	AP_PROTO_NON_DATA	(0x03 << 1)
949104862Sru#define	AP_PROTO_PIO_IN		(0x04 << 1)
950104862Sru#define	AP_PROTO_PIO_OUT	(0x05 << 1)
951104862Sru#define	AP_PROTO_DMA		(0x06 << 1)
952104862Sru#define	AP_PROTO_DMA_QUEUED	(0x07 << 1)
953104862Sru#define	AP_PROTO_DEVICE_DIAG	(0x08 << 1)
954104862Sru#define	AP_PROTO_DEVICE_RESET	(0x09 << 1)
955104862Sru#define	AP_PROTO_UDMA_IN	(0x0a << 1)
956104862Sru#define	AP_PROTO_UDMA_OUT	(0x0b << 1)
957104862Sru#define	AP_PROTO_FPDMA		(0x0c << 1)
958104862Sru#define	AP_PROTO_RESP_INFO	(0x0f << 1)
959104862Sru#define	AP_MULTI	0xe0
960104862Sru	u_int8_t flags;
961104862Sru#define	AP_T_LEN	0x03
962104862Sru#define	AP_BB		0x04
963104862Sru#define	AP_T_DIR	0x08
964104862Sru#define	AP_CK_COND	0x20
965104862Sru#define	AP_OFFLINE	0x60
966104862Sru	u_int8_t features;
967104862Sru	u_int8_t sector_count;
968104862Sru	u_int8_t lba_low;
969104862Sru	u_int8_t lba_mid;
970104862Sru	u_int8_t lba_high;
971104862Sru	u_int8_t device;
972104862Sru	u_int8_t command;
973104862Sru	u_int8_t reserved;
974104862Sru	u_int8_t control;
975104862Sru};
976104862Sru
977104862Srustruct scsi_maintenance_in
978104862Sru{
979104862Sru        uint8_t  opcode;
980104862Sru        uint8_t  byte2;
981104862Sru#define SERVICE_ACTION_MASK  0x1f
982104862Sru#define SA_RPRT_TRGT_GRP     0x0a
983104862Sru        uint8_t  reserved[4];
984104862Sru	uint8_t  length[4];
985104862Sru	uint8_t  reserved1;
986104862Sru	uint8_t  control;
987104862Sru};
988104862Sru
989104862Srustruct scsi_report_supported_opcodes
990104862Sru{
991151497Sru        uint8_t  opcode;
992104862Sru        uint8_t  service_action;
993104862Sru        uint8_t  options;
994151497Sru#define RSO_RCTD		0x80
995151497Sru#define RSO_OPTIONS_MASK	0x07
996151497Sru#define RSO_OPTIONS_ALL		0x00
997151497Sru#define RSO_OPTIONS_OC		0x01
998151497Sru#define RSO_OPTIONS_OC_SA	0x02
999151497Sru        uint8_t  requested_opcode;
1000151497Sru        uint8_t  requested_service_action[2];
1001151497Sru	uint8_t  length[4];
1002151497Sru	uint8_t  reserved1;
1003151497Sru	uint8_t  control;
1004151497Sru};
1005151497Sru
1006151497Srustruct scsi_report_supported_opcodes_timeout
1007151497Sru{
1008151497Sru	uint8_t  length[2];
1009151497Sru	uint8_t  reserved;
1010104862Sru	uint8_t  cmd_specific;
1011104862Sru	uint8_t  nominal_time[4];
1012104862Sru	uint8_t  recommended_time[4];
1013104862Sru};
1014104862Sru
1015104862Srustruct scsi_report_supported_opcodes_descr
1016104862Sru{
1017104862Sru	uint8_t  opcode;
1018104862Sru	uint8_t  reserved;
1019104862Sru	uint8_t  service_action[2];
1020104862Sru	uint8_t  reserved2;
1021151497Sru	uint8_t  flags;
1022104862Sru#define RSO_SERVACTV		0x01
1023104862Sru#define RSO_CTDP		0x02
1024104862Sru	uint8_t  cdb_length[2];
1025104862Sru	struct scsi_report_supported_opcodes_timeout timeout[0];
1026104862Sru};
1027104862Sru
1028104862Srustruct scsi_report_supported_opcodes_all
1029104862Sru{
1030151497Sru	uint8_t  length[4];
1031151497Sru	struct scsi_report_supported_opcodes_descr descr[0];
1032151497Sru};
1033151497Sru
1034151497Srustruct scsi_report_supported_opcodes_one
1035151497Sru{
1036151497Sru	uint8_t  reserved;
1037104862Sru	uint8_t  support;
1038151497Sru#define RSO_ONE_CTDP		0x80
1039151497Sru	uint8_t  cdb_length[2];
1040104862Sru	uint8_t  cdb_usage[];
1041104862Sru};
1042104862Sru
1043104862Srustruct scsi_report_supported_tmf
1044104862Sru{
1045104862Sru	uint8_t  opcode;
1046104862Sru	uint8_t  service_action;
1047104862Sru	uint8_t  reserved[4];
1048104862Sru	uint8_t  length[4];
1049104862Sru	uint8_t  reserved1;
1050104862Sru	uint8_t  control;
1051104862Sru};
1052104862Sru
1053104862Srustruct scsi_report_supported_tmf_data
1054104862Sru{
1055104862Sru	uint8_t  byte1;
1056104862Sru#define RST_WAKES		0x01
1057104862Sru#define RST_TRS			0x02
1058104862Sru#define RST_QTS			0x04
1059104862Sru#define RST_LURS		0x08
1060104862Sru#define RST_CTSS		0x10
1061104862Sru#define RST_CACAS		0x20
1062104862Sru#define RST_ATSS		0x40
1063104862Sru#define RST_ATS			0x80
1064104862Sru	uint8_t  byte2;
1065104862Sru#define RST_ITNRS		0x01
1066104862Sru#define RST_QTSS		0x02
1067104862Sru#define RST_QAES		0x04
1068104862Sru	uint8_t  reserved[2];
1069104862Sru};
1070104862Sru
1071104862Srustruct scsi_report_timestamp
1072104862Sru{
1073104862Sru	uint8_t  opcode;
1074104862Sru	uint8_t  service_action;
1075104862Sru	uint8_t  reserved[4];
1076104862Sru	uint8_t  length[4];
1077104862Sru	uint8_t  reserved1;
1078104862Sru	uint8_t  control;
1079104862Sru};
1080104862Sru
1081104862Srustruct scsi_report_timestamp_data
1082104862Sru{
1083104862Sru	uint8_t  length[2];
1084104862Sru	uint8_t  origin;
1085104862Sru#define RTS_ORIG_MASK		0x00
1086104862Sru#define RTS_ORIG_ZERO		0x00
1087104862Sru#define RTS_ORIG_SET		0x02
1088104862Sru#define RTS_ORIG_OUTSIDE	0x03
1089104862Sru	uint8_t  reserved;
1090104862Sru	uint8_t  timestamp[6];
1091104862Sru	uint8_t  reserve2[2];
1092104862Sru};
1093104862Sru
1094104862Srustruct ata_pass_16 {
1095104862Sru	u_int8_t opcode;
1096104862Sru	u_int8_t protocol;
1097104862Sru#define	AP_EXTEND	0x01
1098104862Sru	u_int8_t flags;
1099104862Sru#define	AP_FLAG_TLEN_NO_DATA	(0 << 0)
1100104862Sru#define	AP_FLAG_TLEN_FEAT	(1 << 0)
1101104862Sru#define	AP_FLAG_TLEN_SECT_CNT	(2 << 0)
1102104862Sru#define	AP_FLAG_TLEN_STPSIU	(3 << 0)
1103104862Sru#define	AP_FLAG_BYT_BLOK_BYTES	(0 << 2)
1104104862Sru#define	AP_FLAG_BYT_BLOK_BLOCKS	(1 << 2)
1105104862Sru#define	AP_FLAG_TDIR_TO_DEV	(0 << 3)
1106104862Sru#define	AP_FLAG_TDIR_FROM_DEV	(1 << 3)
1107104862Sru#define	AP_FLAG_CHK_COND	(1 << 5)
1108104862Sru	u_int8_t features_ext;
1109104862Sru	u_int8_t features;
1110104862Sru	u_int8_t sector_count_ext;
1111104862Sru	u_int8_t sector_count;
1112104862Sru	u_int8_t lba_low_ext;
1113104862Sru	u_int8_t lba_low;
1114104862Sru	u_int8_t lba_mid_ext;
1115104862Sru	u_int8_t lba_mid;
1116104862Sru	u_int8_t lba_high_ext;
1117104862Sru	u_int8_t lba_high;
1118104862Sru	u_int8_t device;
1119104862Sru	u_int8_t command;
1120104862Sru	u_int8_t control;
1121104862Sru};
1122104862Sru
1123104862Sru#define	SC_SCSI_1 0x01
1124104862Sru#define	SC_SCSI_2 0x03
1125104862Sru
1126104862Sru/*
1127104862Sru * Opcodes
1128104862Sru */
1129104862Sru
1130104862Sru#define	TEST_UNIT_READY		0x00
1131104862Sru#define	REQUEST_SENSE		0x03
1132104862Sru#define	READ_6			0x08
1133104862Sru#define	WRITE_6			0x0A
1134104862Sru#define	INQUIRY			0x12
1135104862Sru#define	MODE_SELECT_6		0x15
1136104862Sru#define	MODE_SENSE_6		0x1A
1137104862Sru#define	START_STOP_UNIT		0x1B
1138104862Sru#define	START_STOP		0x1B
1139104862Sru#define	RESERVE      		0x16
1140104862Sru#define	RELEASE      		0x17
1141104862Sru#define	RECEIVE_DIAGNOSTIC	0x1C
1142104862Sru#define	SEND_DIAGNOSTIC		0x1D
1143104862Sru#define	PREVENT_ALLOW		0x1E
1144104862Sru#define	READ_CAPACITY		0x25
1145104862Sru#define	READ_10			0x28
1146104862Sru#define	WRITE_10		0x2A
1147104862Sru#define	POSITION_TO_ELEMENT	0x2B
1148104862Sru#define	WRITE_VERIFY_10		0x2E
1149104862Sru#define	VERIFY_10		0x2F
1150104862Sru#define	SYNCHRONIZE_CACHE	0x35
1151104862Sru#define	READ_DEFECT_DATA_10	0x37
1152104862Sru#define	WRITE_BUFFER            0x3B
1153104862Sru#define	READ_BUFFER             0x3C
1154104862Sru#define	CHANGE_DEFINITION	0x40
1155104862Sru#define	WRITE_SAME_10		0x41
1156104862Sru#define	UNMAP			0x42
1157104862Sru#define	LOG_SELECT		0x4C
1158104862Sru#define	LOG_SENSE		0x4D
1159151497Sru#define	MODE_SELECT_10		0x55
1160104862Sru#define	RESERVE_10		0x56
1161104862Sru#define	RELEASE_10		0x57
1162104862Sru#define	MODE_SENSE_10		0x5A
1163104862Sru#define	PERSISTENT_RES_IN	0x5E
1164104862Sru#define	PERSISTENT_RES_OUT	0x5F
1165104862Sru#define	ATA_PASS_16		0x85
1166104862Sru#define	READ_16			0x88
1167104862Sru#define	COMPARE_AND_WRITE	0x89
1168104862Sru#define	WRITE_16		0x8A
1169104862Sru#define	WRITE_VERIFY_16		0x8E
1170104862Sru#define	VERIFY_16		0x8F
1171104862Sru#define	SYNCHRONIZE_CACHE_16	0x91
1172104862Sru#define	WRITE_SAME_16		0x93
1173151497Sru#define	SERVICE_ACTION_IN	0x9E
1174151497Sru#define	REPORT_LUNS		0xA0
1175151497Sru#define	ATA_PASS_12		0xA1
1176104862Sru#define	MAINTENANCE_IN		0xA3
1177151497Sru#define	MAINTENANCE_OUT		0xA4
1178151497Sru#define	MOVE_MEDIUM     	0xA5
1179104862Sru#define	READ_12			0xA8
1180104862Sru#define	WRITE_12		0xAA
1181151497Sru#define	WRITE_VERIFY_12		0xAE
1182151497Sru#define	VERIFY_12		0xAF
1183104862Sru#define	READ_ELEMENT_STATUS	0xB8
1184151497Sru#define	READ_CD			0xBE
1185151497Sru
1186104862Sru/* Maintenance In Service Action Codes */
1187104862Sru#define	REPORT_IDENTIFYING_INFRMATION		0x05
1188104862Sru#define	REPORT_TARGET_PORT_GROUPS		0x0A
1189151497Sru#define	REPORT_ALIASES				0x0B
1190104862Sru#define	REPORT_SUPPORTED_OPERATION_CODES	0x0C
1191104862Sru#define	REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS	0x0D
1192151497Sru#define	REPORT_PRIORITY				0x0E
1193151497Sru#define	REPORT_TIMESTAMP			0x0F
1194104862Sru#define	MANAGEMENT_PROTOCOL_IN			0x10
1195104862Sru/* Maintenance Out Service Action Codes */
1196151497Sru#define	SET_IDENTIFY_INFORMATION		0x06
1197151497Sru#define	SET_TARGET_PORT_GROUPS			0x0A
1198151497Sru#define	CHANGE_ALIASES				0x0B
1199151497Sru#define	SET_PRIORITY				0x0E
1200151497Sru#define	SET_TIMESTAMP				0x0F
1201151497Sru#define	MANGAEMENT_PROTOCOL_OUT			0x10
1202151497Sru
1203151497Sru/*
1204151497Sru * Device Types
1205151497Sru */
1206151497Sru#define	T_DIRECT	0x00
1207151497Sru#define	T_SEQUENTIAL	0x01
1208151497Sru#define	T_PRINTER	0x02
1209151497Sru#define	T_PROCESSOR	0x03
1210151497Sru#define	T_WORM		0x04
1211151497Sru#define	T_CDROM		0x05
1212151497Sru#define	T_SCANNER	0x06
1213151497Sru#define	T_OPTICAL 	0x07
1214151497Sru#define	T_CHANGER	0x08
1215151497Sru#define	T_COMM		0x09
1216151497Sru#define	T_ASC0		0x0a
1217151497Sru#define	T_ASC1		0x0b
1218151497Sru#define	T_STORARRAY	0x0c
1219151497Sru#define	T_ENCLOSURE	0x0d
1220151497Sru#define	T_RBC		0x0e
1221151497Sru#define	T_OCRW		0x0f
1222151497Sru#define	T_OSD		0x11
1223151497Sru#define	T_ADC		0x12
1224151497Sru#define	T_NODEVICE	0x1f
1225151497Sru#define	T_ANY		0xff	/* Used in Quirk table matches */
1226151497Sru
1227151497Sru#define	T_REMOV		1
1228151497Sru#define	T_FIXED		0
1229151497Sru
1230151497Sru/*
1231151497Sru * This length is the initial inquiry length used by the probe code, as
1232151497Sru * well as the length necessary for scsi_print_inquiry() to function
1233151497Sru * correctly.  If either use requires a different length in the future,
1234151497Sru * the two values should be de-coupled.
1235151497Sru */
1236151497Sru#define	SHORT_INQUIRY_LENGTH	36
1237151497Sru
1238151497Srustruct scsi_inquiry_data
1239151497Sru{
1240151497Sru	u_int8_t device;
1241151497Sru#define	SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
1242151497Sru#define	SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
1243151497Sru#define	SID_QUAL_LU_CONNECTED	0x00	/*
1244151497Sru					 * The specified peripheral device
1245151497Sru					 * type is currently connected to
1246151497Sru					 * logical unit.  If the target cannot
1247151497Sru					 * determine whether or not a physical
1248151497Sru					 * device is currently connected, it
1249151497Sru					 * shall also use this peripheral
1250151497Sru					 * qualifier when returning the INQUIRY
1251151497Sru					 * data.  This peripheral qualifier
1252151497Sru					 * does not mean that the device is
1253151497Sru					 * ready for access by the initiator.
1254151497Sru					 */
1255151497Sru#define	SID_QUAL_LU_OFFLINE	0x01	/*
1256151497Sru					 * The target is capable of supporting
1257151497Sru					 * the specified peripheral device type
1258151497Sru					 * on this logical unit; however, the
1259151497Sru					 * physical device is not currently
1260104862Sru					 * connected to this logical unit.
1261104862Sru					 */
1262104862Sru#define	SID_QUAL_RSVD		0x02
1263151497Sru#define	SID_QUAL_BAD_LU		0x03	/*
1264151497Sru					 * The target is not capable of
1265151497Sru					 * supporting a physical device on
1266151497Sru					 * this logical unit. For this
1267151497Sru					 * peripheral qualifier the peripheral
1268104862Sru					 * device type shall be set to 1Fh to
1269104862Sru					 * provide compatibility with previous
1270104862Sru					 * versions of SCSI. All other
1271104862Sru					 * peripheral device type values are
1272104862Sru					 * reserved for this peripheral
1273104862Sru					 * qualifier.
1274104862Sru					 */
1275104862Sru#define	SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
1276104862Sru	u_int8_t dev_qual2;
1277104862Sru#define	SID_QUAL2	0x7F
1278104862Sru#define	SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
1279104862Sru	u_int8_t version;
1280104862Sru#define	SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
1281104862Sru#define		SCSI_REV_0		0
1282104862Sru#define		SCSI_REV_CCS		1
1283151497Sru#define		SCSI_REV_2		2
1284151497Sru#define		SCSI_REV_SPC		3
1285104862Sru#define		SCSI_REV_SPC2		4
1286151497Sru#define		SCSI_REV_SPC3		5
1287151497Sru#define		SCSI_REV_SPC4		6
1288104862Sru
1289104862Sru#define	SID_ECMA	0x38
1290151497Sru#define	SID_ISO		0xC0
1291151497Sru	u_int8_t response_format;
1292104862Sru#define	SID_AENC	0x80
1293104862Sru#define	SID_TrmIOP	0x40
1294151497Sru#define	SID_NormACA	0x20
1295104862Sru#define	SID_HiSup	0x10
1296104862Sru	u_int8_t additional_length;
1297151497Sru#define	SID_ADDITIONAL_LENGTH(iqd)					\
1298151497Sru	((iqd)->additional_length +					\
1299151497Sru	__offsetof(struct scsi_inquiry_data, additional_length) + 1)
1300151497Sru	u_int8_t spc3_flags;
1301151497Sru#define	SPC3_SID_PROTECT	0x01
1302151497Sru#define	SPC3_SID_3PC		0x08
1303104862Sru#define	SPC3_SID_TPGS_MASK	0x30
1304104862Sru#define	SPC3_SID_TPGS_IMPLICIT	0x10
1305104862Sru#define	SPC3_SID_TPGS_EXPLICIT	0x20
1306104862Sru#define	SPC3_SID_ACC		0x40
1307104862Sru#define	SPC3_SID_SCCS		0x80
1308104862Sru	u_int8_t spc2_flags;
1309104862Sru#define	SPC2_SID_ADDR16		0x01
1310104862Sru#define	SPC2_SID_MChngr 	0x08
1311104862Sru#define	SPC2_SID_MultiP 	0x10
1312151497Sru#define	SPC2_SID_EncServ	0x40
1313104862Sru#define	SPC2_SID_BQueue		0x80
1314151497Sru
1315104862Sru#define	INQ_DATA_TQ_ENABLED(iqd)				\
1316104862Sru    ((SID_ANSI_REV(iqd) < SCSI_REV_SPC2)? ((iqd)->flags & SID_CmdQue) :	\
1317104862Sru    (((iqd)->flags & SID_CmdQue) && !((iqd)->spc2_flags & SPC2_SID_BQueue)) || \
1318104862Sru    (!((iqd)->flags & SID_CmdQue) && ((iqd)->spc2_flags & SPC2_SID_BQueue)))
1319104862Sru
1320104862Sru	u_int8_t flags;
1321104862Sru#define	SID_SftRe	0x01
1322104862Sru#define	SID_CmdQue	0x02
1323104862Sru#define	SID_Linked	0x08
1324151497Sru#define	SID_Sync	0x10
1325104862Sru#define	SID_WBus16	0x20
1326104862Sru#define	SID_WBus32	0x40
1327104862Sru#define	SID_RelAdr	0x80
1328104862Sru#define	SID_VENDOR_SIZE   8
1329104862Sru	char	 vendor[SID_VENDOR_SIZE];
1330104862Sru#define	SID_PRODUCT_SIZE  16
1331104862Sru	char	 product[SID_PRODUCT_SIZE];
1332104862Sru#define	SID_REVISION_SIZE 4
1333104862Sru	char	 revision[SID_REVISION_SIZE];
1334104862Sru	/*
1335104862Sru	 * The following fields were taken from SCSI Primary Commands - 2
1336104862Sru	 * (SPC-2) Revision 14, Dated 11 November 1999
1337104862Sru	 */
1338104862Sru#define	SID_VENDOR_SPECIFIC_0_SIZE	20
1339104862Sru	u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
1340104862Sru	/*
1341104862Sru	 * An extension of SCSI Parallel Specific Values
1342104862Sru	 */
1343104862Sru#define	SID_SPI_IUS		0x01
1344104862Sru#define	SID_SPI_QAS		0x02
1345104862Sru#define	SID_SPI_CLOCK_ST	0x00
1346104862Sru#define	SID_SPI_CLOCK_DT	0x04
1347104862Sru#define	SID_SPI_CLOCK_DT_ST	0x0C
1348104862Sru#define	SID_SPI_MASK		0x0F
1349151497Sru	u_int8_t spi3data;
1350151497Sru	u_int8_t reserved2;
1351151497Sru	/*
1352151497Sru	 * Version Descriptors, stored 2 byte values.
1353151497Sru	 */
1354151497Sru	u_int8_t version1[2];
1355151497Sru	u_int8_t version2[2];
1356151497Sru	u_int8_t version3[2];
1357151497Sru	u_int8_t version4[2];
1358151497Sru	u_int8_t version5[2];
1359151497Sru	u_int8_t version6[2];
1360151497Sru	u_int8_t version7[2];
1361151497Sru	u_int8_t version8[2];
1362151497Sru
1363151497Sru	u_int8_t reserved3[22];
1364151497Sru
1365151497Sru#define	SID_VENDOR_SPECIFIC_1_SIZE	160
1366151497Sru	u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
1367151497Sru};
1368151497Sru
1369151497Sru/*
1370151497Sru * This structure is more suited to initiator operation, because the
1371151497Sru * maximum number of supported pages is already allocated.
1372151497Sru */
1373151497Srustruct scsi_vpd_supported_page_list
1374151497Sru{
1375151497Sru	u_int8_t device;
1376151497Sru	u_int8_t page_code;
1377151497Sru#define	SVPD_SUPPORTED_PAGE_LIST	0x00
1378151497Sru#define	SVPD_SUPPORTED_PAGES_HDR_LEN	4
1379151497Sru	u_int8_t reserved;
1380151497Sru	u_int8_t length;	/* number of VPD entries */
1381151497Sru#define	SVPD_SUPPORTED_PAGES_SIZE	251
1382151497Sru	u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
1383151497Sru};
1384151497Sru
1385151497Sru/*
1386104862Sru * This structure is more suited to target operation, because the
1387104862Sru * number of supported pages is left to the user to allocate.
1388104862Sru */
1389104862Srustruct scsi_vpd_supported_pages
1390104862Sru{
1391104862Sru	u_int8_t device;
1392151497Sru	u_int8_t page_code;
1393151497Sru	u_int8_t reserved;
1394151497Sru#define	SVPD_SUPPORTED_PAGES	0x00
1395151497Sru	u_int8_t length;
1396151497Sru	u_int8_t page_list[0];
1397151497Sru};
1398151497Sru
1399151497Sru
1400151497Srustruct scsi_vpd_unit_serial_number
1401151497Sru{
1402104862Sru	u_int8_t device;
1403104862Sru	u_int8_t page_code;
1404104862Sru#define	SVPD_UNIT_SERIAL_NUMBER	0x80
1405104862Sru	u_int8_t reserved;
1406104862Sru	u_int8_t length; /* serial number length */
1407104862Sru#define	SVPD_SERIAL_NUM_SIZE 251
1408104862Sru	u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
1409104862Sru};
1410104862Sru
1411151497Srustruct scsi_vpd_device_id
1412104862Sru{
1413104862Sru	u_int8_t device;
1414104862Sru	u_int8_t page_code;
1415104862Sru#define	SVPD_DEVICE_ID			0x83
1416104862Sru#define	SVPD_DEVICE_ID_MAX_SIZE		252
1417104862Sru#define	SVPD_DEVICE_ID_HDR_LEN \
1418104862Sru    __offsetof(struct scsi_vpd_device_id, desc_list)
1419104862Sru	u_int8_t length[2];
1420104862Sru	u_int8_t desc_list[];
1421104862Sru};
1422151497Sru
1423151497Srustruct scsi_vpd_id_descriptor
1424151497Sru{
1425104862Sru	u_int8_t	proto_codeset;
1426104862Sru#define	SCSI_PROTO_FC		0x00
1427104862Sru#define	SCSI_PROTO_SPI		0x01
1428104862Sru#define	SCSI_PROTO_SSA		0x02
1429104862Sru#define	SCSI_PROTO_1394		0x03
1430104862Sru#define	SCSI_PROTO_RDMA		0x04
1431104862Sru#define	SCSI_PROTO_ISCSI	0x05
1432104862Sru#define	SCSI_PROTO_SAS		0x06
1433104862Sru#define	SCSI_PROTO_ADT		0x07
1434104862Sru#define	SCSI_PROTO_ATA		0x08
1435104862Sru#define	SVPD_ID_PROTO_SHIFT	4
1436104862Sru#define	SVPD_ID_CODESET_BINARY	0x01
1437104862Sru#define	SVPD_ID_CODESET_ASCII	0x02
1438104862Sru#define	SVPD_ID_CODESET_UTF8	0x03
1439104862Sru#define	SVPD_ID_CODESET_MASK	0x0f
1440104862Sru	u_int8_t	id_type;
1441104862Sru#define	SVPD_ID_PIV		0x80
1442104862Sru#define	SVPD_ID_ASSOC_LUN	0x00
1443104862Sru#define	SVPD_ID_ASSOC_PORT	0x10
1444104862Sru#define	SVPD_ID_ASSOC_TARGET	0x20
1445104862Sru#define	SVPD_ID_ASSOC_MASK	0x30
1446151497Sru#define	SVPD_ID_TYPE_VENDOR	0x00
1447104862Sru#define	SVPD_ID_TYPE_T10	0x01
1448104862Sru#define	SVPD_ID_TYPE_EUI64	0x02
1449104862Sru#define	SVPD_ID_TYPE_NAA	0x03
1450104862Sru#define	SVPD_ID_TYPE_RELTARG	0x04
1451104862Sru#define	SVPD_ID_TYPE_TPORTGRP	0x05
1452104862Sru#define	SVPD_ID_TYPE_LUNGRP	0x06
1453104862Sru#define	SVPD_ID_TYPE_MD5_LUN_ID	0x07
1454104862Sru#define	SVPD_ID_TYPE_SCSI_NAME	0x08
1455104862Sru#define	SVPD_ID_TYPE_MASK	0x0f
1456104862Sru	u_int8_t	reserved;
1457104862Sru	u_int8_t	length;
1458104862Sru#define	SVPD_DEVICE_ID_DESC_HDR_LEN \
1459104862Sru    __offsetof(struct scsi_vpd_id_descriptor, identifier)
1460104862Sru	u_int8_t	identifier[];
1461104862Sru};
1462104862Sru
1463151497Srustruct scsi_vpd_id_t10
1464104862Sru{
1465104862Sru	u_int8_t	vendor[8];
1466104862Sru	u_int8_t	vendor_spec_id[0];
1467104862Sru};
1468151497Sru
1469104862Srustruct scsi_vpd_id_eui64
1470104862Sru{
1471104862Sru	u_int8_t	ieee_company_id[3];
1472104862Sru	u_int8_t	extension_id[5];
1473104862Sru};
1474104862Sru
1475151497Srustruct scsi_vpd_id_naa_basic
1476151497Sru{
1477151497Sru	uint8_t naa;
1478151497Sru	/* big endian, packed:
1479151497Sru	uint8_t	naa : 4;
1480151497Sru	uint8_t naa_desig : 4;
1481151497Sru	*/
1482151497Sru#define	SVPD_ID_NAA_NAA_SHIFT		4
1483151497Sru#define	SVPD_ID_NAA_IEEE_EXT		0x02
1484151497Sru#define	SVPD_ID_NAA_LOCAL_REG		0x03
1485151497Sru#define	SVPD_ID_NAA_IEEE_REG		0x05
1486151497Sru#define	SVPD_ID_NAA_IEEE_REG_EXT	0x06
1487151497Sru	uint8_t	naa_data[];
1488151497Sru};
1489151497Sru
1490151497Srustruct scsi_vpd_id_naa_ieee_extended_id
1491151497Sru{
1492151497Sru	uint8_t naa;
1493151497Sru	uint8_t vendor_specific_id_a;
1494151497Sru	uint8_t ieee_company_id[3];
1495151497Sru	uint8_t vendor_specific_id_b[4];
1496151497Sru};
1497151497Sru
1498151497Srustruct scsi_vpd_id_naa_local_reg
1499151497Sru{
1500151497Sru	uint8_t naa;
1501151497Sru	uint8_t local_value[7];
1502151497Sru};
1503151497Sru
1504104862Srustruct scsi_vpd_id_naa_ieee_reg
1505151497Sru{
1506151497Sru	uint8_t naa;
1507104862Sru	uint8_t reg_value[7];
1508151497Sru	/* big endian, packed:
1509104862Sru	uint8_t naa_basic : 4;
1510151497Sru	uint8_t ieee_company_id_0 : 4;
1511151497Sru	uint8_t ieee_company_id_1[2];
1512151497Sru	uint8_t ieee_company_id_2 : 4;
1513151497Sru	uint8_t vendor_specific_id_0 : 4;
1514104862Sru	uint8_t vendor_specific_id_1[4];
1515151497Sru	*/
1516151497Sru};
1517151497Sru
1518151497Srustruct scsi_vpd_id_naa_ieee_reg_extended
1519151497Sru{
1520104862Sru	uint8_t naa;
1521104862Sru	uint8_t reg_value[15];
1522151497Sru	/* big endian, packed:
1523151497Sru	uint8_t naa_basic : 4;
1524151497Sru	uint8_t ieee_company_id_0 : 4;
1525151497Sru	uint8_t ieee_company_id_1[2];
1526151497Sru	uint8_t ieee_company_id_2 : 4;
1527104862Sru	uint8_t vendor_specific_id_0 : 4;
1528104862Sru	uint8_t vendor_specific_id_1[4];
1529104862Sru	uint8_t vendor_specific_id_ext[8];
1530104862Sru	*/
1531104862Sru};
1532104862Sru
1533104862Srustruct scsi_vpd_id_rel_trgt_port_id
1534104862Sru{
1535104862Sru	uint8_t obsolete[2];
1536104862Sru	uint8_t rel_trgt_port_id[2];
1537151497Sru};
1538104862Sru
1539104862Srustruct scsi_vpd_id_trgt_port_grp_id
1540104862Sru{
1541104862Sru	uint8_t reserved[2];
1542104862Sru	uint8_t trgt_port_grp[2];
1543104862Sru};
1544104862Sru
1545104862Srustruct scsi_vpd_id_lun_grp_id
1546104862Sru{
1547104862Sru	uint8_t reserved[2];
1548104862Sru	uint8_t log_unit_grp[2];
1549104862Sru};
1550104862Sru
1551104862Srustruct scsi_vpd_id_md5_lun_id
1552104862Sru{
1553104862Sru	uint8_t lun_id[16];
1554104862Sru};
1555104862Sru
1556104862Srustruct scsi_vpd_id_scsi_name
1557104862Sru{
1558104862Sru	uint8_t name_string[256];
1559104862Sru};
1560151497Sru
1561104862Srustruct scsi_service_action_in
1562151497Sru{
1563151497Sru	uint8_t opcode;
1564104862Sru	uint8_t service_action;
1565104862Sru	uint8_t action_dependent[13];
1566151497Sru	uint8_t control;
1567104862Sru};
1568104862Sru
1569104862Srustruct scsi_diag_page {
1570104862Sru	uint8_t page_code;
1571104862Sru	uint8_t page_specific_flags;
1572104862Sru	uint8_t length[2];
1573104862Sru	uint8_t params[0];
1574104862Sru};
1575104862Sru
1576104862Srustruct scsi_vpd_port_designation
1577104862Sru{
1578104862Sru	uint8_t reserved[2];
1579104862Sru	uint8_t relative_port_id[2];
1580151497Sru	uint8_t reserved2[2];
1581151497Sru	uint8_t initiator_transportid_length[2];
1582151497Sru	uint8_t initiator_transportid[0];
1583151497Sru};
1584151497Sru
1585151497Srustruct scsi_vpd_port_designation_cont
1586151497Sru{
1587151497Sru	uint8_t reserved[2];
1588151497Sru	uint8_t target_port_descriptors_length[2];
1589151497Sru	struct scsi_vpd_id_descriptor target_port_descriptors[0];
1590151497Sru};
1591151497Sru
1592151497Srustruct scsi_vpd_scsi_ports
1593151497Sru{
1594151497Sru	u_int8_t device;
1595151497Sru	u_int8_t page_code;
1596151497Sru#define	SVPD_SCSI_PORTS		0x88
1597151497Sru	u_int8_t page_length[2];
1598151497Sru	struct scsi_vpd_port_designation design[];
1599151497Sru};
1600151497Sru
1601151497Sru/*
1602151497Sru * ATA Information VPD Page based on
1603151497Sru * T10/2126-D Revision 04
1604151497Sru */
1605151497Sru#define SVPD_ATA_INFORMATION		0x89
1606151497Sru
1607151497Sru/*
1608151497Sru * Block Device Characteristics VPD Page based on
1609151497Sru * T10/1799-D Revision 31
1610151497Sru */
1611151497Srustruct scsi_vpd_block_characteristics
1612151497Sru{
1613151497Sru	u_int8_t device;
1614151497Sru	u_int8_t page_code;
1615151497Sru#define SVPD_BDC			0xB1
1616151497Sru	u_int8_t page_length[2];
1617104862Sru	u_int8_t medium_rotation_rate[2];
1618104862Sru#define SVPD_BDC_RATE_NOT_REPORTED	0x00
1619104862Sru#define SVPD_BDC_RATE_NONE_ROTATING	0x01
1620104862Sru	u_int8_t reserved1;
1621104862Sru	u_int8_t nominal_form_factor;
1622104862Sru#define SVPD_BDC_FORM_NOT_REPORTED	0x00
1623104862Sru#define SVPD_BDC_FORM_5_25INCH		0x01
1624104862Sru#define SVPD_BDC_FORM_3_5INCH		0x02
1625151497Sru#define SVPD_BDC_FORM_2_5INCH		0x03
1626151497Sru#define SVPD_BDC_FORM_1_5INCH		0x04
1627151497Sru#define SVPD_BDC_FORM_LESSTHAN_1_5INCH	0x05
1628151497Sru	u_int8_t reserved2[56];
1629151497Sru};
1630151497Sru
1631104862Sru/*
1632104862Sru * Logical Block Provisioning VPD Page based on
1633104862Sru * T10/1799-D Revision 31
1634151497Sru */
1635151497Srustruct scsi_vpd_logical_block_prov
1636104862Sru{
1637151497Sru	u_int8_t device;
1638104862Sru	u_int8_t page_code;
1639104862Sru#define	SVPD_LBP		0xB2
1640104862Sru	u_int8_t page_length[2];
1641104862Sru#define SVPD_LBP_PL_BASIC	0x04
1642104862Sru	u_int8_t threshold_exponent;
1643104862Sru	u_int8_t flags;
1644104862Sru#define SVPD_LBP_UNMAP		0x80
1645104862Sru#define SVPD_LBP_WS16		0x40
1646104862Sru#define SVPD_LBP_WS10		0x20
1647104862Sru#define SVPD_LBP_RZ		0x04
1648104862Sru#define SVPD_LBP_ANC_SUP	0x02
1649104862Sru#define SVPD_LBP_DP		0x01
1650104862Sru	u_int8_t prov_type;
1651104862Sru#define SVPD_LBP_RESOURCE	0x01
1652104862Sru#define SVPD_LBP_THIN		0x02
1653151497Sru	u_int8_t reserved;
1654151497Sru	/*
1655151497Sru	 * Provisioning Group Descriptor can be here if SVPD_LBP_DP is set
1656151497Sru	 * Its size can be determined from page_length - 4
1657104862Sru	 */
1658104862Sru};
1659104862Sru
1660104862Sru/*
1661104862Sru * Block Limits VDP Page based on
1662104862Sru * T10/1799-D Revision 31
1663104862Sru */
1664104862Srustruct scsi_vpd_block_limits
1665104862Sru{
1666104862Sru	u_int8_t device;
1667104862Sru	u_int8_t page_code;
1668104862Sru#define	SVPD_BLOCK_LIMITS	0xB0
1669104862Sru	u_int8_t page_length[2];
1670104862Sru#define SVPD_BL_PL_BASIC	0x10
1671104862Sru#define SVPD_BL_PL_TP		0x3C
1672104862Sru	u_int8_t reserved1;
1673104862Sru	u_int8_t max_cmp_write_len;
1674104862Sru	u_int8_t opt_txfer_len_grain[2];
1675104862Sru	u_int8_t max_txfer_len[4];
1676104862Sru	u_int8_t opt_txfer_len[4];
1677104862Sru	u_int8_t max_prefetch[4];
1678104862Sru	u_int8_t max_unmap_lba_cnt[4];
1679104862Sru	u_int8_t max_unmap_blk_cnt[4];
1680104862Sru	u_int8_t opt_unmap_grain[4];
1681151497Sru	u_int8_t unmap_grain_align[4];
1682104862Sru	u_int8_t max_write_same_length[8];
1683104862Sru	u_int8_t reserved2[20];
1684151497Sru};
1685151497Sru
1686104862Srustruct scsi_read_capacity
1687104862Sru{
1688151497Sru	u_int8_t opcode;
1689151497Sru	u_int8_t byte2;
1690151497Sru#define	SRC_RELADR	0x01
1691104862Sru	u_int8_t addr[4];
1692104862Sru	u_int8_t unused[2];
1693151497Sru	u_int8_t pmi;
1694104862Sru#define	SRC_PMI		0x01
1695104862Sru	u_int8_t control;
1696151497Sru};
1697151497Sru
1698151497Srustruct scsi_read_capacity_16
1699104862Sru{
1700151497Sru	uint8_t opcode;
1701151497Sru#define	SRC16_SERVICE_ACTION	0x10
1702104862Sru	uint8_t service_action;
1703104862Sru	uint8_t addr[8];
1704104862Sru	uint8_t alloc_len[4];
1705104862Sru#define	SRC16_PMI		0x01
1706104862Sru#define	SRC16_RELADR		0x02
1707104862Sru	uint8_t reladr;
1708104862Sru	uint8_t control;
1709104862Sru};
1710104862Sru
1711104862Srustruct scsi_read_capacity_data
1712104862Sru{
1713104862Sru	u_int8_t addr[4];
1714104862Sru	u_int8_t length[4];
1715104862Sru};
1716104862Sru
1717104862Srustruct scsi_read_capacity_data_long
1718104862Sru{
1719104862Sru	uint8_t addr[8];
1720104862Sru	uint8_t length[4];
1721104862Sru#define	SRC16_PROT_EN		0x01
1722104862Sru#define	SRC16_P_TYPE		0x0e
1723104862Sru#define	SRC16_PTYPE_1		0x00
1724104862Sru#define	SRC16_PTYPE_2		0x02
1725104862Sru#define	SRC16_PTYPE_3		0x04
1726104862Sru	uint8_t prot;
1727104862Sru#define	SRC16_LBPPBE		0x0f
1728104862Sru#define	SRC16_PI_EXPONENT	0xf0
1729104862Sru#define	SRC16_PI_EXPONENT_SHIFT	4
1730104862Sru	uint8_t prot_lbppbe;
1731104862Sru#define	SRC16_LALBA		0x3f
1732104862Sru#define	SRC16_LBPRZ		0x40
1733104862Sru#define	SRC16_LBPME		0x80
1734104862Sru/*
1735104862Sru * Alternate versions of these macros that are intended for use on a 16-bit
1736104862Sru * version of the lalba_lbp field instead of the array of 2 8 bit numbers.
1737104862Sru */
1738151497Sru#define	SRC16_LALBA_A		0x3fff
1739151497Sru#define	SRC16_LBPRZ_A		0x4000
1740151497Sru#define	SRC16_LBPME_A		0x8000
1741151497Sru	uint8_t lalba_lbp[2];
1742151497Sru	uint8_t	reserved[16];
1743151497Sru};
1744151497Sru
1745151497Srustruct scsi_report_luns
1746151497Sru{
1747151497Sru	uint8_t opcode;
1748151497Sru	uint8_t reserved1;
1749151497Sru#define	RPL_REPORT_DEFAULT	0x00
1750151497Sru#define	RPL_REPORT_WELLKNOWN	0x01
1751151497Sru#define	RPL_REPORT_ALL		0x02
1752151497Sru	uint8_t select_report;
1753151497Sru	uint8_t reserved2[3];
1754151497Sru	uint8_t length[4];
1755151497Sru	uint8_t reserved3;
1756151497Sru	uint8_t control;
1757151497Sru};
1758151497Sru
1759151497Srustruct scsi_report_luns_lundata {
1760151497Sru	uint8_t lundata[8];
1761151497Sru#define	RPL_LUNDATA_PERIPH_BUS_MASK	0x3f
1762151497Sru#define	RPL_LUNDATA_FLAT_LUN_MASK	0x3f
1763151497Sru#define	RPL_LUNDATA_FLAT_LUN_BITS	0x06
1764151497Sru#define	RPL_LUNDATA_LUN_TARG_MASK	0x3f
1765151497Sru#define	RPL_LUNDATA_LUN_BUS_MASK	0xe0
1766151497Sru#define	RPL_LUNDATA_LUN_LUN_MASK	0x1f
1767151497Sru#define	RPL_LUNDATA_EXT_LEN_MASK	0x30
1768151497Sru#define	RPL_LUNDATA_EXT_EAM_MASK	0x0f
1769151497Sru#define	RPL_LUNDATA_EXT_EAM_WK		0x01
1770151497Sru#define	RPL_LUNDATA_EXT_EAM_NOT_SPEC	0x0f
1771151497Sru#define	RPL_LUNDATA_ATYP_MASK	0xc0	/* MBZ for type 0 lun */
1772151497Sru#define	RPL_LUNDATA_ATYP_PERIPH	0x00
1773151497Sru#define	RPL_LUNDATA_ATYP_FLAT	0x40
1774151497Sru#define	RPL_LUNDATA_ATYP_LUN	0x80
1775151497Sru#define	RPL_LUNDATA_ATYP_EXTLUN	0xc0
1776151497Sru};
1777151497Sru
1778151497Srustruct scsi_report_luns_data {
1779151497Sru	u_int8_t length[4];	/* length of LUN inventory, in bytes */
1780151497Sru	u_int8_t reserved[4];	/* unused */
1781151497Sru	/*
1782151497Sru	 * LUN inventory- we only support the type zero form for now.
1783151497Sru	 */
1784151497Sru	struct scsi_report_luns_lundata luns[0];
1785151497Sru};
1786151497Sru
1787151497Srustruct scsi_target_group
1788151497Sru{
1789151497Sru	uint8_t opcode;
1790151497Sru	uint8_t service_action;
1791151497Sru#define	STG_PDF_MASK		0xe0
1792151497Sru#define	STG_PDF_LENGTH		0x00
1793151497Sru#define	STG_PDF_EXTENDED	0x20
1794151497Sru	uint8_t reserved1[4];
1795151497Sru	uint8_t length[4];
1796151497Sru	uint8_t reserved2;
1797151497Sru	uint8_t control;
1798151497Sru};
1799151497Sru
1800151497Srustruct scsi_target_port_descriptor {
1801151497Sru	uint8_t	reserved[2];
1802151497Sru	uint8_t	relative_target_port_identifier[2];
1803151497Sru	uint8_t desc_list[];
1804151497Sru};
1805151497Sru
1806151497Srustruct scsi_target_port_group_descriptor {
1807151497Sru	uint8_t	pref_state;
1808151497Sru#define	TPG_PRIMARY				0x80
1809151497Sru#define	TPG_ASYMMETRIC_ACCESS_STATE_MASK	0xf
1810151497Sru#define	TPG_ASYMMETRIC_ACCESS_OPTIMIZED		0x0
1811151497Sru#define	TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED	0x1
1812151497Sru#define	TPG_ASYMMETRIC_ACCESS_STANDBY		0x2
1813151497Sru#define	TPG_ASYMMETRIC_ACCESS_UNAVAILABLE	0x3
1814151497Sru#define	TPG_ASYMMETRIC_ACCESS_LBA_DEPENDENT	0x4
1815151497Sru#define	TPG_ASYMMETRIC_ACCESS_OFFLINE		0xE
1816104862Sru#define	TPG_ASYMMETRIC_ACCESS_TRANSITIONING	0xF
1817104862Sru	uint8_t support;
1818104862Sru#define	TPG_AO_SUP	0x01
1819104862Sru#define	TPG_AN_SUP	0x02
1820104862Sru#define	TPG_S_SUP	0x04
1821104862Sru#define	TPG_U_SUP	0x08
1822104862Sru#define	TPG_LBD_SUP	0x10
1823104862Sru#define	TPG_O_SUP	0x40
1824104862Sru#define	TPG_T_SUP	0x80
1825104862Sru	uint8_t target_port_group[2];
1826104862Sru	uint8_t reserved;
1827104862Sru	uint8_t status;
1828104862Sru#define TPG_UNAVLBL      0
1829104862Sru#define TPG_SET_BY_STPG  0x01
1830104862Sru#define TPG_IMPLICIT     0x02
1831104862Sru	uint8_t vendor_specific;
1832104862Sru	uint8_t	target_port_count;
1833104862Sru	struct scsi_target_port_descriptor descriptors[];
1834104862Sru};
1835104862Sru
1836104862Srustruct scsi_target_group_data {
1837104862Sru	uint8_t length[4];	/* length of returned data, in bytes */
1838104862Sru	struct scsi_target_port_group_descriptor groups[];
1839104862Sru};
1840104862Sru
1841104862Srustruct scsi_target_group_data_extended {
1842104862Sru	uint8_t length[4];	/* length of returned data, in bytes */
1843104862Sru	uint8_t format_type;	/* STG_PDF_LENGTH or STG_PDF_EXTENDED */
1844104862Sru	uint8_t	implicit_transition_time;
1845104862Sru	uint8_t reserved[2];
1846104862Sru	struct scsi_target_port_group_descriptor groups[];
1847104862Sru};
1848104862Sru
1849104862Sru
1850104862Srutypedef enum {
1851104862Sru	SSD_TYPE_NONE,
1852104862Sru	SSD_TYPE_FIXED,
1853104862Sru	SSD_TYPE_DESC
1854104862Sru} scsi_sense_data_type;
1855104862Sru
1856104862Srutypedef enum {
1857104862Sru	SSD_ELEM_NONE,
1858104862Sru	SSD_ELEM_SKIP,
1859104862Sru	SSD_ELEM_DESC,
1860104862Sru	SSD_ELEM_SKS,
1861104862Sru	SSD_ELEM_COMMAND,
1862104862Sru	SSD_ELEM_INFO,
1863104862Sru	SSD_ELEM_FRU,
1864104862Sru	SSD_ELEM_STREAM,
1865104862Sru	SSD_ELEM_MAX
1866104862Sru} scsi_sense_elem_type;
1867104862Sru
1868104862Sru
1869104862Srustruct scsi_sense_data
1870104862Sru{
1871104862Sru	uint8_t error_code;
1872104862Sru	/*
1873104862Sru	 * SPC-4 says that the maximum length of sense data is 252 bytes.
1874104862Sru	 * So this structure is exactly 252 bytes log.
1875104862Sru	 */
1876104862Sru#define	SSD_FULL_SIZE 252
1877104862Sru	uint8_t sense_buf[SSD_FULL_SIZE - 1];
1878104862Sru	/*
1879104862Sru	 * XXX KDM is this still a reasonable minimum size?
1880104862Sru	 */
1881104862Sru#define	SSD_MIN_SIZE 18
1882104862Sru	/*
1883104862Sru	 * Maximum value for the extra_len field in the sense data.
1884104862Sru	 */
1885104862Sru#define	SSD_EXTRA_MAX 244
1886104862Sru};
1887104862Sru
1888104862Sru/*
1889104862Sru * Fixed format sense data.
1890104862Sru */
1891104862Srustruct scsi_sense_data_fixed
1892104862Sru{
1893104862Sru	u_int8_t error_code;
1894104862Sru#define	SSD_ERRCODE			0x7F
1895104862Sru#define		SSD_CURRENT_ERROR	0x70
1896104862Sru#define		SSD_DEFERRED_ERROR	0x71
1897104862Sru#define	SSD_ERRCODE_VALID	0x80
1898104862Sru	u_int8_t segment;
1899104862Sru	u_int8_t flags;
1900104862Sru#define	SSD_KEY				0x0F
1901104862Sru#define		SSD_KEY_NO_SENSE	0x00
1902104862Sru#define		SSD_KEY_RECOVERED_ERROR	0x01
1903104862Sru#define		SSD_KEY_NOT_READY	0x02
1904104862Sru#define		SSD_KEY_MEDIUM_ERROR	0x03
1905104862Sru#define		SSD_KEY_HARDWARE_ERROR	0x04
1906104862Sru#define		SSD_KEY_ILLEGAL_REQUEST	0x05
1907104862Sru#define		SSD_KEY_UNIT_ATTENTION	0x06
1908104862Sru#define		SSD_KEY_DATA_PROTECT	0x07
1909104862Sru#define		SSD_KEY_BLANK_CHECK	0x08
1910104862Sru#define		SSD_KEY_Vendor_Specific	0x09
1911104862Sru#define		SSD_KEY_COPY_ABORTED	0x0a
1912104862Sru#define		SSD_KEY_ABORTED_COMMAND	0x0b
1913104862Sru#define		SSD_KEY_EQUAL		0x0c
1914104862Sru#define		SSD_KEY_VOLUME_OVERFLOW	0x0d
1915104862Sru#define		SSD_KEY_MISCOMPARE	0x0e
1916104862Sru#define		SSD_KEY_COMPLETED	0x0f
1917104862Sru#define	SSD_ILI		0x20
1918104862Sru#define	SSD_EOM		0x40
1919104862Sru#define	SSD_FILEMARK	0x80
1920104862Sru	u_int8_t info[4];
1921104862Sru	u_int8_t extra_len;
1922104862Sru	u_int8_t cmd_spec_info[4];
1923104862Sru	u_int8_t add_sense_code;
1924104862Sru	u_int8_t add_sense_code_qual;
1925104862Sru	u_int8_t fru;
1926104862Sru	u_int8_t sense_key_spec[3];
1927104862Sru#define	SSD_SCS_VALID		0x80
1928104862Sru#define	SSD_FIELDPTR_CMD	0x40
1929104862Sru#define	SSD_BITPTR_VALID	0x08
1930104862Sru#define	SSD_BITPTR_VALUE	0x07
1931104862Sru	u_int8_t extra_bytes[14];
1932104862Sru#define	SSD_FIXED_IS_PRESENT(sense, length, field) 			\
1933104862Sru	((length >= (offsetof(struct scsi_sense_data_fixed, field) +	\
1934104862Sru	sizeof(sense->field))) ? 1 :0)
1935104862Sru#define	SSD_FIXED_IS_FILLED(sense, field) 				\
1936104862Sru	((((offsetof(struct scsi_sense_data_fixed, field) +		\
1937104862Sru	sizeof(sense->field)) -						\
1938104862Sru	(offsetof(struct scsi_sense_data_fixed, extra_len) +		\
1939104862Sru	sizeof(sense->extra_len))) <= sense->extra_len) ? 1 : 0)
1940104862Sru};
1941104862Sru
1942104862Sru/*
1943104862Sru * Descriptor format sense data definitions.
1944104862Sru * Introduced in SPC-3.
1945104862Sru */
1946104862Srustruct scsi_sense_data_desc
1947104862Sru{
1948104862Sru	uint8_t	error_code;
1949104862Sru#define	SSD_DESC_CURRENT_ERROR	0x72
1950104862Sru#define	SSD_DESC_DEFERRED_ERROR	0x73
1951104862Sru	uint8_t sense_key;
1952104862Sru	uint8_t	add_sense_code;
1953104862Sru	uint8_t	add_sense_code_qual;
1954104862Sru	uint8_t	reserved[3];
1955104862Sru	/*
1956104862Sru	 * Note that SPC-4, section 4.5.2.1 says that the extra_len field
1957104862Sru	 * must be less than or equal to 244.
1958104862Sru	 */
1959104862Sru	uint8_t	extra_len;
1960104862Sru	uint8_t	sense_desc[0];
1961104862Sru#define	SSD_DESC_IS_PRESENT(sense, length, field) 			\
1962104862Sru	((length >= (offsetof(struct scsi_sense_data_desc, field) +	\
1963104862Sru	sizeof(sense->field))) ? 1 :0)
1964104862Sru};
1965104862Sru
1966104862Srustruct scsi_sense_desc_header
1967104862Sru{
1968104862Sru	uint8_t desc_type;
1969104862Sru	uint8_t length;
1970104862Sru};
1971114402Sru/*
1972104862Sru * The information provide in the Information descriptor is device type or
1973104862Sru * command specific information, and defined in a command standard.
1974104862Sru *
1975104862Sru * Note that any changes to the field names or positions in this structure,
1976104862Sru * even reserved fields, should be accompanied by an examination of the
1977104862Sru * code in ctl_set_sense() that uses them.
1978104862Sru *
1979104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
1980104862Sru */
1981104862Srustruct scsi_sense_info
1982104862Sru{
1983104862Sru	uint8_t	desc_type;
1984104862Sru#define	SSD_DESC_INFO	0x00
1985104862Sru	uint8_t	length;
1986104862Sru	uint8_t	byte2;
1987104862Sru#define	SSD_INFO_VALID	0x80
1988104862Sru	uint8_t	reserved;
1989104862Sru	uint8_t	info[8];
1990104862Sru};
1991104862Sru
1992104862Sru/*
1993104862Sru * Command-specific information depends on the command for which the
1994104862Sru * reported condition occured.
1995104862Sru *
1996104862Sru * Note that any changes to the field names or positions in this structure,
1997104862Sru * even reserved fields, should be accompanied by an examination of the
1998104862Sru * code in ctl_set_sense() that uses them.
1999104862Sru *
2000104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2001104862Sru */
2002104862Srustruct scsi_sense_command
2003104862Sru{
2004104862Sru	uint8_t	desc_type;
2005104862Sru#define	SSD_DESC_COMMAND	0x01
2006104862Sru	uint8_t	length;
2007104862Sru	uint8_t	reserved[2];
2008104862Sru	uint8_t	command_info[8];
2009104862Sru};
2010104862Sru
2011104862Sru/*
2012104862Sru * Sense key specific descriptor.  The sense key specific data format
2013104862Sru * depends on the sense key in question.
2014104862Sru *
2015104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2016104862Sru */
2017104862Srustruct scsi_sense_sks
2018104862Sru{
2019104862Sru	uint8_t	desc_type;
2020104862Sru#define	SSD_DESC_SKS		0x02
2021104862Sru	uint8_t	length;
2022104862Sru	uint8_t reserved1[2];
2023104862Sru	uint8_t	sense_key_spec[3];
2024104862Sru#define	SSD_SKS_VALID		0x80
2025104862Sru	uint8_t reserved2;
2026104862Sru};
2027104862Sru
2028104862Sru/*
2029104862Sru * This is used for the Illegal Request sense key (0x05) only.
2030104862Sru */
2031104862Srustruct scsi_sense_sks_field
2032104862Sru{
2033104862Sru	uint8_t	byte0;
2034104862Sru#define	SSD_SKS_FIELD_VALID	0x80
2035104862Sru#define	SSD_SKS_FIELD_CMD	0x40
2036104862Sru#define	SSD_SKS_BPV		0x08
2037104862Sru#define	SSD_SKS_BIT_VALUE	0x07
2038104862Sru	uint8_t	field[2];
2039104862Sru};
2040104862Sru
2041104862Sru
2042104862Sru/*
2043104862Sru * This is used for the Hardware Error (0x04), Medium Error (0x03) and
2044104862Sru * Recovered Error (0x01) sense keys.
2045104862Sru */
2046104862Srustruct scsi_sense_sks_retry
2047104862Sru{
2048104862Sru	uint8_t byte0;
2049104862Sru#define	SSD_SKS_RETRY_VALID	0x80
2050104862Sru	uint8_t actual_retry_count[2];
2051104862Sru};
2052104862Sru
2053104862Sru/*
2054104862Sru * Used with the NO Sense (0x00) or Not Ready (0x02) sense keys.
2055104862Sru */
2056104862Srustruct scsi_sense_sks_progress
2057104862Sru{
2058104862Sru	uint8_t byte0;
2059104862Sru#define	SSD_SKS_PROGRESS_VALID	0x80
2060104862Sru	uint8_t progress[2];
2061104862Sru#define	SSD_SKS_PROGRESS_DENOM	0x10000
2062104862Sru};
2063104862Sru
2064104862Sru/*
2065104862Sru * Used with the Copy Aborted (0x0a) sense key.
2066104862Sru */
2067104862Srustruct scsi_sense_sks_segment
2068104862Sru{
2069104862Sru	uint8_t byte0;
2070104862Sru#define	SSD_SKS_SEGMENT_VALID	0x80
2071104862Sru#define	SSD_SKS_SEGMENT_SD	0x20
2072104862Sru#define	SSD_SKS_SEGMENT_BPV	0x08
2073104862Sru#define	SSD_SKS_SEGMENT_BITPTR	0x07
2074104862Sru	uint8_t field[2];
2075104862Sru};
2076104862Sru
2077104862Sru/*
2078104862Sru * Used with the Unit Attention (0x06) sense key.
2079104862Sru *
2080104862Sru * This is currently used to indicate that the unit attention condition
2081104862Sru * queue has overflowed (when the overflow bit is set).
2082104862Sru */
2083104862Srustruct scsi_sense_sks_overflow
2084104862Sru{
2085104862Sru	uint8_t byte0;
2086104862Sru#define	SSD_SKS_OVERFLOW_VALID	0x80
2087104862Sru#define	SSD_SKS_OVERFLOW_SET	0x01
2088104862Sru	uint8_t	reserved[2];
2089104862Sru};
2090104862Sru
2091104862Sru/*
2092104862Sru * This specifies which component is associated with the sense data.  There
2093104862Sru * is no standard meaning for the fru value.
2094104862Sru *
2095104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2096104862Sru */
2097104862Srustruct scsi_sense_fru
2098104862Sru{
2099104862Sru	uint8_t	desc_type;
2100104862Sru#define	SSD_DESC_FRU		0x03
2101104862Sru	uint8_t	length;
2102104862Sru	uint8_t reserved;
2103104862Sru	uint8_t fru;
2104104862Sru};
2105104862Sru
2106104862Sru/*
2107104862Sru * Used for Stream commands, defined in SSC-4.
2108104862Sru *
2109104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2110104862Sru */
2111104862Sru
2112104862Srustruct scsi_sense_stream
2113104862Sru{
2114104862Sru	uint8_t	desc_type;
2115104862Sru#define	SSD_DESC_STREAM		0x04
2116104862Sru	uint8_t	length;
2117104862Sru	uint8_t	reserved;
2118104862Sru	uint8_t	byte3;
2119104862Sru#define	SSD_DESC_STREAM_FM	0x80
2120104862Sru#define	SSD_DESC_STREAM_EOM	0x40
2121104862Sru#define	SSD_DESC_STREAM_ILI	0x20
2122104862Sru};
2123104862Sru
2124104862Sru/*
2125104862Sru * Used for Block commands, defined in SBC-3.
2126104862Sru *
2127104862Sru * This is currently (as of SBC-3) only used for the Incorrect Length
2128104862Sru * Indication (ILI) bit, which says that the data length requested in the
2129104862Sru * READ LONG or WRITE LONG command did not match the length of the logical
2130114402Sru * block.
2131104862Sru *
2132104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2133104862Sru */
2134104862Srustruct scsi_sense_block
2135104862Sru{
2136104862Sru	uint8_t	desc_type;
2137104862Sru#define	SSD_DESC_BLOCK		0x05
2138104862Sru	uint8_t	length;
2139104862Sru	uint8_t	reserved;
2140104862Sru	uint8_t	byte3;
2141104862Sru#define	SSD_DESC_BLOCK_ILI	0x20
2142104862Sru};
2143104862Sru
2144104862Sru/*
2145104862Sru * Used for Object-Based Storage Devices (OSD-3).
2146104862Sru *
2147104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2148104862Sru */
2149104862Srustruct scsi_sense_osd_objid
2150104862Sru{
2151104862Sru	uint8_t	desc_type;
2152104862Sru#define	SSD_DESC_OSD_OBJID	0x06
2153104862Sru	uint8_t	length;
2154104862Sru	uint8_t	reserved[6];
2155104862Sru	/*
2156104862Sru	 * XXX KDM provide the bit definitions here?  There are a lot of
2157104862Sru	 * them, and we don't have an OSD driver yet.
2158104862Sru	 */
2159104862Sru	uint8_t	not_init_cmds[4];
2160104862Sru	uint8_t	completed_cmds[4];
2161104862Sru	uint8_t	partition_id[8];
2162104862Sru	uint8_t	object_id[8];
2163104862Sru};
2164104862Sru
2165104862Sru/*
2166104862Sru * Used for Object-Based Storage Devices (OSD-3).
2167104862Sru *
2168104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2169104862Sru */
2170104862Srustruct scsi_sense_osd_integrity
2171104862Sru{
2172104862Sru	uint8_t	desc_type;
2173104862Sru#define	SSD_DESC_OSD_INTEGRITY	0x07
2174104862Sru	uint8_t	length;
2175104862Sru	uint8_t	integ_check_val[32];
2176104862Sru};
2177104862Sru
2178104862Sru/*
2179104862Sru * Used for Object-Based Storage Devices (OSD-3).
2180104862Sru *
2181104862Sru * Maximum descriptors allowed: 1 (as of SPC-4)
2182104862Sru */
2183104862Srustruct scsi_sense_osd_attr_id
2184104862Sru{
2185104862Sru	uint8_t	desc_type;
2186104862Sru#define	SSD_DESC_OSD_ATTR_ID	0x08
2187104862Sru	uint8_t	length;
2188104862Sru	uint8_t	reserved[2];
2189104862Sru	uint8_t	attr_desc[0];
2190104862Sru};
2191104862Sru
2192104862Sru/*
2193104862Sru * Used with Sense keys No Sense (0x00) and Not Ready (0x02).
2194104862Sru *
2195104862Sru * Maximum descriptors allowed: 32 (as of SPC-4)
2196104862Sru */
2197104862Srustruct scsi_sense_progress
2198104862Sru{
2199104862Sru	uint8_t	desc_type;
2200104862Sru#define	SSD_DESC_PROGRESS	0x0a
2201104862Sru	uint8_t	length;
2202104862Sru	uint8_t	sense_key;
2203104862Sru	uint8_t	add_sense_code;
2204104862Sru	uint8_t	add_sense_code_qual;
2205104862Sru	uint8_t reserved;
2206151497Sru	uint8_t	progress[2];
2207104862Sru};
2208151497Sru
2209104862Sru/*
2210104862Sru * This is typically forwarded as the result of an EXTENDED COPY command.
2211104862Sru *
2212104862Sru * Maximum descriptors allowed: 2 (as of SPC-4)
2213104862Sru */
2214104862Srustruct scsi_sense_forwarded
2215104862Sru{
2216104862Sru	uint8_t	desc_type;
2217104862Sru#define	SSD_DESC_FORWARDED	0x0c
2218104862Sru	uint8_t	length;
2219104862Sru	uint8_t	byte2;
2220104862Sru#define	SSD_FORWARDED_FSDT	0x80
2221104862Sru#define	SSD_FORWARDED_SDS_MASK	0x0f
2222104862Sru#define	SSD_FORWARDED_SDS_UNK	0x00
2223104862Sru#define	SSD_FORWARDED_SDS_EXSRC	0x01
2224104862Sru#define	SSD_FORWARDED_SDS_EXDST	0x02
2225104862Sru};
2226104862Sru
2227104862Sru/*
2228104862Sru * Vendor-specific sense descriptor.  The desc_type field will be in the
2229104862Sru * range bewteen MIN and MAX inclusive.
2230104862Sru */
2231104862Srustruct scsi_sense_vendor
2232104862Sru{
2233104862Sru	uint8_t	desc_type;
2234104862Sru#define	SSD_DESC_VENDOR_MIN	0x80
2235104862Sru#define	SSD_DESC_VENDOR_MAX	0xff
2236104862Sru	uint8_t length;
2237104862Sru	uint8_t	data[0];
2238104862Sru};
2239104862Sru
2240104862Srustruct scsi_mode_header_6
2241104862Sru{
2242104862Sru	u_int8_t data_length;	/* Sense data length */
2243104862Sru	u_int8_t medium_type;
2244104862Sru	u_int8_t dev_spec;
2245104862Sru	u_int8_t blk_desc_len;
2246104862Sru};
2247104862Sru
2248104862Srustruct scsi_mode_header_10
2249104862Sru{
2250104862Sru	u_int8_t data_length[2];/* Sense data length */
2251104862Sru	u_int8_t medium_type;
2252104862Sru	u_int8_t dev_spec;
2253104862Sru	u_int8_t unused[2];
2254104862Sru	u_int8_t blk_desc_len[2];
2255104862Sru};
2256104862Sru
2257104862Srustruct scsi_mode_page_header
2258104862Sru{
2259104862Sru	u_int8_t page_code;
2260104862Sru#define	SMPH_PS		0x80
2261104862Sru#define	SMPH_SPF	0x40
2262104862Sru#define	SMPH_PC_MASK	0x3f
2263104862Sru	u_int8_t page_length;
2264104862Sru};
2265104862Sru
2266104862Srustruct scsi_mode_page_header_sp
2267104862Sru{
2268104862Sru	uint8_t page_code;
2269104862Sru	uint8_t subpage;
2270104862Sru	uint8_t page_length[2];
2271104862Sru};
2272104862Sru
2273104862Sru
2274104862Srustruct scsi_mode_blk_desc
2275104862Sru{
2276104862Sru	u_int8_t density;
2277104862Sru	u_int8_t nblocks[3];
2278104862Sru	u_int8_t reserved;
2279104862Sru	u_int8_t blklen[3];
2280104862Sru};
2281104862Sru
2282104862Sru#define	SCSI_DEFAULT_DENSITY	0x00	/* use 'default' density */
2283104862Sru#define	SCSI_SAME_DENSITY	0x7f	/* use 'same' density- >= SCSI-2 only */
2284104862Sru
2285104862Sru
2286104862Sru/*
2287104862Sru * Status Byte
2288104862Sru */
2289104862Sru#define	SCSI_STATUS_OK			0x00
2290104862Sru#define	SCSI_STATUS_CHECK_COND		0x02
2291104862Sru#define	SCSI_STATUS_COND_MET		0x04
2292104862Sru#define	SCSI_STATUS_BUSY		0x08
2293104862Sru#define	SCSI_STATUS_INTERMED		0x10
2294104862Sru#define	SCSI_STATUS_INTERMED_COND_MET	0x14
2295104862Sru#define	SCSI_STATUS_RESERV_CONFLICT	0x18
2296104862Sru#define	SCSI_STATUS_CMD_TERMINATED	0x22	/* Obsolete in SAM-2 */
2297104862Sru#define	SCSI_STATUS_QUEUE_FULL		0x28
2298104862Sru#define	SCSI_STATUS_ACA_ACTIVE		0x30
2299104862Sru#define	SCSI_STATUS_TASK_ABORTED	0x40
2300104862Sru
2301104862Srustruct scsi_inquiry_pattern {
2302104862Sru	u_int8_t   type;
2303104862Sru	u_int8_t   media_type;
2304104862Sru#define	SIP_MEDIA_REMOVABLE	0x01
2305104862Sru#define	SIP_MEDIA_FIXED		0x02
2306104862Sru	const char *vendor;
2307104862Sru	const char *product;
2308104862Sru	const char *revision;
2309104862Sru};
2310104862Sru
2311104862Srustruct scsi_static_inquiry_pattern {
2312104862Sru	u_int8_t   type;
2313104862Sru	u_int8_t   media_type;
2314104862Sru	char       vendor[SID_VENDOR_SIZE+1];
2315104862Sru	char       product[SID_PRODUCT_SIZE+1];
2316104862Sru	char       revision[SID_REVISION_SIZE+1];
2317104862Sru};
2318104862Sru
2319104862Srustruct scsi_sense_quirk_entry {
2320104862Sru	struct scsi_inquiry_pattern	inq_pat;
2321104862Sru	int				num_sense_keys;
2322104862Sru	int				num_ascs;
2323104862Sru	struct sense_key_table_entry	*sense_key_info;
2324104862Sru	struct asc_table_entry		*asc_info;
2325104862Sru};
2326104862Sru
2327104862Srustruct sense_key_table_entry {
2328104862Sru	u_int8_t    sense_key;
2329104862Sru	u_int32_t   action;
2330104862Sru	const char *desc;
2331104862Sru};
2332104862Sru
2333104862Srustruct asc_table_entry {
2334104862Sru	u_int8_t    asc;
2335104862Sru	u_int8_t    ascq;
2336104862Sru	u_int32_t   action;
2337104862Sru	const char *desc;
2338104862Sru};
2339104862Sru
2340104862Srustruct op_table_entry {
2341104862Sru	u_int8_t    opcode;
2342104862Sru	u_int32_t   opmask;
2343104862Sru	const char  *desc;
2344104862Sru};
2345104862Sru
2346104862Srustruct scsi_op_quirk_entry {
2347104862Sru	struct scsi_inquiry_pattern	inq_pat;
2348104862Sru	int				num_ops;
2349104862Sru	struct op_table_entry		*op_table;
2350104862Sru};
2351104862Sru
2352104862Srutypedef enum {
2353104862Sru	SSS_FLAG_NONE		= 0x00,
2354104862Sru	SSS_FLAG_PRINT_COMMAND	= 0x01
2355104862Sru} scsi_sense_string_flags;
2356104862Sru
2357104862Srustruct ccb_scsiio;
2358104862Srustruct cam_periph;
2359104862Sruunion  ccb;
2360104862Sru#ifndef _KERNEL
2361104862Srustruct cam_device;
2362104862Sru#endif
2363104862Sru
2364104862Sruextern const char *scsi_sense_key_text[];
2365104862Sru
2366104862Srustruct sbuf;
2367104862Sru
2368104862Sru__BEGIN_DECLS
2369104862Sruvoid scsi_sense_desc(int sense_key, int asc, int ascq,
2370104862Sru		     struct scsi_inquiry_data *inq_data,
2371104862Sru		     const char **sense_key_desc, const char **asc_desc);
2372104862Sruscsi_sense_action scsi_error_action(struct ccb_scsiio* csio,
2373104862Sru				    struct scsi_inquiry_data *inq_data,
2374104862Sru				    u_int32_t sense_flags);
2375104862Sruconst char *	scsi_status_string(struct ccb_scsiio *csio);
2376104862Sru
2377104862Sruvoid scsi_desc_iterate(struct scsi_sense_data_desc *sense, u_int sense_len,
2378104862Sru		       int (*iter_func)(struct scsi_sense_data_desc *sense,
2379104862Sru					u_int, struct scsi_sense_desc_header *,
2380104862Sru					void *), void *arg);
2381104862Sruuint8_t *scsi_find_desc(struct scsi_sense_data_desc *sense, u_int sense_len,
2382104862Sru			uint8_t desc_type);
2383104862Sruvoid scsi_set_sense_data(struct scsi_sense_data *sense_data,
2384104862Sru			 scsi_sense_data_type sense_format, int current_error,
2385104862Sru			 int sense_key, int asc, int ascq, ...) ;
2386104862Sruvoid scsi_set_sense_data_va(struct scsi_sense_data *sense_data,
2387104862Sru			    scsi_sense_data_type sense_format,
2388104862Sru			    int current_error, int sense_key, int asc,
2389104862Sru			    int ascq, va_list ap);
2390104862Sruint scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len,
2391104862Sru			uint8_t info_type, uint64_t *info,
2392104862Sru			int64_t *signed_info);
2393151497Sruint scsi_get_sks(struct scsi_sense_data *sense_data, u_int sense_len,
2394151497Sru		 uint8_t *sks);
2395151497Sruint scsi_get_block_info(struct scsi_sense_data *sense_data, u_int sense_len,
2396151497Sru			struct scsi_inquiry_data *inq_data,
2397151497Sru			uint8_t *block_bits);
2398151497Sruint scsi_get_stream_info(struct scsi_sense_data *sense_data, u_int sense_len,
2399104862Sru			 struct scsi_inquiry_data *inq_data,
2400104862Sru			 uint8_t *stream_bits);
2401104862Sruvoid scsi_info_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len,
2402104862Sru		    struct scsi_inquiry_data *inq_data, uint64_t info);
2403104862Sruvoid scsi_command_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len,
2404104862Sru		       struct scsi_inquiry_data *inq_data, uint64_t csi);
2405151497Sruvoid scsi_progress_sbuf(struct sbuf *sb, uint16_t progress);
2406104862Sruint scsi_sks_sbuf(struct sbuf *sb, int sense_key, uint8_t *sks);
2407104862Sruvoid scsi_fru_sbuf(struct sbuf *sb, uint64_t fru);
2408151497Sruvoid scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info);
2409151497Sruvoid scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits, uint64_t info);
2410151497Sruvoid scsi_sense_info_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2411104862Sru			  u_int sense_len, uint8_t *cdb, int cdb_len,
2412104862Sru			  struct scsi_inquiry_data *inq_data,
2413104862Sru			  struct scsi_sense_desc_header *header);
2414104862Sru
2415104862Sruvoid scsi_sense_command_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2416151497Sru			     u_int sense_len, uint8_t *cdb, int cdb_len,
2417104862Sru			     struct scsi_inquiry_data *inq_data,
2418104862Sru			     struct scsi_sense_desc_header *header);
2419104862Sruvoid scsi_sense_sks_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2420104862Sru			 u_int sense_len, uint8_t *cdb, int cdb_len,
2421104862Sru			 struct scsi_inquiry_data *inq_data,
2422151497Sru			 struct scsi_sense_desc_header *header);
2423104862Sruvoid scsi_sense_fru_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2424104862Sru			 u_int sense_len, uint8_t *cdb, int cdb_len,
2425104862Sru			 struct scsi_inquiry_data *inq_data,
2426104862Sru			 struct scsi_sense_desc_header *header);
2427104862Sruvoid scsi_sense_stream_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2428104862Sru			    u_int sense_len, uint8_t *cdb, int cdb_len,
2429151497Sru			    struct scsi_inquiry_data *inq_data,
2430104862Sru			    struct scsi_sense_desc_header *header);
2431104862Sruvoid scsi_sense_block_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2432104862Sru			   u_int sense_len, uint8_t *cdb, int cdb_len,
2433104862Sru			   struct scsi_inquiry_data *inq_data,
2434104862Sru			   struct scsi_sense_desc_header *header);
2435151497Sruvoid scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2436104862Sru			      u_int sense_len, uint8_t *cdb, int cdb_len,
2437104862Sru			      struct scsi_inquiry_data *inq_data,
2438104862Sru			      struct scsi_sense_desc_header *header);
2439104862Sruvoid scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2440104862Sru			     u_int sense_len, uint8_t *cdb, int cdb_len,
2441104862Sru			     struct scsi_inquiry_data *inq_data,
2442104862Sru			     struct scsi_sense_desc_header *header);
2443104862Sruvoid scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
2444104862Sru			  u_int sense_len, uint8_t *cdb, int cdb_len,
2445104862Sru			  struct scsi_inquiry_data *inq_data,
2446104862Sru			  struct scsi_sense_desc_header *header);
2447104862Sruscsi_sense_data_type scsi_sense_type(struct scsi_sense_data *sense_data);
2448151497Sru
2449151497Sruvoid scsi_sense_only_sbuf(struct scsi_sense_data *sense, u_int sense_len,
2450151497Sru			  struct sbuf *sb, char *path_str,
2451151497Sru			  struct scsi_inquiry_data *inq_data, uint8_t *cdb,
2452151497Sru			  int cdb_len);
2453104862Sru
2454104862Sru#ifdef _KERNEL
2455104862Sruint		scsi_command_string(struct ccb_scsiio *csio, struct sbuf *sb);
2456104862Sruint		scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
2457104862Sru				scsi_sense_string_flags flags);
2458151497Sruchar *		scsi_sense_string(struct ccb_scsiio *csio,
2459151497Sru				  char *str, int str_len);
2460151497Sruvoid		scsi_sense_print(struct ccb_scsiio *csio);
2461151497Sruint 		scsi_vpd_supported_page(struct cam_periph *periph,
2462151497Sru					uint8_t page_id);
2463151497Sru#else /* _KERNEL */
2464151497Sruint		scsi_command_string(struct cam_device *device,
2465151497Sru				    struct ccb_scsiio *csio, struct sbuf *sb);
2466151497Sruint		scsi_sense_sbuf(struct cam_device *device,
2467104862Sru				struct ccb_scsiio *csio, struct sbuf *sb,
2468104862Sru				scsi_sense_string_flags flags);
2469104862Sruchar *		scsi_sense_string(struct cam_device *device,
2470104862Sru				  struct ccb_scsiio *csio,
2471104862Sru				  char *str, int str_len);
2472104862Sruvoid		scsi_sense_print(struct cam_device *device,
2473104862Sru				 struct ccb_scsiio *csio, FILE *ofile);
2474104862Sru#endif /* _KERNEL */
2475104862Sru
2476104862Sruconst char *	scsi_op_desc(u_int16_t opcode,
2477104862Sru			     struct scsi_inquiry_data *inq_data);
2478104862Sruchar *		scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
2479104862Sru				size_t len);
2480104862Sru
2481104862Sruvoid		scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
2482104862Sruvoid		scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data);
2483104862Sru
2484104862Sruu_int		scsi_calc_syncsrate(u_int period_factor);
2485104862Sruu_int		scsi_calc_syncparam(u_int period);
2486104862Sru
2487104862Srutypedef int	(*scsi_devid_checkfn_t)(uint8_t *);
2488104862Sruint		scsi_devid_is_naa_ieee_reg(uint8_t *bufp);
2489104862Sruint		scsi_devid_is_sas_target(uint8_t *bufp);
2490104862Sruint		scsi_devid_is_lun_eui64(uint8_t *bufp);
2491104862Sruint		scsi_devid_is_lun_naa(uint8_t *bufp);
2492104862Sruint		scsi_devid_is_lun_name(uint8_t *bufp);
2493104862Sruint		scsi_devid_is_lun_t10(uint8_t *bufp);
2494104862Srustruct scsi_vpd_id_descriptor *
2495104862Sru		scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
2496104862Sru			       scsi_devid_checkfn_t ck_fn);
2497104862Sru
2498104862Sruvoid		scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
2499104862Sru				     void (*cbfcnp)(struct cam_periph *,
2500104862Sru						    union ccb *),
2501104862Sru				     u_int8_t tag_action,
2502104862Sru				     u_int8_t sense_len, u_int32_t timeout);
2503104862Sru
2504104862Sruvoid		scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
2505104862Sru				   void (*cbfcnp)(struct cam_periph *,
2506104862Sru						  union ccb *),
2507151497Sru				   void *data_ptr, u_int8_t dxfer_len,
2508151497Sru				   u_int8_t tag_action, u_int8_t sense_len,
2509151497Sru				   u_int32_t timeout);
2510151497Sru
2511151497Sruvoid		scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
2512151497Sru			     void (*cbfcnp)(struct cam_periph *, union ccb *),
2513151497Sru			     u_int8_t tag_action, u_int8_t *inq_buf,
2514151497Sru			     u_int32_t inq_len, int evpd, u_int8_t page_code,
2515151497Sru			     u_int8_t sense_len, u_int32_t timeout);
2516151497Sru
2517151497Sruvoid		scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
2518151497Sru				void (*cbfcnp)(struct cam_periph *,
2519151497Sru					       union ccb *),
2520151497Sru				u_int8_t tag_action, int dbd,
2521151497Sru				u_int8_t page_code, u_int8_t page,
2522151497Sru				u_int8_t *param_buf, u_int32_t param_len,
2523151497Sru				u_int8_t sense_len, u_int32_t timeout);
2524104862Sru
2525104862Sruvoid		scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
2526104862Sru				    void (*cbfcnp)(struct cam_periph *,
2527104862Sru						   union ccb *),
2528104862Sru				    u_int8_t tag_action, int dbd,
2529104862Sru				    u_int8_t page_code, u_int8_t page,
2530104862Sru				    u_int8_t *param_buf, u_int32_t param_len,
2531104862Sru				    int minimum_cmd_size, u_int8_t sense_len,
2532104862Sru				    u_int32_t timeout);
2533104862Sru
2534104862Sruvoid		scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
2535104862Sru				 void (*cbfcnp)(struct cam_periph *,
2536104862Sru						union ccb *),
2537104862Sru				 u_int8_t tag_action, int scsi_page_fmt,
2538104862Sru				 int save_pages, u_int8_t *param_buf,
2539104862Sru				 u_int32_t param_len, u_int8_t sense_len,
2540104862Sru				 u_int32_t timeout);
2541104862Sru
2542104862Sruvoid		scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
2543104862Sru				     void (*cbfcnp)(struct cam_periph *,
2544104862Sru						    union ccb *),
2545104862Sru				     u_int8_t tag_action, int scsi_page_fmt,
2546104862Sru				     int save_pages, u_int8_t *param_buf,
2547104862Sru				     u_int32_t param_len, int minimum_cmd_size,
2548104862Sru				     u_int8_t sense_len, u_int32_t timeout);
2549104862Sru
2550104862Sruvoid		scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries,
2551104862Sru			       void (*cbfcnp)(struct cam_periph *, union ccb *),
2552104862Sru			       u_int8_t tag_action, u_int8_t page_code,
2553104862Sru			       u_int8_t page, int save_pages, int ppc,
2554104862Sru			       u_int32_t paramptr, u_int8_t *param_buf,
2555104862Sru			       u_int32_t param_len, u_int8_t sense_len,
2556104862Sru			       u_int32_t timeout);
2557104862Sru
2558104862Sruvoid		scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries,
2559104862Sru				void (*cbfcnp)(struct cam_periph *,
2560104862Sru				union ccb *), u_int8_t tag_action,
2561104862Sru				u_int8_t page_code, int save_pages,
2562104862Sru				int pc_reset, u_int8_t *param_buf,
2563104862Sru				u_int32_t param_len, u_int8_t sense_len,
2564104862Sru				u_int32_t timeout);
2565104862Sru
2566104862Sruvoid		scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
2567104862Sru			     void (*cbfcnp)(struct cam_periph *, union ccb *),
2568104862Sru			     u_int8_t tag_action, u_int8_t action,
2569104862Sru			     u_int8_t sense_len, u_int32_t timeout);
2570104862Sru
2571104862Sruvoid		scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
2572104862Sru				   void (*cbfcnp)(struct cam_periph *,
2573104862Sru				   union ccb *), u_int8_t tag_action,
2574104862Sru				   struct scsi_read_capacity_data *,
2575104862Sru				   u_int8_t sense_len, u_int32_t timeout);
2576104862Sruvoid		scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries,
2577104862Sru				      void (*cbfcnp)(struct cam_periph *,
2578104862Sru				      union ccb *), uint8_t tag_action,
2579104862Sru				      uint64_t lba, int reladr, int pmi,
2580104862Sru				      uint8_t *rcap_buf, int rcap_buf_len,
2581104862Sru				      uint8_t sense_len, uint32_t timeout);
2582104862Sru
2583104862Sruvoid		scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries,
2584104862Sru				 void (*cbfcnp)(struct cam_periph *,
2585104862Sru				 union ccb *), u_int8_t tag_action,
2586104862Sru				 u_int8_t select_report,
2587104862Sru				 struct scsi_report_luns_data *rpl_buf,
2588104862Sru				 u_int32_t alloc_len, u_int8_t sense_len,
2589104862Sru				 u_int32_t timeout);
2590104862Sru
2591104862Sruvoid		scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
2592104862Sru				 void (*cbfcnp)(struct cam_periph *,
2593151497Sru				 union ccb *), u_int8_t tag_action,
2594151497Sru				 u_int8_t pdf,
2595151497Sru				 void *buf,
2596151497Sru				 u_int32_t alloc_len, u_int8_t sense_len,
2597151497Sru				 u_int32_t timeout);
2598151497Sru
2599151497Sruvoid		scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
2600151497Sru				 void (*cbfcnp)(struct cam_periph *,
2601151497Sru				 union ccb *), u_int8_t tag_action, void *buf,
2602151497Sru				 u_int32_t alloc_len, u_int8_t sense_len,
2603104862Sru				 u_int32_t timeout);
2604104862Sru
2605104862Sruvoid		scsi_synchronize_cache(struct ccb_scsiio *csio,
2606104862Sru				       u_int32_t retries,
2607151497Sru				       void (*cbfcnp)(struct cam_periph *,
2608104862Sru				       union ccb *), u_int8_t tag_action,
2609104862Sru				       u_int32_t begin_lba, u_int16_t lb_count,
2610104862Sru				       u_int8_t sense_len, u_int32_t timeout);
2611104862Sru
2612104862Sruvoid scsi_receive_diagnostic_results(struct ccb_scsiio *csio, u_int32_t retries,
2613104862Sru				     void (*cbfcnp)(struct cam_periph *,
2614151497Sru						    union ccb*),
2615104862Sru				     uint8_t tag_action, int pcv,
2616104862Sru				     uint8_t page_code, uint8_t *data_ptr,
2617104862Sru				     uint16_t allocation_length,
2618104862Sru				     uint8_t sense_len, uint32_t timeout);
2619104862Sru
2620151497Sruvoid scsi_send_diagnostic(struct ccb_scsiio *csio, u_int32_t retries,
2621104862Sru			  void (*cbfcnp)(struct cam_periph *, union ccb *),
2622104862Sru			  uint8_t tag_action, int unit_offline,
2623104862Sru			  int device_offline, int self_test, int page_format,
2624151497Sru			  int self_test_code, uint8_t *data_ptr,
2625151497Sru			  uint16_t param_list_length, uint8_t sense_len,
2626151497Sru			  uint32_t timeout);
2627151497Sru
2628151497Sruvoid scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
2629151497Sru			void (*cbfcnp)(struct cam_periph *, union ccb*),
2630151497Sru			uint8_t tag_action, int mode,
2631151497Sru			uint8_t buffer_id, u_int32_t offset,
2632151497Sru			uint8_t *data_ptr, uint32_t allocation_length,
2633151497Sru			uint8_t sense_len, uint32_t timeout);
2634151497Sru
2635151497Sruvoid scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
2636151497Sru			void (*cbfcnp)(struct cam_periph *, union ccb *),
2637151497Sru			uint8_t tag_action, int mode,
2638104862Sru			uint8_t buffer_id, u_int32_t offset,
2639104862Sru			uint8_t *data_ptr, uint32_t param_list_length,
2640104862Sru			uint8_t sense_len, uint32_t timeout);
2641151497Sru
2642104862Sru#define	SCSI_RW_READ	0x0001
2643104862Sru#define	SCSI_RW_WRITE	0x0002
2644104862Sru#define	SCSI_RW_DIRMASK	0x0003
2645104862Sru#define	SCSI_RW_BIO	0x1000
2646151497Sruvoid scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
2647104862Sru		     void (*cbfcnp)(struct cam_periph *, union ccb *),
2648151497Sru		     u_int8_t tag_action, int readop, u_int8_t byte2,
2649151497Sru		     int minimum_cmd_size, u_int64_t lba,
2650151497Sru		     u_int32_t block_count, u_int8_t *data_ptr,
2651151497Sru		     u_int32_t dxfer_len, u_int8_t sense_len,
2652151497Sru		     u_int32_t timeout);
2653151497Sru
2654151497Sruvoid scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries,
2655151497Sru		     void (*cbfcnp)(struct cam_periph *, union ccb *),
2656104862Sru		     u_int8_t tag_action, u_int8_t byte2,
2657104862Sru		     int minimum_cmd_size, u_int64_t lba,
2658151497Sru		     u_int32_t block_count, u_int8_t *data_ptr,
2659151497Sru		     u_int32_t dxfer_len, u_int8_t sense_len,
2660104862Sru		     u_int32_t timeout);
2661104862Sru
2662104862Sruvoid scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t retries,
2663104862Sru		       void (*cbfcnp)(struct cam_periph *, union ccb *),
2664104862Sru		       u_int8_t tag_action, u_int8_t *data_ptr,
2665151497Sru		       u_int16_t dxfer_len, u_int8_t sense_len,
2666104862Sru		       u_int32_t timeout);
2667104862Sru
2668104862Sruvoid scsi_ata_trim(struct ccb_scsiio *csio, u_int32_t retries,
2669104862Sru	           void (*cbfcnp)(struct cam_periph *, union ccb *),
2670104862Sru	           u_int8_t tag_action, u_int16_t block_count,
2671104862Sru	           u_int8_t *data_ptr, u_int16_t dxfer_len,
2672104862Sru	           u_int8_t sense_len, u_int32_t timeout);
2673104862Sru
2674104862Sruvoid scsi_ata_pass_16(struct ccb_scsiio *csio, u_int32_t retries,
2675104862Sru		      void (*cbfcnp)(struct cam_periph *, union ccb *),
2676104862Sru		      u_int32_t flags, u_int8_t tag_action,
2677104862Sru		      u_int8_t protocol, u_int8_t ata_flags, u_int16_t features,
2678114402Sru		      u_int16_t sector_count, uint64_t lba, u_int8_t command,
2679114402Sru		      u_int8_t control, u_int8_t *data_ptr, u_int16_t dxfer_len,
2680114402Sru		      u_int8_t sense_len, u_int32_t timeout);
2681114402Sru
2682114402Sruvoid scsi_unmap(struct ccb_scsiio *csio, u_int32_t retries,
2683114402Sru		void (*cbfcnp)(struct cam_periph *, union ccb *),
2684114402Sru		u_int8_t tag_action, u_int8_t byte2,
2685114402Sru		u_int8_t *data_ptr, u_int16_t dxfer_len,
2686114402Sru		u_int8_t sense_len, u_int32_t timeout);
2687151497Sru
2688151497Sruvoid scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
2689151497Sru		     void (*cbfcnp)(struct cam_periph *, union ccb *),
2690151497Sru		     u_int8_t tag_action, int start, int load_eject,
2691114402Sru		     int immediate, u_int8_t sense_len, u_int32_t timeout);
2692114402Sru
2693114402Sruint		scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
2694114402Sruint		scsi_static_inquiry_match(caddr_t inqbuffer,
2695114402Sru					  caddr_t table_entry);
2696114402Sruint		scsi_devid_match(uint8_t *rhs, size_t rhs_len,
2697114402Sru				 uint8_t *lhs, size_t lhs_len);
2698151497Sru
2699114402Sruvoid scsi_extract_sense(struct scsi_sense_data *sense, int *error_code,
2700151497Sru			int *sense_key, int *asc, int *ascq);
2701114402Sruint scsi_extract_sense_ccb(union ccb *ccb, int *error_code, int *sense_key,
2702114402Sru			   int *asc, int *ascq);
2703151497Sruvoid scsi_extract_sense_len(struct scsi_sense_data *sense,
2704114402Sru			    u_int sense_len, int *error_code, int *sense_key,
2705151497Sru			    int *asc, int *ascq, int show_errors);
2706151497Sruint scsi_get_sense_key(struct scsi_sense_data *sense, u_int sense_len,
2707151497Sru		       int show_errors);
2708151497Sruint scsi_get_asc(struct scsi_sense_data *sense, u_int sense_len,
2709151497Sru		 int show_errors);
2710151497Sruint scsi_get_ascq(struct scsi_sense_data *sense, u_int sense_len,
2711114402Sru		  int show_errors);
2712114402Srustatic __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
2713114402Srustatic __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
2714104862Srustatic __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
2715104862Srustatic __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes);
2716104862Srustatic __inline uint32_t scsi_2btoul(const uint8_t *bytes);
2717104862Srustatic __inline uint32_t scsi_3btoul(const uint8_t *bytes);
2718104862Srustatic __inline int32_t scsi_3btol(const uint8_t *bytes);
2719104862Srustatic __inline uint32_t scsi_4btoul(const uint8_t *bytes);
2720104862Srustatic __inline uint64_t scsi_8btou64(const uint8_t *bytes);
2721104862Srustatic __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
2722104862Srustatic __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
2723104862Sru
2724104862Srustatic __inline void
2725104862Sruscsi_ulto2b(u_int32_t val, u_int8_t *bytes)
2726104862Sru{
2727104862Sru
2728104862Sru	bytes[0] = (val >> 8) & 0xff;
2729104862Sru	bytes[1] = val & 0xff;
2730104862Sru}
2731104862Sru
2732104862Srustatic __inline void
2733104862Sruscsi_ulto3b(u_int32_t val, u_int8_t *bytes)
2734104862Sru{
2735104862Sru
2736104862Sru	bytes[0] = (val >> 16) & 0xff;
2737104862Sru	bytes[1] = (val >> 8) & 0xff;
2738151497Sru	bytes[2] = val & 0xff;
2739151497Sru}
2740104862Sru
2741104862Srustatic __inline void
2742104862Sruscsi_ulto4b(u_int32_t val, u_int8_t *bytes)
2743104862Sru{
2744104862Sru
2745104862Sru	bytes[0] = (val >> 24) & 0xff;
2746104862Sru	bytes[1] = (val >> 16) & 0xff;
2747104862Sru	bytes[2] = (val >> 8) & 0xff;
2748104862Sru	bytes[3] = val & 0xff;
2749104862Sru}
2750104862Sru
2751104862Srustatic __inline void
2752104862Sruscsi_u64to8b(u_int64_t val, u_int8_t *bytes)
2753104862Sru{
2754104862Sru
2755104862Sru	bytes[0] = (val >> 56) & 0xff;
2756104862Sru	bytes[1] = (val >> 48) & 0xff;
2757104862Sru	bytes[2] = (val >> 40) & 0xff;
2758104862Sru	bytes[3] = (val >> 32) & 0xff;
2759104862Sru	bytes[4] = (val >> 24) & 0xff;
2760104862Sru	bytes[5] = (val >> 16) & 0xff;
2761104862Sru	bytes[6] = (val >> 8) & 0xff;
2762104862Sru	bytes[7] = val & 0xff;
2763104862Sru}
2764104862Sru
2765104862Srustatic __inline uint32_t
2766104862Sruscsi_2btoul(const uint8_t *bytes)
2767104862Sru{
2768104862Sru	uint32_t rv;
2769104862Sru
2770104862Sru	rv = (bytes[0] << 8) |
2771104862Sru	     bytes[1];
2772104862Sru	return (rv);
2773104862Sru}
2774104862Sru
2775104862Srustatic __inline uint32_t
2776104862Sruscsi_3btoul(const uint8_t *bytes)
2777104862Sru{
2778104862Sru	uint32_t rv;
2779104862Sru
2780104862Sru	rv = (bytes[0] << 16) |
2781104862Sru	     (bytes[1] << 8) |
2782104862Sru	     bytes[2];
2783104862Sru	return (rv);
2784151497Sru}
2785151497Sru
2786151497Srustatic __inline int32_t
2787151497Sruscsi_3btol(const uint8_t *bytes)
2788151497Sru{
2789151497Sru	uint32_t rc = scsi_3btoul(bytes);
2790151497Sru
2791151497Sru	if (rc & 0x00800000)
2792151497Sru		rc |= 0xff000000;
2793151497Sru
2794151497Sru	return (int32_t) rc;
2795151497Sru}
2796151497Sru
2797151497Srustatic __inline uint32_t
2798151497Sruscsi_4btoul(const uint8_t *bytes)
2799151497Sru{
2800151497Sru	uint32_t rv;
2801151497Sru
2802151497Sru	rv = (bytes[0] << 24) |
2803151497Sru	     (bytes[1] << 16) |
2804151497Sru	     (bytes[2] << 8) |
2805151497Sru	     bytes[3];
2806151497Sru	return (rv);
2807151497Sru}
2808151497Sru
2809151497Srustatic __inline uint64_t
2810151497Sruscsi_8btou64(const uint8_t *bytes)
2811151497Sru{
2812151497Sru        uint64_t rv;
2813151497Sru
2814151497Sru	rv = (((uint64_t)bytes[0]) << 56) |
2815151497Sru	     (((uint64_t)bytes[1]) << 48) |
2816151497Sru	     (((uint64_t)bytes[2]) << 40) |
2817151497Sru	     (((uint64_t)bytes[3]) << 32) |
2818151497Sru	     (((uint64_t)bytes[4]) << 24) |
2819151497Sru	     (((uint64_t)bytes[5]) << 16) |
2820151497Sru	     (((uint64_t)bytes[6]) << 8) |
2821151497Sru	     bytes[7];
2822151497Sru	return (rv);
2823151497Sru}
2824151497Sru
2825151497Sru/*
2826151497Sru * Given the pointer to a returned mode sense buffer, return a pointer to
2827151497Sru * the start of the first mode page.
2828151497Sru */
2829151497Srustatic __inline void *
2830151497Srufind_mode_page_6(struct scsi_mode_header_6 *mode_header)
2831151497Sru{
2832151497Sru	void *page_start;
2833151497Sru
2834151497Sru	page_start = (void *)((u_int8_t *)&mode_header[1] +
2835151497Sru			      mode_header->blk_desc_len);
2836151497Sru
2837151497Sru	return(page_start);
2838151497Sru}
2839151497Sru
2840151497Srustatic __inline void *
2841151497Srufind_mode_page_10(struct scsi_mode_header_10 *mode_header)
2842151497Sru{
2843151497Sru	void *page_start;
2844151497Sru
2845151497Sru	page_start = (void *)((u_int8_t *)&mode_header[1] +
2846151497Sru			       scsi_2btoul(mode_header->blk_desc_len));
2847151497Sru
2848151497Sru	return(page_start);
2849151497Sru}
2850151497Sru
2851151497Sru__END_DECLS
2852151497Sru
2853151497Sru#endif /*_SCSI_SCSI_ALL_H*/
2854151497Sru