USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
masstorage.h
Go to the documentation of this file.
1 #if !defined(__MASSTORAGE_H__)
2 #define __MASSTORAGE_H__
3 
4 #include <inttypes.h>
5 #include <avr/pgmspace.h>
6 #include "avrpins.h"
7 #include "max3421e.h"
8 #include "usbhost.h"
9 #include "usb_ch9.h"
10 #include "Usb.h"
11 
12 #if defined(ARDUINO) && ARDUINO >=100
13 #include "Arduino.h"
14 #else
15 #include <WProgram.h>
16 #endif
17 
18 #include "printhex.h"
19 #include "hexdump.h"
20 #include "message.h"
21 
22 #include "confdescparser.h"
23 
24 #define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
25 
26 #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
27 #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
28 
29 // Mass Storage Subclass Constants
30 #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
31 #define MASS_SUBCLASS_RBC 0x01
32 #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
33 #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
34 #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
35 #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
36 #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
37 #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
38 #define MASS_SUBCLASS_IEEE1667 0x08
39 
40 // Mass Storage Class Protocols
41 #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
42 #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
43 #define MASS_PROTO_OBSOLETE 0x02
44 #define MASS_PROTO_BBB 0x50 // Bulk Only Transport
45 #define MASS_PROTO_UAS 0x62
46 
47 // Request Codes
48 #define MASS_REQ_ADSC 0x00
49 #define MASS_REQ_GET 0xFC
50 #define MASS_REQ_PUT 0xFD
51 #define MASS_REQ_GET_MAX_LUN 0xFE
52 #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
53 
54 #define MASS_CBW_SIGNATURE 0x43425355
55 #define MASS_CSW_SIGNATURE 0x53425355
56 
57 #define MASS_CMD_DIR_OUT (0 << 7)
58 #define MASS_CMD_DIR_IN (1 << 7)
59 
60 #define SCSI_CMD_INQUIRY 0x12
61 #define SCSI_CMD_REPORT_LUNS 0xA0
62 #define SCSI_CMD_REQUEST_SENSE 0x03
63 #define SCSI_CMD_FORMAT_UNIT 0x04
64 #define SCSI_CMD_READ_6 0x08
65 #define SCSI_CMD_READ_10 0x28
66 #define SCSI_CMD_READ_CAPACITY_10 0x25
67 #define SCSI_CMD_TEST_UNIT_READY 0x00
68 #define SCSI_CMD_WRITE_6 0x0A
69 #define SCSI_CMD_WRITE_10 0x2A
70 #define SCSI_CMD_MODE_SENSE_6 0x1A
71 #define SCSI_CMD_MODE_SENSE_10 0x5A
72 
73 #define MASS_ERR_SUCCESS 0x00
74 #define MASS_ERR_PHASE_ERROR 0x01
75 #define MASS_ERR_DEVICE_DISCONNECTED 0x11
76 #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
77 #define MASS_ERR_GENERAL_USB_ERROR 0xFF
78 
79 #define MASS_TRANS_FLG_CALLBACK 0x01 // Callback is involved
80 #define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
81 #define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
82 
83 
84 struct Capacity
85 {
86  uint8_t data[8];
87  //uint32_t dwBlockAddress;
88  //uint32_t dwBlockLength;
89 };
90 
92 {
93  uint8_t DeviceType : 5;
94  uint8_t PeripheralQualifier : 3;
95 
96  unsigned Reserved : 7;
97  unsigned Removable : 1;
98 
99  uint8_t Version;
100 
101  unsigned ResponseDataFormat : 4;
102  unsigned Reserved2 : 1;
103  unsigned NormACA : 1;
104  unsigned TrmTsk : 1;
105  unsigned AERC : 1;
106 
108  uint8_t Reserved3[2];
109 
110  unsigned SoftReset : 1;
111  unsigned CmdQue : 1;
112  unsigned Reserved4 : 1;
113  unsigned Linked : 1;
114  unsigned Sync : 1;
115  unsigned WideBus16Bit : 1;
116  unsigned WideBus32Bit : 1;
117  unsigned RelAddr : 1;
118 
119  uint8_t VendorID[8];
120  uint8_t ProductID[16];
121  uint8_t RevisionID[4];
122 };
123 
125 {
126  uint32_t dCBWSignature;
127  uint32_t dCBWTag;
129  uint8_t bmCBWFlags;
130 
131  struct
132  {
133  uint8_t bmCBWLUN : 4;
134  uint8_t bmReserved1 : 4;
135  };
136  struct
137  {
138  uint8_t bmCBWCBLength : 4;
139  uint8_t bmReserved2 : 4;
140  };
141 
142  uint8_t CBWCB[16];
143 } ;
144 
146 {
147  uint32_t dCSWSignature;
148  uint32_t dCSWTag;
149  uint32_t dCSWDataResidue;
150  uint8_t bCSWStatus;
151 };
152 
154 {
155  uint8_t bResponseCode;
156  uint8_t bSegmentNumber;
157 
158  uint8_t bmSenseKey : 4;
159  uint8_t bmReserved : 1;
160  uint8_t bmILI : 1;
161  uint8_t bmEOM : 1;
162  uint8_t bmFileMark : 1;
163 
164  uint8_t Information[4];
170  uint8_t SenseKeySpecific[3];
171 };
172 
173 //class BulkReadParser : public USBReadParser
174 //{
175 //protected:
176 // bool IsValidCSW(uint8_t size, uint8_t *pcsw);
177 // bool IsMeaningfulCSW(uint8_t size, uint8_t *pcsw);
178 //
179 //public:
180 // virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) = 0;
181 //};
182 
183 #define MASS_MAX_ENDPOINTS 3
184 
186 {
187 protected:
188  static const uint8_t epDataInIndex; // DataIn endpoint index
189  static const uint8_t epDataOutIndex; // DataOUT endpoint index
190  static const uint8_t epInterruptInIndex; // InterruptIN endpoint index
191 
193  uint8_t bAddress;
194  uint8_t bConfNum; // configuration number
195  uint8_t bIface; // interface value
196  uint8_t bNumEP; // total number of EP in the configuration
197  uint32_t qNextPollTime; // next poll time
198  bool bPollEnable; // poll enable flag
199 
201 
202  uint32_t dCBWTag; // Tag
203  uint32_t dCBWDataTransferLength; // Data Transfer Length
204  uint8_t bMaxLUN; // Max LUN
205  uint8_t bLastUsbError; // Last USB error
206 
207 protected:
208  //union TransFlags
209  //{
210  // uint8_t nValue;
211 
212  // struct {
213  // uint8_t bmCallback : 1;
214  // uint8_t bmCheckPhaseErr : 1;
215  // uint8_t bmDummy : 6;
216  // };
217  //};
219 
220  bool IsValidCBW(uint8_t size, uint8_t *pcbw);
221  bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
222 
223  uint8_t ClearEpHalt(uint8_t index);
224  uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
225  uint8_t HandleUsbError(uint8_t index);
226 
227 public:
228  BulkOnly(USB *p);
229  uint8_t GetLastUsbError() { return bLastUsbError; };
230 
231  uint8_t Reset();
232  uint8_t GetMaxLUN(uint8_t *max_lun);
233 
234  uint8_t ResetRecovery();
235  uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
236  uint8_t TestUnitReady(uint8_t lun);
237  uint8_t ReadCapacity(uint8_t lun, uint16_t size, uint8_t *buf);
238  uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
239  //uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t *buf);
240  uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, USBReadParser *prs);
241 
242  // USBDeviceConfig implementation
243  virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
244  virtual uint8_t Release();
245  virtual uint8_t Poll();
246  virtual uint8_t GetAddress() { return bAddress; };
247 
248  // UsbConfigXtracter implementation
249  virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
250 };
251 
252 #endif // __MASSTORAGE_H__