1 #if !defined(__MASSTORAGE_H__)
2 #define __MASSTORAGE_H__
6 #define MS_WANT_PARSER 0
11 #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
12 #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
15 #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
16 #define MASS_SUBCLASS_RBC 0x01
17 #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
18 #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
19 #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
20 #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
21 #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
22 #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
23 #define MASS_SUBCLASS_IEEE1667 0x08
26 #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
27 #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
28 #define MASS_PROTO_OBSOLETE 0x02
29 #define MASS_PROTO_BBB 0x50 // Bulk Only Transport
30 #define MASS_PROTO_UAS 0x62
33 #define MASS_REQ_ADSC 0x00
34 #define MASS_REQ_GET 0xFC
35 #define MASS_REQ_PUT 0xFD
36 #define MASS_REQ_GET_MAX_LUN 0xFE
37 #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
39 #define MASS_CBW_SIGNATURE 0x43425355
40 #define MASS_CSW_SIGNATURE 0x53425355
42 #define MASS_CMD_DIR_OUT 0 // (0 << 7)
43 #define MASS_CMD_DIR_IN 0x80 //(1 << 7)
53 #define SCSI_CMD_TEST_UNIT_READY 0x00
54 #define SCSI_CMD_REQUEST_SENSE 0x03
55 #define SCSI_CMD_FORMAT_UNIT 0x04
56 #define SCSI_CMD_READ_6 0x08
57 #define SCSI_CMD_WRITE_6 0x0A
58 #define SCSI_CMD_INQUIRY 0x12
59 #define SCSI_CMD_MODE_SELECT_6 0x15
60 #define SCSI_CMD_MODE_SENSE_6 0x1A
61 #define SCSI_CMD_START_STOP_UNIT 0x1B
62 #define SCSI_CMD_PREVENT_REMOVAL 0x1E
64 #define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23
65 #define SCSI_CMD_READ_CAPACITY_10 0x25
66 #define SCSI_CMD_READ_10 0x28
67 #define SCSI_CMD_WRITE_10 0x2A
68 #define SCSI_CMD_SEEK_10 0x2B
69 #define SCSI_CMD_ERASE_10 0x2C
70 #define SCSI_CMD_WRITE_AND_VERIFY_10 0x2E
71 #define SCSI_CMD_VERIFY_10 0x2F
72 #define SCSI_CMD_SYNCHRONIZE_CACHE 0x35
73 #define SCSI_CMD_WRITE_BUFFER 0x3B
74 #define SCSI_CMD_READ_BUFFER 0x3C
75 #define SCSI_CMD_READ_SUBCHANNEL 0x42
76 #define SCSI_CMD_READ_TOC 0x43
77 #define SCSI_CMD_READ_HEADER 0x44
78 #define SCSI_CMD_PLAY_AUDIO_10 0x45
79 #define SCSI_CMD_GET_CONFIGURATION 0x46
80 #define SCSI_CMD_PLAY_AUDIO_MSF 0x47
81 #define SCSI_CMD_PLAY_AUDIO_TI 0x48
82 #define SCSI_CMD_PLAY_TRACK_REL_10 0x49
83 #define SCSI_CMD_GET_EVENT_STATUS 0x4A
84 #define SCSI_CMD_PAUSE_RESUME 0x4B
85 #define SCSI_CMD_READ_DISC_INFORMATION 0x51
86 #define SCSI_CMD_READ_TRACK_INFORMATION 0x52
87 #define SCSI_CMD_RESERVE_TRACK 0x53
88 #define SCSI_CMD_SEND_OPC_INFORMATION 0x54
89 #define SCSI_CMD_MODE_SELECT_10 0x55
90 #define SCSI_CMD_REPAIR_TRACK 0x58
91 #define SCSI_CMD_MODE_SENSE_10 0x5A
92 #define SCSI_CMD_CLOSE_TRACK_SESSION 0x5B
93 #define SCSI_CMD_READ_BUFFER_CAPACITY 0x5C
94 #define SCSI_CMD_SEND_CUE_SHEET 0x5D
96 #define SCSI_CMD_REPORT_LUNS 0xA0
97 #define SCSI_CMD_BLANK 0xA1
98 #define SCSI_CMD_SECURITY_PROTOCOL_IN 0xA2
99 #define SCSI_CMD_SEND_KEY 0xA3
100 #define SCSI_CMD_REPORT_KEY 0xA4
101 #define SCSI_CMD_PLAY_AUDIO_12 0xA5
102 #define SCSI_CMD_LOAD_UNLOAD 0xA6
103 #define SCSI_CMD_SET_READ_AHEAD 0xA7
104 #define SCSI_CMD_READ_12 0xA8
105 #define SCSI_CMD_PLAY_TRACK_REL_12 0xA9
106 #define SCSI_CMD_WRITE_12 0xAA
107 #define SCSI_CMD_READ_MEDIA_SERIAL_12 0xAB
108 #define SCSI_CMD_GET_PERFORMANCE 0xAC
109 #define SCSI_CMD_READ_DVD_STRUCTURE 0xAD
110 #define SCSI_CMD_SECURITY_PROTOCOL_OUT 0xB5
111 #define SCSI_CMD_SET_STREAMING 0xB6
112 #define SCSI_CMD_READ_MSF 0xB9
113 #define SCSI_CMD_SET_SPEED 0xBB
114 #define SCSI_CMD_MECHANISM_STATUS 0xBD
115 #define SCSI_CMD_READ_CD 0xBE
116 #define SCSI_CMD_SEND_DISC_STRUCTURE 0xBF
118 #define SCSI_CMD_CD_PLAYBACK_STATUS 0xC4
119 #define SCSI_CMD_PLAYBACK_CONTROL 0xC9
120 #define SCSI_CMD_READ_CDDA 0xD8
121 #define SCSI_CMD_READ_CDXA 0xDB
122 #define SCSI_CMD_READ_ALL_SUBCODES 0xDF
125 #define SCSI_S_NOT_READY 0x02
126 #define SCSI_S_MEDIUM_ERROR 0x03
127 #define SCSI_S_ILLEGAL_REQUEST 0x05
128 #define SCSI_S_UNIT_ATTENTION 0x06
129 #define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
130 #define SCSI_ASC_MEDIA_CHANGED 0x28
131 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
134 #define MASS_ERR_SUCCESS 0x00
135 #define MASS_ERR_PHASE_ERROR 0x02
136 #define MASS_ERR_UNIT_NOT_READY 0x03
137 #define MASS_ERR_UNIT_BUSY 0x04
138 #define MASS_ERR_STALL 0x05
139 #define MASS_ERR_CMD_NOT_SUPPORTED 0x06
140 #define MASS_ERR_INVALID_CSW 0x07
141 #define MASS_ERR_NO_MEDIA 0x08
142 #define MASS_ERR_BAD_LBA 0x09
143 #define MASS_ERR_MEDIA_CHANGED 0x0A
144 #define MASS_ERR_DEVICE_DISCONNECTED 0x11
145 #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
146 #define MASS_ERR_INVALID_LUN 0x13
147 #define MASS_ERR_WRITE_STALL 0x14
148 #define MASS_ERR_READ_NAKS 0x15
149 #define MASS_ERR_WRITE_NAKS 0x16
150 #define MASS_ERR_WRITE_PROTECTED 0x17
151 #define MASS_ERR_NOT_IMPLEMENTED 0xFD
152 #define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
153 #define MASS_ERR_GENERAL_USB_ERROR 0xFF
154 #define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes
156 #define MASS_TRANS_FLG_CALLBACK 0x01 // Callback is involved
157 #define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
158 #define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
160 #define MASS_MAX_ENDPOINTS 3
166 } __attribute__((packed));
175 } __attribute__((packed));
192 CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
197 CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
201 } __attribute__((packed));
224 CDB10(uint8_t _Opcode, uint8_t _LUN) :
230 CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
235 } __attribute__((packed));
253 } __attribute__((packed));
280 } __attribute__((packed));
303 } __attribute__((packed));
351 } __attribute__((packed));
366 } __attribute__((packed));
387 for(
int i = 0; i < 16; i++)
CBWCB[i] = 0;
392 CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
395 for(
int i = 0; i < 16; i++)
CBWCB[i] = 0;
399 BASICCDB_t *x =
reinterpret_cast<BASICCDB_t *
>(
CBWCB);
408 memcpy(&
CBWCB, cdb, 6);
415 memcpy(&
CBWCB, cdb, 10);
417 } __attribute__((packed));
424 } __attribute__((packed));
443 } __attribute__((packed));
494 uint8_t
MediaCTL(uint8_t lun, uint8_t ctl);
495 uint8_t
Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
496 uint8_t
Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
USBReadParser *prs);
497 uint8_t
Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t *buf);
498 uint8_t
LockMedia(uint8_t lun, uint8_t lock);
505 virtual uint8_t
Init(uint8_t parent, uint8_t port,
bool lowspeed);
506 virtual uint8_t
ConfigureDevice(uint8_t parent, uint8_t port,
bool lowspeed);
509 virtual uint8_t
Poll();
522 uint8_t
SCSITransaction6(CDB6_t *cdb, uint16_t buf_size,
void *buf, uint8_t dir);
523 uint8_t
SCSITransaction10(CDB10_t *cdb, uint16_t buf_size,
void *buf, uint8_t dir);
526 uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
527 uint8_t TestUnitReady(uint8_t lun);
528 uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
529 uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
530 uint8_t GetMaxLUN(uint8_t *max_lun);
531 uint8_t SetCurLUN(uint8_t lun);
533 uint8_t ResetRecovery();
534 uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
537 boolean CheckLUN(uint8_t lun);
538 uint8_t Page3F(uint8_t lun);
539 bool IsValidCBW(uint8_t size, uint8_t *pcbw);
540 bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
544 uint8_t ClearEpHalt(uint8_t index);
549 uint8_t HandleUsbError(uint8_t error, uint8_t index);
550 uint8_t HandleSCSIError(uint8_t status);
554 #endif // __MASSTORAGE_H__
CommandBlockWrapperBase()
uint8_t MediaCTL(uint8_t lun, uint8_t ctl)
CDB10(uint8_t _Opcode, uint8_t _LUN)
static const uint8_t epDataOutIndex
bool LUNOk[MASS_MAX_SUPPORTED_LUN]
static const uint8_t epInterruptInIndex
uint8_t bAdditionalLength
#define USB_CLASS_MASS_STORAGE
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir)
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed)
uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]
bool WriteOk[MASS_MAX_SUPPORTED_LUN]
#define MASS_MAX_SUPPORTED_LUN
uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir)
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR *ep_ptr)
virtual uint8_t Release()
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf)
uint32_t dCBWDataTransferLength
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir)
uint8_t GetLastUsbError()
uint32_t GetCapacity(uint8_t lun)
CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs)
uint8_t bFieldReplaceableUnitCode
unsigned ResponseDataFormat
static const uint8_t epDataInIndex
uint8_t PeripheralQualifier
uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]
#define MASS_MAX_ENDPOINTS
uint8_t bAdditionalSenseCode
bool LUNIsGood(uint8_t lun)
virtual uint8_t GetAddress()
uint8_t bAdditionalSenseQualifier
uint16_t GetSectorSize(uint8_t lun)
uint8_t LockMedia(uint8_t lun, uint8_t lock)
EpInfo epInfo[MASS_MAX_ENDPOINTS]
uint8_t CmdSpecificInformation[4]
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control)
CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA)
CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd)
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir)
uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf)
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
uint8_t SenseKeySpecific[3]
boolean WriteProtected(uint8_t lun)
#define MASS_CBW_SIGNATURE
virtual boolean DEVCLASSOK(uint8_t klass)
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control)