1 #ifndef _IPXE_SCSI_H 2 #define _IPXE_SCSI_H 3 4 #include <stdint.h> 5 #include <ipxe/uaccess.h> 6 #include <ipxe/interface.h> 7 8 /** @file 9 * 10 * SCSI devices 11 * 12 */ 13 14 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); 15 16 /** Maximum block for READ/WRITE (10) commands */ 17 #define SCSI_MAX_BLOCK_10 0xffffffffULL 18 19 /** 20 * @defgroup scsiops SCSI operation codes 21 * @{ 22 */ 23 24 #define SCSI_OPCODE_READ_10 0x28 /**< READ (10) */ 25 #define SCSI_OPCODE_READ_16 0x88 /**< READ (16) */ 26 #define SCSI_OPCODE_WRITE_10 0x2a /**< WRITE (10) */ 27 #define SCSI_OPCODE_WRITE_16 0x8a /**< WRITE (16) */ 28 #define SCSI_OPCODE_READ_CAPACITY_10 0x25 /**< READ CAPACITY (10) */ 29 #define SCSI_OPCODE_SERVICE_ACTION_IN 0x9e /**< SERVICE ACTION IN */ 30 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */ 31 #define SCSI_OPCODE_TEST_UNIT_READY 0x00 /**< TEST UNIT READY */ 32 33 /** @} */ 34 35 /** 36 * @defgroup scsiflags SCSI flags 37 * @{ 38 */ 39 40 #define SCSI_FL_FUA_NV 0x02 /**< Force unit access to NVS */ 41 #define SCSI_FL_FUA 0x08 /**< Force unit access */ 42 #define SCSI_FL_DPO 0x10 /**< Disable cache page out */ 43 44 /** @} */ 45 46 /** 47 * @defgroup scsicdbs SCSI command data blocks 48 * @{ 49 */ 50 51 /** A SCSI "READ (10)" CDB */ 52 struct scsi_cdb_read_10 { 53 /** Opcode (0x28) */ 54 uint8_t opcode; 55 /** Flags */ 56 uint8_t flags; 57 /** Start address 58 * 59 * This is a logical block number, in big-endian order. 60 */ 61 uint32_t lba; 62 /** Group number */ 63 uint8_t group; 64 /** Transfer length 65 * 66 * This is a logical block count, in big-endian order. 67 */ 68 uint16_t len; 69 /** Control byte */ 70 uint8_t control; 71 } __attribute__ (( packed )); 72 73 /** A SCSI "READ (16)" CDB */ 74 struct scsi_cdb_read_16 { 75 /** Opcode (0x88) */ 76 uint8_t opcode; 77 /** Flags */ 78 uint8_t flags; 79 /** Start address 80 * 81 * This is a logical block number, in big-endian order. 82 */ 83 uint64_t lba; 84 /** Transfer length 85 * 86 * This is a logical block count, in big-endian order. 87 */ 88 uint32_t len; 89 /** Group number */ 90 uint8_t group; 91 /** Control byte */ 92 uint8_t control; 93 } __attribute__ (( packed )); 94 95 /** A SCSI "WRITE (10)" CDB */ 96 struct scsi_cdb_write_10 { 97 /** Opcode (0x2a) */ 98 uint8_t opcode; 99 /** Flags */ 100 uint8_t flags; 101 /** Start address 102 * 103 * This is a logical block number, in big-endian order. 104 */ 105 uint32_t lba; 106 /** Group number */ 107 uint8_t group; 108 /** Transfer length 109 * 110 * This is a logical block count, in big-endian order. 111 */ 112 uint16_t len; 113 /** Control byte */ 114 uint8_t control; 115 } __attribute__ (( packed )); 116 117 /** A SCSI "WRITE (16)" CDB */ 118 struct scsi_cdb_write_16 { 119 /** Opcode (0x8a) */ 120 uint8_t opcode; 121 /** Flags */ 122 uint8_t flags; 123 /** Start address 124 * 125 * This is a logical block number, in big-endian order. 126 */ 127 uint64_t lba; 128 /** Transfer length 129 * 130 * This is a logical block count, in big-endian order. 131 */ 132 uint32_t len; 133 /** Group number */ 134 uint8_t group; 135 /** Control byte */ 136 uint8_t control; 137 } __attribute__ (( packed )); 138 139 /** A SCSI "READ CAPACITY (10)" CDB */ 140 struct scsi_cdb_read_capacity_10 { 141 /** Opcode (0x25) */ 142 uint8_t opcode; 143 /** Reserved */ 144 uint8_t reserved_a; 145 /** Logical block address 146 * 147 * Applicable only if the PMI bit is set. 148 */ 149 uint32_t lba; 150 /** Reserved */ 151 uint8_t reserved_b[3]; 152 /** Control byte */ 153 uint8_t control; 154 } __attribute__ (( packed )); 155 156 /** SCSI "READ CAPACITY (10)" parameter data */ 157 struct scsi_capacity_10 { 158 /** Maximum logical block number */ 159 uint32_t lba; 160 /** Block length in bytes */ 161 uint32_t blksize; 162 } __attribute__ (( packed )); 163 164 /** A SCSI "READ CAPACITY (16)" CDB */ 165 struct scsi_cdb_read_capacity_16 { 166 /** Opcode (0x9e) */ 167 uint8_t opcode; 168 /** Service action */ 169 uint8_t service_action; 170 /** Logical block address 171 * 172 * Applicable only if the PMI bit is set. 173 */ 174 uint64_t lba; 175 /** Transfer length 176 * 177 * This is the size of the data-in buffer, in bytes. 178 */ 179 uint32_t len; 180 /** Reserved */ 181 uint8_t reserved; 182 /** Control byte */ 183 uint8_t control; 184 } __attribute__ (( packed )); 185 186 /** SCSI "READ CAPACITY (16)" parameter data */ 187 struct scsi_capacity_16 { 188 /** Maximum logical block number */ 189 uint64_t lba; 190 /** Block length in bytes */ 191 uint32_t blksize; 192 /** Reserved */ 193 uint8_t reserved[20]; 194 } __attribute__ (( packed )); 195 196 /** A SCSI "TEST UNIT READY" CDB */ 197 struct scsi_cdb_test_unit_ready { 198 /** Opcode (0x00) */ 199 uint8_t opcode; 200 /** Reserved */ 201 uint8_t reserved[4]; 202 /** Control byte */ 203 uint8_t control; 204 } __attribute__ (( packed )); 205 206 /** A SCSI Command Data Block */ 207 union scsi_cdb { 208 struct scsi_cdb_read_10 read10; 209 struct scsi_cdb_read_16 read16; 210 struct scsi_cdb_write_10 write10; 211 struct scsi_cdb_write_16 write16; 212 struct scsi_cdb_read_capacity_10 readcap10; 213 struct scsi_cdb_read_capacity_16 readcap16; 214 struct scsi_cdb_test_unit_ready testready; 215 unsigned char bytes[16]; 216 }; 217 218 /** printf() format for dumping a scsi_cdb */ 219 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ 220 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" 221 222 /** printf() parameters for dumping a scsi_cdb */ 223 #define SCSI_CDB_DATA(cdb) \ 224 (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3], \ 225 (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7], \ 226 (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \ 227 (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15] 228 229 /** @} */ 230 231 /** A SCSI LUN 232 * 233 * This is a four-level LUN as specified by SAM-2, in big-endian 234 * order. 235 */ 236 struct scsi_lun { 237 uint16_t u16[4]; 238 } __attribute__ (( packed )); 239 240 /** printf() format for dumping a scsi_lun */ 241 #define SCSI_LUN_FORMAT "%04x-%04x-%04x-%04x" 242 243 /** printf() parameters for dumping a scsi_lun */ 244 #define SCSI_LUN_DATA(lun) \ 245 ntohs ( (lun).u16[0] ), ntohs ( (lun).u16[1] ), \ 246 ntohs ( (lun).u16[2] ), ntohs ( (lun).u16[3] ) 247 248 /** A SCSI command information unit */ 249 struct scsi_cmd { 250 /** LUN */ 251 struct scsi_lun lun; 252 /** CDB for this command */ 253 union scsi_cdb cdb; 254 /** Data-out buffer (may be NULL) */ 255 userptr_t data_out; 256 /** Data-out buffer length 257 * 258 * Must be zero if @c data_out is NULL 259 */ 260 size_t data_out_len; 261 /** Data-in buffer (may be NULL) */ 262 userptr_t data_in; 263 /** Data-in buffer length 264 * 265 * Must be zero if @c data_in is NULL 266 */ 267 size_t data_in_len; 268 }; 269 270 /** SCSI fixed-format sense data */ 271 struct scsi_sns_fixed { 272 /** Response code */ 273 uint8_t code; 274 /** Reserved */ 275 uint8_t reserved; 276 /** Sense key */ 277 uint8_t key; 278 /** Information */ 279 uint32_t info; 280 /** Additional sense length */ 281 uint8_t len; 282 /** Command-specific information */ 283 uint32_t cs_info; 284 /** Additional sense code and qualifier */ 285 uint16_t additional; 286 } __attribute__ (( packed )); 287 288 /** SCSI descriptor-format sense data */ 289 struct scsi_sns_descriptor { 290 /** Response code */ 291 uint8_t code; 292 /** Sense key */ 293 uint8_t key; 294 /** Additional sense code and qualifier */ 295 uint16_t additional; 296 } __attribute__ (( packed )); 297 298 /** SCSI sense data */ 299 union scsi_sns { 300 /** Response code */ 301 uint8_t code; 302 /** Fixed-format sense data */ 303 struct scsi_sns_fixed fixed; 304 /** Descriptor-format sense data */ 305 struct scsi_sns_descriptor desc; 306 }; 307 308 /** SCSI sense response code mask */ 309 #define SCSI_SENSE_CODE_MASK 0x7f 310 311 /** Test if SCSI sense data is in fixed format 312 * 313 * @v code Response code 314 * @ret is_fixed Sense data is in fixed format 315 */ 316 #define SCSI_SENSE_FIXED( code ) ( ( (code) & 0x7e ) == 0x70 ) 317 318 /** SCSI sense key mask */ 319 #define SCSI_SENSE_KEY_MASK 0x0f 320 321 /** A SCSI response information unit */ 322 struct scsi_rsp { 323 /** SCSI status code */ 324 uint8_t status; 325 /** Data overrun (or negative underrun) */ 326 ssize_t overrun; 327 /** Autosense data (if any) 328 * 329 * To minimise code size, this is stored as the first four 330 * bytes of a descriptor-format sense data block (even if the 331 * response code indicates fixed-format sense data). 332 */ 333 struct scsi_sns_descriptor sense; 334 }; 335 336 extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ); 337 extern void scsi_parse_sense ( const void *data, size_t len, 338 struct scsi_sns_descriptor *sense ); 339 340 extern int scsi_command ( struct interface *control, struct interface *data, 341 struct scsi_cmd *command ); 342 #define scsi_command_TYPE( object_type ) \ 343 typeof ( int ( object_type, struct interface *data, \ 344 struct scsi_cmd *command ) ) 345 346 extern void scsi_response ( struct interface *intf, struct scsi_rsp *response ); 347 #define scsi_response_TYPE( object_type ) \ 348 typeof ( void ( object_type, struct scsi_rsp *response ) ) 349 350 extern int scsi_open ( struct interface *block, struct interface *scsi, 351 struct scsi_lun *lun ); 352 353 #endif /* _IPXE_SCSI_H */ 354