scsi_all.h revision 172605
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 172605 2007-10-12 22:11:22Z scottl $
1839213Sgibbs */
1939213Sgibbs
2039213Sgibbs/*
2139213Sgibbs * SCSI general  interface description
2239213Sgibbs */
2339213Sgibbs
2439213Sgibbs#ifndef	_SCSI_SCSI_ALL_H
2539213Sgibbs#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 */
4439213Sgibbs#define SCSI_CTL_LINK		0x01
4539213Sgibbs#define SCSI_CTL_FLAG		0x02
4639213Sgibbs#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
5039213Sgibbs#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 */
5963171Smjacob#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 */
9739213Sgibbs#define SS_ERRMASK	0xff
9839213Sgibbs
9974840Sken/* The default, retyable, error action */
10074840Sken#define SS_RDEF		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
10139213Sgibbs
10274840Sken/* The retyable, error action, with table specified error code */
10374840Sken#define SS_RET		SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
10439213Sgibbs
10574840Sken/* Fatal error action, with table specified error code */
10674840Sken#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
17139213Sgibbs#define SMS_VENDOR_SPECIFIC_PAGE	0x00
17239213Sgibbs#define SMS_DISCONNECT_RECONNECT_PAGE	0x02
173172605Sscottl#define SMS_CACHE_PAGE			0x08
17439213Sgibbs#define SMS_PERIPHERAL_DEVICE_PAGE	0x09
17539213Sgibbs#define SMS_CONTROL_MODE_PAGE		0x0A
176172605Sscottl#define SMS_PROTO_SPECIFIC_PAGE		0x19
177172605Sscottl#define SMS_INFO_EXCEPTIONS_PAGE	0x1C
17839213Sgibbs#define SMS_ALL_PAGES_PAGE		0x3F
17939213Sgibbs#define	SMS_PAGE_CTRL_MASK		0xC0
18039213Sgibbs#define	SMS_PAGE_CTRL_CURRENT 		0x00
18139213Sgibbs#define	SMS_PAGE_CTRL_CHANGEABLE 	0x40
18239213Sgibbs#define	SMS_PAGE_CTRL_DEFAULT 		0x80
18339213Sgibbs#define	SMS_PAGE_CTRL_SAVED 		0xC0
18439213Sgibbs	u_int8_t unused;
18539213Sgibbs	u_int8_t length;
18639213Sgibbs	u_int8_t control;
18739213Sgibbs};
18839213Sgibbs
18939213Sgibbsstruct scsi_mode_sense_10
19039213Sgibbs{
19139213Sgibbs	u_int8_t opcode;
19239213Sgibbs	u_int8_t byte2;		/* same bits as small version */
19339213Sgibbs	u_int8_t page; 		/* same bits as small version */
19439213Sgibbs	u_int8_t unused[4];
19539213Sgibbs	u_int8_t length[2];
19639213Sgibbs	u_int8_t control;
19739213Sgibbs};
19839213Sgibbs
19939213Sgibbsstruct scsi_mode_select_6
20039213Sgibbs{
20139213Sgibbs	u_int8_t opcode;
20239213Sgibbs	u_int8_t byte2;
20339213Sgibbs#define	SMS_SP	0x01
20439213Sgibbs#define	SMS_PF	0x10
20539213Sgibbs	u_int8_t unused[2];
20639213Sgibbs	u_int8_t length;
20739213Sgibbs	u_int8_t control;
20839213Sgibbs};
20939213Sgibbs
21039213Sgibbsstruct scsi_mode_select_10
21139213Sgibbs{
21239213Sgibbs	u_int8_t opcode;
21339213Sgibbs	u_int8_t byte2;		/* same bits as small version */
21439213Sgibbs	u_int8_t unused[5];
21539213Sgibbs	u_int8_t length[2];
21639213Sgibbs	u_int8_t control;
21739213Sgibbs};
21839213Sgibbs
21939213Sgibbs/*
22039213Sgibbs * When sending a mode select to a tape drive, the medium type must be 0.
22139213Sgibbs */
22239213Sgibbsstruct scsi_mode_hdr_6
22339213Sgibbs{
22439213Sgibbs	u_int8_t datalen;
22539213Sgibbs	u_int8_t medium_type;
22639213Sgibbs	u_int8_t dev_specific;
22739213Sgibbs	u_int8_t block_descr_len;
22839213Sgibbs};
22939213Sgibbs
23039213Sgibbsstruct scsi_mode_hdr_10
23139213Sgibbs{
23239213Sgibbs	u_int8_t datalen[2];
23339213Sgibbs	u_int8_t medium_type;
23439213Sgibbs	u_int8_t dev_specific;
23539213Sgibbs	u_int8_t reserved[2];
23639213Sgibbs	u_int8_t block_descr_len[2];
23739213Sgibbs};
23839213Sgibbs
23939213Sgibbsstruct scsi_mode_block_descr
24039213Sgibbs{
24139213Sgibbs	u_int8_t density_code;
24239213Sgibbs	u_int8_t num_blocks[3];
24339213Sgibbs	u_int8_t reserved;
24439213Sgibbs	u_int8_t block_len[3];
24539213Sgibbs};
24639213Sgibbs
24782384Skbyancstruct scsi_log_sense
24882384Skbyanc{
24982384Skbyanc	u_int8_t opcode;
25082384Skbyanc	u_int8_t byte2;
25182384Skbyanc#define	SLS_SP				0x01
25282384Skbyanc#define	SLS_PPC				0x02
25382384Skbyanc	u_int8_t page;
25482384Skbyanc#define	SLS_PAGE_CODE 			0x3F
25582384Skbyanc#define	SLS_ALL_PAGES_PAGE		0x00
25682384Skbyanc#define	SLS_OVERRUN_PAGE		0x01
25782384Skbyanc#define	SLS_ERROR_WRITE_PAGE		0x02
25882384Skbyanc#define	SLS_ERROR_READ_PAGE		0x03
25982384Skbyanc#define	SLS_ERROR_READREVERSE_PAGE	0x04
26082384Skbyanc#define	SLS_ERROR_VERIFY_PAGE		0x05
26182384Skbyanc#define	SLS_ERROR_NONMEDIUM_PAGE	0x06
26282384Skbyanc#define	SLS_ERROR_LASTN_PAGE		0x07
263172605Sscottl#define SLS_SELF_TEST_PAGE		0x10
264172605Sscottl#define SLS_IE_PAGE			0x2f
26582384Skbyanc#define	SLS_PAGE_CTRL_MASK		0xC0
26682384Skbyanc#define	SLS_PAGE_CTRL_THRESHOLD		0x00
26782384Skbyanc#define	SLS_PAGE_CTRL_CUMULATIVE	0x40
26882384Skbyanc#define	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80
26982384Skbyanc#define	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0
27082384Skbyanc	u_int8_t reserved[2];
27182384Skbyanc	u_int8_t paramptr[2];
27282384Skbyanc	u_int8_t length[2];
27382384Skbyanc	u_int8_t control;
27482384Skbyanc};
27582384Skbyanc
27682384Skbyancstruct scsi_log_select
27782384Skbyanc{
27882384Skbyanc	u_int8_t opcode;
27982384Skbyanc	u_int8_t byte2;
28082384Skbyanc/*	SLS_SP				0x01 */
28182384Skbyanc#define	SLS_PCR				0x02
28282384Skbyanc	u_int8_t page;
28382384Skbyanc/*	SLS_PAGE_CTRL_MASK		0xC0 */
28482384Skbyanc/*	SLS_PAGE_CTRL_THRESHOLD		0x00 */
28582384Skbyanc/*	SLS_PAGE_CTRL_CUMULATIVE	0x40 */
28682384Skbyanc/*	SLS_PAGE_CTRL_THRESH_DEFAULT	0x80 */
28782384Skbyanc/*	SLS_PAGE_CTRL_CUMUL_DEFAULT	0xC0 */
28882384Skbyanc	u_int8_t reserved[4];
28982384Skbyanc	u_int8_t length[2];
29082384Skbyanc	u_int8_t control;
29182384Skbyanc};
29282384Skbyanc
29382384Skbyancstruct scsi_log_header
29482384Skbyanc{
29582384Skbyanc	u_int8_t page;
29682384Skbyanc	u_int8_t reserved;
29782384Skbyanc	u_int8_t datalen[2];
29882384Skbyanc};
29982384Skbyanc
30082384Skbyancstruct scsi_log_param_header {
30182384Skbyanc	u_int8_t param_code[2];
30282384Skbyanc	u_int8_t param_control;
30382384Skbyanc#define	SLP_LP				0x01
30482384Skbyanc#define	SLP_LBIN			0x02
30582384Skbyanc#define	SLP_TMC_MASK			0x0C
30682384Skbyanc#define	SLP_TMC_ALWAYS			0x00
30782384Skbyanc#define	SLP_TMC_EQUAL			0x04
30882384Skbyanc#define	SLP_TMC_NOTEQUAL		0x08
30982384Skbyanc#define	SLP_TMC_GREATER			0x0C
31082384Skbyanc#define	SLP_ETC				0x10
31182384Skbyanc#define	SLP_TSD				0x20
31282384Skbyanc#define	SLP_DS				0x40
31382384Skbyanc#define	SLP_DU				0x80
31482384Skbyanc	u_int8_t param_len;
31582384Skbyanc};
31682384Skbyanc
31739213Sgibbsstruct scsi_control_page {
31839213Sgibbs	u_int8_t page_code;
31939213Sgibbs	u_int8_t page_length;
32039213Sgibbs	u_int8_t rlec;
32139213Sgibbs#define SCB_RLEC			0x01	/*Report Log Exception Cond*/
32239213Sgibbs	u_int8_t queue_flags;
32339213Sgibbs#define SCP_QUEUE_ALG_MASK		0xF0
32439213Sgibbs#define SCP_QUEUE_ALG_RESTRICTED	0x00
32539213Sgibbs#define SCP_QUEUE_ALG_UNRESTRICTED	0x10
32639213Sgibbs#define SCP_QUEUE_ERR			0x02	/*Queued I/O aborted for CACs*/
32739213Sgibbs#define SCP_QUEUE_DQUE			0x01	/*Queued I/O disabled*/
32839213Sgibbs	u_int8_t eca_and_aen;
32939213Sgibbs#define SCP_EECA			0x80	/*Enable Extended CA*/
33039213Sgibbs#define SCP_RAENP			0x04	/*Ready AEN Permission*/
33139213Sgibbs#define SCP_UAAENP			0x02	/*UA AEN Permission*/
33239213Sgibbs#define SCP_EAENP			0x01	/*Error AEN Permission*/
33339213Sgibbs	u_int8_t reserved;
33439213Sgibbs	u_int8_t aen_holdoff_period[2];
33539213Sgibbs};
33639213Sgibbs
337172605Sscottlstruct scsi_cache_page {
338172605Sscottl	u_int8_t page_code;
339172605Sscottl#define SCHP_PAGE_SAVABLE		0x80	/* Page is savable */
340172605Sscottl	u_int8_t page_length;
341172605Sscottl	u_int8_t cache_flags;
342172605Sscottl#define SCHP_FLAGS_WCE			0x04	/* Write Cache Enable */
343172605Sscottl#define SCHP_FLAGS_MF			0x02	/* Multiplication factor */
344172605Sscottl#define SCHP_FLAGS_RCD			0x01	/* Read Cache Disable */
345172605Sscottl	u_int8_t rw_cache_policy;
346172605Sscottl	u_int8_t dis_prefetch[2];
347172605Sscottl	u_int8_t min_prefetch[2];
348172605Sscottl	u_int8_t max_prefetch[2];
349172605Sscottl	u_int8_t max_prefetch_ceil[2];
350172605Sscottl};
351172605Sscottl
352172605Sscottlstruct scsi_info_exceptions_page {
353172605Sscottl	u_int8_t page_code;
354172605Sscottl#define SIEP_PAGE_SAVABLE		0x80	/* Page is savable */
355172605Sscottl	u_int8_t page_length;
356172605Sscottl	u_int8_t info_flags;
357172605Sscottl#define SIEP_FLAGS_PERF			0x80
358172605Sscottl#define SIEP_FLAGS_EBF			0x20
359172605Sscottl#define SIEP_FLAGS_EWASC		0x10
360172605Sscottl#define SIEP_FLAGS_DEXCPT		0x08
361172605Sscottl#define SIEP_FLAGS_TEST			0x04
362172605Sscottl#define SIEP_FLAGS_EBACKERR		0x02
363172605Sscottl#define SIEP_FLAGS_LOGERR		0x01
364172605Sscottl	u_int8_t mrie;
365172605Sscottl	u_int8_t interval_timer[4];
366172605Sscottl	u_int8_t report_count[4];
367172605Sscottl};
368172605Sscottl
369172605Sscottlstruct scsi_proto_specific_page {
370172605Sscottl	u_int8_t page_code;
371172605Sscottl#define SPSP_PAGE_SAVABLE		0x80	/* Page is savable */
372172605Sscottl	u_int8_t page_length;
373172605Sscottl	u_int8_t protocol;
374172605Sscottl#define SPSP_PROTO_FC			0x00
375172605Sscottl#define SPSP_PROTO_SPI			0x01
376172605Sscottl#define SPSP_PROTO_SSA			0x02
377172605Sscottl#define SPSP_PROTO_1394			0x03
378172605Sscottl#define SPSP_PROTO_RDMA			0x04
379172605Sscottl#define SPSP_PROTO_ISCSI		0x05
380172605Sscottl#define SPSP_PROTO_SAS			0x06
381172605Sscottl#define SPSP_PROTO_ADT			0x07
382172605Sscottl#define SPSP_PROTO_ATA			0x08
383172605Sscottl#define SPSP_PROTO_NONE			0x0f
384172605Sscottl};
385172605Sscottl
38639213Sgibbsstruct scsi_reserve
38739213Sgibbs{
38839213Sgibbs	u_int8_t opcode;
38939213Sgibbs	u_int8_t byte2;
39039213Sgibbs	u_int8_t unused[2];
39139213Sgibbs	u_int8_t length;
39239213Sgibbs	u_int8_t control;
39339213Sgibbs};
39439213Sgibbs
39539213Sgibbsstruct scsi_release
39639213Sgibbs{
39739213Sgibbs	u_int8_t opcode;
39839213Sgibbs	u_int8_t byte2;
39939213Sgibbs	u_int8_t unused[2];
40039213Sgibbs	u_int8_t length;
40139213Sgibbs	u_int8_t control;
40239213Sgibbs};
40339213Sgibbs
40439213Sgibbsstruct scsi_prevent
40539213Sgibbs{
40639213Sgibbs	u_int8_t opcode;
40739213Sgibbs	u_int8_t byte2;
40839213Sgibbs	u_int8_t unused[2];
40939213Sgibbs	u_int8_t how;
41039213Sgibbs	u_int8_t control;
41139213Sgibbs};
41239213Sgibbs#define	PR_PREVENT 0x01
41339213Sgibbs#define PR_ALLOW   0x00
41439213Sgibbs
41539213Sgibbsstruct scsi_sync_cache
41639213Sgibbs{
41739213Sgibbs	u_int8_t opcode;
41839213Sgibbs	u_int8_t byte2;
41939213Sgibbs	u_int8_t begin_lba[4];
42039213Sgibbs	u_int8_t reserved;
42139213Sgibbs	u_int8_t lb_count[2];
42239213Sgibbs	u_int8_t control;
42339213Sgibbs};
42439213Sgibbs
42539213Sgibbs
42639213Sgibbsstruct scsi_changedef
42739213Sgibbs{
42839213Sgibbs	u_int8_t opcode;
42939213Sgibbs	u_int8_t byte2;
43039213Sgibbs	u_int8_t unused1;
43139213Sgibbs	u_int8_t how;
43239213Sgibbs	u_int8_t unused[4];
43339213Sgibbs	u_int8_t datalen;
43439213Sgibbs	u_int8_t control;
43539213Sgibbs};
43639213Sgibbs
43739213Sgibbsstruct scsi_read_buffer
43839213Sgibbs{
43939213Sgibbs	u_int8_t opcode;
44039213Sgibbs	u_int8_t byte2;
44139213Sgibbs#define	RWB_MODE		0x07
44239213Sgibbs#define	RWB_MODE_HDR_DATA	0x00
44339213Sgibbs#define	RWB_MODE_DATA		0x02
44439213Sgibbs#define	RWB_MODE_DOWNLOAD	0x04
44539213Sgibbs#define	RWB_MODE_DOWNLOAD_SAVE	0x05
44639213Sgibbs        u_int8_t buffer_id;
44739213Sgibbs        u_int8_t offset[3];
44839213Sgibbs        u_int8_t length[3];
44939213Sgibbs        u_int8_t control;
45039213Sgibbs};
45139213Sgibbs
45239213Sgibbsstruct scsi_write_buffer
45339213Sgibbs{
45439213Sgibbs	u_int8_t opcode;
45539213Sgibbs	u_int8_t byte2;
45639213Sgibbs	u_int8_t buffer_id;
45739213Sgibbs	u_int8_t offset[3];
45839213Sgibbs	u_int8_t length[3];
45939213Sgibbs	u_int8_t control;
46039213Sgibbs};
46139213Sgibbs
46239466Skenstruct scsi_rw_6
46339466Sken{
46439466Sken	u_int8_t opcode;
46539466Sken	u_int8_t addr[3];
46639466Sken/* only 5 bits are valid in the MSB address byte */
46739466Sken#define	SRW_TOPADDR	0x1F
46839466Sken	u_int8_t length;
46939466Sken	u_int8_t control;
47039466Sken};
47139466Sken
47239466Skenstruct scsi_rw_10
47339466Sken{
47439466Sken	u_int8_t opcode;
47539466Sken#define	SRW10_RELADDR	0x01
476114261Sken/* EBP defined for WRITE(10) only */
477114261Sken#define	SRW10_EBP	0x04
478114261Sken#define	SRW10_FUA	0x08
47939466Sken#define	SRW10_DPO	0x10
48039466Sken	u_int8_t byte2;
48139466Sken	u_int8_t addr[4];
48239466Sken	u_int8_t reserved;
48339466Sken	u_int8_t length[2];
48439466Sken	u_int8_t control;
48539466Sken};
48639466Sken
48739466Skenstruct scsi_rw_12
48839466Sken{
48939466Sken	u_int8_t opcode;
49039466Sken#define	SRW12_RELADDR	0x01
49139466Sken#define SRW12_FUA	0x08
49239466Sken#define	SRW12_DPO	0x10
49339466Sken	u_int8_t byte2;
49439466Sken	u_int8_t addr[4];
495104681Sken	u_int8_t length[4];
49639466Sken	u_int8_t reserved;
49739466Sken	u_int8_t control;
49839466Sken};
49939466Sken
500114261Skenstruct scsi_rw_16
501114261Sken{
502114261Sken	u_int8_t opcode;
503114261Sken#define	SRW16_RELADDR	0x01
504114261Sken#define	SRW16_FUA	0x08
505114261Sken#define	SRW16_DPO	0x10
506114261Sken	u_int8_t byte2;
507114261Sken	u_int8_t addr[8];
508114261Sken	u_int8_t length[4];
509114261Sken	u_int8_t reserved;
510114261Sken	u_int8_t control;
511114261Sken};
512114261Sken
51339466Skenstruct scsi_start_stop_unit
51439466Sken{
51539466Sken	u_int8_t opcode;
51639466Sken	u_int8_t byte2;
51739466Sken#define	SSS_IMMED		0x01
51839466Sken	u_int8_t reserved[2];
51939466Sken	u_int8_t how;
52039466Sken#define	SSS_START		0x01
52139466Sken#define	SSS_LOEJ		0x02
52239466Sken	u_int8_t control;
52339466Sken};
52439466Sken
525172605Sscottlstruct ata_pass_12 {
526172605Sscottl	u_int8_t opcode;
527172605Sscottl	u_int8_t protocol;
528172605Sscottl#define AP_MULTI	0xe0
529172605Sscottl	u_int8_t flags;
530172605Sscottl#define AP_T_LEN	0x03
531172605Sscottl#define AP_BB		0x04
532172605Sscottl#define AP_T_DIR	0x08
533172605Sscottl#define AP_CK_COND	0x20
534172605Sscottl#define AP_OFFLINE	0x60
535172605Sscottl	u_int8_t features;
536172605Sscottl	u_int8_t sector_count;
537172605Sscottl	u_int8_t lba_low;
538172605Sscottl	u_int8_t lba_mid;
539172605Sscottl	u_int8_t lba_high;
540172605Sscottl	u_int8_t device;
541172605Sscottl	u_int8_t command;
542172605Sscottl	u_int8_t reserved;
543172605Sscottl	u_int8_t control;
544172605Sscottl};
545172605Sscottl
546172605Sscottlstruct ata_pass_16 {
547172605Sscottl	u_int8_t opcode;
548172605Sscottl	u_int8_t protocol;
549172605Sscottl#define AP_EXTEND	0x01
550172605Sscottl	u_int8_t flags;
551172605Sscottl	u_int8_t features_ext;
552172605Sscottl	u_int8_t features;
553172605Sscottl	u_int8_t sector_count_ext;
554172605Sscottl	u_int8_t sector_count;
555172605Sscottl	u_int8_t lba_low_ext;
556172605Sscottl	u_int8_t lba_low;
557172605Sscottl	u_int8_t lba_mid_ext;
558172605Sscottl	u_int8_t lba_mid;
559172605Sscottl	u_int8_t lba_high_ext;
560172605Sscottl	u_int8_t lba_high;
561172605Sscottl	u_int8_t device;
562172605Sscottl	u_int8_t command;
563172605Sscottl	u_int8_t control;
564172605Sscottl};
565172605Sscottl
56639213Sgibbs#define SC_SCSI_1 0x01
56739213Sgibbs#define SC_SCSI_2 0x03
56839213Sgibbs
56939213Sgibbs/*
57039213Sgibbs * Opcodes
57139213Sgibbs */
57239213Sgibbs
57339213Sgibbs#define	TEST_UNIT_READY		0x00
57439213Sgibbs#define REQUEST_SENSE		0x03
57539466Sken#define	READ_6			0x08
57639466Sken#define WRITE_6			0x0a
57739213Sgibbs#define INQUIRY			0x12
57839213Sgibbs#define MODE_SELECT_6		0x15
57939213Sgibbs#define MODE_SENSE_6		0x1a
58039466Sken#define START_STOP_UNIT		0x1b
58139213Sgibbs#define START_STOP		0x1b
58239213Sgibbs#define RESERVE      		0x16
58339213Sgibbs#define RELEASE      		0x17
58456053Smjacob#define	RECEIVE_DIAGNOSTIC	0x1c
58556053Smjacob#define	SEND_DIAGNOSTIC		0x1d
58639213Sgibbs#define PREVENT_ALLOW		0x1e
58739213Sgibbs#define	READ_CAPACITY		0x25
58839466Sken#define	READ_10			0x28
58939466Sken#define WRITE_10		0x2a
59039213Sgibbs#define POSITION_TO_ELEMENT	0x2b
59139213Sgibbs#define	SYNCHRONIZE_CACHE	0x35
592172605Sscottl#define	READ_DEFECT_DATA_10	0x37
59339213Sgibbs#define	WRITE_BUFFER            0x3b
59439213Sgibbs#define	READ_BUFFER             0x3c
59539213Sgibbs#define	CHANGE_DEFINITION	0x40
59682384Skbyanc#define	LOG_SELECT		0x4c
59782384Skbyanc#define	LOG_SENSE		0x4d
59839213Sgibbs#define	MODE_SELECT_10		0x55
59939213Sgibbs#define	MODE_SENSE_10		0x5A
600172605Sscottl#define	ATA_PASS_16		0x85
601114261Sken#define	READ_16			0x88
602114261Sken#define	WRITE_16		0x8a
603114261Sken#define	SERVICE_ACTION_IN	0x9e
60497825Smjacob#define	REPORT_LUNS		0xA0
605172605Sscottl#define	ATA_PASS_12		0xa1
606114261Sken#define	MOVE_MEDIUM     	0xa5
607114261Sken#define	READ_12			0xa8
608114261Sken#define	WRITE_12		0xaa
609114261Sken#define	READ_ELEMENT_STATUS	0xb8
61039213Sgibbs
61139213Sgibbs
61239213Sgibbs/*
61339213Sgibbs * Device Types
61439213Sgibbs */
61539213Sgibbs#define T_DIRECT	0x00
61639213Sgibbs#define T_SEQUENTIAL	0x01
61739213Sgibbs#define T_PRINTER	0x02
61839213Sgibbs#define T_PROCESSOR	0x03
61939213Sgibbs#define T_WORM		0x04
62039213Sgibbs#define T_CDROM		0x05
62139213Sgibbs#define T_SCANNER 	0x06
62239213Sgibbs#define T_OPTICAL 	0x07
62339213Sgibbs#define T_CHANGER	0x08
62439213Sgibbs#define T_COMM		0x09
62539213Sgibbs#define T_ASC0		0x0a
62639213Sgibbs#define T_ASC1		0x0b
62739213Sgibbs#define	T_STORARRAY	0x0c
62839213Sgibbs#define	T_ENCLOSURE	0x0d
62956147Smjacob#define	T_RBC		0x0e
63056147Smjacob#define	T_OCRW		0x0f
63139213Sgibbs#define T_NODEVICE	0x1F
63239213Sgibbs#define	T_ANY		0xFF	/* Used in Quirk table matches */
63339213Sgibbs
63439213Sgibbs#define T_REMOV		1
63539213Sgibbs#define	T_FIXED		0
63639213Sgibbs
63757349Sken/*
63857349Sken * This length is the initial inquiry length used by the probe code, as
63957349Sken * well as the legnth necessary for scsi_print_inquiry() to function
64057349Sken * correctly.  If either use requires a different length in the future,
64157349Sken * the two values should be de-coupled.
64257349Sken */
64356147Smjacob#define	SHORT_INQUIRY_LENGTH	36
64456147Smjacob
64539213Sgibbsstruct scsi_inquiry_data
64639213Sgibbs{
64739213Sgibbs	u_int8_t device;
64839213Sgibbs#define	SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
64939213Sgibbs#define	SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
65074840Sken#define	SID_QUAL_LU_CONNECTED	0x00	/*
65174840Sken					 * The specified peripheral device
65239213Sgibbs					 * type is currently connected to
65339213Sgibbs					 * logical unit.  If the target cannot
65439213Sgibbs					 * determine whether or not a physical
65539213Sgibbs					 * device is currently connected, it
65639213Sgibbs					 * shall also use this peripheral
65739213Sgibbs					 * qualifier when returning the INQUIRY
65839213Sgibbs					 * data.  This peripheral qualifier
65939213Sgibbs					 * does not mean that the device is
66039213Sgibbs					 * ready for access by the initiator.
66139213Sgibbs					 */
66274840Sken#define	SID_QUAL_LU_OFFLINE	0x01	/*
66374840Sken					 * The target is capable of supporting
66439213Sgibbs					 * the specified peripheral device type
66539213Sgibbs					 * on this logical unit; however, the
66639213Sgibbs					 * physical device is not currently
66739213Sgibbs					 * connected to this logical unit.
66839213Sgibbs					 */
66939213Sgibbs#define SID_QUAL_RSVD		0x02
67074840Sken#define	SID_QUAL_BAD_LU		0x03	/*
67174840Sken					 * The target is not capable of
67239213Sgibbs					 * supporting a physical device on
67339213Sgibbs					 * this logical unit. For this
67439213Sgibbs					 * peripheral qualifier the peripheral
67539213Sgibbs					 * device type shall be set to 1Fh to
67639213Sgibbs					 * provide compatibility with previous
67739213Sgibbs					 * versions of SCSI. All other
67839213Sgibbs					 * peripheral device type values are
67939213Sgibbs					 * reserved for this peripheral
68039213Sgibbs					 * qualifier.
68139213Sgibbs					 */
68239213Sgibbs#define	SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
68339213Sgibbs	u_int8_t dev_qual2;
68439213Sgibbs#define	SID_QUAL2	0x7F
68539213Sgibbs#define	SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
68639213Sgibbs	u_int8_t version;
68739213Sgibbs#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
68841542Smjacob#define		SCSI_REV_0		0
68941542Smjacob#define		SCSI_REV_CCS		1
69041542Smjacob#define		SCSI_REV_2		2
69174840Sken#define		SCSI_REV_SPC		3
69256147Smjacob#define		SCSI_REV_SPC2		4
69341542Smjacob
69439213Sgibbs#define SID_ECMA	0x38
69539213Sgibbs#define SID_ISO		0xC0
69639213Sgibbs	u_int8_t response_format;
69739213Sgibbs#define SID_AENC	0x80
69839213Sgibbs#define SID_TrmIOP	0x40
69939213Sgibbs	u_int8_t additional_length;
700164894Smjacob#define	SID_ADDITIONAL_LENGTH(iqd)					\
701164894Smjacob	((iqd)->additional_length +					\
702164894Smjacob	offsetof(struct scsi_inquiry_data, additional_length) + 1)
703159086Smjacob	u_int8_t reserved;
704159086Smjacob	u_int8_t spc2_flags;
705159086Smjacob#define SPC2_SID_MChngr 	0x08
706159086Smjacob#define SPC2_SID_MultiP 	0x10
707159086Smjacob#define SPC2_SID_EncServ	0x40
708159086Smjacob#define SPC2_SID_BQueue		0x80
709159086Smjacob
710159086Smjacob#define INQ_DATA_TQ_ENABLED(iqd)				\
711159086Smjacob    ((SID_ANSI_REV(iqd) < SCSI_REV_SPC2)? ((iqd)->flags & SID_CmdQue) :	\
712159086Smjacob    (((iqd)->flags & SID_CmdQue) && !((iqd)->spc2_flags & SPC2_SID_BQueue)) || \
713159086Smjacob    (!((iqd)->flags & SID_CmdQue) && ((iqd)->spc2_flags & SPC2_SID_BQueue)))
714159086Smjacob
71539213Sgibbs	u_int8_t flags;
71639213Sgibbs#define	SID_SftRe	0x01
71739213Sgibbs#define	SID_CmdQue	0x02
71839213Sgibbs#define	SID_Linked	0x08
71939213Sgibbs#define	SID_Sync	0x10
72039213Sgibbs#define	SID_WBus16	0x20
72139213Sgibbs#define	SID_WBus32	0x40
72239213Sgibbs#define	SID_RelAdr	0x80
72339213Sgibbs#define SID_VENDOR_SIZE   8
72439213Sgibbs	char	 vendor[SID_VENDOR_SIZE];
72539213Sgibbs#define SID_PRODUCT_SIZE  16
72639213Sgibbs	char	 product[SID_PRODUCT_SIZE];
72739213Sgibbs#define SID_REVISION_SIZE 4
72839213Sgibbs	char	 revision[SID_REVISION_SIZE];
72956147Smjacob	/*
73056147Smjacob	 * The following fields were taken from SCSI Primary Commands - 2
73156147Smjacob	 * (SPC-2) Revision 14, Dated 11 November 1999
73256147Smjacob	 */
73356147Smjacob#define	SID_VENDOR_SPECIFIC_0_SIZE	20
73456147Smjacob	u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
73556147Smjacob	/*
73656147Smjacob	 * An extension of SCSI Parallel Specific Values
73756147Smjacob	 */
73856147Smjacob#define	SID_SPI_IUS		0x01
73956147Smjacob#define	SID_SPI_QAS		0x02
74056147Smjacob#define	SID_SPI_CLOCK_ST	0x00
74156147Smjacob#define	SID_SPI_CLOCK_DT	0x04
74256147Smjacob#define	SID_SPI_CLOCK_DT_ST	0x0C
74374840Sken#define	SID_SPI_MASK		0x0F
74456147Smjacob	u_int8_t spi3data;
74556147Smjacob	u_int8_t reserved2;
74656147Smjacob	/*
74756147Smjacob	 * Version Descriptors, stored 2 byte values.
74856147Smjacob	 */
74956147Smjacob	u_int8_t version1[2];
75056147Smjacob	u_int8_t version2[2];
75156147Smjacob	u_int8_t version3[2];
75256147Smjacob	u_int8_t version4[2];
75356147Smjacob	u_int8_t version5[2];
75456147Smjacob	u_int8_t version6[2];
75556147Smjacob	u_int8_t version7[2];
75656147Smjacob	u_int8_t version8[2];
75756147Smjacob
75856147Smjacob	u_int8_t reserved3[22];
75956147Smjacob
76056593Smjacob#define	SID_VENDOR_SPECIFIC_1_SIZE	160
76156147Smjacob	u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
76239213Sgibbs};
76339213Sgibbs
764172605Sscottlstruct scsi_vpd_supported_page_list
765172605Sscottl{
766172605Sscottl	u_int8_t device;
767172605Sscottl	u_int8_t page_code;
768172605Sscottl#define SVPD_SUPPORTED_PAGE_LIST 0x00
769172605Sscottl	u_int8_t reserved;
770172605Sscottl	u_int8_t length;	/* number of VPD entries */
771172605Sscottl#define SVPD_SUPPORTED_PAGES_SIZE	251
772172605Sscottl	u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
773172605Sscottl};
774172605Sscottl
77539213Sgibbsstruct scsi_vpd_unit_serial_number
77639213Sgibbs{
77739213Sgibbs	u_int8_t device;
77839213Sgibbs	u_int8_t page_code;
77939213Sgibbs#define SVPD_UNIT_SERIAL_NUMBER	0x80
78039213Sgibbs	u_int8_t reserved;
78139213Sgibbs	u_int8_t length; /* serial number length */
78239213Sgibbs#define SVPD_SERIAL_NUM_SIZE 251
78356147Smjacob	u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
78439213Sgibbs};
78539213Sgibbs
78639213Sgibbsstruct scsi_read_capacity
78739213Sgibbs{
78839213Sgibbs	u_int8_t opcode;
78939213Sgibbs	u_int8_t byte2;
79039213Sgibbs	u_int8_t addr[4];
79139213Sgibbs	u_int8_t unused[3];
79239213Sgibbs	u_int8_t control;
79339213Sgibbs};
79439213Sgibbs
795114261Skenstruct scsi_read_capacity_16
796114261Sken{
797114261Sken	uint8_t opcode;
798114261Sken#define	SRC16_SERVICE_ACTION	0x10
799114261Sken	uint8_t service_action;
800114261Sken	uint8_t addr[8];
801114261Sken	uint8_t alloc_len[4];
802114261Sken#define	SRC16_PMI		0x01
803114261Sken#define	SRC16_RELADR		0x02
804114261Sken	uint8_t reladr;
805114261Sken	uint8_t control;
806114261Sken};
807114261Sken
80839213Sgibbsstruct scsi_read_capacity_data
80939213Sgibbs{
81039213Sgibbs	u_int8_t addr[4];
81139213Sgibbs	u_int8_t length[4];
81239213Sgibbs};
81339213Sgibbs
814114261Skenstruct scsi_read_capacity_data_long
815114261Sken{
816114261Sken	uint8_t addr[8];
817114261Sken	uint8_t length[4];
818114261Sken};
819114261Sken
82097825Smjacobstruct scsi_report_luns
82197825Smjacob{
822161506Sken	uint8_t opcode;
823161506Sken	uint8_t reserved1;
824161506Sken#define	RPL_REPORT_DEFAULT	0x00
825161506Sken#define	RPL_REPORT_WELLKNOWN	0x01
826161506Sken#define	RPL_REPORT_ALL		0x02
827161506Sken	uint8_t select_report;
828161506Sken	uint8_t reserved2[3];
829161506Sken	uint8_t length[4];
830161506Sken	uint8_t reserved3;
831161506Sken	uint8_t control;
83297825Smjacob};
83397825Smjacob
83497825Smjacobstruct scsi_report_luns_data {
83597825Smjacob	u_int8_t length[4];	/* length of LUN inventory, in bytes */
83697825Smjacob	u_int8_t reserved[4];	/* unused */
83797825Smjacob	/*
83897825Smjacob	 * LUN inventory- we only support the type zero form for now.
83997825Smjacob	 */
84097825Smjacob	struct {
84197825Smjacob		u_int8_t lundata[8];
842161506Sken	} luns[0];
84397825Smjacob};
844161506Sken#define	RPL_LUNDATA_PERIPH_BUS_MASK	0x3f
845161506Sken#define	RPL_LUNDATA_FLAT_LUN_MASK	0x3f
846161506Sken#define	RPL_LUNDATA_LUN_TARG_MASK	0x3f
847161506Sken#define	RPL_LUNDATA_LUN_BUS_MASK	0xe0
848161506Sken#define	RPL_LUNDATA_LUN_LUN_MASK	0x1f
849161506Sken#define	RPL_LUNDATA_EXT_LEN_MASK	0x30
850161506Sken#define	RPL_LUNDATA_EXT_EAM_MASK	0x0f
851161506Sken#define	RPL_LUNDATA_EXT_EAM_WK		0x01
852161506Sken#define	RPL_LUNDATA_EXT_EAM_NOT_SPEC	0x0f
85397825Smjacob#define	RPL_LUNDATA_ATYP_MASK	0xc0	/* MBZ for type 0 lun */
854161506Sken#define	RPL_LUNDATA_ATYP_PERIPH	0x00
855161506Sken#define	RPL_LUNDATA_ATYP_FLAT	0x40
856161506Sken#define	RPL_LUNDATA_ATYP_LUN	0x80
857161506Sken#define	RPL_LUNDATA_ATYP_EXTLUN	0xc0
85897825Smjacob
85997825Smjacob
86039213Sgibbsstruct scsi_sense_data
86139213Sgibbs{
86239213Sgibbs	u_int8_t error_code;
86339213Sgibbs#define	SSD_ERRCODE			0x7F
86439213Sgibbs#define		SSD_CURRENT_ERROR	0x70
86539213Sgibbs#define		SSD_DEFERRED_ERROR	0x71
86639213Sgibbs#define	SSD_ERRCODE_VALID	0x80
86739213Sgibbs	u_int8_t segment;
86839213Sgibbs	u_int8_t flags;
86939213Sgibbs#define	SSD_KEY				0x0F
87039213Sgibbs#define		SSD_KEY_NO_SENSE	0x00
87139213Sgibbs#define		SSD_KEY_RECOVERED_ERROR	0x01
87239213Sgibbs#define		SSD_KEY_NOT_READY	0x02
87339213Sgibbs#define		SSD_KEY_MEDIUM_ERROR	0x03
87439213Sgibbs#define		SSD_KEY_HARDWARE_ERROR	0x04
87539213Sgibbs#define		SSD_KEY_ILLEGAL_REQUEST	0x05
87639213Sgibbs#define		SSD_KEY_UNIT_ATTENTION	0x06
87739213Sgibbs#define		SSD_KEY_DATA_PROTECT	0x07
87839213Sgibbs#define		SSD_KEY_BLANK_CHECK	0x08
87939213Sgibbs#define		SSD_KEY_Vendor_Specific	0x09
88039213Sgibbs#define		SSD_KEY_COPY_ABORTED	0x0a
88139213Sgibbs#define		SSD_KEY_ABORTED_COMMAND	0x0b
88239213Sgibbs#define		SSD_KEY_EQUAL		0x0c
88339213Sgibbs#define		SSD_KEY_VOLUME_OVERFLOW	0x0d
88439213Sgibbs#define		SSD_KEY_MISCOMPARE	0x0e
88539213Sgibbs#define		SSD_KEY_RESERVED	0x0f
88639213Sgibbs#define	SSD_ILI		0x20
88739213Sgibbs#define	SSD_EOM		0x40
88839213Sgibbs#define	SSD_FILEMARK	0x80
88939213Sgibbs	u_int8_t info[4];
89039213Sgibbs	u_int8_t extra_len;
89139213Sgibbs	u_int8_t cmd_spec_info[4];
89239213Sgibbs	u_int8_t add_sense_code;
89339213Sgibbs	u_int8_t add_sense_code_qual;
89439213Sgibbs	u_int8_t fru;
89539213Sgibbs	u_int8_t sense_key_spec[3];
89639213Sgibbs#define	SSD_SCS_VALID		0x80
89739213Sgibbs#define SSD_FIELDPTR_CMD	0x40
89839213Sgibbs#define SSD_BITPTR_VALID	0x08
89939213Sgibbs#define SSD_BITPTR_VALUE	0x07
90039213Sgibbs#define SSD_MIN_SIZE 18
90139213Sgibbs	u_int8_t extra_bytes[14];
90239213Sgibbs#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
90339213Sgibbs};
90439213Sgibbs
90539213Sgibbsstruct scsi_mode_header_6
90639213Sgibbs{
90739213Sgibbs	u_int8_t data_length;	/* Sense data length */
90839213Sgibbs	u_int8_t medium_type;
90939213Sgibbs	u_int8_t dev_spec;
91039213Sgibbs	u_int8_t blk_desc_len;
91139213Sgibbs};
91239213Sgibbs
91339213Sgibbsstruct scsi_mode_header_10
91439213Sgibbs{
91539213Sgibbs	u_int8_t data_length[2];/* Sense data length */
91639213Sgibbs	u_int8_t medium_type;
91739213Sgibbs	u_int8_t dev_spec;
91839213Sgibbs	u_int8_t unused[2];
91939213Sgibbs	u_int8_t blk_desc_len[2];
92039213Sgibbs};
92139213Sgibbs
92264382Skbyancstruct scsi_mode_page_header
92339213Sgibbs{
92464382Skbyanc	u_int8_t page_code;
92564382Skbyanc	u_int8_t page_length;
92664382Skbyanc};
92764382Skbyanc
92864382Skbyancstruct scsi_mode_blk_desc
92964382Skbyanc{
93039213Sgibbs	u_int8_t density;
93139213Sgibbs	u_int8_t nblocks[3];
93239213Sgibbs	u_int8_t reserved;
93339213Sgibbs	u_int8_t blklen[3];
93439213Sgibbs};
93539213Sgibbs
93641542Smjacob#define	SCSI_DEFAULT_DENSITY	0x00	/* use 'default' density */
93741542Smjacob#define	SCSI_SAME_DENSITY	0x7f	/* use 'same' density- >= SCSI-2 only */
93897825Smjacob
93997825Smjacob
94039213Sgibbs/*
94139213Sgibbs * Status Byte
94239213Sgibbs */
94339213Sgibbs#define	SCSI_STATUS_OK			0x00
94439213Sgibbs#define	SCSI_STATUS_CHECK_COND		0x02
94539213Sgibbs#define	SCSI_STATUS_COND_MET		0x04
94639213Sgibbs#define	SCSI_STATUS_BUSY		0x08
94739213Sgibbs#define SCSI_STATUS_INTERMED		0x10
94839213Sgibbs#define SCSI_STATUS_INTERMED_COND_MET	0x14
94939213Sgibbs#define SCSI_STATUS_RESERV_CONFLICT	0x18
95074840Sken#define SCSI_STATUS_CMD_TERMINATED	0x22	/* Obsolete in SAM-2 */
95139213Sgibbs#define SCSI_STATUS_QUEUE_FULL		0x28
95274840Sken#define SCSI_STATUS_ACA_ACTIVE		0x30
95374840Sken#define SCSI_STATUS_TASK_ABORTED	0x40
95439213Sgibbs
95539213Sgibbsstruct scsi_inquiry_pattern {
95639213Sgibbs	u_int8_t   type;
95739213Sgibbs	u_int8_t   media_type;
95839213Sgibbs#define	SIP_MEDIA_REMOVABLE	0x01
95939213Sgibbs#define	SIP_MEDIA_FIXED		0x02
96039213Sgibbs	const char *vendor;
96139213Sgibbs	const char *product;
96239213Sgibbs	const char *revision;
96339213Sgibbs};
96439213Sgibbs
96539213Sgibbsstruct scsi_static_inquiry_pattern {
96639213Sgibbs	u_int8_t   type;
96739213Sgibbs	u_int8_t   media_type;
96839213Sgibbs	char       vendor[SID_VENDOR_SIZE+1];
96939213Sgibbs	char       product[SID_PRODUCT_SIZE+1];
97039213Sgibbs	char       revision[SID_REVISION_SIZE+1];
97139213Sgibbs};
97239213Sgibbs
97339213Sgibbsstruct scsi_sense_quirk_entry {
97439213Sgibbs	struct scsi_inquiry_pattern	inq_pat;
97574840Sken	int				num_sense_keys;
97639213Sgibbs	int				num_ascs;
97774840Sken	struct sense_key_table_entry	*sense_key_info;
97839213Sgibbs	struct asc_table_entry		*asc_info;
97939213Sgibbs};
98039213Sgibbs
98174840Skenstruct sense_key_table_entry {
98274840Sken	u_int8_t    sense_key;
98374840Sken	u_int32_t   action;
98474840Sken	const char *desc;
98574840Sken};
98674840Sken
98739213Sgibbsstruct asc_table_entry {
98839213Sgibbs	u_int8_t    asc;
98939213Sgibbs	u_int8_t    ascq;
99039213Sgibbs	u_int32_t   action;
99139213Sgibbs	const char *desc;
99239213Sgibbs};
99339213Sgibbs
99439213Sgibbsstruct op_table_entry {
99539213Sgibbs	u_int8_t    opcode;
99639213Sgibbs	u_int16_t   opmask;
99739213Sgibbs	const char  *desc;
99839213Sgibbs};
99939213Sgibbs
100039213Sgibbsstruct scsi_op_quirk_entry {
100139213Sgibbs	struct scsi_inquiry_pattern	inq_pat;
100239213Sgibbs	int				num_ops;
100339213Sgibbs	struct op_table_entry		*op_table;
100439213Sgibbs};
100539213Sgibbs
100674840Skentypedef enum {
100774840Sken	SSS_FLAG_NONE		= 0x00,
100874840Sken	SSS_FLAG_PRINT_COMMAND	= 0x01
100974840Sken} scsi_sense_string_flags;
101039213Sgibbs
101139213Sgibbsstruct ccb_scsiio;
101239213Sgibbsstruct cam_periph;
101339213Sgibbsunion  ccb;
101455205Speter#ifndef _KERNEL
101539213Sgibbsstruct cam_device;
101639213Sgibbs#endif
101739213Sgibbs
101839213Sgibbsextern const char *scsi_sense_key_text[];
101939213Sgibbs
102074840Skenstruct sbuf;
102174840Sken
102239213Sgibbs__BEGIN_DECLS
102374840Skenvoid scsi_sense_desc(int sense_key, int asc, int ascq,
102474840Sken		     struct scsi_inquiry_data *inq_data,
102574840Sken		     const char **sense_key_desc, const char **asc_desc);
102674840Skenscsi_sense_action scsi_error_action(struct ccb_scsiio* csio,
102774840Sken				    struct scsi_inquiry_data *inq_data,
102874840Sken				    u_int32_t sense_flags);
102974840Skenconst char *	scsi_status_string(struct ccb_scsiio *csio);
103055205Speter#ifdef _KERNEL
103174840Skenint		scsi_command_string(struct ccb_scsiio *csio, struct sbuf *sb);
103274840Skenint		scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
103374840Sken				scsi_sense_string_flags flags);
103474840Skenchar *		scsi_sense_string(struct ccb_scsiio *csio,
103574840Sken				  char *str, int str_len);
103639213Sgibbsvoid		scsi_sense_print(struct ccb_scsiio *csio);
103739213Sgibbsint		scsi_interpret_sense(union ccb *ccb,
103839213Sgibbs				     u_int32_t sense_flags,
103939213Sgibbs				     u_int32_t *relsim_flags,
104039213Sgibbs				     u_int32_t *reduction,
104139213Sgibbs				     u_int32_t *timeout,
104239213Sgibbs				     scsi_sense_action error_action);
104374840Sken#else /* _KERNEL */
104474840Skenint		scsi_command_string(struct cam_device *device,
104574840Sken				    struct ccb_scsiio *csio, struct sbuf *sb);
104674840Skenint		scsi_sense_sbuf(struct cam_device *device,
104774840Sken				struct ccb_scsiio *csio, struct sbuf *sb,
104874840Sken				scsi_sense_string_flags flags);
104939213Sgibbschar *		scsi_sense_string(struct cam_device *device,
105039213Sgibbs				  struct ccb_scsiio *csio,
105139213Sgibbs				  char *str, int str_len);
105239213Sgibbsvoid		scsi_sense_print(struct cam_device *device,
105339213Sgibbs				 struct ccb_scsiio *csio, FILE *ofile);
105439213Sgibbsint		scsi_interpret_sense(struct cam_device *device,
105539213Sgibbs				     union ccb *ccb,
105639213Sgibbs				     u_int32_t sense_flags,
105739213Sgibbs				     u_int32_t *relsim_flags,
105839213Sgibbs				     u_int32_t *reduction,
105939213Sgibbs				     u_int32_t *timeout,
106039213Sgibbs				     scsi_sense_action error_action);
106155205Speter#endif /* _KERNEL */
106239213Sgibbs
106339213Sgibbs#define	SF_RETRY_UA	0x01
106439213Sgibbs#define SF_NO_PRINT	0x02
106539213Sgibbs#define SF_QUIET_IR	0x04	/* Be quiet about Illegal Request reponses */
106639787Sken#define SF_PRINT_ALWAYS	0x08
106739213Sgibbs
106839213Sgibbs
106939213Sgibbsconst char *	scsi_op_desc(u_int16_t opcode,
107039213Sgibbs			     struct scsi_inquiry_data *inq_data);
107140401Skenchar *		scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
107240401Sken				size_t len);
107339213Sgibbs
107439213Sgibbsvoid		scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
107539213Sgibbs
107639213Sgibbsu_int		scsi_calc_syncsrate(u_int period_factor);
107739213Sgibbsu_int		scsi_calc_syncparam(u_int period);
107839213Sgibbs
107939213Sgibbsvoid		scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
108039213Sgibbs				     void (*cbfcnp)(struct cam_periph *,
108139213Sgibbs						    union ccb *),
108239213Sgibbs				     u_int8_t tag_action,
108339213Sgibbs				     u_int8_t sense_len, u_int32_t timeout);
108439213Sgibbs
108539213Sgibbsvoid		scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
108639213Sgibbs				   void (*cbfcnp)(struct cam_periph *,
108739213Sgibbs						  union ccb *),
108839213Sgibbs				   void *data_ptr, u_int8_t dxfer_len,
108939213Sgibbs				   u_int8_t tag_action, u_int8_t sense_len,
109039213Sgibbs				   u_int32_t timeout);
109139213Sgibbs
109239213Sgibbsvoid		scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
109339213Sgibbs			     void (*cbfcnp)(struct cam_periph *, union ccb *),
109439213Sgibbs			     u_int8_t tag_action, u_int8_t *inq_buf,
109539213Sgibbs			     u_int32_t inq_len, int evpd, u_int8_t page_code,
109639213Sgibbs			     u_int8_t sense_len, u_int32_t timeout);
109739213Sgibbs
109839213Sgibbsvoid		scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
109939213Sgibbs				void (*cbfcnp)(struct cam_periph *,
110039213Sgibbs					       union ccb *),
110139213Sgibbs				u_int8_t tag_action, int dbd,
110239213Sgibbs				u_int8_t page_code, u_int8_t page,
110339213Sgibbs				u_int8_t *param_buf, u_int32_t param_len,
110439213Sgibbs				u_int8_t sense_len, u_int32_t timeout);
110539213Sgibbs
1106111206Skenvoid		scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
1107111206Sken				    void (*cbfcnp)(struct cam_periph *,
1108111206Sken						   union ccb *),
1109111206Sken				    u_int8_t tag_action, int dbd,
1110111206Sken				    u_int8_t page_code, u_int8_t page,
1111111206Sken				    u_int8_t *param_buf, u_int32_t param_len,
1112111206Sken				    int minimum_cmd_size, u_int8_t sense_len,
1113111206Sken				    u_int32_t timeout);
1114111206Sken
111539213Sgibbsvoid		scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
111639213Sgibbs				 void (*cbfcnp)(struct cam_periph *,
111739213Sgibbs						union ccb *),
111839213Sgibbs				 u_int8_t tag_action, int scsi_page_fmt,
111939213Sgibbs				 int save_pages, u_int8_t *param_buf,
112039213Sgibbs				 u_int32_t param_len, u_int8_t sense_len,
112139213Sgibbs				 u_int32_t timeout);
112239213Sgibbs
1123111206Skenvoid		scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
1124111206Sken				     void (*cbfcnp)(struct cam_periph *,
1125111206Sken						    union ccb *),
1126111206Sken				     u_int8_t tag_action, int scsi_page_fmt,
1127111206Sken				     int save_pages, u_int8_t *param_buf,
1128111206Sken				     u_int32_t param_len, int minimum_cmd_size,
1129111206Sken				     u_int8_t sense_len, u_int32_t timeout);
1130111206Sken
113182384Skbyancvoid		scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries,
113282384Skbyanc			       void (*cbfcnp)(struct cam_periph *, union ccb *),
113382384Skbyanc			       u_int8_t tag_action, u_int8_t page_code,
113482384Skbyanc			       u_int8_t page, int save_pages, int ppc,
113582384Skbyanc			       u_int32_t paramptr, u_int8_t *param_buf,
113682384Skbyanc			       u_int32_t param_len, u_int8_t sense_len,
113782384Skbyanc			       u_int32_t timeout);
113882384Skbyanc
113982384Skbyancvoid		scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries,
114082384Skbyanc				void (*cbfcnp)(struct cam_periph *,
114182384Skbyanc				union ccb *), u_int8_t tag_action,
114282384Skbyanc				u_int8_t page_code, int save_pages,
114382384Skbyanc				int pc_reset, u_int8_t *param_buf,
114482384Skbyanc				u_int32_t param_len, u_int8_t sense_len,
114582384Skbyanc				u_int32_t timeout);
114682384Skbyanc
114797825Smjacobvoid		scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
114897825Smjacob			     void (*cbfcnp)(struct cam_periph *, union ccb *),
114997825Smjacob			     u_int8_t tag_action, u_int8_t action,
115097825Smjacob			     u_int8_t sense_len, u_int32_t timeout);
115197825Smjacob
115239213Sgibbsvoid		scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
115339213Sgibbs				   void (*cbfcnp)(struct cam_periph *,
115439213Sgibbs				   union ccb *), u_int8_t tag_action,
115597825Smjacob				   struct scsi_read_capacity_data *,
115639213Sgibbs				   u_int8_t sense_len, u_int32_t timeout);
1157114261Skenvoid		scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries,
1158114261Sken				      void (*cbfcnp)(struct cam_periph *,
1159114261Sken				      union ccb *), uint8_t tag_action,
1160114261Sken				      uint64_t lba, int reladr, int pmi,
1161114261Sken				      struct scsi_read_capacity_data_long
1162114261Sken				      *rcap_buf, uint8_t sense_len,
1163114261Sken				      uint32_t timeout);
116439213Sgibbs
116597825Smjacobvoid		scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries,
1166161506Sken				 void (*cbfcnp)(struct cam_periph *,
1167161506Sken				 union ccb *), u_int8_t tag_action,
1168161506Sken				 u_int8_t select_report,
1169161506Sken				 struct scsi_report_luns_data *rpl_buf,
1170161506Sken				 u_int32_t alloc_len, u_int8_t sense_len,
1171161506Sken				 u_int32_t timeout);
117239213Sgibbs
117339213Sgibbsvoid		scsi_synchronize_cache(struct ccb_scsiio *csio,
117439213Sgibbs				       u_int32_t retries,
117539213Sgibbs				       void (*cbfcnp)(struct cam_periph *,
117639213Sgibbs				       union ccb *), u_int8_t tag_action,
117739213Sgibbs				       u_int32_t begin_lba, u_int16_t lb_count,
117839213Sgibbs				       u_int8_t sense_len, u_int32_t timeout);
117939213Sgibbs
118039466Skenvoid scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
118139466Sken		     void (*cbfcnp)(struct cam_periph *, union ccb *),
118239466Sken		     u_int8_t tag_action, int readop, u_int8_t byte2,
1183114261Sken		     int minimum_cmd_size, u_int64_t lba,
118439466Sken		     u_int32_t block_count, u_int8_t *data_ptr,
118539466Sken		     u_int32_t dxfer_len, u_int8_t sense_len,
118639466Sken		     u_int32_t timeout);
118739466Sken
118839466Skenvoid scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
118939466Sken		     void (*cbfcnp)(struct cam_periph *, union ccb *),
119039466Sken		     u_int8_t tag_action, int start, int load_eject,
119139466Sken		     int immediate, u_int8_t sense_len, u_int32_t timeout);
119239466Sken
119339213Sgibbsint		scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
119439213Sgibbsint		scsi_static_inquiry_match(caddr_t inqbuffer,
119539213Sgibbs					  caddr_t table_entry);
119639213Sgibbs
119739213Sgibbsstatic __inline void scsi_extract_sense(struct scsi_sense_data *sense,
119839213Sgibbs					int *error_code, int *sense_key,
119939213Sgibbs					int *asc, int *ascq);
120039213Sgibbsstatic __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
120139213Sgibbsstatic __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
120239213Sgibbsstatic __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
1203114261Skenstatic __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes);
120439213Sgibbsstatic __inline u_int32_t scsi_2btoul(u_int8_t *bytes);
120539213Sgibbsstatic __inline u_int32_t scsi_3btoul(u_int8_t *bytes);
120639213Sgibbsstatic __inline int32_t scsi_3btol(u_int8_t *bytes);
120739213Sgibbsstatic __inline u_int32_t scsi_4btoul(u_int8_t *bytes);
1208114261Skenstatic __inline u_int64_t scsi_8btou64(u_int8_t *bytes);
120939885Skenstatic __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
121039885Skenstatic __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
121139213Sgibbs
121239213Sgibbsstatic __inline void scsi_extract_sense(struct scsi_sense_data *sense,
121339213Sgibbs					int *error_code, int *sense_key,
121439213Sgibbs					int *asc, int *ascq)
121539213Sgibbs{
121639213Sgibbs	*error_code = sense->error_code & SSD_ERRCODE;
121739213Sgibbs	*sense_key = sense->flags & SSD_KEY;
121839213Sgibbs	*asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
121939213Sgibbs	*ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
122039213Sgibbs}
122139213Sgibbs
122239213Sgibbsstatic __inline void
122339213Sgibbsscsi_ulto2b(u_int32_t val, u_int8_t *bytes)
122439213Sgibbs{
122539213Sgibbs
122639213Sgibbs	bytes[0] = (val >> 8) & 0xff;
122739213Sgibbs	bytes[1] = val & 0xff;
122839213Sgibbs}
122939213Sgibbs
123039213Sgibbsstatic __inline void
123139213Sgibbsscsi_ulto3b(u_int32_t val, u_int8_t *bytes)
123239213Sgibbs{
123339213Sgibbs
123439213Sgibbs	bytes[0] = (val >> 16) & 0xff;
123539213Sgibbs	bytes[1] = (val >> 8) & 0xff;
123639213Sgibbs	bytes[2] = val & 0xff;
123739213Sgibbs}
123839213Sgibbs
123939213Sgibbsstatic __inline void
124039213Sgibbsscsi_ulto4b(u_int32_t val, u_int8_t *bytes)
124139213Sgibbs{
124239213Sgibbs
124339213Sgibbs	bytes[0] = (val >> 24) & 0xff;
124439213Sgibbs	bytes[1] = (val >> 16) & 0xff;
124539213Sgibbs	bytes[2] = (val >> 8) & 0xff;
124639213Sgibbs	bytes[3] = val & 0xff;
124739213Sgibbs}
124839213Sgibbs
1249114261Skenstatic __inline void
1250114261Skenscsi_u64to8b(u_int64_t val, u_int8_t *bytes)
1251114261Sken{
1252114261Sken
1253114261Sken	bytes[0] = (val >> 56) & 0xff;
1254114261Sken	bytes[1] = (val >> 48) & 0xff;
1255114261Sken	bytes[2] = (val >> 40) & 0xff;
1256114261Sken	bytes[3] = (val >> 32) & 0xff;
1257114261Sken	bytes[4] = (val >> 24) & 0xff;
1258114261Sken	bytes[5] = (val >> 16) & 0xff;
1259114261Sken	bytes[6] = (val >> 8) & 0xff;
1260114261Sken	bytes[7] = val & 0xff;
1261114261Sken}
1262114261Sken
126339213Sgibbsstatic __inline u_int32_t
126439213Sgibbsscsi_2btoul(u_int8_t *bytes)
126539213Sgibbs{
126639213Sgibbs	u_int32_t rv;
126739213Sgibbs
126839213Sgibbs	rv = (bytes[0] << 8) |
126939213Sgibbs	     bytes[1];
127039213Sgibbs	return (rv);
127139213Sgibbs}
127239213Sgibbs
127339213Sgibbsstatic __inline u_int32_t
127439213Sgibbsscsi_3btoul(u_int8_t *bytes)
127539213Sgibbs{
127639213Sgibbs	u_int32_t rv;
127739213Sgibbs
127839213Sgibbs	rv = (bytes[0] << 16) |
127939213Sgibbs	     (bytes[1] << 8) |
128039213Sgibbs	     bytes[2];
128139213Sgibbs	return (rv);
128239213Sgibbs}
128339213Sgibbs
128439213Sgibbsstatic __inline int32_t
128539213Sgibbsscsi_3btol(u_int8_t *bytes)
128639213Sgibbs{
128739213Sgibbs	u_int32_t rc = scsi_3btoul(bytes);
128839213Sgibbs
128939213Sgibbs	if (rc & 0x00800000)
129039213Sgibbs		rc |= 0xff000000;
129139213Sgibbs
129239213Sgibbs	return (int32_t) rc;
129339213Sgibbs}
129439213Sgibbs
129539213Sgibbsstatic __inline u_int32_t
129639213Sgibbsscsi_4btoul(u_int8_t *bytes)
129739213Sgibbs{
129839213Sgibbs	u_int32_t rv;
129939213Sgibbs
130039213Sgibbs	rv = (bytes[0] << 24) |
130139213Sgibbs	     (bytes[1] << 16) |
130239213Sgibbs	     (bytes[2] << 8) |
130339213Sgibbs	     bytes[3];
130439213Sgibbs	return (rv);
130539213Sgibbs}
130639885Sken
1307114261Skenstatic __inline uint64_t
1308114261Skenscsi_8btou64(uint8_t *bytes)
1309114261Sken{
1310114261Sken        uint64_t rv;
1311114261Sken
1312114261Sken	rv = (((uint64_t)bytes[0]) << 56) |
1313114261Sken	     (((uint64_t)bytes[1]) << 48) |
1314114261Sken	     (((uint64_t)bytes[2]) << 40) |
1315114261Sken	     (((uint64_t)bytes[3]) << 32) |
1316114261Sken	     (((uint64_t)bytes[4]) << 24) |
1317114261Sken	     (((uint64_t)bytes[5]) << 16) |
1318114261Sken	     (((uint64_t)bytes[6]) << 8) |
1319114261Sken	     bytes[7];
1320114261Sken	return (rv);
1321114261Sken}
1322114261Sken
132339885Sken/*
132439885Sken * Given the pointer to a returned mode sense buffer, return a pointer to
132539885Sken * the start of the first mode page.
132639885Sken */
132739885Skenstatic __inline void *
132839885Skenfind_mode_page_6(struct scsi_mode_header_6 *mode_header)
132939885Sken{
133039885Sken	void *page_start;
133139885Sken
133239885Sken	page_start = (void *)((u_int8_t *)&mode_header[1] +
133339885Sken			      mode_header->blk_desc_len);
133439885Sken
133539885Sken	return(page_start);
133639885Sken}
133739885Sken
133839885Skenstatic __inline void *
133939885Skenfind_mode_page_10(struct scsi_mode_header_10 *mode_header)
134039885Sken{
134139885Sken	void *page_start;
134239885Sken
1343172605Sscottl	page_start = (void *)((u_int8_t *)&mode_header[2] +
134439885Sken			       scsi_2btoul(mode_header->blk_desc_len));
134539885Sken
134639885Sken	return(page_start);
134739885Sken}
134839885Sken
134939213Sgibbs__END_DECLS
135039213Sgibbs
135139213Sgibbs#endif /*_SCSI_SCSI_ALL_H*/
1352