Home | History | Annotate | Download | only in gpxe
      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