1 #if !defined(__MASSTORAGE_H__)
2 #define __MASSTORAGE_H__
12 #define MASS_MAX_SUPPORTED_LUN 8
16 #include <avr/pgmspace.h>
23 #if defined(ARDUINO) && ARDUINO >=100
34 #define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
36 #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
37 #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
40 #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
41 #define MASS_SUBCLASS_RBC 0x01
42 #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
43 #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
44 #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
45 #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
46 #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
47 #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
48 #define MASS_SUBCLASS_IEEE1667 0x08
51 #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
52 #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
53 #define MASS_PROTO_OBSOLETE 0x02
54 #define MASS_PROTO_BBB 0x50 // Bulk Only Transport
55 #define MASS_PROTO_UAS 0x62
58 #define MASS_REQ_ADSC 0x00
59 #define MASS_REQ_GET 0xFC
60 #define MASS_REQ_PUT 0xFD
61 #define MASS_REQ_GET_MAX_LUN 0xFE
62 #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
64 #define MASS_CBW_SIGNATURE 0x43425355
65 #define MASS_CSW_SIGNATURE 0x53425355
67 #define MASS_CMD_DIR_OUT (0 << 7)
68 #define MASS_CMD_DIR_IN (1 << 7)
70 #define SCSI_CMD_INQUIRY 0x12
71 #define SCSI_CMD_REPORT_LUNS 0xA0
72 #define SCSI_CMD_REQUEST_SENSE 0x03
73 #define SCSI_CMD_FORMAT_UNIT 0x04
74 #define SCSI_CMD_READ_6 0x08
75 #define SCSI_CMD_READ_10 0x28
76 #define SCSI_CMD_READ_CAPACITY_10 0x25
77 #define SCSI_CMD_TEST_UNIT_READY 0x00
78 #define SCSI_CMD_WRITE_6 0x0A
79 #define SCSI_CMD_WRITE_10 0x2A
80 #define SCSI_CMD_MODE_SENSE_6 0x1A
81 #define SCSI_CMD_MODE_SENSE_10 0x5A
82 #define SCSI_CMD_START_STOP_UNIT 0x1B
83 #define SCSI_CMD_PREVENT_REMOVAL 0x1E
84 #define SCSI_S_NOT_READY 0x02
85 #define SCSI_S_MEDIUM_ERROR 0x03
86 #define SCSI_S_ILLEGAL_REQUEST 0x05
87 #define SCSI_S_UNIT_ATTENTION 0x06
89 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
90 #define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
91 #define SCSI_ASC_MEDIA_CHANGED 0x28
93 #define MASS_ERR_SUCCESS 0x00
94 #define MASS_ERR_PHASE_ERROR 0x02
95 #define MASS_ERR_UNIT_NOT_READY 0x03
96 #define MASS_ERR_UNIT_BUSY 0x04
97 #define MASS_ERR_STALL 0x05
98 #define MASS_ERR_CMD_NOT_SUPPORTED 0x06
99 #define MASS_ERR_INVALID_CSW 0x07
100 #define MASS_ERR_NO_MEDIA 0x08
101 #define MASS_ERR_BAD_LBA 0x09
102 #define MASS_ERR_MEDIA_CHANGED 0x0A
103 #define MASS_ERR_DEVICE_DISCONNECTED 0x11
104 #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
105 #define MASS_ERR_INVALID_LUN 0x13
106 #define MASS_ERR_WRITE_STALL 0x14
107 #define MASS_ERR_READ_NAKS 0x15
108 #define MASS_ERR_WRITE_NAKS 0x16
109 #define MASS_ERR_WRITE_PROTECTED 0x17
110 #define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
111 #define MASS_ERR_GENERAL_USB_ERROR 0xFF
112 #define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes
114 #define MASS_TRANS_FLG_CALLBACK 0x01 // Callback is involved
115 #define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
116 #define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
118 #define MASS_MAX_ENDPOINTS 3
124 } __attribute__((packed));
156 } __attribute__((packed));
163 } __attribute__((packed));
178 } __attribute__((packed));
185 } __attribute__((packed));
204 } __attribute__((packed));
255 uint8_t
MediaCTL(uint8_t lun, uint8_t ctl);
256 uint8_t
Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
257 uint8_t
Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
USBReadParser *prs);
258 uint8_t
Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t *buf);
259 uint8_t
LockMedia(uint8_t lun, uint8_t lock);
266 virtual uint8_t
Init(uint8_t parent, uint8_t port,
bool lowspeed);
267 virtual uint8_t
ConfigureDevice(uint8_t parent, uint8_t port,
bool lowspeed);
270 virtual uint8_t
Poll();
282 uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
283 uint8_t TestUnitReady(uint8_t lun);
284 uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
285 uint8_t ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
286 uint8_t GetMaxLUN(uint8_t *max_lun);
287 uint8_t SetCurLUN(uint8_t lun);
289 uint8_t ResetRecovery();
290 uint8_t ReadCapacity(uint8_t lun, uint16_t size, uint8_t *buf);
293 boolean CheckLUN(uint8_t lun);
294 uint8_t Page3F(uint8_t lun);
295 bool IsValidCBW(uint8_t size, uint8_t *pcbw);
296 bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
300 uint8_t ClearEpHalt(uint8_t index);
302 uint8_t HandleUsbError(uint8_t error, uint8_t index);
303 uint8_t HandleSCSIError(uint8_t status);
307 #endif // __MASSTORAGE_H__