scsi.h

Go to the documentation of this file.
00001 #ifndef _GPXE_SCSI_H
00002 #define _GPXE_SCSI_H
00003 
00004 #include <stdint.h>
00005 #include <gpxe/blockdev.h>
00006 #include <gpxe/uaccess.h>
00007 #include <gpxe/refcnt.h>
00008 
00009 /** @file
00010  *
00011  * SCSI devices
00012  *
00013  */
00014 
00015 FILE_LICENCE ( GPL2_OR_LATER );
00016 
00017 /**
00018  * @defgroup scsiops SCSI operation codes
00019  * @{
00020  */
00021 
00022 #define SCSI_OPCODE_READ_10             0x28    /**< READ (10) */
00023 #define SCSI_OPCODE_READ_16             0x88    /**< READ (16) */
00024 #define SCSI_OPCODE_WRITE_10            0x2a    /**< WRITE (10) */
00025 #define SCSI_OPCODE_WRITE_16            0x8a    /**< WRITE (16) */
00026 #define SCSI_OPCODE_READ_CAPACITY_10    0x25    /**< READ CAPACITY (10) */
00027 #define SCSI_OPCODE_SERVICE_ACTION_IN   0x9e    /**< SERVICE ACTION IN */
00028 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
00029 
00030 /** @} */
00031 
00032 /**
00033  * @defgroup scsiflags SCSI flags
00034  * @{
00035  */
00036 
00037 #define SCSI_FL_FUA_NV          0x02    /**< Force unit access to NVS */
00038 #define SCSI_FL_FUA             0x08    /**< Force unit access */
00039 #define SCSI_FL_DPO             0x10    /**< Disable cache page out */
00040 
00041 /** @} */
00042 
00043 /**
00044  * @defgroup scsicdbs SCSI command data blocks
00045  * @{
00046  */
00047 
00048 /** A SCSI "READ (10)" CDB */
00049 struct scsi_cdb_read_10 {
00050         /** Opcode (0x28) */
00051         uint8_t opcode;
00052         /** Flags */
00053         uint8_t flags;
00054         /** Start address
00055          *
00056          * This is a logical block number, in big-endian order.
00057          */
00058         uint32_t lba;
00059         /** Group number */
00060         uint8_t group;
00061         /** Transfer length
00062          *
00063          * This is a logical block count, in big-endian order.
00064          */
00065         uint16_t len;
00066         /** Control byte */
00067         uint8_t control;
00068 } __attribute__ (( packed ));
00069 
00070 /** A SCSI "READ (16)" CDB */
00071 struct scsi_cdb_read_16 {
00072         /** Opcode (0x88) */
00073         uint8_t opcode;
00074         /** Flags */
00075         uint8_t flags;
00076         /** Start address
00077          *
00078          * This is a logical block number, in big-endian order.
00079          */
00080         uint64_t lba;
00081         /** Transfer length
00082          *
00083          * This is a logical block count, in big-endian order.
00084          */
00085         uint32_t len;
00086         /** Group number */
00087         uint8_t group;
00088         /** Control byte */
00089         uint8_t control;
00090 } __attribute__ (( packed ));
00091 
00092 /** A SCSI "WRITE (10)" CDB */
00093 struct scsi_cdb_write_10 {
00094         /** Opcode (0x2a) */
00095         uint8_t opcode;
00096         /** Flags */
00097         uint8_t flags;
00098         /** Start address
00099          *
00100          * This is a logical block number, in big-endian order.
00101          */
00102         uint32_t lba;
00103         /** Group number */
00104         uint8_t group;
00105         /** Transfer length
00106          *
00107          * This is a logical block count, in big-endian order.
00108          */
00109         uint16_t len;
00110         /** Control byte */
00111         uint8_t control;
00112 } __attribute__ (( packed ));
00113 
00114 /** A SCSI "WRITE (16)" CDB */
00115 struct scsi_cdb_write_16 {
00116         /** Opcode (0x8a) */
00117         uint8_t opcode;
00118         /** Flags */
00119         uint8_t flags;
00120         /** Start address
00121          *
00122          * This is a logical block number, in big-endian order.
00123          */
00124         uint64_t lba;
00125         /** Transfer length
00126          *
00127          * This is a logical block count, in big-endian order.
00128          */
00129         uint32_t len;
00130         /** Group number */
00131         uint8_t group;
00132         /** Control byte */
00133         uint8_t control;
00134 } __attribute__ (( packed ));
00135 
00136 /** A SCSI "READ CAPACITY (10)" CDB */
00137 struct scsi_cdb_read_capacity_10 {
00138         /** Opcode (0x25) */
00139         uint8_t opcode;
00140         /** Reserved */
00141         uint8_t reserved_a;
00142         /** Logical block address
00143          *
00144          * Applicable only if the PMI bit is set.
00145          */
00146         uint32_t lba;
00147         /** Reserved */
00148         uint8_t reserved_b[3];
00149         /** Control byte */
00150         uint8_t control;        
00151 } __attribute__ (( packed ));
00152 
00153 /** SCSI "READ CAPACITY (10)" parameter data */
00154 struct scsi_capacity_10 {
00155         /** Maximum logical block number */
00156         uint32_t lba;
00157         /** Block length in bytes */
00158         uint32_t blksize;
00159 } __attribute__ (( packed ));
00160 
00161 /** A SCSI "READ CAPACITY (16)" CDB */
00162 struct scsi_cdb_read_capacity_16 {
00163         /** Opcode (0x9e) */
00164         uint8_t opcode;
00165         /** Service action */
00166         uint8_t service_action;
00167         /** Logical block address
00168          *
00169          * Applicable only if the PMI bit is set.
00170          */
00171         uint64_t lba;
00172         /** Transfer length
00173          *
00174          * This is the size of the data-in buffer, in bytes.
00175          */
00176         uint32_t len;
00177         /** Reserved */
00178         uint8_t reserved;
00179         /** Control byte */
00180         uint8_t control;
00181 } __attribute__ (( packed ));
00182 
00183 /** SCSI "READ CAPACITY (16)" parameter data */
00184 struct scsi_capacity_16 {
00185         /** Maximum logical block number */
00186         uint64_t lba;
00187         /** Block length in bytes */
00188         uint32_t blksize;
00189         /** Reserved */
00190         uint8_t reserved[20];
00191 } __attribute__ (( packed ));
00192 
00193 /** A SCSI Command Data Block */
00194 union scsi_cdb {
00195         struct scsi_cdb_read_10 read10;
00196         struct scsi_cdb_read_16 read16;
00197         struct scsi_cdb_write_10 write10;
00198         struct scsi_cdb_write_16 write16;
00199         struct scsi_cdb_read_capacity_10 readcap10;
00200         struct scsi_cdb_read_capacity_16 readcap16;
00201         unsigned char bytes[16];
00202 };
00203 
00204 /** printf() format for dumping a scsi_cdb */
00205 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \
00206                         "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
00207 
00208 /** printf() parameters for dumping a scsi_cdb */
00209 #define SCSI_CDB_DATA(cdb)                                                \
00210         (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3],   \
00211         (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7],   \
00212         (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \
00213         (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15]
00214 
00215 /** @} */
00216 
00217 /** A SCSI command */
00218 struct scsi_command {
00219         /** CDB for this command */
00220         union scsi_cdb cdb;
00221         /** Data-out buffer (may be NULL) */
00222         userptr_t data_out;
00223         /** Data-out buffer length
00224          *
00225          * Must be zero if @c data_out is NULL
00226          */
00227         size_t data_out_len;
00228         /** Data-in buffer (may be NULL) */
00229         userptr_t data_in;
00230         /** Data-in buffer length
00231          *
00232          * Must be zero if @c data_in is NULL
00233          */
00234         size_t data_in_len;
00235         /** SCSI status code */
00236         uint8_t status;
00237         /** SCSI sense response code */
00238         uint8_t sense_response;
00239         /** Command status code */
00240         int rc;
00241 };
00242 
00243 /** A SCSI LUN
00244  *
00245  * This is a four-level LUN as specified by SAM-2, in big-endian
00246  * order.
00247  */
00248 struct scsi_lun {
00249         uint16_t u16[4];
00250 }  __attribute__ (( packed ));
00251 
00252 /** A SCSI device */
00253 struct scsi_device {
00254         /** Block device interface */
00255         struct block_device blockdev;
00256         /**
00257          * Issue SCSI command
00258          *
00259          * @v scsi              SCSI device
00260          * @v command           SCSI command
00261          * @ret rc              Return status code
00262          *
00263          * Note that a successful return status code indicates only
00264          * that the SCSI command was issued.  The caller must check
00265          * the status field in the command structure to see when the
00266          * command completes and whether, for example, the device
00267          * returned CHECK CONDITION or some other non-success status
00268          * code.
00269          */
00270         int ( * command ) ( struct scsi_device *scsi,
00271                             struct scsi_command *command );
00272         /** Backing device */
00273         struct refcnt *backend;
00274 };
00275 
00276 extern int scsi_detached_command ( struct scsi_device *scsi,
00277                                    struct scsi_command *command );
00278 extern int init_scsidev ( struct scsi_device *scsi );
00279 extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
00280 
00281 #endif /* _GPXE_SCSI_H */

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1