- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# include/scsi/cdb.h

Go to the documentation of this file.

    00001
    00041 #ifndef SCSI_CDB_H_INCLUDED
    00042 #define SCSI_CDB_H_INCLUDED
    00043
    00044 #include <assert.h>
    00045 #include <types.h>
    00046
    00047 #include <scsi/spc_protocol.h>
    00048
    00049 static inline uint16_t scsi_cdb_get_u16(const uint8_t *cdb, unsigned int offset)
    00050 {
    00051         /* cdb[offset] may be unaligned, so do it the hard way */
    00052         return (cdb[offset] << 8) | cdb[offset + 1];
    00053 }
    00054
    00055 static inline uint32_t scsi_cdb_get_u32(const uint8_t *cdb, unsigned int offset)
    00056 {
    00057         /* cdb[offset] may be unaligned, so do it the hard way */
    00058         return ((cdb[offset] << 24)
    00059                         | (cdb[offset + 1] << 16)
    00060                         | (cdb[offset + 2] << 8)
    00061                         | cdb[offset + 3]);
    00062 }
    00063
    00064 static inline uint8_t scsi_cdb_get_opcode(const uint8_t *cdb)
    00065 {
    00066         return cdb[0];
    00067 }
    00068
    00069 static inline uint8_t scsi_cdb_get_group_code(const uint8_t *cdb)
    00070 {
    00071         return scsi_cdb_get_opcode(cdb) >> 5;
    00072 }
    00073
    00074 extern void scsi_cdb_bad_opcode(void);
    00075
    00076 static inline uint32_t scsi_cdb_get_lba(const uint8_t *cdb,
    00077                 unsigned int cdb_len)
    00078 {
    00079         uint32_t        lba;
    00080
    00081         switch (cdb_len) {
    00082         case 6:
    00083                 assert(scsi_cdb_get_group_code(cdb) == 0);
    00084                 lba = (cdb[1] & 0x1f) << 16;
    00085                 lba |= cdb[2] << 8;
    00086                 lba |= cdb[3];
    00087                 break;
    00088
    00089         case 10:
    00090                 assert(scsi_cdb_get_group_code(cdb) == 1
    00091                                 || scsi_cdb_get_group_code(cdb) == 2);
    00092                 lba = cdb[2] << 24;
    00093                 lba |= cdb[3] << 16;
    00094                 lba |= cdb[4] << 8;
    00095                 lba |= cdb[5];
    00096                 break;
    00097         }
    00098
    00099         return lba;
    00100 }
    00101
    00102 static inline uint32_t scsi_cdb_get_xfer_len(const uint8_t *cdb,
    00103                 unsigned int cdb_len)
    00104 {
    00105         uint32_t        len;
    00106
    00107         /* REVISIT: This may not be correct for all CDBs, but it does
    00108          * the trick for READx and WRITEx */
    00109
    00110         switch (cdb_len) {
    00111         case 6:
    00112                 assert(scsi_cdb_get_group_code(cdb) == 0);
    00113                 len = cdb[4];
    00114                 if (!len)
    00115                         len = 256;
    00116                 break;
    00117
    00118         case 10:
    00119                 assert(scsi_cdb_get_group_code(cdb) == 1
    00120                                 || scsi_cdb_get_group_code(cdb) == 2);
    00121                 len = cdb[7] << 8;
    00122                 len |= cdb[8];
    00123                 break;
    00124         }
    00125
    00126         return len;
    00127 }
    00128
    00129 static inline uint32_t scsi_cdb_get_alloc_len(const uint8_t *cdb,
    00130                 uint8_t opcode)
    00131 {
    00132         uint32_t        len;
    00133
    00134         switch (opcode) {
    00135         case SCSI_CMD_REQUEST_SENSE:
    00136         case SCSI_CMD_MODE_SENSE6:
    00137                 len = cdb[4];
    00138                 break;
    00139         case SCSI_CMD_MODE_SENSE10:
    00140                 len = scsi_cdb_get_u16(cdb, 7);
    00141                 break;
    00142         }
    00143
    00144         return len;
    00145 }
    00146
    00147 static inline bool scsi_cdb_bytchk_is_set(const uint8_t *cdb,
    00148                 unsigned int cdb_len)
    00149 {
    00150         switch (cdb_len) {
    00151         case 10:
    00152                 return cdb[1] & (1 << 1);
    00153         default:
    00154                 unhandled_case(cdb_len);
    00155                 return false;
    00156         }
    00157 }
    00158
    00159 #endif /* SCSI_CDB_H_INCLUDED */