00001
00038 #ifndef SCSI_CDB_H_INCLUDED
00039 #define SCSI_CDB_H_INCLUDED
00040
00041 #include <assert.h>
00042 #include <types.h>
00043 #include <unaligned.h>
00044
00045 #include <scsi/spc_protocol.h>
00046
00047 static inline uint16_t scsi_cdb_get_u16(const uint8_t *cdb, unsigned int offset)
00048 {
00049 return read_unaligned_be16(cdb + offset);
00050 }
00051
00052 static inline uint32_t scsi_cdb_get_u32(const uint8_t *cdb, unsigned int offset)
00053 {
00054 return read_unaligned_be32(cdb + offset);
00055 }
00056
00057 static inline uint8_t scsi_cdb_get_opcode(const uint8_t *cdb)
00058 {
00059 return cdb[0];
00060 }
00061
00062 static inline uint8_t scsi_cdb_get_group_code(const uint8_t *cdb)
00063 {
00064 return scsi_cdb_get_opcode(cdb) >> 5;
00065 }
00066
00067 static inline uint32_t scsi_cdb6_get_lba(const uint8_t *cdb)
00068 {
00069 uint32_t lba;
00070
00071 assert(scsi_cdb_get_group_code(cdb) == 0);
00072
00073 lba = (uint32_t)(cdb[1] & 0x1f) << 16;
00074 lba |= (uint32_t)cdb[2] << 8;
00075 lba |= (uint32_t)cdb[3];
00076
00077 return lba;
00078 }
00079
00080 static inline uint32_t scsi_cdb10_get_lba(const uint8_t *cdb)
00081 {
00082 assert(scsi_cdb_get_group_code(cdb) == 1
00083 || scsi_cdb_get_group_code(cdb) == 2);
00084
00085 return scsi_cdb_get_u32(cdb, 2);
00086 }
00087
00088 static inline uint32_t scsi_cdb6_get_xfer_len(const uint8_t *cdb)
00089 {
00090 uint32_t len;
00091
00092
00093
00094
00095 assert(scsi_cdb_get_group_code(cdb) == 0);
00096 len = cdb[4];
00097 if (!len)
00098 len = 256;
00099
00100 return len;
00101 }
00102
00103
00104 static inline uint32_t scsi_cdb10_get_xfer_len(const uint8_t *cdb)
00105 {
00106 assert(scsi_cdb_get_group_code(cdb) == 1
00107 || scsi_cdb_get_group_code(cdb) == 2);
00108
00109 return scsi_cdb_get_u16(cdb, 7);
00110 }
00111
00112 static inline uint32_t scsi_cdb6_get_alloc_len(const uint8_t *cdb)
00113 {
00114 return cdb[4];
00115 }
00116
00117 static inline uint32_t scsi_cdb10_get_alloc_len(const uint8_t *cdb)
00118 {
00119 return scsi_cdb_get_u16(cdb, 7);
00120 }
00121
00122 static inline bool scsi_cdb10_bytchk_is_set(const uint8_t *cdb)
00123 {
00124 return cdb[1] & (1 << 1);
00125 }
00126
00127 #endif