1 #ifndef _GPXE_SCSI_H 2 #define _GPXE_SCSI_H 3 4 #include <stdint.h> 5 #include <gpxe/blockdev.h> 6 #include <gpxe/uaccess.h> 7 #include <gpxe/refcnt.h> 8 9 /** @file 10 * 11 * SCSI devices 12 * 13 */ 14 15 FILE_LICENCE ( GPL2_OR_LATER ); 16 17 /** 18 * @defgroup scsiops SCSI operation codes 19 * @{ 20 */ 21 22 #define SCSI_OPCODE_READ_10 0x28 /**< READ (10) */ 23 #define SCSI_OPCODE_READ_16 0x88 /**< READ (16) */ 24 #define SCSI_OPCODE_WRITE_10 0x2a /**< WRITE (10) */ 25 #define SCSI_OPCODE_WRITE_16 0x8a /**< WRITE (16) */ 26 #define SCSI_OPCODE_READ_CAPACITY_10 0x25 /**< READ CAPACITY (10) */ 27 #define SCSI_OPCODE_SERVICE_ACTION_IN 0x9e /**< SERVICE ACTION IN */ 28 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */ 29 30 /** @} */ 31 32 /** 33 * @defgroup scsiflags SCSI flags 34 * @{ 35 */ 36 37 #define SCSI_FL_FUA_NV 0x02 /**< Force unit access to NVS */ 38 #define SCSI_FL_FUA 0x08 /**< Force unit access */ 39 #define SCSI_FL_DPO 0x10 /**< Disable cache page out */ 40 41 /** @} */ 42 43 /** 44 * @defgroup scsicdbs SCSI command data blocks 45 * @{ 46 */ 47 48 /** A SCSI "READ (10)" CDB */ 49 struct scsi_cdb_read_10 { 50 /** Opcode (0x28) */ 51 uint8_t opcode; 52 /** Flags */ 53 uint8_t flags; 54 /** Start address 55 * 56 * This is a logical block number, in big-endian order. 57 */ 58 uint32_t lba; 59 /** Group number */ 60 uint8_t group; 61 /** Transfer length 62 * 63 * This is a logical block count, in big-endian order. 64 */ 65 uint16_t len; 66 /** Control byte */ 67 uint8_t control; 68 } __attribute__ (( packed )); 69 70 /** A SCSI "READ (16)" CDB */ 71 struct scsi_cdb_read_16 { 72 /** Opcode (0x88) */ 73 uint8_t opcode; 74 /** Flags */ 75 uint8_t flags; 76 /** Start address 77 * 78 * This is a logical block number, in big-endian order. 79 */ 80 uint64_t lba; 81 /** Transfer length 82 * 83 * This is a logical block count, in big-endian order. 84 */ 85 uint32_t len; 86 /** Group number */ 87 uint8_t group; 88 /** Control byte */ 89 uint8_t control; 90 } __attribute__ (( packed )); 91 92 /** A SCSI "WRITE (10)" CDB */ 93 struct scsi_cdb_write_10 { 94 /** Opcode (0x2a) */ 95 uint8_t opcode; 96 /** Flags */ 97 uint8_t flags; 98 /** Start address 99 * 100 * This is a logical block number, in big-endian order. 101 */ 102 uint32_t lba; 103 /** Group number */ 104 uint8_t group; 105 /** Transfer length 106 * 107 * This is a logical block count, in big-endian order. 108 */ 109 uint16_t len; 110 /** Control byte */ 111 uint8_t control; 112 } __attribute__ (( packed )); 113 114 /** A SCSI "WRITE (16)" CDB */ 115 struct scsi_cdb_write_16 { 116 /** Opcode (0x8a) */ 117 uint8_t opcode; 118 /** Flags */ 119 uint8_t flags; 120 /** Start address 121 * 122 * This is a logical block number, in big-endian order. 123 */ 124 uint64_t lba; 125 /** Transfer length 126 * 127 * This is a logical block count, in big-endian order. 128 */ 129 uint32_t len; 130 /** Group number */ 131 uint8_t group; 132 /** Control byte */ 133 uint8_t control; 134 } __attribute__ (( packed )); 135 136 /** A SCSI "READ CAPACITY (10)" CDB */ 137 struct scsi_cdb_read_capacity_10 { 138 /** Opcode (0x25) */ 139 uint8_t opcode; 140 /** Reserved */ 141 uint8_t reserved_a; 142 /** Logical block address 143 * 144 * Applicable only if the PMI bit is set. 145 */ 146 uint32_t lba; 147 /** Reserved */ 148 uint8_t reserved_b[3]; 149 /** Control byte */ 150 uint8_t control; 151 } __attribute__ (( packed )); 152 153 /** SCSI "READ CAPACITY (10)" parameter data */ 154 struct scsi_capacity_10 { 155 /** Maximum logical block number */ 156 uint32_t lba; 157 /** Block length in bytes */ 158 uint32_t blksize; 159 } __attribute__ (( packed )); 160 161 /** A SCSI "READ CAPACITY (16)" CDB */ 162 struct scsi_cdb_read_capacity_16 { 163 /** Opcode (0x9e) */ 164 uint8_t opcode; 165 /** Service action */ 166 uint8_t service_action; 167 /** Logical block address 168 * 169 * Applicable only if the PMI bit is set. 170 */ 171 uint64_t lba; 172 /** Transfer length 173 * 174 * This is the size of the data-in buffer, in bytes. 175 */ 176 uint32_t len; 177 /** Reserved */ 178 uint8_t reserved; 179 /** Control byte */ 180 uint8_t control; 181 } __attribute__ (( packed )); 182 183 /** SCSI "READ CAPACITY (16)" parameter data */ 184 struct scsi_capacity_16 { 185 /** Maximum logical block number */ 186 uint64_t lba; 187 /** Block length in bytes */ 188 uint32_t blksize; 189 /** Reserved */ 190 uint8_t reserved[20]; 191 } __attribute__ (( packed )); 192 193 /** A SCSI Command Data Block */ 194 union scsi_cdb { 195 struct scsi_cdb_read_10 read10; 196 struct scsi_cdb_read_16 read16; 197 struct scsi_cdb_write_10 write10; 198 struct scsi_cdb_write_16 write16; 199 struct scsi_cdb_read_capacity_10 readcap10; 200 struct scsi_cdb_read_capacity_16 readcap16; 201 unsigned char bytes[16]; 202 }; 203 204 /** printf() format for dumping a scsi_cdb */ 205 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ 206 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" 207 208 /** printf() parameters for dumping a scsi_cdb */ 209 #define SCSI_CDB_DATA(cdb) \ 210 (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3], \ 211 (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7], \ 212 (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \ 213 (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15] 214 215 /** @} */ 216 217 /** A SCSI command */ 218 struct scsi_command { 219 /** CDB for this command */ 220 union scsi_cdb cdb; 221 /** Data-out buffer (may be NULL) */ 222 userptr_t data_out; 223 /** Data-out buffer length 224 * 225 * Must be zero if @c data_out is NULL 226 */ 227 size_t data_out_len; 228 /** Data-in buffer (may be NULL) */ 229 userptr_t data_in; 230 /** Data-in buffer length 231 * 232 * Must be zero if @c data_in is NULL 233 */ 234 size_t data_in_len; 235 /** SCSI status code */ 236 uint8_t status; 237 /** SCSI sense response code */ 238 uint8_t sense_response; 239 /** Command status code */ 240 int rc; 241 }; 242 243 /** A SCSI LUN 244 * 245 * This is a four-level LUN as specified by SAM-2, in big-endian 246 * order. 247 */ 248 struct scsi_lun { 249 uint16_t u16[4]; 250 } __attribute__ (( packed )); 251 252 /** A SCSI device */ 253 struct scsi_device { 254 /** Block device interface */ 255 struct block_device blockdev; 256 /** 257 * Issue SCSI command 258 * 259 * @v scsi SCSI device 260 * @v command SCSI command 261 * @ret rc Return status code 262 * 263 * Note that a successful return status code indicates only 264 * that the SCSI command was issued. The caller must check 265 * the status field in the command structure to see when the 266 * command completes and whether, for example, the device 267 * returned CHECK CONDITION or some other non-success status 268 * code. 269 */ 270 int ( * command ) ( struct scsi_device *scsi, 271 struct scsi_command *command ); 272 /** Backing device */ 273 struct refcnt *backend; 274 }; 275 276 extern int scsi_detached_command ( struct scsi_device *scsi, 277 struct scsi_command *command ); 278 extern int init_scsidev ( struct scsi_device *scsi ); 279 extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ); 280 281 #endif /* _GPXE_SCSI_H */ 282