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