18 #if !defined(__MASSTORAGE_H__) 19 #define __MASSTORAGE_H__ 22 #ifndef MS_WANT_PARSER 23 #define MS_WANT_PARSER 0 28 #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 29 #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 32 #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use 33 #define MASS_SUBCLASS_RBC 0x01 34 #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI) 35 #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157 36 #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB 37 #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i 38 #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set 39 #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI 40 #define MASS_SUBCLASS_IEEE1667 0x08 43 #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt) 44 #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt) 45 #define MASS_PROTO_OBSOLETE 0x02 46 #define MASS_PROTO_BBB 0x50 // Bulk Only Transport 47 #define MASS_PROTO_UAS 0x62 50 #define MASS_REQ_ADSC 0x00 51 #define MASS_REQ_GET 0xFC 52 #define MASS_REQ_PUT 0xFD 53 #define MASS_REQ_GET_MAX_LUN 0xFE 54 #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset 56 #define MASS_CBW_SIGNATURE 0x43425355 57 #define MASS_CSW_SIGNATURE 0x53425355 59 #define MASS_CMD_DIR_OUT 0 // (0 << 7) 60 #define MASS_CMD_DIR_IN 0x80 //(1 << 7) 70 #define SCSI_CMD_TEST_UNIT_READY 0x00 71 #define SCSI_CMD_REQUEST_SENSE 0x03 72 #define SCSI_CMD_FORMAT_UNIT 0x04 73 #define SCSI_CMD_READ_6 0x08 74 #define SCSI_CMD_WRITE_6 0x0A 75 #define SCSI_CMD_INQUIRY 0x12 76 #define SCSI_CMD_MODE_SELECT_6 0x15 77 #define SCSI_CMD_MODE_SENSE_6 0x1A 78 #define SCSI_CMD_START_STOP_UNIT 0x1B 79 #define SCSI_CMD_PREVENT_REMOVAL 0x1E 81 #define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23 82 #define SCSI_CMD_READ_CAPACITY_10 0x25 83 #define SCSI_CMD_READ_10 0x28 84 #define SCSI_CMD_WRITE_10 0x2A 85 #define SCSI_CMD_SEEK_10 0x2B 86 #define SCSI_CMD_ERASE_10 0x2C 87 #define SCSI_CMD_WRITE_AND_VERIFY_10 0x2E 88 #define SCSI_CMD_VERIFY_10 0x2F 89 #define SCSI_CMD_SYNCHRONIZE_CACHE 0x35 90 #define SCSI_CMD_WRITE_BUFFER 0x3B 91 #define SCSI_CMD_READ_BUFFER 0x3C 92 #define SCSI_CMD_READ_SUBCHANNEL 0x42 93 #define SCSI_CMD_READ_TOC 0x43 94 #define SCSI_CMD_READ_HEADER 0x44 95 #define SCSI_CMD_PLAY_AUDIO_10 0x45 96 #define SCSI_CMD_GET_CONFIGURATION 0x46 97 #define SCSI_CMD_PLAY_AUDIO_MSF 0x47 98 #define SCSI_CMD_PLAY_AUDIO_TI 0x48 99 #define SCSI_CMD_PLAY_TRACK_REL_10 0x49 100 #define SCSI_CMD_GET_EVENT_STATUS 0x4A 101 #define SCSI_CMD_PAUSE_RESUME 0x4B 102 #define SCSI_CMD_READ_DISC_INFORMATION 0x51 103 #define SCSI_CMD_READ_TRACK_INFORMATION 0x52 104 #define SCSI_CMD_RESERVE_TRACK 0x53 105 #define SCSI_CMD_SEND_OPC_INFORMATION 0x54 106 #define SCSI_CMD_MODE_SELECT_10 0x55 107 #define SCSI_CMD_REPAIR_TRACK 0x58 108 #define SCSI_CMD_MODE_SENSE_10 0x5A 109 #define SCSI_CMD_CLOSE_TRACK_SESSION 0x5B 110 #define SCSI_CMD_READ_BUFFER_CAPACITY 0x5C 111 #define SCSI_CMD_SEND_CUE_SHEET 0x5D 113 #define SCSI_CMD_REPORT_LUNS 0xA0 114 #define SCSI_CMD_BLANK 0xA1 115 #define SCSI_CMD_SECURITY_PROTOCOL_IN 0xA2 116 #define SCSI_CMD_SEND_KEY 0xA3 117 #define SCSI_CMD_REPORT_KEY 0xA4 118 #define SCSI_CMD_PLAY_AUDIO_12 0xA5 119 #define SCSI_CMD_LOAD_UNLOAD 0xA6 120 #define SCSI_CMD_SET_READ_AHEAD 0xA7 121 #define SCSI_CMD_READ_12 0xA8 122 #define SCSI_CMD_PLAY_TRACK_REL_12 0xA9 123 #define SCSI_CMD_WRITE_12 0xAA 124 #define SCSI_CMD_READ_MEDIA_SERIAL_12 0xAB 125 #define SCSI_CMD_GET_PERFORMANCE 0xAC 126 #define SCSI_CMD_READ_DVD_STRUCTURE 0xAD 127 #define SCSI_CMD_SECURITY_PROTOCOL_OUT 0xB5 128 #define SCSI_CMD_SET_STREAMING 0xB6 129 #define SCSI_CMD_READ_MSF 0xB9 130 #define SCSI_CMD_SET_SPEED 0xBB 131 #define SCSI_CMD_MECHANISM_STATUS 0xBD 132 #define SCSI_CMD_READ_CD 0xBE 133 #define SCSI_CMD_SEND_DISC_STRUCTURE 0xBF 135 #define SCSI_CMD_CD_PLAYBACK_STATUS 0xC4 136 #define SCSI_CMD_PLAYBACK_CONTROL 0xC9 137 #define SCSI_CMD_READ_CDDA 0xD8 138 #define SCSI_CMD_READ_CDXA 0xDB 139 #define SCSI_CMD_READ_ALL_SUBCODES 0xDF 142 #define SCSI_S_NOT_READY 0x02 143 #define SCSI_S_MEDIUM_ERROR 0x03 144 #define SCSI_S_ILLEGAL_REQUEST 0x05 145 #define SCSI_S_UNIT_ATTENTION 0x06 146 #define SCSI_ASC_LBA_OUT_OF_RANGE 0x21 147 #define SCSI_ASC_MEDIA_CHANGED 0x28 148 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A 151 #define MASS_ERR_SUCCESS 0x00 152 #define MASS_ERR_PHASE_ERROR 0x02 153 #define MASS_ERR_UNIT_NOT_READY 0x03 154 #define MASS_ERR_UNIT_BUSY 0x04 155 #define MASS_ERR_STALL 0x05 156 #define MASS_ERR_CMD_NOT_SUPPORTED 0x06 157 #define MASS_ERR_INVALID_CSW 0x07 158 #define MASS_ERR_NO_MEDIA 0x08 159 #define MASS_ERR_BAD_LBA 0x09 160 #define MASS_ERR_MEDIA_CHANGED 0x0A 161 #define MASS_ERR_DEVICE_DISCONNECTED 0x11 162 #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error 163 #define MASS_ERR_INVALID_LUN 0x13 164 #define MASS_ERR_WRITE_STALL 0x14 165 #define MASS_ERR_READ_NAKS 0x15 166 #define MASS_ERR_WRITE_NAKS 0x16 167 #define MASS_ERR_WRITE_PROTECTED 0x17 168 #define MASS_ERR_NOT_IMPLEMENTED 0xFD 169 #define MASS_ERR_GENERAL_SCSI_ERROR 0xFE 170 #define MASS_ERR_GENERAL_USB_ERROR 0xFF 171 #define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes 173 #define MASS_TRANS_FLG_CALLBACK 0x01 // Callback is involved 174 #define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked 175 #define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked 177 #define MASS_MAX_ENDPOINTS 3 183 } __attribute__((packed));
192 } __attribute__((packed));
209 CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
210 Opcode(_Opcode), LBAMSB(
BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(
BGRAB1(LBA)), LBALB(
BGRAB0(LBA)),
211 AllocationLength(_AllocationLength), Control(_Control) {
214 CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
215 Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
216 AllocationLength(_AllocationLength), Control(_Control) {
218 } __attribute__((packed));
225 unsigned Service_Action : 5;
241 CDB10(uint8_t _Opcode, uint8_t _LUN) :
242 Opcode(_Opcode), Service_Action(0), LUN(_LUN),
243 LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
244 Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
247 CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
248 Opcode(_Opcode), Service_Action(0), LUN(_LUN),
250 Misc2(0), ALC_MB(
BGRAB1(xflen)), ALC_LB(
BGRAB0(xflen)), Control(0) {
252 } __attribute__((packed));
259 unsigned Service_Action : 5;
270 } __attribute__((packed));
277 unsigned Service_Action : 5;
297 } __attribute__((packed));
320 } __attribute__((packed));
323 uint8_t DeviceType : 5;
324 uint8_t PeripheralQualifier : 3;
326 unsigned Reserved : 7;
327 unsigned Removable : 1;
331 unsigned ResponseDataFormat : 4;
333 unsigned NormACA : 1;
340 unsigned PROTECT : 1;
342 unsigned ThreePC : 1;
353 unsigned ENCSERV : 1;
356 unsigned SoftReset : 1;
358 unsigned Reserved4 : 1;
361 unsigned WideBus16Bit : 1;
362 unsigned WideBus32Bit : 1;
363 unsigned RelAddr : 1;
366 uint8_t ProductID[16];
367 uint8_t RevisionID[4];
368 } __attribute__((packed));
381 dCBWSignature(
MASS_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
383 } __attribute__((packed));
388 uint8_t bmCBWLUN : 4;
389 uint8_t bmReserved1 : 4;
393 uint8_t bmCBWCBLength : 4;
394 uint8_t bmReserved2 : 4;
404 for(
int i = 0; i < 16; i++) CBWCB[i] = 0;
409 CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
411 bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
412 for(
int i = 0; i < 16; i++) CBWCB[i] = 0;
416 BASICCDB_t *x =
reinterpret_cast<BASICCDB_t *
>(CBWCB);
424 bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
425 memcpy(&CBWCB, cdb, 6);
431 bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
432 memcpy(&CBWCB, cdb, 10);
434 } __attribute__((packed));
441 } __attribute__((packed));
447 uint8_t bmSenseKey : 4;
448 uint8_t bmReserved : 1;
451 uint8_t bmFileMark : 1;
453 uint8_t Information[4];
455 uint8_t CmdSpecificInformation[4];
459 uint8_t SenseKeySpecific[3];
460 } __attribute__((packed));
499 return bLastUsbError;
510 bool WriteProtected(uint8_t lun);
511 uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
512 uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
513 uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
USBReadParser *prs);
514 uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t *buf);
515 uint8_t LockMedia(uint8_t lun, uint8_t lock);
517 bool LUNIsGood(uint8_t lun);
518 uint32_t GetCapacity(uint8_t lun);
519 uint16_t GetSectorSize(uint8_t lun);
522 uint8_t Init(uint8_t parent, uint8_t port,
bool lowspeed);
523 uint8_t ConfigureDevice(uint8_t parent, uint8_t port,
bool lowspeed);
533 void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto,
const USB_ENDPOINT_DESCRIPTOR *ep);
539 uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size,
void *buf, uint8_t dir);
540 uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size,
void *buf, uint8_t dir);
543 uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
544 uint8_t TestUnitReady(uint8_t lun);
545 uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
546 uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
547 uint8_t GetMaxLUN(uint8_t *max_lun);
548 uint8_t SetCurLUN(uint8_t lun);
550 uint8_t ResetRecovery();
551 uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
554 bool CheckLUN(uint8_t lun);
555 uint8_t Page3F(uint8_t lun);
556 bool IsValidCBW(uint8_t size, uint8_t *pcbw);
557 bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
561 uint8_t ClearEpHalt(uint8_t index);
566 uint8_t HandleUsbError(uint8_t error, uint8_t index);
567 uint8_t HandleSCSIError(uint8_t status);
571 #endif // __MASSTORAGE_H__ CommandBlockWrapperBase()
CDB10(uint8_t _Opcode, uint8_t _LUN)
static const uint8_t epDataOutIndex
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)
#define MASS_MAX_SUPPORTED_LUN
uint32_t dCBWDataTransferLength
uint8_t GetLastUsbError()
CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs)
uint8_t bFieldReplaceableUnitCode
static const uint8_t epDataInIndex
#define MASS_MAX_ENDPOINTS
uint8_t bAdditionalSenseCode
virtual uint8_t GetAddress()
uint8_t bAdditionalSenseQualifier
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)
virtual bool DEVCLASSOK(uint8_t klass)
#define MASS_CBW_SIGNATURE
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control)