1 /* 2 * SCSI commands related definitions 3 */ 4 5 #ifndef _SCSI_H_ 6 #define _SCSI_H_ 7 8 #if 0 9 #include <sys/endian.h> /* be16dec... */ 10 #else 11 #define be16enc(base, val) { \ 12 (base)[0] = (((val) >> 8) & 0xff); \ 13 (base)[1] = ((val) & 0xff); \ 14 } 15 #define be16dec(base) \ 16 (((base)[0] << 8) | (base)[1]) 17 #define be32enc(base, val) { \ 18 (base)[0] = (((val) >> 24) & 0xff); \ 19 (base)[1] = (((val) >> 16) & 0xff); \ 20 (base)[2] = (((val) >> 8) & 0xff); \ 21 (base)[3] = ((val) & 0xff); \ 22 } 23 #define be32dec(base) \ 24 (((base)[0] << 24) | ((base)[1] << 16) | \ 25 ((base)[2] << 8) | (base)[3]) 26 #endif 27 28 #include "bulk.h" 29 30 #define SCSI_FORMAT_UNIT (0x04) 31 #define SCSI_INQUIRY (0x12) 32 #define SCSI_START_STOP (0x1B) 33 #define SCSI_MODE_SELECT (0x55) 34 #define SCSI_MODE_SENSE (0x5A) 35 #define SCSI_PREVENT_ALLOW (0x1E) 36 #define SCSI_READ (0x28) 37 #define SCSI_READ_12 (0xA8) 38 #define SCSI_READ_CAPACITY (0x25) 39 #define SCSI_READ_FORMAT_CAP (0x23) 40 #define SCSI_REQUEST_SENSE (0x03) 41 #define SCSI_REZERO_UNIT (0x01) 42 #define SCSI_SEEK (0x2B) 43 #define SCSI_SEND_DIAGNOSTIC (0x1D) 44 #define SCSI_TEST_UNIT_READY (0x00) 45 #define SCSI_VERIFY (0x2F) 46 #define SCSI_WRITE (0x2A) 47 #define SCSI_WRITE_12 (0xAA) 48 #define SCSI_WRITE_VERIFY (0x2E) 49 50 #define SCSI_INQUIRY_DATA_LEN (36) 51 #define SCSI_INQUIRY_CMD_LEN (6) 52 53 #define SCSI_MODE_SENSE_FLEX_DATA_LEN (32) 54 #define SCSI_MODE_SENSE_CMD_LEN (12) 55 56 #define SCSI_READ_DATA_LEN (0) 57 #define SCSI_READ_CMD_LEN (10) 58 59 #define SCSI_READ_CAPACITY_DATA_LEN (8) 60 #define SCSI_READ_CAPACITY_CMD_LEN (10) 61 62 #define SCSI_TEST_DATA_LEN (0) 63 #define SCSI_TEST_CMD_LEN (6) 64 65 #define SCSI_WRITE_DATA_LEN (0) 66 #define SCSI_WRITE_CMD_LEN (10) 67 68 /* These macros are immune to unaligned access 69 * so they can be used on any address */ 70 /* 1 Byte SCSI operation */ 71 #define SCSI_WR1(base, offset, value)\ 72 (((uint8_t*)(base))[offset] = value) 73 #define SCSI_RD1(base, offset)\ 74 (((uint8_t*)(base))[offset]) 75 #define SCSI_SET1(base, offset, value)\ 76 (((uint8_t*)(base))[offset] |= value) 77 /* 2 Byte SCSI operation */ 78 #define SCSI_WR2(base, offset, value)\ 79 be16enc( &(((uint8_t*)(base))[offset]), value ) 80 #define SCSI_RD2(base, offset)\ 81 be16dec( &(((uint8_t*)(base))[offset]) ) 82 /* 4 Byte SCSI operation */ 83 #define SCSI_WR4(base, offset, value)\ 84 be32enc( &(((uint8_t*)(base))[offset]), value ) 85 #define SCSI_RD4(base, offset)\ 86 be32dec( &(((uint8_t*)(base))[offset]) ) 87 88 #define SCSI_SET_INQUIRY_OP_CODE(x) SCSI_WR1((x), 0, SCSI_INQUIRY) 89 #define SCSI_SET_INQUIRY_EVPD(x) SCSI_SET1((x), 1, 0x01) 90 #define SCSI_SET_INQUIRY_CMDDT(x) SCSI_SET1((x), 1, 0x02) 91 #define SCSI_SET_INQUIRY_PAGE_CODE(x, code) SCSI_WR1((x), 2, code) 92 #define SCSI_SET_INQUIRY_ALLOC_LEN(x, len) SCSI_WR1((x), 4, len) 93 94 #define SCSI_GET_INQUIRY_PERIPH_QUALIF(x) ((SCSI_RD1(x, 0) >> 5) & 0x7) 95 #define SCSI_GET_INQUIRY_VENDOR_NAME(x) ((const char *)(&((x)[8]))) 96 #define SCSI_INQUIRY_VENDOR_NAME_LEN (8) 97 #define SCSI_GET_INQUIRY_PRODUCT_NAME(x) ((const char *)(&((x)[16]))) 98 #define SCSI_INQUIRY_PRODUCT_NAME_LEN (16) 99 100 #define SCSI_MODE_SENSE_FLEXIBLE_DISK_PAGE (0x5) 101 #define SCSI_SET_MODE_SENSE_OP_CODE(x) SCSI_WR1((x), 0, \ 102 SCSI_MODE_SENSE) 103 #define SCSI_SET_MODE_SENSE_PAGE_CODE(x, code) SCSI_SET1((x), 2, \ 104 (code)&0x3F) 105 #define SCSI_GET_MODE_SENSE_CYLINDERS(x) SCSI_RD2((x), 8) 106 #define SCSI_GET_MODE_SENSE_HEADS(x) SCSI_RD1((x), 4) 107 #define SCSI_GET_MODE_SENSE_SECTORS(x) SCSI_RD1((x), 5) 108 109 #define SCSI_SET_READ_OP_CODE(x) SCSI_WR1((x), 0, SCSI_READ) 110 #define SCSI_SET_READ_LBA(x, lba) SCSI_WR4((x), 2, (lba)) 111 #define SCSI_SET_READ_BLEN(x, len) SCSI_WR2((x), 7, (len)) 112 113 #define SCSI_SET_READ_CAPACITY_OP_CODE(x) SCSI_WR1((x), 0, \ 114 SCSI_READ_CAPACITY) 115 #define SCSI_SET_READ_CAPACITY_LBA(x, lba) SCSI_WR4((x), 2, (lba)) 116 #define SCSI_SET_READ_CAPACITY_PMI(x) SCSI_SET1((x), 8, 0x01) 117 #define SCSI_GET_READ_CAPACITY_LBA(x) SCSI_RD4((x), 0) 118 #define SCSI_GET_READ_CAPACITY_BLEN(x) SCSI_RD4((x), 4) 119 120 #define SCSI_SET_TEST_OP_CODE(x) SCSI_WR1((x), 0, \ 121 SCSI_TEST_UNIT_READY) 122 123 #define SCSI_SET_WRITE_OP_CODE(x) SCSI_WR1((x), 0, SCSI_WRITE) 124 #define SCSI_SET_WRITE_LBA(x, lba) SCSI_WR4((x), 2, (lba)) 125 #define SCSI_SET_WRITE_BLEN(x, len) SCSI_WR2((x), 7, (len)) 126 127 typedef struct scsi_transfer { 128 129 unsigned int lba; /* logical block address */ 130 unsigned int length; /* transfer length */ 131 } 132 scsi_transfer; 133 134 /*---------------------------* 135 * declared functions * 136 *---------------------------*/ 137 int create_scsi_cmd(mass_storage_cbw *, int, struct scsi_transfer *); 138 int check_inquiry_reply(uint8_t *); 139 int check_read_capacity_reply(uint8_t *, uint32_t *, uint32_t *); 140 int check_mode_sense_reply(uint8_t *, unsigned *, unsigned *, unsigned *); 141 int check_csw(mass_storage_csw *, unsigned int); 142 143 #endif /* !_SCSI_H_ */ 144