00001
00044 #ifndef SCSI_SPC_PROTOCOL_H_INCLUDED
00045 #define SCSI_SPC_PROTOCOL_H_INCLUDED
00046
00047 #define SCSI_CMD_TEST_UNIT_READY 0x00
00048 #define SCSI_CMD_REQUEST_SENSE 0x03
00049 #define SCSI_CMD_INQUIRY 0x12
00050 #define SCSI_CMD_MODE_SELECT6 0x15
00051 #define SCSI_CMD_MODE_SENSE6 0x1a
00052 #define SCSI_CMD_SEND_DIAGNOSTIC 0x1d
00053 #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
00054 #define SCSI_CMD_MODE_SENSE10 0x5a
00055 #define SCSI_CMD_REPORT_LUNS 0xa0
00056
00057
00058 #define SCSI_INQ_REQ_EVPD 0x01
00059
00060
00063 struct scsi_inquiry_data {
00064 uint8_t pq_pdt;
00065 #define SCSI_INQ_PQ_CONNECTED 0x00
00066 #define SCSI_INQ_PQ_NOT_CONN 0x20
00067 #define SCSI_INQ_PQ_NOT_SUPP 0x60
00068 #define SCSI_INQ_DT_DIR_ACCESS 0x00
00069 #define SCSI_INQ_DT_SEQ_ACCESS 0x01
00070 #define SCSI_INQ_DT_PRINTER 0x02
00071 #define SCSI_INQ_DT_PROCESSOR 0x03
00072 #define SCSI_INQ_DT_WRITE_ONCE 0x04
00073 #define SCSI_INQ_DT_CD_DVD 0x05
00074 #define SCSI_INQ_DT_OPTICAL 0x07
00075 #define SCSI_INQ_DT_MC 0x08
00076 #define SCSI_INQ_DT_ARRAY 0x0c
00077 #define SCSI_INQ_DT_ENCLOSURE 0x0d
00078 #define SCSI_INQ_DT_RBC 0x0e
00079 #define SCSI_INQ_DT_OCRW 0x0f
00080 #define SCSI_INQ_DT_BCC 0x10
00081 #define SCSI_INQ_DT_OSD 0x11
00082 #define SCSI_INQ_DT_NONE 0x1f
00083 uint8_t flags1;
00084 #define SCSI_INQ_RMB 0x80
00085 uint8_t version;
00086 #define SCSI_INQ_VER_NONE 0x00
00087 #define SCSI_INQ_VER_SPC 0x03
00088 #define SCSI_INQ_VER_SPC2 0x04
00089 #define SCSI_INQ_VER_SPC3 0x05
00090 uint8_t flags3;
00091 #define SCSI_INQ_NORMACA 0x20
00092 #define SCSI_INQ_HISUP 0x10
00093 #define SCSI_INQ_RSP_SPC2 0x02
00094 uint8_t addl_len;
00095 #define SCSI_INQ_ADDL_LEN(tot) ((tot) - 5)
00096 uint8_t flags5;
00097 #define SCSI_INQ_SCCS 0x80
00098 uint8_t flags6;
00099 #define SCSI_INQ_BQUE 0x80
00100 #define SCSI_INQ_ENCSERV 0x40
00101 #define SCSI_INQ_MULTIP 0x10
00102 #define SCSI_INQ_MCHGR 0x08
00103 #define SCSI_INQ_ADDR16 0x01
00104 uint8_t flags7;
00105 #define SCSI_INQ_WBUS16 0x20
00106 #define SCSI_INQ_SYNC 0x10
00107 #define SCSI_INQ_LINKED 0x08
00108 #define SCSI_INQ_CMDQUE 0x02
00109 uint8_t vendor_id[8];
00110 uint8_t product_id[16];
00111 uint8_t product_rev[4];
00112 } __packed;
00113
00114
00115 enum scsi_vpd_page_code {
00116 SCSI_VPD_SUPPORTED_PAGES = 0x00,
00117 SCSI_VPD_UNIT_SERIAL_NUMBER = 0x80,
00118 SCSI_VPD_DEVICE_IDENTIFICATION = 0x83,
00119 };
00120 #define SCSI_VPD_HEADER_SIZE 4
00121
00122
00123 #define SCSI_VPD_ID_HEADER_SIZE 4
00124
00125 #define SCSI_VPD_CODE_SET_BINARY 1
00126 #define SCSI_VPD_CODE_SET_ASCII 2
00127 #define SCSI_VPD_CODE_SET_UTF8 3
00128
00129 #define SCSI_VPD_ID_TYPE_T10 1
00130
00131
00132 #define SCSI_SENSE_VALID 0x80
00133 #define SCSI_SENSE_CURRENT 0x70
00134 #define SCSI_SENSE_DEFERRED 0x71
00135
00136
00137 #define SCSI_SENSE_FILEMARK 0x80
00138 #define SCSI_SENSE_EOM 0x40
00139 #define SCSI_SENSE_ILI 0x20
00140 #define SCSI_SENSE_KEY(x) (x)
00141
00142
00143 #define SCSI_SENSE_ADDL_LEN(total_len) ((total_len) - 8)
00144
00145
00146 #define SCSI_SENSE_SKSV 0x80
00147
00148
00149 enum scsi_sense_key {
00150 SCSI_SK_NO_SENSE = 0x0,
00151 SCSI_SK_RECOVERED_ERROR = 0x1,
00152 SCSI_SK_NOT_READY = 0x2,
00153 SCSI_SK_MEDIUM_ERROR = 0x3,
00154 SCSI_SK_HARDWARE_ERROR = 0x4,
00155 SCSI_SK_ILLEGAL_REQUEST = 0x5,
00156 SCSI_SK_UNIT_ATTENTION = 0x6,
00157 SCSI_SK_DATA_PROTECT = 0x7,
00158 SCSI_SK_BLANK_CHECK = 0x8,
00159 SCSI_SK_VENDOR_SPECIFIC = 0x9,
00160 SCSI_SK_COPY_ABORTED = 0xa,
00161 SCSI_SK_ABORTED_COMMAND = 0xb,
00162 SCSI_SK_VOLUME_OVERFLOW = 0xd,
00163 SCSI_SK_MISCOMPARE = 0xe,
00164 };
00165
00166
00167 enum scsi_asc_ascq {
00168 SCSI_ASC_NO_ADDITIONAL_SENSE_INFO = 0x0000,
00169 SCSI_ASC_LU_NOT_READY_REBUILD_IN_PROGRESS = 0x0405,
00170 SCSI_ASC_WRITE_ERROR = 0x0c00,
00171 SCSI_ASC_UNRECOVERED_READ_ERROR = 0x1100,
00172 SCSI_ASC_INVALID_COMMAND_OPERATION_CODE = 0x2000,
00173 SCSI_ASC_INVALID_FIELD_IN_CDB = 0x2400,
00174 SCSI_ASC_MEDIUM_NOT_PRESENT = 0x3a00,
00175 SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x4400,
00176 };
00177
00178
00179
00180 enum scsi_spc_mode_page_code {
00181 SCSI_MS_PAGE_VENDOR_SPEC = 0x00,
00182 SCSI_MS_PAGE_ALL = 0x3f,
00183 };
00184
00185 enum scsi_spc_mode_sense_pc {
00186 SCSI_MS_PC_CURRENT = 0,
00187 SCSI_MS_PC_CHANGEABLE = 1,
00188 SCSI_MS_PC_DEFAULT = 2,
00189 SCSI_MS_PC_SAVED = 3,
00190 };
00191
00192 static inline bool scsi_mode_sense_dbd_is_set(const uint8_t *cdb)
00193 {
00194 return (cdb[1] >> 3) & 1;
00195 }
00196
00197 static inline uint8_t scsi_mode_sense_get_page_code(const uint8_t *cdb)
00198 {
00199 return cdb[2] & 0x3f;
00200 }
00201
00202 static inline uint8_t scsi_mode_sense_get_pc(const uint8_t *cdb)
00203 {
00204 return cdb[2] >> 6;
00205 }
00206
00211 struct scsi_mode_param_header6 {
00212 uint8_t mode_data_length;
00213 uint8_t medium_type;
00214 uint8_t device_specific_parameter;
00215 uint8_t block_descriptor_length;
00216 };
00217
00222 struct scsi_mode_param_header10 {
00223 be16_t mode_data_length;
00224 uint8_t medium_type;
00225 uint8_t device_specific_parameter;
00226 uint8_t flags4;
00227 uint8_t reserved;
00228 be16_t block_descriptor_length;
00229 };
00230
00234 struct scsi_mode_page_0_header {
00235 uint8_t page_code;
00236 #define SCSI_PAGE_CODE_PS (1 << 7)
00237 #define SCSI_PAGE_CODE_SPF (1 << 6)
00238 uint8_t page_length;
00239 #define SCSI_MS_PAGE_LEN(total) ((total) - 2)
00240 };
00241
00242 #endif