scsi_all.h revision 216088
1139743Simp/*-
239213Sgibbs * Largely written by Julian Elischer (julian@tfs.com)
339213Sgibbs * for TRW Financial Systems.
439213Sgibbs *
539213Sgibbs * TRW Financial Systems, in accordance with their agreement with Carnegie
639213Sgibbs * Mellon University, makes this software available to CMU to distribute
739213Sgibbs * or use in any manner that they see fit as long as this message is kept with
839213Sgibbs * the software. For this reason TFS also grants any other persons or
939213Sgibbs * organisations permission to use or modify this software.
1039213Sgibbs *
1139213Sgibbs * TFS supplies this software to be publicly redistributed
1239213Sgibbs * on the understanding that TFS is not responsible for the correct
1339213Sgibbs * functioning of this software in any circumstances.
1439213Sgibbs *
1539213Sgibbs * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
1639213Sgibbs *
1750477Speter * $FreeBSD: head/sys/cam/scsi/scsi_all.h 216088 2010-11-30 22:39:46Z ken $
1839213Sgibbs */
1939213Sgibbs
2039213Sgibbs/*
2139213Sgibbs * SCSI general  interface description
2239213Sgibbs */
2339213Sgibbs
2439213Sgibbs#ifndef	_SCSI_SCSI_ALL_H
25208905Smjacob#define	_SCSI_SCSI_ALL_H 1
2639213Sgibbs
2739213Sgibbs#include <sys/cdefs.h>
2839213Sgibbs
2955205Speter#ifdef _KERNEL
3039213Sgibbs/*
3147413Sgibbs * This is the number of seconds we wait for devices to settle after a SCSI
3247413Sgibbs * bus reset.
3347413Sgibbs */
34102862Sbrooksextern int scsi_delay;
3555205Speter#endif /* _KERNEL */
3647413Sgibbs
3747413Sgibbs/*
3839213Sgibbs * SCSI command format
3939213Sgibbs */
4039213Sgibbs
4139213Sgibbs/*
4239213Sgibbs * Define dome bits that are in ALL (or a lot of) scsi commands
4339213Sgibbs */
44208905Smjacob#define	SCSI_CTL_LINK		0x01
45208905Smjacob#define	SCSI_CTL_FLAG		0x02
46208905Smjacob#define	SCSI_CTL_VENDOR		0xC0
4739213Sgibbs#define	SCSI_CMD_LUN		0xA0	/* these two should not be needed */
4839213Sgibbs#define	SCSI_CMD_LUN_SHIFT	5	/* LUN in the cmd is no longer SCSI */
4939213Sgibbs
50208905Smjacob#define	SCSI_MAX_CDBLEN		16	/*
5139213Sgibbs					 * 16 byte commands are in the
5239213Sgibbs					 * SCSI-3 spec
5339213Sgibbs					 */
5439213Sgibbs#if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN)
5539213Sgibbs#error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN"
5639213Sgibbs#endif
5739213Sgibbs
5863171Smjacob/* 6byte CDBs special case 0 length to be 256 */
59208905Smjacob#define	SCSI_CDB6_LEN(len)	((len) == 0 ? 256 : len)
6063171Smjacob
6139213Sgibbs/*
6239213Sgibbs * This type defines actions to be taken when a particular sense code is
6339213Sgibbs * received.  Right now, these flags are only defined to take up 16 bits,
6439213Sgibbs * but can be expanded in the future if necessary.
6539213Sgibbs */
6639213Sgibbstypedef enum {
6739213Sgibbs	SS_NOP      = 0x000000,	/* Do nothing */
6839213Sgibbs	SS_RETRY    = 0x010000,	/* Retry the command */
6939213Sgibbs	SS_FAIL     = 0x020000,	/* Bail out */
7039213Sgibbs	SS_START    = 0x030000,	/* Send a Start Unit command to the device,
7139213Sgibbs				 * then retry the original command.
7239213Sgibbs				 */
7339213Sgibbs	SS_TUR      = 0x040000,	/* Send a Test Unit Ready command to the
7439213Sgibbs				 * device, then retry the original command.
7539213Sgibbs				 */
7674840Sken	SS_REQSENSE = 0x050000,	/* Send a RequestSense command to the
7774840Sken				 * device, then retry the original command.
7839213Sgibbs				 */
7939213Sgibbs	SS_MASK     = 0xff0000
8039213Sgibbs} scsi_sense_action;
8139213Sgibbs
8239213Sgibbstypedef enum {
8339213Sgibbs	SSQ_NONE		= 0x0000,
8439213Sgibbs	SSQ_DECREMENT_COUNT	= 0x0100,  /* Decrement the retry count */
8539213Sgibbs	SSQ_MANY		= 0x0200,  /* send lots of recovery commands */
8639213Sgibbs	SSQ_RANGE		= 0x0400,  /*
8774840Sken					    * This table entry represents the
8874840Sken					    * end of a range of ASCQs that
8974840Sken					    * have identical error actions
9074840Sken					    * and text.
9139213Sgibbs					    */
9239213Sgibbs	SSQ_PRINT_SENSE		= 0x0800,
9339213Sgibbs	SSQ_MASK		= 0xff00
9439213Sgibbs} scsi_sense_action_qualifier;
9539213Sgibbs
9639213Sgibbs/* Mask for error status values */
97208905Smjacob#define	SS_ERRMASK	0xff
9839213Sgibbs
9974840Sken/* The default, retyable, error action */
100208905Smjacob#define	SS_RDEF		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
10139213Sgibbs
10274840Sken/* The retyable, error action, with table specified error code */
103208905Smjacob#define	SS_RET		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
10439213Sgibbs
10574840Sken/* Fatal error action, with table specified error code */
106208905Smjacob#define	SS_FATAL	SS_FAIL|SSQ_PRINT_SENSE
10739213Sgibbs
10839213Sgibbsstruct scsi_generic
10939213Sgibbs{
11039213Sgibbs	u_int8_t opcode;
11139213Sgibbs	u_int8_t bytes[11];
11239213Sgibbs};
11339213Sgibbs
11439213Sgibbsstruct scsi_request_sense
11539213Sgibbs{
11639213Sgibbs	u_int8_t opcode;
11739213Sgibbs	u_int8_t byte2;
11839213Sgibbs	u_int8_t unused[2];
11939213Sgibbs	u_int8_t length;
12039213Sgibbs	u_int8_t control;
12139213Sgibbs};
12239213Sgibbs
12339213Sgibbsstruct scsi_test_unit_ready
12439213Sgibbs{
12539213Sgibbs	u_int8_t opcode;
12639213Sgibbs	u_int8_t byte2;
12739213Sgibbs	u_int8_t unused[3];
12839213Sgibbs	u_int8_t control;
12939213Sgibbs};
13039213Sgibbs
13139213Sgibbsstruct scsi_send_diag
13239213Sgibbs{
13339213Sgibbs	u_int8_t opcode;
13439213Sgibbs	u_int8_t byte2;
13539213Sgibbs#define	SSD_UOL		0x01
13639213Sgibbs#define	SSD_DOL		0x02
13739213Sgibbs#define	SSD_SELFTEST	0x04
13839213Sgibbs#define	SSD_PF		0x10
13939213Sgibbs	u_int8_t unused[1];
14039213Sgibbs	u_int8_t paramlen[2];
14139213Sgibbs	u_int8_t control;
14239213Sgibbs};
14339213Sgibbs
14439213Sgibbsstruct scsi_sense
14539213Sgibbs{
14639213Sgibbs	u_int8_t opcode;
14739213Sgibbs	u_int8_t byte2;
14839213Sgibbs	u_int8_t unused[2];
14939213Sgibbs	u_int8_t length;
15039213Sgibbs	u_int8_t control;
15139213Sgibbs};
15239213Sgibbs
15339213Sgibbsstruct scsi_inquiry
15439213Sgibbs{
15539213Sgibbs	u_int8_t opcode;
15639213Sgibbs	u_int8_t byte2;
15739213Sgibbs#define	SI_EVPD 0x01
15839213Sgibbs	u_int8_t page_code;
15939213Sgibbs	u_int8_t reserved;
16039213Sgibbs	u_int8_t length;
16139213Sgibbs	u_int8_t control;
16239213Sgibbs};
16339213Sgibbs
16439213Sgibbsstruct scsi_mode_sense_6
16539213Sgibbs{
16639213Sgibbs	u_int8_t opcode;
16739213Sgibbs	u_int8_t byte2;
16839213Sgibbs#define	SMS_DBD				0x08
16939213Sgibbs	u_int8_t page;
17039213Sgibbs#define	SMS_PAGE_CODE 			0x3F
171208905Smjacob#define	SMS_VENDOR_SPECIFIC_PAGE	0x00
172208905Smjacob#define	SMS_DISCONNECT_RECONNECT_PAGE	0x02
173208905Smjacob#define	SMS_FORMAT_DEVICE_PAGE		0x03
174208905Smjacob#define	SMS_GEOMETRY_PAGE		0x04
175208905Smjacob#define	SMS_CACHE_PAGE			0x08
176208905Smjacob#define	SMS_PERIPHERAL_DEVICE_PAGE	0x09
177208905Smjacob#define	SMS_CONTROL_MODE_PAGE		0x0A
178208905Smjacob#define	SMS_PROTO_SPECIFIC_PAGE		0x19
179208905Smjacob#define	SMS_INFO_EXCEPTIONS_PAGE	0x1C
180208905Smjacob#define	SMS_ALL_PAGES_PAGE		0x3F
18139213Sgibbs#define	SMS_PAGE_CTRL_MASK		0xC0
18239213Sgibbs#define	SMS_PAGE_CTRL_CURRENT 		0x00
18339213Sgibbs#define	SMS_PAGE_CTRL_CHANGEABLE 	0x40
18439213Sgibbs#define	SMS_PAGE_CTRL_DEFAULT 		0x80
18539213Sgibbs#define	SMS_PAGE_CTRL_SAVED 		0xC0
18639213Sgibbs	u_int8_t unused;
18739213Sgibbs	u_int8_t length;
18839213Sgibbs	u_int8_t control;
18939213Sgibbs};
19039213Sgibbs
19139213Sgibbsstruct scsi_mode_sense_10
19239213Sgibbs{
19339213Sgibbs	u_int8_t opcode;
19439213Sgibbs	u_int8_t byte2;		/* same bits as small version */
19539213Sgibbs	u_int8_t page; 		/* same bits as small version */
19639213Sgibbs	u_int8_t unused[4];
19739213Sgibbs	u_int8_t length[2];
19839213Sgibbs	u_int8_t control;
19939213Sgibbs};
20039213Sgibbs
20139213Sgibbsstruct scsi_mode_select_6
20239213Sgibbs{
20339213Sgibbs	u_int8_t opcode;
20439213Sgibbs	u_int8_t byte2;
20539213Sgibbs#define	SMS_SP	0x01
20639213Sgibbs#define	SMS_PF	0x10
20739213Sgibbs	u_int8_t unused[2];
20839213Sgibbs	u_int8_t length;
20939213Sgibbs	u_int8_t control;
21039213Sgibbs};
21139213Sgibbs
21239213Sgibbsstruct scsi_mode_select_10
21339213Sgibbs{
21439213Sgibbs	u_int8_t opcode;
21539213Sgibbs	u_int8_t byte2;		/* same bits as small version */
21639213Sgibbs	u_int8_t unused[5];
21739213Sgibbs	u_int8_t length[2];
21839213Sgibbs	u_int8_t control;
21939213Sgibbs};
22039213Sgibbs
22139213Sgibbs/*
22239213Sgibbs * When sending a mode select to a tape drive, the medium type must be 0.
22339213Sgibbs */
22439213Sgibbsstruct scsi_mode_hdr_6
22539213Sgibbs{
22639213Sgibbs	u_int8_t datalen;
22739213Sgibbs	u_int8_t medium_type;
22839213Sgibbs	u_int8_t dev_specific;
22939213Sgibbs	u_int8_t block_descr_len;
23039213Sgibbs};
23139213Sgibbs
23239213Sgibbsstruct scsi_mode_hdr_10
23339213Sgibbs{
23439213Sgibbs	u_int8_t datalen[2];
23539213Sgibbs	u_int8_t medium_type;
23639213Sgibbs	u_int8_t dev_specific;
23739213Sgibbs	u_int8_t reserved[2];
23839213Sgibbs	u_int8_t block_descr_len[2];
23939213Sgibbs};
24039213Sgibbs
24139213Sgibbsstruct scsi_mode_block_descr
24239213Sgibbs{
24339213Sgibbs	u_int8_t density_code;
24439213Sgibbs	u_int8_t num_blocks[3];
24539213Sgibbs	u_int8_t reserved;
24639213Sgibbs	u_int8_t block_len[3];
24739213Sgibbs};
24839213Sgibbs
24982384Skbyancstruct scsi_log_sense
25082384Skbyanc{
25182384Skbyanc	u_int8_t opcode;
25282384Skbyanc	u_int8_t byte2;
25382384Skbyanc#define	SLS_SP				0x01
25482384Skbyanc#define	SLS_PPC				0x02
25582384Skbyanc	u_int8_t page;
25682384Skbyanc#define	SLS_PAGE_CODE 			0x3F
25782384Skbyanc#define	SLS_ALL_PAGES_PAGE		0x00
25882384Skbyanc#define	SLS_OVERRUN_PAGE		0x01
25982384Skbyanc#define	SLS_ERROR_WRITE_PAGE		0x02
26082384Skbyanc#define	SLS_ERROR_READ_PAGE		0x03
26182384Skbyanc#define	SLS_ERROR_READREVERSE_PAGE	0x04
26282384Skbyanc#define	SLS_ERROR_VERIFY_PAGE		0x05
26382384Skbyanc#define	SLS_ERROR_NONMEDIUM_PAGE	0x06
26482384Skbyanc#define	SLS_ERROR_LASTN_PAGE		0x07
265208905Smjacob#define	SLS_SELF_TEST_PAGE		0x10
266208905Smjacob#define	SLS_IE_PAGE			0x2f
26782384Skbyanc#define	SLS_PAGE_CTRL_MASK		0xC0
26882384Skbyanc#define	SLS_PAGE_CTRL_THRESHOLD		0x00
26982384Skbyanc#define	SLS_PAGE_CTRL_CUMULATIVE	0x40
27082384Skbyanc#define	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80
27182384Skbyanc#define	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0
27282384Skbyanc	u_int8_t reserved[2];
27382384Skbyanc	u_int8_t paramptr[2];
27482384Skbyanc	u_int8_t length[2];
27582384Skbyanc	u_int8_t control;
27682384Skbyanc};
27782384Skbyanc
27882384Skbyancstruct scsi_log_select
27982384Skbyanc{
28082384Skbyanc	u_int8_t opcode;
28182384Skbyanc	u_int8_t byte2;
28282384Skbyanc/*	SLS_SP				0x01 */
28382384Skbyanc#define	SLS_PCR				0x02
28482384Skbyanc	u_int8_t page;
28582384Skbyanc/*	SLS_PAGE_CTRL_MASK		0xC0 */
28682384Skbyanc/*	SLS_PAGE_CTRL_THRESHOLD		0x00 */
28782384Skbyanc/*	SLS_PAGE_CTRL_CUMULATIVE	0x40 */
28882384Skbyanc/*	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80 */
28982384Skbyanc/*	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0 */
29082384Skbyanc	u_int8_t reserved[4];
29182384Skbyanc	u_int8_t length[2];
29282384Skbyanc	u_int8_t control;
29382384Skbyanc};
29482384Skbyanc
29582384Skbyancstruct scsi_log_header
29682384Skbyanc{
29782384Skbyanc	u_int8_t page;
29882384Skbyanc	u_int8_t reserved;
29982384Skbyanc	u_int8_t datalen[2];
30082384Skbyanc};
30182384Skbyanc
30282384Skbyancstruct scsi_log_param_header {
30382384Skbyanc	u_int8_t param_code[2];
30482384Skbyanc	u_int8_t param_control;
30582384Skbyanc#define	SLP_LP				0x01
30682384Skbyanc#define	SLP_LBIN			0x02
30782384Skbyanc#define	SLP_TMC_MASK			0x0C
30882384Skbyanc#define	SLP_TMC_ALWAYS			0x00
30982384Skbyanc#define	SLP_TMC_EQUAL			0x04
31082384Skbyanc#define	SLP_TMC_NOTEQUAL		0x08
31182384Skbyanc#define	SLP_TMC_GREATER			0x0C
31282384Skbyanc#define	SLP_ETC				0x10
31382384Skbyanc#define	SLP_TSD				0x20
31482384Skbyanc#define	SLP_DS				0x40
31582384Skbyanc#define	SLP_DU				0x80
31682384Skbyanc	u_int8_t param_len;
31782384Skbyanc};
31882384Skbyanc
31939213Sgibbsstruct scsi_control_page {
32039213Sgibbs	u_int8_t page_code;
32139213Sgibbs	u_int8_t page_length;
32239213Sgibbs	u_int8_t rlec;
323208905Smjacob#define	SCB_RLEC			0x01	/*Report Log Exception Cond*/
32439213Sgibbs	u_int8_t queue_flags;
325208905Smjacob#define	SCP_QUEUE_ALG_MASK		0xF0
326208905Smjacob#define	SCP_QUEUE_ALG_RESTRICTED	0x00
327208905Smjacob#define	SCP_QUEUE_ALG_UNRESTRICTED	0x10
328208905Smjacob#define	SCP_QUEUE_ERR			0x02	/*Queued I/O aborted for CACs*/
329208905Smjacob#define	SCP_QUEUE_DQUE			0x01	/*Queued I/O disabled*/
33039213Sgibbs	u_int8_t eca_and_aen;
331208905Smjacob#define	SCP_EECA			0x80	/*Enable Extended CA*/
332208905Smjacob#define	SCP_RAENP			0x04	/*Ready AEN Permission*/
333208905Smjacob#define	SCP_UAAENP			0x02	/*UA AEN Permission*/
334208905Smjacob#define	SCP_EAENP			0x01	/*Error AEN Permission*/
33539213Sgibbs	u_int8_t reserved;
33639213Sgibbs	u_int8_t aen_holdoff_period[2];
33739213Sgibbs};
33839213Sgibbs
339172605Sscottlstruct scsi_cache_page {
340172605Sscottl	u_int8_t page_code;
341208905Smjacob#define	SCHP_PAGE_SAVABLE		0x80	/* Page is savable */
342172605Sscottl	u_int8_t page_length;
343172605Sscottl	u_int8_t cache_flags;
344208905Smjacob#define	SCHP_FLAGS_WCE			0x04	/* Write Cache Enable */
345208905Smjacob#define	SCHP_FLAGS_MF			0x02	/* Multiplication factor */
346208905Smjacob#define	SCHP_FLAGS_RCD			0x01	/* Read Cache Disable */
347172605Sscottl	u_int8_t rw_cache_policy;
348172605Sscottl	u_int8_t dis_prefetch[2];
349172605Sscottl	u_int8_t min_prefetch[2];
350172605Sscottl	u_int8_t max_prefetch[2];
351172605Sscottl	u_int8_t max_prefetch_ceil[2];
352172605Sscottl};
353172605Sscottl
354172605Sscottlstruct scsi_info_exceptions_page {
355172605Sscottl	u_int8_t page_code;
356208905Smjacob#define	SIEP_PAGE_SAVABLE		0x80	/* Page is savable */
357172605Sscottl	u_int8_t page_length;
358172605Sscottl	u_int8_t info_flags;
359208905Smjacob#define	SIEP_FLAGS_PERF			0x80
360208905Smjacob#define	SIEP_FLAGS_EBF			0x20
361208905Smjacob#define	SIEP_FLAGS_EWASC		0x10
362208905Smjacob#define	SIEP_FLAGS_DEXCPT		0x08
363208905Smjacob#define	SIEP_FLAGS_TEST			0x04
364208905Smjacob#define	SIEP_FLAGS_EBACKERR		0x02
365208905Smjacob#define	SIEP_FLAGS_LOGERR		0x01
366172605Sscottl	u_int8_t mrie;
367172605Sscottl	u_int8_t interval_timer[4];
368172605Sscottl	u_int8_t report_count[4];
369172605Sscottl};
370172605Sscottl
371172605Sscottlstruct scsi_proto_specific_page {
372172605Sscottl	u_int8_t page_code;
373208905Smjacob#define	SPSP_PAGE_SAVABLE		0x80	/* Page is savable */
374172605Sscottl	u_int8_t page_length;
375172605Sscottl	u_int8_t protocol;
376208905Smjacob#define	SPSP_PROTO_FC			0x00
377208905Smjacob#define	SPSP_PROTO_SPI			0x01
378208905Smjacob#define	SPSP_PROTO_SSA			0x02
379208905Smjacob#define	SPSP_PROTO_1394			0x03
380208905Smjacob#define	SPSP_PROTO_RDMA			0x04
381208905Smjacob#define	SPSP_PROTO_ISCSI		0x05
382208905Smjacob#define	SPSP_PROTO_SAS			0x06
383208905Smjacob#define	SPSP_PROTO_ADT			0x07
384208905Smjacob#define	SPSP_PROTO_ATA			0x08
385208905Smjacob#define	SPSP_PROTO_NONE			0x0f
386172605Sscottl};
387172605Sscottl
38839213Sgibbsstruct scsi_reserve
38939213Sgibbs{
39039213Sgibbs	u_int8_t opcode;
39139213Sgibbs	u_int8_t byte2;
39239213Sgibbs	u_int8_t unused[2];
39339213Sgibbs	u_int8_t length;
39439213Sgibbs	u_int8_t control;
39539213Sgibbs};
39639213Sgibbs
39739213Sgibbsstruct scsi_release
39839213Sgibbs{
39939213Sgibbs	u_int8_t opcode;
40039213Sgibbs	u_int8_t byte2;
40139213Sgibbs	u_int8_t unused[2];
40239213Sgibbs	u_int8_t length;
40339213Sgibbs	u_int8_t control;
40439213Sgibbs};
40539213Sgibbs
40639213Sgibbsstruct scsi_prevent
40739213Sgibbs{
40839213Sgibbs	u_int8_t opcode;
40939213Sgibbs	u_int8_t byte2;
41039213Sgibbs	u_int8_t unused[2];
41139213Sgibbs	u_int8_t how;
41239213Sgibbs	u_int8_t control;
41339213Sgibbs};
41439213Sgibbs#define	PR_PREVENT 0x01
415208905Smjacob#define	PR_ALLOW   0x00
41639213Sgibbs
41739213Sgibbsstruct scsi_sync_cache
41839213Sgibbs{
41939213Sgibbs	u_int8_t opcode;
42039213Sgibbs	u_int8_t byte2;
42139213Sgibbs	u_int8_t begin_lba[4];
42239213Sgibbs	u_int8_t reserved;
42339213Sgibbs	u_int8_t lb_count[2];
42439213Sgibbs	u_int8_t control;
42539213Sgibbs};
42639213Sgibbs
42739213Sgibbs
42839213Sgibbsstruct scsi_changedef
42939213Sgibbs{
43039213Sgibbs	u_int8_t opcode;
43139213Sgibbs	u_int8_t byte2;
43239213Sgibbs	u_int8_t unused1;
43339213Sgibbs	u_int8_t how;
43439213Sgibbs	u_int8_t unused[4];
43539213Sgibbs	u_int8_t datalen;
43639213Sgibbs	u_int8_t control;
43739213Sgibbs};
43839213Sgibbs
43939213Sgibbsstruct scsi_read_buffer
44039213Sgibbs{
44139213Sgibbs	u_int8_t opcode;
44239213Sgibbs	u_int8_t byte2;
44339213Sgibbs#define	RWB_MODE		0x07
44439213Sgibbs#define	RWB_MODE_HDR_DATA	0x00
44539213Sgibbs#define	RWB_MODE_DATA		0x02
44639213Sgibbs#define	RWB_MODE_DOWNLOAD	0x04
44739213Sgibbs#define	RWB_MODE_DOWNLOAD_SAVE	0x05
44839213Sgibbs        u_int8_t buffer_id;
44939213Sgibbs        u_int8_t offset[3];
45039213Sgibbs        u_int8_t length[3];
45139213Sgibbs        u_int8_t control;
45239213Sgibbs};
45339213Sgibbs
45439213Sgibbsstruct scsi_write_buffer
45539213Sgibbs{
45639213Sgibbs	u_int8_t opcode;
45739213Sgibbs	u_int8_t byte2;
45839213Sgibbs	u_int8_t buffer_id;
45939213Sgibbs	u_int8_t offset[3];
46039213Sgibbs	u_int8_t length[3];
46139213Sgibbs	u_int8_t control;
46239213Sgibbs};
46339213Sgibbs
46439466Skenstruct scsi_rw_6
46539466Sken{
46639466Sken	u_int8_t opcode;
46739466Sken	u_int8_t addr[3];
46839466Sken/* only 5 bits are valid in the MSB address byte */
46939466Sken#define	SRW_TOPADDR	0x1F
47039466Sken	u_int8_t length;
47139466Sken	u_int8_t control;
47239466Sken};
47339466Sken
47439466Skenstruct scsi_rw_10
47539466Sken{
47639466Sken	u_int8_t opcode;
47739466Sken#define	SRW10_RELADDR	0x01
478114261Sken/* EBP defined for WRITE(10) only */
479114261Sken#define	SRW10_EBP	0x04
480114261Sken#define	SRW10_FUA	0x08
48139466Sken#define	SRW10_DPO	0x10
48239466Sken	u_int8_t byte2;
48339466Sken	u_int8_t addr[4];
48439466Sken	u_int8_t reserved;
48539466Sken	u_int8_t length[2];
48639466Sken	u_int8_t control;
48739466Sken};
48839466Sken
48939466Skenstruct scsi_rw_12
49039466Sken{
49139466Sken	u_int8_t opcode;
49239466Sken#define	SRW12_RELADDR	0x01
493208905Smjacob#define	SRW12_FUA	0x08
49439466Sken#define	SRW12_DPO	0x10
49539466Sken	u_int8_t byte2;
49639466Sken	u_int8_t addr[4];
497104681Sken	u_int8_t length[4];
49839466Sken	u_int8_t reserved;
49939466Sken	u_int8_t control;
50039466Sken};
50139466Sken
502114261Skenstruct scsi_rw_16
503114261Sken{
504114261Sken	u_int8_t opcode;
505114261Sken#define	SRW16_RELADDR	0x01
506114261Sken#define	SRW16_FUA	0x08
507114261Sken#define	SRW16_DPO	0x10
508114261Sken	u_int8_t byte2;
509114261Sken	u_int8_t addr[8];
510114261Sken	u_int8_t length[4];
511114261Sken	u_int8_t reserved;
512114261Sken	u_int8_t control;
513114261Sken};
514114261Sken
51539466Skenstruct scsi_start_stop_unit
51639466Sken{
51739466Sken	u_int8_t opcode;
51839466Sken	u_int8_t byte2;
51939466Sken#define	SSS_IMMED		0x01
52039466Sken	u_int8_t reserved[2];
52139466Sken	u_int8_t how;
52239466Sken#define	SSS_START		0x01
52339466Sken#define	SSS_LOEJ		0x02
52439466Sken	u_int8_t control;
52539466Sken};
52639466Sken
527172605Sscottlstruct ata_pass_12 {
528172605Sscottl	u_int8_t opcode;
529172605Sscottl	u_int8_t protocol;
530208905Smjacob#define	AP_MULTI	0xe0
531172605Sscottl	u_int8_t flags;
532208905Smjacob#define	AP_T_LEN	0x03
533208905Smjacob#define	AP_BB		0x04
534208905Smjacob#define	AP_T_DIR	0x08
535208905Smjacob#define	AP_CK_COND	0x20
536208905Smjacob#define	AP_OFFLINE	0x60
537172605Sscottl	u_int8_t features;
538172605Sscottl	u_int8_t sector_count;
539172605Sscottl	u_int8_t lba_low;
540172605Sscottl	u_int8_t lba_mid;
541172605Sscottl	u_int8_t lba_high;
542172605Sscottl	u_int8_t device;
543172605Sscottl	u_int8_t command;
544172605Sscottl	u_int8_t reserved;
545172605Sscottl	u_int8_t control;
546172605Sscottl};
547172605Sscottl
548172605Sscottlstruct ata_pass_16 {
549172605Sscottl	u_int8_t opcode;
550172605Sscottl	u_int8_t protocol;
551208905Smjacob#define	AP_EXTEND	0x01
552172605Sscottl	u_int8_t flags;
553172605Sscottl	u_int8_t features_ext;
554172605Sscottl	u_int8_t features;
555172605Sscottl	u_int8_t sector_count_ext;
556172605Sscottl	u_int8_t sector_count;
557172605Sscottl	u_int8_t lba_low_ext;
558172605Sscottl	u_int8_t lba_low;
559172605Sscottl	u_int8_t lba_mid_ext;
560172605Sscottl	u_int8_t lba_mid;
561172605Sscottl	u_int8_t lba_high_ext;
562172605Sscottl	u_int8_t lba_high;
563172605Sscottl	u_int8_t device;
564172605Sscottl	u_int8_t command;
565172605Sscottl	u_int8_t control;
566172605Sscottl};
567172605Sscottl
568208905Smjacob#define	SC_SCSI_1 0x01
569208905Smjacob#define	SC_SCSI_2 0x03
57039213Sgibbs
57139213Sgibbs/*
57239213Sgibbs * Opcodes
57339213Sgibbs */
57439213Sgibbs
57539213Sgibbs#define	TEST_UNIT_READY		0x00
576208905Smjacob#define	REQUEST_SENSE		0x03
57739466Sken#define	READ_6			0x08
578208905Smjacob#define	WRITE_6			0x0A
579208905Smjacob#define	INQUIRY			0x12
580208905Smjacob#define	MODE_SELECT_6		0x15
581208905Smjacob#define	MODE_SENSE_6		0x1A
582208905Smjacob#define	START_STOP_UNIT		0x1B
583208905Smjacob#define	START_STOP		0x1B
584208905Smjacob#define	RESERVE      		0x16
585208905Smjacob#define	RELEASE      		0x17
586208905Smjacob#define	RECEIVE_DIAGNOSTIC	0x1C
587208905Smjacob#define	SEND_DIAGNOSTIC		0x1D
588208905Smjacob#define	PREVENT_ALLOW		0x1E
58939213Sgibbs#define	READ_CAPACITY		0x25
59039466Sken#define	READ_10			0x28
591208905Smjacob#define	WRITE_10		0x2A
592208905Smjacob#define	POSITION_TO_ELEMENT	0x2B
59339213Sgibbs#define	SYNCHRONIZE_CACHE	0x35
594172605Sscottl#define	READ_DEFECT_DATA_10	0x37
595208905Smjacob#define	WRITE_BUFFER            0x3B
596208905Smjacob#define	READ_BUFFER             0x3C
59739213Sgibbs#define	CHANGE_DEFINITION	0x40
598208905Smjacob#define	LOG_SELECT		0x4C
599208905Smjacob#define	LOG_SENSE		0x4D
60039213Sgibbs#define	MODE_SELECT_10		0x55
60139213Sgibbs#define	MODE_SENSE_10		0x5A
602172605Sscottl#define	ATA_PASS_16		0x85
603114261Sken#define	READ_16			0x88
604208905Smjacob#define	WRITE_16		0x8A
605208905Smjacob#define	SERVICE_ACTION_IN	0x9E
60697825Smjacob#define	REPORT_LUNS		0xA0
607208905Smjacob#define	ATA_PASS_12		0xA1
608208905Smjacob#define	MAINTENANCE_IN		0xA3
609208905Smjacob#define	MAINTENANCE_OUT		0xA4
610208905Smjacob#define	MOVE_MEDIUM     	0xA5
611208905Smjacob#define	READ_12			0xA8
612208905Smjacob#define	WRITE_12		0xAA
613208905Smjacob#define	READ_ELEMENT_STATUS	0xB8
61439213Sgibbs
615208905Smjacob/* Maintenance In Service Action Codes */
616208905Smjacob#define	REPORT_IDENTIFYING_INFRMATION		0x05
617208905Smjacob#define	REPORT_TARGET_PORT_GROUPS		0x0A
618208905Smjacob#define	REPORT_ALIASES				0x0B
619208905Smjacob#define	REPORT_SUPPORTED_OPERATION_CODES	0x0C
620208905Smjacob#define	REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS	0x0D
621208905Smjacob#define	REPORT_PRIORITY				0x0E
622208905Smjacob#define	REPORT_TIMESTAMP			0x0F
623208905Smjacob#define	MANAGEMENT_PROTOCOL_IN			0x10
624208905Smjacob/* Maintenance Out Service Action Codes */
625208905Smjacob#define	SET_IDENTIFY_INFORMATION		0x06
626208905Smjacob#define	SET_TARGET_PORT_GROUPS			0x0A
627208905Smjacob#define	CHANGE_ALIASES				0x0B
628208905Smjacob#define	SET_PRIORITY				0x0E
629208905Smjacob#define	SET_TIMESTAMP				0x0F
630208905Smjacob#define	MANGAEMENT_PROTOCOL_OUT			0x10
63139213Sgibbs
63239213Sgibbs/*
63339213Sgibbs * Device Types
63439213Sgibbs */
635181381Sjkim#define	T_DIRECT	0x00
636181381Sjkim#define	T_SEQUENTIAL	0x01
637181381Sjkim#define	T_PRINTER	0x02
638181381Sjkim#define	T_PROCESSOR	0x03
639181381Sjkim#define	T_WORM		0x04
640181381Sjkim#define	T_CDROM		0x05
641181381Sjkim#define	T_SCANNER	0x06
642181381Sjkim#define	T_OPTICAL 	0x07
643181381Sjkim#define	T_CHANGER	0x08
644181381Sjkim#define	T_COMM		0x09
645181381Sjkim#define	T_ASC0		0x0a
646181381Sjkim#define	T_ASC1		0x0b
64739213Sgibbs#define	T_STORARRAY	0x0c
64839213Sgibbs#define	T_ENCLOSURE	0x0d
64956147Smjacob#define	T_RBC		0x0e
65056147Smjacob#define	T_OCRW		0x0f
651181381Sjkim#define	T_OSD		0x11
652181381Sjkim#define	T_ADC		0x12
653181381Sjkim#define	T_NODEVICE	0x1f
654181381Sjkim#define	T_ANY		0xff	/* Used in Quirk table matches */
65539213Sgibbs
656208905Smjacob#define	T_REMOV		1
65739213Sgibbs#define	T_FIXED		0
65839213Sgibbs
65957349Sken/*
66057349Sken * This length is the initial inquiry length used by the probe code, as
66157349Sken * well as the legnth necessary for scsi_print_inquiry() to function
66257349Sken * correctly.  If either use requires a different length in the future,
66357349Sken * the two values should be de-coupled.
66457349Sken */
66556147Smjacob#define	SHORT_INQUIRY_LENGTH	36
66656147Smjacob
66739213Sgibbsstruct scsi_inquiry_data
66839213Sgibbs{
66939213Sgibbs	u_int8_t device;
67039213Sgibbs#define	SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
67139213Sgibbs#define	SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
67274840Sken#define	SID_QUAL_LU_CONNECTED	0x00	/*
67374840Sken					 * The specified peripheral device
67439213Sgibbs					 * type is currently connected to
67539213Sgibbs					 * logical unit.  If the target cannot
67639213Sgibbs					 * determine whether or not a physical
67739213Sgibbs					 * device is currently connected, it
67839213Sgibbs					 * shall also use this peripheral
67939213Sgibbs					 * qualifier when returning the INQUIRY
68039213Sgibbs					 * data.  This peripheral qualifier
68139213Sgibbs					 * does not mean that the device is
68239213Sgibbs					 * ready for access by the initiator.
68339213Sgibbs					 */
68474840Sken#define	SID_QUAL_LU_OFFLINE	0x01	/*
68574840Sken					 * The target is capable of supporting
68639213Sgibbs					 * the specified peripheral device type
68739213Sgibbs					 * on this logical unit; however, the
68839213Sgibbs					 * physical device is not currently
68939213Sgibbs					 * connected to this logical unit.
69039213Sgibbs					 */
691208905Smjacob#define	SID_QUAL_RSVD		0x02
69274840Sken#define	SID_QUAL_BAD_LU		0x03	/*
69374840Sken					 * The target is not capable of
69439213Sgibbs					 * supporting a physical device on
69539213Sgibbs					 * this logical unit. For this
69639213Sgibbs					 * peripheral qualifier the peripheral
69739213Sgibbs					 * device type shall be set to 1Fh to
69839213Sgibbs					 * provide compatibility with previous
69939213Sgibbs					 * versions of SCSI. All other
70039213Sgibbs					 * peripheral device type values are
70139213Sgibbs					 * reserved for this peripheral
70239213Sgibbs					 * qualifier.
70339213Sgibbs					 */
70439213Sgibbs#define	SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
70539213Sgibbs	u_int8_t dev_qual2;
70639213Sgibbs#define	SID_QUAL2	0x7F
70739213Sgibbs#define	SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
70839213Sgibbs	u_int8_t version;
709208905Smjacob#define	SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
71041542Smjacob#define		SCSI_REV_0		0
71141542Smjacob#define		SCSI_REV_CCS		1
71241542Smjacob#define		SCSI_REV_2		2
71374840Sken#define		SCSI_REV_SPC		3
71456147Smjacob#define		SCSI_REV_SPC2		4
715208905Smjacob#define		SCSI_REV_SPC3		5
716208905Smjacob#define		SCSI_REV_SPC4		6
71741542Smjacob
718208905Smjacob#define	SID_ECMA	0x38
719208905Smjacob#define	SID_ISO		0xC0
72039213Sgibbs	u_int8_t response_format;
721208905Smjacob#define	SID_AENC	0x80
722208905Smjacob#define	SID_TrmIOP	0x40
72339213Sgibbs	u_int8_t additional_length;
724164894Smjacob#define	SID_ADDITIONAL_LENGTH(iqd)					\
725164894Smjacob	((iqd)->additional_length +					\
726164894Smjacob	offsetof(struct scsi_inquiry_data, additional_length) + 1)
727208905Smjacob	u_int8_t spc3_flags;
728208905Smjacob#define	SPC3_SID_PROTECT	0x01
729208905Smjacob#define	SPC3_SID_3PC		0x08
730208905Smjacob#define	SPC3_SID_TPGS_MASK	0x30
731208905Smjacob#define	SPC3_SID_TPGS_IMPLICIT	0x10
732208905Smjacob#define	SPC3_SID_TPGS_EXPLICIT	0x20
733208905Smjacob#define	SPC3_SID_ACC		0x40
734208905Smjacob#define	SPC3_SID_SCCS		0x80
735159086Smjacob	u_int8_t spc2_flags;
736208905Smjacob#define	SPC2_SID_MChngr 	0x08
737208905Smjacob#define	SPC2_SID_MultiP 	0x10
738208905Smjacob#define	SPC2_SID_EncServ	0x40
739208905Smjacob#define	SPC2_SID_BQueue		0x80
740159086Smjacob
741208905Smjacob#define	INQ_DATA_TQ_ENABLED(iqd)				\
742159086Smjacob    ((SID_ANSI_REV(iqd) < SCSI_REV_SPC2)? ((iqd)->flags & SID_CmdQue) :	\
743159086Smjacob    (((iqd)->flags & SID_CmdQue) && !((iqd)->spc2_flags & SPC2_SID_BQueue)) || \
744159086Smjacob    (!((iqd)->flags & SID_CmdQue) && ((iqd)->spc2_flags & SPC2_SID_BQueue)))
745159086Smjacob
74639213Sgibbs	u_int8_t flags;
74739213Sgibbs#define	SID_SftRe	0x01
74839213Sgibbs#define	SID_CmdQue	0x02
74939213Sgibbs#define	SID_Linked	0x08
75039213Sgibbs#define	SID_Sync	0x10
75139213Sgibbs#define	SID_WBus16	0x20
75239213Sgibbs#define	SID_WBus32	0x40
75339213Sgibbs#define	SID_RelAdr	0x80
754208905Smjacob#define	SID_VENDOR_SIZE   8
75539213Sgibbs	char	 vendor[SID_VENDOR_SIZE];
756208905Smjacob#define	SID_PRODUCT_SIZE  16
75739213Sgibbs	char	 product[SID_PRODUCT_SIZE];
758208905Smjacob#define	SID_REVISION_SIZE 4
75939213Sgibbs	char	 revision[SID_REVISION_SIZE];
76056147Smjacob	/*
76156147Smjacob	 * The following fields were taken from SCSI Primary Commands - 2
76256147Smjacob	 * (SPC-2) Revision 14, Dated 11 November 1999
76356147Smjacob	 */
76456147Smjacob#define	SID_VENDOR_SPECIFIC_0_SIZE	20
76556147Smjacob	u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
76656147Smjacob	/*
76756147Smjacob	 * An extension of SCSI Parallel Specific Values
76856147Smjacob	 */
76956147Smjacob#define	SID_SPI_IUS		0x01
77056147Smjacob#define	SID_SPI_QAS		0x02
77156147Smjacob#define	SID_SPI_CLOCK_ST	0x00
77256147Smjacob#define	SID_SPI_CLOCK_DT	0x04
77356147Smjacob#define	SID_SPI_CLOCK_DT_ST	0x0C
77474840Sken#define	SID_SPI_MASK		0x0F
77556147Smjacob	u_int8_t spi3data;
77656147Smjacob	u_int8_t reserved2;
77756147Smjacob	/*
77856147Smjacob	 * Version Descriptors, stored 2 byte values.
77956147Smjacob	 */
78056147Smjacob	u_int8_t version1[2];
78156147Smjacob	u_int8_t version2[2];
78256147Smjacob	u_int8_t version3[2];
78356147Smjacob	u_int8_t version4[2];
78456147Smjacob	u_int8_t version5[2];
78556147Smjacob	u_int8_t version6[2];
78656147Smjacob	u_int8_t version7[2];
78756147Smjacob	u_int8_t version8[2];
78856147Smjacob
78956147Smjacob	u_int8_t reserved3[22];
79056147Smjacob
79156593Smjacob#define	SID_VENDOR_SPECIFIC_1_SIZE	160
79256147Smjacob	u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
79339213Sgibbs};
79439213Sgibbs
795172605Sscottlstruct scsi_vpd_supported_page_list
796172605Sscottl{
797172605Sscottl	u_int8_t device;
798172605Sscottl	u_int8_t page_code;
799216088Sken#define	SVPD_SUPPORTED_PAGE_LIST	0x00
800216088Sken#define	SVPD_SUPPORTED_PAGES_HDR_LEN	4
801172605Sscottl	u_int8_t reserved;
802172605Sscottl	u_int8_t length;	/* number of VPD entries */
803208905Smjacob#define	SVPD_SUPPORTED_PAGES_SIZE	251
804172605Sscottl	u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
805172605Sscottl};
806172605Sscottl
807216088Sken/*
808216088Sken * This structure is more suited to target operation, because the
809216088Sken * number of supported pages is left to the user to allocate.
810216088Sken */
811216088Skenstruct scsi_vpd_supported_pages
812216088Sken{
813216088Sken	u_int8_t device;
814216088Sken	u_int8_t page_code;
815216088Sken	u_int8_t reserved;
816216088Sken#define	SVPD_SUPPORTED_PAGES	0x00
817216088Sken	u_int8_t length;
818216088Sken	u_int8_t page_list[0];
819216088Sken};
820216088Sken
821216088Sken
82239213Sgibbsstruct scsi_vpd_unit_serial_number
82339213Sgibbs{
82439213Sgibbs	u_int8_t device;
82539213Sgibbs	u_int8_t page_code;
826208905Smjacob#define	SVPD_UNIT_SERIAL_NUMBER	0x80
82739213Sgibbs	u_int8_t reserved;
82839213Sgibbs	u_int8_t length; /* serial number length */
829208905Smjacob#define	SVPD_SERIAL_NUM_SIZE 251
83056147Smjacob	u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
83139213Sgibbs};
83239213Sgibbs
833216088Skenstruct scsi_vpd_device_id
834216088Sken{
835216088Sken	u_int8_t device;
836216088Sken	u_int8_t page_code;
837216088Sken#define	SVPD_DEVICE_ID			0x83
838216088Sken#define	SVPD_DEVICE_ID_MAX_SIZE		0xffff
839216088Sken#define	SVPD_DEVICE_ID_HDR_LEN		4
840216088Sken#define	SVPD_DEVICE_ID_DESC_HDR_LEN	4
841216088Sken	u_int8_t length[2];
842216088Sken	u_int8_t desc_list[0];
843216088Sken};
844216088Sken
845216088Skenstruct scsi_vpd_id_descriptor
846216088Sken{
847216088Sken	u_int8_t	proto_codeset;
848216088Sken#define	SCSI_PROTO_FC		0x00
849216088Sken#define	SCSI_PROTO_SPI		0x01
850216088Sken#define	SCSI_PROTO_SSA		0x02
851216088Sken#define	SCSI_PROTO_1394		0x03
852216088Sken#define	SCSI_PROTO_RDMA		0x04
853216088Sken#define SCSI_PROTO_iSCSI	0x05
854216088Sken#define	SCSI_PROTO_SAS		0x06
855216088Sken#define	SVPD_ID_PROTO_SHIFT	4
856216088Sken#define	SVPD_ID_CODESET_BINARY	0x01
857216088Sken#define	SVPD_ID_CODESET_ASCII	0x02
858216088Sken	u_int8_t	id_type;
859216088Sken#define	SVPD_ID_PIV		0x80
860216088Sken#define	SVPD_ID_ASSOC_LUN	0x00
861216088Sken#define	SVPD_ID_ASSOC_PORT	0x10
862216088Sken#define	SVPD_ID_ASSOC_TARGET	0x20
863216088Sken#define	SVPD_ID_TYPE_VENDOR	0x00
864216088Sken#define	SVPD_ID_TYPE_T10	0x01
865216088Sken#define	SVPD_ID_TYPE_EUI64	0x02
866216088Sken#define	SVPD_ID_TYPE_NAA	0x03
867216088Sken#define	SVPD_ID_TYPE_RELTARG	0x04
868216088Sken#define	SVPD_ID_TYPE_TPORTGRP	0x05
869216088Sken#define	SVPD_ID_TYPE_LUNGRP	0x06
870216088Sken#define	SVPD_ID_TYPE_MD5_LUN_ID	0x07
871216088Sken#define	SVPD_ID_TYPE_SCSI_NAME	0x08
872216088Sken#define	SVPD_ID_TYPE_MASK	0x0f
873216088Sken	u_int8_t	reserved;
874216088Sken	u_int8_t	length;
875216088Sken	u_int8_t	identifier[0];
876216088Sken};
877216088Sken
878216088Skenstruct scsi_vpd_id_t10
879216088Sken{
880216088Sken	u_int8_t	vendor[8];
881216088Sken	u_int8_t	vendor_spec_id[0];
882216088Sken};
883216088Sken
884216088Skenstruct scsi_vpd_id_eui64
885216088Sken{
886216088Sken	u_int8_t	ieee_company_id[3];
887216088Sken	u_int8_t	extension_id[5];
888216088Sken};
889216088Sken
890216088Skenstruct scsi_vpd_id_naa_basic
891216088Sken{
892216088Sken	uint8_t naa;
893216088Sken	/* big endian, packed:
894216088Sken	uint8_t	naa : 4;
895216088Sken	uint8_t naa_desig : 4;
896216088Sken	*/
897216088Sken#define	SVPD_ID_NAA_IEEE_EXT		0x02
898216088Sken#define	SVPD_ID_NAA_LOCAL_REG		0x03
899216088Sken#define	SVPD_ID_NAA_IEEE_REG		0x05
900216088Sken#define	SVPD_ID_NAA_IEEE_REG_EXT	0x06
901216088Sken	uint8_t	naa_data[0];
902216088Sken};
903216088Sken
904216088Skenstruct scsi_vpd_id_naa_ieee_extended_id
905216088Sken{
906216088Sken	uint8_t naa;
907216088Sken	uint8_t vendor_specific_id_a;
908216088Sken	uint8_t ieee_company_id[3];
909216088Sken	uint8_t vendor_specific_id_b[4];
910216088Sken};
911216088Sken
912216088Skenstruct scsi_vpd_id_naa_local_reg
913216088Sken{
914216088Sken	uint8_t naa;
915216088Sken	uint8_t local_value[7];
916216088Sken};
917216088Sken
918216088Skenstruct scsi_vpd_id_naa_ieee_reg
919216088Sken{
920216088Sken	uint8_t naa;
921216088Sken	uint8_t reg_value[7];
922216088Sken	/* big endian, packed:
923216088Sken	uint8_t naa_basic : 4;
924216088Sken	uint8_t ieee_company_id_0 : 4;
925216088Sken	uint8_t ieee_company_id_1[2];
926216088Sken	uint8_t ieee_company_id_2 : 4;
927216088Sken	uint8_t vendor_specific_id_0 : 4;
928216088Sken	uint8_t vendor_specific_id_1[4];
929216088Sken	*/
930216088Sken};
931216088Sken
932216088Skenstruct scsi_vpd_id_naa_ieee_reg_extended
933216088Sken{
934216088Sken	uint8_t naa;
935216088Sken	uint8_t reg_value[15];
936216088Sken	/* big endian, packed:
937216088Sken	uint8_t naa_basic : 4;
938216088Sken	uint8_t ieee_company_id_0 : 4;
939216088Sken	uint8_t ieee_company_id_1[2];
940216088Sken	uint8_t ieee_company_id_2 : 4;
941216088Sken	uint8_t vendor_specific_id_0 : 4;
942216088Sken	uint8_t vendor_specific_id_1[4];
943216088Sken	uint8_t vendor_specific_id_ext[8];
944216088Sken	*/
945216088Sken};
946216088Sken
947216088Skenstruct scsi_vpd_id_rel_trgt_port_id
948216088Sken{
949216088Sken	uint8_t obsolete[2];
950216088Sken	uint8_t rel_trgt_port_id[2];
951216088Sken};
952216088Sken
953216088Skenstruct scsi_vpd_id_trgt_port_grp_id
954216088Sken{
955216088Sken	uint8_t reserved[2];
956216088Sken	uint8_t trgt_port_grp[2];
957216088Sken};
958216088Sken
959216088Skenstruct scsi_vpd_id_lun_grp_id
960216088Sken{
961216088Sken	uint8_t reserved[2];
962216088Sken	uint8_t log_unit_grp[2];
963216088Sken};
964216088Sken
965216088Skenstruct scsi_vpd_id_md5_lun_id
966216088Sken{
967216088Sken	uint8_t lun_id[16];
968216088Sken};
969216088Sken
970216088Skenstruct scsi_vpd_id_scsi_name
971216088Sken{
972216088Sken	uint8_t name_string[256];
973216088Sken};
974216088Sken
97539213Sgibbsstruct scsi_read_capacity
97639213Sgibbs{
97739213Sgibbs	u_int8_t opcode;
97839213Sgibbs	u_int8_t byte2;
97939213Sgibbs	u_int8_t addr[4];
98039213Sgibbs	u_int8_t unused[3];
98139213Sgibbs	u_int8_t control;
98239213Sgibbs};
98339213Sgibbs
984114261Skenstruct scsi_read_capacity_16
985114261Sken{
986114261Sken	uint8_t opcode;
987114261Sken#define	SRC16_SERVICE_ACTION	0x10
988114261Sken	uint8_t service_action;
989114261Sken	uint8_t addr[8];
990114261Sken	uint8_t alloc_len[4];
991114261Sken#define	SRC16_PMI		0x01
992114261Sken#define	SRC16_RELADR		0x02
993114261Sken	uint8_t reladr;
994114261Sken	uint8_t control;
995114261Sken};
996114261Sken
99739213Sgibbsstruct scsi_read_capacity_data
99839213Sgibbs{
99939213Sgibbs	u_int8_t addr[4];
100039213Sgibbs	u_int8_t length[4];
100139213Sgibbs};
100239213Sgibbs
1003114261Skenstruct scsi_read_capacity_data_long
1004114261Sken{
1005114261Sken	uint8_t addr[8];
1006114261Sken	uint8_t length[4];
1007114261Sken};
1008114261Sken
100997825Smjacobstruct scsi_report_luns
101097825Smjacob{
1011161506Sken	uint8_t opcode;
1012161506Sken	uint8_t reserved1;
1013161506Sken#define	RPL_REPORT_DEFAULT	0x00
1014161506Sken#define	RPL_REPORT_WELLKNOWN	0x01
1015161506Sken#define	RPL_REPORT_ALL		0x02
1016161506Sken	uint8_t select_report;
1017161506Sken	uint8_t reserved2[3];
1018161506Sken	uint8_t length[4];
1019161506Sken	uint8_t reserved3;
1020161506Sken	uint8_t control;
102197825Smjacob};
102297825Smjacob
102397825Smjacobstruct scsi_report_luns_data {
102497825Smjacob	u_int8_t length[4];	/* length of LUN inventory, in bytes */
102597825Smjacob	u_int8_t reserved[4];	/* unused */
102697825Smjacob	/*
102797825Smjacob	 * LUN inventory- we only support the type zero form for now.
102897825Smjacob	 */
102997825Smjacob	struct {
103097825Smjacob		u_int8_t lundata[8];
1031161506Sken	} luns[0];
103297825Smjacob};
1033161506Sken#define	RPL_LUNDATA_PERIPH_BUS_MASK	0x3f
1034161506Sken#define	RPL_LUNDATA_FLAT_LUN_MASK	0x3f
1035161506Sken#define	RPL_LUNDATA_LUN_TARG_MASK	0x3f
1036161506Sken#define	RPL_LUNDATA_LUN_BUS_MASK	0xe0
1037161506Sken#define	RPL_LUNDATA_LUN_LUN_MASK	0x1f
1038161506Sken#define	RPL_LUNDATA_EXT_LEN_MASK	0x30
1039161506Sken#define	RPL_LUNDATA_EXT_EAM_MASK	0x0f
1040161506Sken#define	RPL_LUNDATA_EXT_EAM_WK		0x01
1041161506Sken#define	RPL_LUNDATA_EXT_EAM_NOT_SPEC	0x0f
104297825Smjacob#define	RPL_LUNDATA_ATYP_MASK	0xc0	/* MBZ for type 0 lun */
1043161506Sken#define	RPL_LUNDATA_ATYP_PERIPH	0x00
1044161506Sken#define	RPL_LUNDATA_ATYP_FLAT	0x40
1045161506Sken#define	RPL_LUNDATA_ATYP_LUN	0x80
1046161506Sken#define	RPL_LUNDATA_ATYP_EXTLUN	0xc0
104797825Smjacob
1048208905Smjacobstruct scsi_target_group
1049208905Smjacob{
1050208905Smjacob	uint8_t opcode;
1051208905Smjacob	uint8_t service_action;
1052208905Smjacob#define	STG_PDF_LENGTH		0x00
1053208905Smjacob#define	RPL_PDF_EXTENDED	0x20
1054208918Smjacob	uint8_t reserved1[4];
1055208905Smjacob	uint8_t length[4];
1056208905Smjacob	uint8_t reserved2;
1057208905Smjacob	uint8_t control;
1058208905Smjacob};
105997825Smjacob
1060208905Smjacobstruct scsi_target_port_descriptor {
1061208905Smjacob	uint8_t	reserved[2];
1062208905Smjacob	uint8_t	relative_target_port_identifier[2];
1063209188Sken	uint8_t desc_list[];
1064208905Smjacob};
1065208905Smjacob
1066208905Smjacobstruct scsi_target_port_group_descriptor {
1067208905Smjacob	uint8_t	pref_state;
1068208905Smjacob#define	TPG_PRIMARY				0x80
1069208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_STATE_MASK	0xf
1070208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_OPTIMIZED		0x0
1071208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED	0x1
1072208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_STANDBY		0x2
1073208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_UNAVAILABLE	0x3
1074208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_LBA_DEPENDENT	0x4
1075208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_OFFLINE		0xE
1076208905Smjacob#define	TPG_ASYMMETRIC_ACCESS_TRANSITIONING	0xF
1077208905Smjacob	uint8_t support;
1078208905Smjacob#define	TPG_AO_SUP	0x01
1079208905Smjacob#define	TPG_AN_SUP	0x02
1080208905Smjacob#define	TPG_S_SUP	0x04
1081208905Smjacob#define	TPG_U_SUP	0x08
1082208905Smjacob#define	TPG_LBD_SUP	0x10
1083208905Smjacob#define	TPG_O_SUP	0x40
1084208905Smjacob#define	TPG_T_SUP	0x80
1085208905Smjacob	uint8_t target_port_group[2];
1086208905Smjacob	uint8_t reserved;
1087208905Smjacob	uint8_t status;
1088208905Smjacob	uint8_t vendor_specific;
1089208905Smjacob	uint8_t	target_port_count;
1090209188Sken	struct scsi_target_port_descriptor descriptors[];
1091208905Smjacob};
1092208905Smjacob
1093208905Smjacobstruct scsi_target_group_data {
1094208905Smjacob	uint8_t length[4];	/* length of returned data, in bytes */
1095209188Sken	struct scsi_target_port_group_descriptor groups[];
1096208905Smjacob};
1097208905Smjacob
1098208905Smjacobstruct scsi_target_group_data_extended {
1099208905Smjacob	uint8_t length[4];	/* length of returned data, in bytes */
1100208905Smjacob	uint8_t format_type;	/* STG_PDF_LENGTH or RPL_PDF_EXTENDED */
1101208905Smjacob	uint8_t	implicit_transition_time;
1102208905Smjacob	uint8_t reserved[2];
1103209188Sken	struct scsi_target_port_group_descriptor groups[];
1104208905Smjacob};
1105208905Smjacob
1106208905Smjacob
110739213Sgibbsstruct scsi_sense_data
110839213Sgibbs{
110939213Sgibbs	u_int8_t error_code;
111039213Sgibbs#define	SSD_ERRCODE			0x7F
111139213Sgibbs#define		SSD_CURRENT_ERROR	0x70
111239213Sgibbs#define		SSD_DEFERRED_ERROR	0x71
111339213Sgibbs#define	SSD_ERRCODE_VALID	0x80
111439213Sgibbs	u_int8_t segment;
111539213Sgibbs	u_int8_t flags;
111639213Sgibbs#define	SSD_KEY				0x0F
111739213Sgibbs#define		SSD_KEY_NO_SENSE	0x00
111839213Sgibbs#define		SSD_KEY_RECOVERED_ERROR	0x01
111939213Sgibbs#define		SSD_KEY_NOT_READY	0x02
112039213Sgibbs#define		SSD_KEY_MEDIUM_ERROR	0x03
112139213Sgibbs#define		SSD_KEY_HARDWARE_ERROR	0x04
112239213Sgibbs#define		SSD_KEY_ILLEGAL_REQUEST	0x05
112339213Sgibbs#define		SSD_KEY_UNIT_ATTENTION	0x06
112439213Sgibbs#define		SSD_KEY_DATA_PROTECT	0x07
112539213Sgibbs#define		SSD_KEY_BLANK_CHECK	0x08
112639213Sgibbs#define		SSD_KEY_Vendor_Specific	0x09
112739213Sgibbs#define		SSD_KEY_COPY_ABORTED	0x0a
112839213Sgibbs#define		SSD_KEY_ABORTED_COMMAND	0x0b
112939213Sgibbs#define		SSD_KEY_EQUAL		0x0c
113039213Sgibbs#define		SSD_KEY_VOLUME_OVERFLOW	0x0d
113139213Sgibbs#define		SSD_KEY_MISCOMPARE	0x0e
113239213Sgibbs#define		SSD_KEY_RESERVED	0x0f
113339213Sgibbs#define	SSD_ILI		0x20
113439213Sgibbs#define	SSD_EOM		0x40
113539213Sgibbs#define	SSD_FILEMARK	0x80
113639213Sgibbs	u_int8_t info[4];
113739213Sgibbs	u_int8_t extra_len;
113839213Sgibbs	u_int8_t cmd_spec_info[4];
113939213Sgibbs	u_int8_t add_sense_code;
114039213Sgibbs	u_int8_t add_sense_code_qual;
114139213Sgibbs	u_int8_t fru;
114239213Sgibbs	u_int8_t sense_key_spec[3];
114339213Sgibbs#define	SSD_SCS_VALID		0x80
1144208905Smjacob#define	SSD_FIELDPTR_CMD	0x40
1145208905Smjacob#define	SSD_BITPTR_VALID	0x08
1146208905Smjacob#define	SSD_BITPTR_VALUE	0x07
1147208905Smjacob#define	SSD_MIN_SIZE 18
114839213Sgibbs	u_int8_t extra_bytes[14];
1149208905Smjacob#define	SSD_FULL_SIZE sizeof(struct scsi_sense_data)
115039213Sgibbs};
115139213Sgibbs
115239213Sgibbsstruct scsi_mode_header_6
115339213Sgibbs{
115439213Sgibbs	u_int8_t data_length;	/* Sense data length */
115539213Sgibbs	u_int8_t medium_type;
115639213Sgibbs	u_int8_t dev_spec;
115739213Sgibbs	u_int8_t blk_desc_len;
115839213Sgibbs};
115939213Sgibbs
116039213Sgibbsstruct scsi_mode_header_10
116139213Sgibbs{
116239213Sgibbs	u_int8_t data_length[2];/* Sense data length */
116339213Sgibbs	u_int8_t medium_type;
116439213Sgibbs	u_int8_t dev_spec;
116539213Sgibbs	u_int8_t unused[2];
116639213Sgibbs	u_int8_t blk_desc_len[2];
116739213Sgibbs};
116839213Sgibbs
116964382Skbyancstruct scsi_mode_page_header
117039213Sgibbs{
117164382Skbyanc	u_int8_t page_code;
117264382Skbyanc	u_int8_t page_length;
117364382Skbyanc};
117464382Skbyanc
117564382Skbyancstruct scsi_mode_blk_desc
117664382Skbyanc{
117739213Sgibbs	u_int8_t density;
117839213Sgibbs	u_int8_t nblocks[3];
117939213Sgibbs	u_int8_t reserved;
118039213Sgibbs	u_int8_t blklen[3];
118139213Sgibbs};
118239213Sgibbs
118341542Smjacob#define	SCSI_DEFAULT_DENSITY	0x00	/* use 'default' density */
118441542Smjacob#define	SCSI_SAME_DENSITY	0x7f	/* use 'same' density- >= SCSI-2 only */
118597825Smjacob
118697825Smjacob
118739213Sgibbs/*
118839213Sgibbs * Status Byte
118939213Sgibbs */
119039213Sgibbs#define	SCSI_STATUS_OK			0x00
119139213Sgibbs#define	SCSI_STATUS_CHECK_COND		0x02
119239213Sgibbs#define	SCSI_STATUS_COND_MET		0x04
119339213Sgibbs#define	SCSI_STATUS_BUSY		0x08
1194208905Smjacob#define	SCSI_STATUS_INTERMED		0x10
1195208905Smjacob#define	SCSI_STATUS_INTERMED_COND_MET	0x14
1196208905Smjacob#define	SCSI_STATUS_RESERV_CONFLICT	0x18
1197208905Smjacob#define	SCSI_STATUS_CMD_TERMINATED	0x22	/* Obsolete in SAM-2 */
1198208905Smjacob#define	SCSI_STATUS_QUEUE_FULL		0x28
1199208905Smjacob#define	SCSI_STATUS_ACA_ACTIVE		0x30
1200208905Smjacob#define	SCSI_STATUS_TASK_ABORTED	0x40
120139213Sgibbs
120239213Sgibbsstruct scsi_inquiry_pattern {
120339213Sgibbs	u_int8_t   type;
120439213Sgibbs	u_int8_t   media_type;
120539213Sgibbs#define	SIP_MEDIA_REMOVABLE	0x01
120639213Sgibbs#define	SIP_MEDIA_FIXED		0x02
120739213Sgibbs	const char *vendor;
120839213Sgibbs	const char *product;
120939213Sgibbs	const char *revision;
121039213Sgibbs};
121139213Sgibbs
121239213Sgibbsstruct scsi_static_inquiry_pattern {
121339213Sgibbs	u_int8_t   type;
121439213Sgibbs	u_int8_t   media_type;
121539213Sgibbs	char       vendor[SID_VENDOR_SIZE+1];
121639213Sgibbs	char       product[SID_PRODUCT_SIZE+1];
121739213Sgibbs	char       revision[SID_REVISION_SIZE+1];
121839213Sgibbs};
121939213Sgibbs
122039213Sgibbsstruct scsi_sense_quirk_entry {
122139213Sgibbs	struct scsi_inquiry_pattern	inq_pat;
122274840Sken	int				num_sense_keys;
122339213Sgibbs	int				num_ascs;
122474840Sken	struct sense_key_table_entry	*sense_key_info;
122539213Sgibbs	struct asc_table_entry		*asc_info;
122639213Sgibbs};
122739213Sgibbs
122874840Skenstruct sense_key_table_entry {
122974840Sken	u_int8_t    sense_key;
123074840Sken	u_int32_t   action;
123174840Sken	const char *desc;
123274840Sken};
123374840Sken
123439213Sgibbsstruct asc_table_entry {
123539213Sgibbs	u_int8_t    asc;
123639213Sgibbs	u_int8_t    ascq;
123739213Sgibbs	u_int32_t   action;
123839213Sgibbs	const char *desc;
123939213Sgibbs};
124039213Sgibbs
124139213Sgibbsstruct op_table_entry {
124239213Sgibbs	u_int8_t    opcode;
1243181381Sjkim	u_int32_t   opmask;
124439213Sgibbs	const char  *desc;
124539213Sgibbs};
124639213Sgibbs
124739213Sgibbsstruct scsi_op_quirk_entry {
124839213Sgibbs	struct scsi_inquiry_pattern	inq_pat;
124939213Sgibbs	int				num_ops;
125039213Sgibbs	struct op_table_entry		*op_table;
125139213Sgibbs};
125239213Sgibbs
125374840Skentypedef enum {
125474840Sken	SSS_FLAG_NONE		= 0x00,
125574840Sken	SSS_FLAG_PRINT_COMMAND	= 0x01
125674840Sken} scsi_sense_string_flags;
125739213Sgibbs
125839213Sgibbsstruct ccb_scsiio;
125939213Sgibbsstruct cam_periph;
126039213Sgibbsunion  ccb;
126155205Speter#ifndef _KERNEL
126239213Sgibbsstruct cam_device;
126339213Sgibbs#endif
126439213Sgibbs
126539213Sgibbsextern const char *scsi_sense_key_text[];
126639213Sgibbs
126774840Skenstruct sbuf;
126874840Sken
126939213Sgibbs__BEGIN_DECLS
127074840Skenvoid scsi_sense_desc(int sense_key, int asc, int ascq,
127174840Sken		     struct scsi_inquiry_data *inq_data,
127274840Sken		     const char **sense_key_desc, const char **asc_desc);
127374840Skenscsi_sense_action scsi_error_action(struct ccb_scsiio* csio,
127474840Sken				    struct scsi_inquiry_data *inq_data,
127574840Sken				    u_int32_t sense_flags);
127674840Skenconst char *	scsi_status_string(struct ccb_scsiio *csio);
127755205Speter#ifdef _KERNEL
127874840Skenint		scsi_command_string(struct ccb_scsiio *csio, struct sbuf *sb);
127974840Skenint		scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
128074840Sken				scsi_sense_string_flags flags);
128174840Skenchar *		scsi_sense_string(struct ccb_scsiio *csio,
128274840Sken				  char *str, int str_len);
128339213Sgibbsvoid		scsi_sense_print(struct ccb_scsiio *csio);
128439213Sgibbsint		scsi_interpret_sense(union ccb *ccb,
128539213Sgibbs				     u_int32_t sense_flags,
128639213Sgibbs				     u_int32_t *relsim_flags,
128739213Sgibbs				     u_int32_t *reduction,
128839213Sgibbs				     u_int32_t *timeout,
128939213Sgibbs				     scsi_sense_action error_action);
129074840Sken#else /* _KERNEL */
129174840Skenint		scsi_command_string(struct cam_device *device,
129274840Sken				    struct ccb_scsiio *csio, struct sbuf *sb);
129374840Skenint		scsi_sense_sbuf(struct cam_device *device,
129474840Sken				struct ccb_scsiio *csio, struct sbuf *sb,
129574840Sken				scsi_sense_string_flags flags);
129639213Sgibbschar *		scsi_sense_string(struct cam_device *device,
129739213Sgibbs				  struct ccb_scsiio *csio,
129839213Sgibbs				  char *str, int str_len);
129939213Sgibbsvoid		scsi_sense_print(struct cam_device *device,
130039213Sgibbs				 struct ccb_scsiio *csio, FILE *ofile);
130139213Sgibbsint		scsi_interpret_sense(struct cam_device *device,
130239213Sgibbs				     union ccb *ccb,
130339213Sgibbs				     u_int32_t sense_flags,
130439213Sgibbs				     u_int32_t *relsim_flags,
130539213Sgibbs				     u_int32_t *reduction,
130639213Sgibbs				     u_int32_t *timeout,
130739213Sgibbs				     scsi_sense_action error_action);
130855205Speter#endif /* _KERNEL */
130939213Sgibbs
131039213Sgibbs#define	SF_RETRY_UA	0x01
1311208905Smjacob#define	SF_NO_PRINT	0x02
1312208905Smjacob#define	SF_QUIET_IR	0x04	/* Be quiet about Illegal Request reponses */
1313208905Smjacob#define	SF_PRINT_ALWAYS	0x08
131439213Sgibbs
131539213Sgibbs
131639213Sgibbsconst char *	scsi_op_desc(u_int16_t opcode,
131739213Sgibbs			     struct scsi_inquiry_data *inq_data);
131840401Skenchar *		scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
131940401Sken				size_t len);
132039213Sgibbs
132139213Sgibbsvoid		scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
132239213Sgibbs
132339213Sgibbsu_int		scsi_calc_syncsrate(u_int period_factor);
132439213Sgibbsu_int		scsi_calc_syncparam(u_int period);
1325216088Skenuint8_t *	scsi_get_sas_addr(struct scsi_vpd_device_id *id, uint32_t len);
1326216088Sken
132739213Sgibbsvoid		scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
132839213Sgibbs				     void (*cbfcnp)(struct cam_periph *,
132939213Sgibbs						    union ccb *),
133039213Sgibbs				     u_int8_t tag_action,
133139213Sgibbs				     u_int8_t sense_len, u_int32_t timeout);
133239213Sgibbs
133339213Sgibbsvoid		scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
133439213Sgibbs				   void (*cbfcnp)(struct cam_periph *,
133539213Sgibbs						  union ccb *),
133639213Sgibbs				   void *data_ptr, u_int8_t dxfer_len,
133739213Sgibbs				   u_int8_t tag_action, u_int8_t sense_len,
133839213Sgibbs				   u_int32_t timeout);
133939213Sgibbs
134039213Sgibbsvoid		scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
134139213Sgibbs			     void (*cbfcnp)(struct cam_periph *, union ccb *),
134239213Sgibbs			     u_int8_t tag_action, u_int8_t *inq_buf,
134339213Sgibbs			     u_int32_t inq_len, int evpd, u_int8_t page_code,
134439213Sgibbs			     u_int8_t sense_len, u_int32_t timeout);
134539213Sgibbs
134639213Sgibbsvoid		scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
134739213Sgibbs				void (*cbfcnp)(struct cam_periph *,
134839213Sgibbs					       union ccb *),
134939213Sgibbs				u_int8_t tag_action, int dbd,
135039213Sgibbs				u_int8_t page_code, u_int8_t page,
135139213Sgibbs				u_int8_t *param_buf, u_int32_t param_len,
135239213Sgibbs				u_int8_t sense_len, u_int32_t timeout);
135339213Sgibbs
1354111206Skenvoid		scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
1355111206Sken				    void (*cbfcnp)(struct cam_periph *,
1356111206Sken						   union ccb *),
1357111206Sken				    u_int8_t tag_action, int dbd,
1358111206Sken				    u_int8_t page_code, u_int8_t page,
1359111206Sken				    u_int8_t *param_buf, u_int32_t param_len,
1360111206Sken				    int minimum_cmd_size, u_int8_t sense_len,
1361111206Sken				    u_int32_t timeout);
1362111206Sken
136339213Sgibbsvoid		scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
136439213Sgibbs				 void (*cbfcnp)(struct cam_periph *,
136539213Sgibbs						union ccb *),
136639213Sgibbs				 u_int8_t tag_action, int scsi_page_fmt,
136739213Sgibbs				 int save_pages, u_int8_t *param_buf,
136839213Sgibbs				 u_int32_t param_len, u_int8_t sense_len,
136939213Sgibbs				 u_int32_t timeout);
137039213Sgibbs
1371111206Skenvoid		scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
1372111206Sken				     void (*cbfcnp)(struct cam_periph *,
1373111206Sken						    union ccb *),
1374111206Sken				     u_int8_t tag_action, int scsi_page_fmt,
1375111206Sken				     int save_pages, u_int8_t *param_buf,
1376111206Sken				     u_int32_t param_len, int minimum_cmd_size,
1377111206Sken				     u_int8_t sense_len, u_int32_t timeout);
1378111206Sken
137982384Skbyancvoid		scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries,
138082384Skbyanc			       void (*cbfcnp)(struct cam_periph *, union ccb *),
138182384Skbyanc			       u_int8_t tag_action, u_int8_t page_code,
138282384Skbyanc			       u_int8_t page, int save_pages, int ppc,
138382384Skbyanc			       u_int32_t paramptr, u_int8_t *param_buf,
138482384Skbyanc			       u_int32_t param_len, u_int8_t sense_len,
138582384Skbyanc			       u_int32_t timeout);
138682384Skbyanc
138782384Skbyancvoid		scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries,
138882384Skbyanc				void (*cbfcnp)(struct cam_periph *,
138982384Skbyanc				union ccb *), u_int8_t tag_action,
139082384Skbyanc				u_int8_t page_code, int save_pages,
139182384Skbyanc				int pc_reset, u_int8_t *param_buf,
139282384Skbyanc				u_int32_t param_len, u_int8_t sense_len,
139382384Skbyanc				u_int32_t timeout);
139482384Skbyanc
139597825Smjacobvoid		scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
139697825Smjacob			     void (*cbfcnp)(struct cam_periph *, union ccb *),
139797825Smjacob			     u_int8_t tag_action, u_int8_t action,
139897825Smjacob			     u_int8_t sense_len, u_int32_t timeout);
139997825Smjacob
140039213Sgibbsvoid		scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
140139213Sgibbs				   void (*cbfcnp)(struct cam_periph *,
140239213Sgibbs				   union ccb *), u_int8_t tag_action,
140397825Smjacob				   struct scsi_read_capacity_data *,
140439213Sgibbs				   u_int8_t sense_len, u_int32_t timeout);
1405114261Skenvoid		scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries,
1406114261Sken				      void (*cbfcnp)(struct cam_periph *,
1407114261Sken				      union ccb *), uint8_t tag_action,
1408114261Sken				      uint64_t lba, int reladr, int pmi,
1409114261Sken				      struct scsi_read_capacity_data_long
1410114261Sken				      *rcap_buf, uint8_t sense_len,
1411114261Sken				      uint32_t timeout);
141239213Sgibbs
141397825Smjacobvoid		scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries,
1414161506Sken				 void (*cbfcnp)(struct cam_periph *,
1415161506Sken				 union ccb *), u_int8_t tag_action,
1416161506Sken				 u_int8_t select_report,
1417161506Sken				 struct scsi_report_luns_data *rpl_buf,
1418161506Sken				 u_int32_t alloc_len, u_int8_t sense_len,
1419161506Sken				 u_int32_t timeout);
142039213Sgibbs
1421208905Smjacobvoid		scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
1422208905Smjacob				 void (*cbfcnp)(struct cam_periph *,
1423208905Smjacob				 union ccb *), u_int8_t tag_action,
1424208905Smjacob				 u_int8_t pdf,
1425208905Smjacob				 void *buf,
1426208905Smjacob				 u_int32_t alloc_len, u_int8_t sense_len,
1427208905Smjacob				 u_int32_t timeout);
1428208905Smjacob
1429208905Smjacobvoid		scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
1430208905Smjacob				 void (*cbfcnp)(struct cam_periph *,
1431208905Smjacob				 union ccb *), u_int8_t tag_action, void *buf,
1432208905Smjacob				 u_int32_t alloc_len, u_int8_t sense_len,
1433208905Smjacob				 u_int32_t timeout);
1434208905Smjacob
143539213Sgibbsvoid		scsi_synchronize_cache(struct ccb_scsiio *csio,
143639213Sgibbs				       u_int32_t retries,
143739213Sgibbs				       void (*cbfcnp)(struct cam_periph *,
143839213Sgibbs				       union ccb *), u_int8_t tag_action,
143939213Sgibbs				       u_int32_t begin_lba, u_int16_t lb_count,
144039213Sgibbs				       u_int8_t sense_len, u_int32_t timeout);
144139213Sgibbs
144239466Skenvoid scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
144339466Sken		     void (*cbfcnp)(struct cam_periph *, union ccb *),
144439466Sken		     u_int8_t tag_action, int readop, u_int8_t byte2,
1445114261Sken		     int minimum_cmd_size, u_int64_t lba,
144639466Sken		     u_int32_t block_count, u_int8_t *data_ptr,
144739466Sken		     u_int32_t dxfer_len, u_int8_t sense_len,
144839466Sken		     u_int32_t timeout);
144939466Sken
145039466Skenvoid scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
145139466Sken		     void (*cbfcnp)(struct cam_periph *, union ccb *),
145239466Sken		     u_int8_t tag_action, int start, int load_eject,
145339466Sken		     int immediate, u_int8_t sense_len, u_int32_t timeout);
145439466Sken
145539213Sgibbsint		scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
145639213Sgibbsint		scsi_static_inquiry_match(caddr_t inqbuffer,
145739213Sgibbs					  caddr_t table_entry);
145839213Sgibbs
145939213Sgibbsstatic __inline void scsi_extract_sense(struct scsi_sense_data *sense,
146039213Sgibbs					int *error_code, int *sense_key,
146139213Sgibbs					int *asc, int *ascq);
146239213Sgibbsstatic __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
146339213Sgibbsstatic __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
146439213Sgibbsstatic __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
1465114261Skenstatic __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes);
146639213Sgibbsstatic __inline u_int32_t scsi_2btoul(u_int8_t *bytes);
146739213Sgibbsstatic __inline u_int32_t scsi_3btoul(u_int8_t *bytes);
146839213Sgibbsstatic __inline int32_t scsi_3btol(u_int8_t *bytes);
146939213Sgibbsstatic __inline u_int32_t scsi_4btoul(u_int8_t *bytes);
1470114261Skenstatic __inline u_int64_t scsi_8btou64(u_int8_t *bytes);
147139885Skenstatic __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
147239885Skenstatic __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
147339213Sgibbs
147439213Sgibbsstatic __inline void scsi_extract_sense(struct scsi_sense_data *sense,
147539213Sgibbs					int *error_code, int *sense_key,
147639213Sgibbs					int *asc, int *ascq)
147739213Sgibbs{
147839213Sgibbs	*error_code = sense->error_code & SSD_ERRCODE;
147939213Sgibbs	*sense_key = sense->flags & SSD_KEY;
148039213Sgibbs	*asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
148139213Sgibbs	*ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
148239213Sgibbs}
148339213Sgibbs
148439213Sgibbsstatic __inline void
148539213Sgibbsscsi_ulto2b(u_int32_t val, u_int8_t *bytes)
148639213Sgibbs{
148739213Sgibbs
148839213Sgibbs	bytes[0] = (val >> 8) & 0xff;
148939213Sgibbs	bytes[1] = val & 0xff;
149039213Sgibbs}
149139213Sgibbs
149239213Sgibbsstatic __inline void
149339213Sgibbsscsi_ulto3b(u_int32_t val, u_int8_t *bytes)
149439213Sgibbs{
149539213Sgibbs
149639213Sgibbs	bytes[0] = (val >> 16) & 0xff;
149739213Sgibbs	bytes[1] = (val >> 8) & 0xff;
149839213Sgibbs	bytes[2] = val & 0xff;
149939213Sgibbs}
150039213Sgibbs
150139213Sgibbsstatic __inline void
150239213Sgibbsscsi_ulto4b(u_int32_t val, u_int8_t *bytes)
150339213Sgibbs{
150439213Sgibbs
150539213Sgibbs	bytes[0] = (val >> 24) & 0xff;
150639213Sgibbs	bytes[1] = (val >> 16) & 0xff;
150739213Sgibbs	bytes[2] = (val >> 8) & 0xff;
150839213Sgibbs	bytes[3] = val & 0xff;
150939213Sgibbs}
151039213Sgibbs
1511114261Skenstatic __inline void
1512114261Skenscsi_u64to8b(u_int64_t val, u_int8_t *bytes)
1513114261Sken{
1514114261Sken
1515114261Sken	bytes[0] = (val >> 56) & 0xff;
1516114261Sken	bytes[1] = (val >> 48) & 0xff;
1517114261Sken	bytes[2] = (val >> 40) & 0xff;
1518114261Sken	bytes[3] = (val >> 32) & 0xff;
1519114261Sken	bytes[4] = (val >> 24) & 0xff;
1520114261Sken	bytes[5] = (val >> 16) & 0xff;
1521114261Sken	bytes[6] = (val >> 8) & 0xff;
1522114261Sken	bytes[7] = val & 0xff;
1523114261Sken}
1524114261Sken
152539213Sgibbsstatic __inline u_int32_t
152639213Sgibbsscsi_2btoul(u_int8_t *bytes)
152739213Sgibbs{
152839213Sgibbs	u_int32_t rv;
152939213Sgibbs
153039213Sgibbs	rv = (bytes[0] << 8) |
153139213Sgibbs	     bytes[1];
153239213Sgibbs	return (rv);
153339213Sgibbs}
153439213Sgibbs
153539213Sgibbsstatic __inline u_int32_t
153639213Sgibbsscsi_3btoul(u_int8_t *bytes)
153739213Sgibbs{
153839213Sgibbs	u_int32_t rv;
153939213Sgibbs
154039213Sgibbs	rv = (bytes[0] << 16) |
154139213Sgibbs	     (bytes[1] << 8) |
154239213Sgibbs	     bytes[2];
154339213Sgibbs	return (rv);
154439213Sgibbs}
154539213Sgibbs
154639213Sgibbsstatic __inline int32_t
154739213Sgibbsscsi_3btol(u_int8_t *bytes)
154839213Sgibbs{
154939213Sgibbs	u_int32_t rc = scsi_3btoul(bytes);
155039213Sgibbs
155139213Sgibbs	if (rc & 0x00800000)
155239213Sgibbs		rc |= 0xff000000;
155339213Sgibbs
155439213Sgibbs	return (int32_t) rc;
155539213Sgibbs}
155639213Sgibbs
155739213Sgibbsstatic __inline u_int32_t
155839213Sgibbsscsi_4btoul(u_int8_t *bytes)
155939213Sgibbs{
156039213Sgibbs	u_int32_t rv;
156139213Sgibbs
156239213Sgibbs	rv = (bytes[0] << 24) |
156339213Sgibbs	     (bytes[1] << 16) |
156439213Sgibbs	     (bytes[2] << 8) |
156539213Sgibbs	     bytes[3];
156639213Sgibbs	return (rv);
156739213Sgibbs}
156839885Sken
1569114261Skenstatic __inline uint64_t
1570114261Skenscsi_8btou64(uint8_t *bytes)
1571114261Sken{
1572114261Sken        uint64_t rv;
1573114261Sken
1574114261Sken	rv = (((uint64_t)bytes[0]) << 56) |
1575114261Sken	     (((uint64_t)bytes[1]) << 48) |
1576114261Sken	     (((uint64_t)bytes[2]) << 40) |
1577114261Sken	     (((uint64_t)bytes[3]) << 32) |
1578114261Sken	     (((uint64_t)bytes[4]) << 24) |
1579114261Sken	     (((uint64_t)bytes[5]) << 16) |
1580114261Sken	     (((uint64_t)bytes[6]) << 8) |
1581114261Sken	     bytes[7];
1582114261Sken	return (rv);
1583114261Sken}
1584114261Sken
158539885Sken/*
158639885Sken * Given the pointer to a returned mode sense buffer, return a pointer to
158739885Sken * the start of the first mode page.
158839885Sken */
158939885Skenstatic __inline void *
159039885Skenfind_mode_page_6(struct scsi_mode_header_6 *mode_header)
159139885Sken{
159239885Sken	void *page_start;
159339885Sken
159439885Sken	page_start = (void *)((u_int8_t *)&mode_header[1] +
159539885Sken			      mode_header->blk_desc_len);
159639885Sken
159739885Sken	return(page_start);
159839885Sken}
159939885Sken
160039885Skenstatic __inline void *
160139885Skenfind_mode_page_10(struct scsi_mode_header_10 *mode_header)
160239885Sken{
160339885Sken	void *page_start;
160439885Sken
1605173639Sscottl	page_start = (void *)((u_int8_t *)&mode_header[1] +
160639885Sken			       scsi_2btoul(mode_header->blk_desc_len));
160739885Sken
160839885Sken	return(page_start);
160939885Sken}
161039885Sken
161139213Sgibbs__END_DECLS
161239213Sgibbs
161339213Sgibbs#endif /*_SCSI_SCSI_ALL_H*/
1614