]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/protocol/usb_hid/USB_Host_Shield_2.0/masstorage.h
lufa: usb-usb: Use LUFA startup instead of cusotom
[max/tmk_keyboard.git] / tmk_core / protocol / usb_hid / USB_Host_Shield_2.0 / masstorage.h
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9
10 Contact information
11 -------------------
12
13 Circuits At Home, LTD
14 Web      :  http://www.circuitsathome.com
15 e-mail   :  support@circuitsathome.com
16  */
17
18 #if !defined(__MASSTORAGE_H__)
19 #define __MASSTORAGE_H__
20
21 // Cruft removal, makes driver smaller, faster.
22 #ifndef MS_WANT_PARSER
23 #define MS_WANT_PARSER 0
24 #endif
25
26 #include "Usb.h"
27
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
30
31 // Mass Storage Subclass Constants
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
41
42 // Mass Storage Class Protocols
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
48
49 // Request Codes
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
55
56 #define MASS_CBW_SIGNATURE              0x43425355
57 #define MASS_CSW_SIGNATURE              0x53425355
58
59 #define MASS_CMD_DIR_OUT                0 // (0 << 7)
60 #define MASS_CMD_DIR_IN                 0x80 //(1 << 7)
61
62 /*
63  * Reference documents from T10 (http://www.t10.org)
64  * SCSI Primary Commands - 3 (SPC-3)
65  * SCSI Block Commands - 2 (SBC-2)
66  * Multi-Media Commands - 5 (MMC-5)
67  */
68
69 /* Group 1 commands (CDB's here are should all be 6-bytes) */
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
80 /* Group 2 Commands (CDB's here are 10-bytes) */
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
112 /* Group 5 Commands (CDB's here are 12-bytes) */
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
134 /* Vendor-unique Commands, included for completeness */
135 #define SCSI_CMD_CD_PLAYBACK_STATUS     0xC4 /* SONY unique */
136 #define SCSI_CMD_PLAYBACK_CONTROL       0xC9 /* SONY unique */
137 #define SCSI_CMD_READ_CDDA              0xD8 /* Vendor unique */
138 #define SCSI_CMD_READ_CDXA              0xDB /* Vendor unique */
139 #define SCSI_CMD_READ_ALL_SUBCODES      0xDF /* Vendor unique */
140
141 /* SCSI error codes */
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
149
150 /* USB error codes */
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
172
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
176
177 #define MASS_MAX_ENDPOINTS              3
178
179 struct Capacity {
180         uint8_t data[8];
181         //uint32_t dwBlockAddress;
182         //uint32_t dwBlockLength;
183 } __attribute__((packed));
184
185 struct BASICCDB {
186         uint8_t Opcode;
187
188         unsigned unused : 5;
189         unsigned LUN : 3;
190
191         uint8_t info[12];
192 } __attribute__((packed));
193
194 typedef BASICCDB BASICCDB_t;
195
196 struct CDB6 {
197         uint8_t Opcode;
198
199         unsigned LBAMSB : 5;
200         unsigned LUN : 3;
201
202         uint8_t LBAHB;
203         uint8_t LBALB;
204         uint8_t AllocationLength;
205         uint8_t Control;
206
207 public:
208
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) {
212         }
213
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) {
217         }
218 } __attribute__((packed));
219
220 typedef CDB6 CDB6_t;
221
222 struct CDB10 {
223         uint8_t Opcode;
224
225         unsigned Service_Action : 5;
226         unsigned LUN : 3;
227
228         uint8_t LBA_L_M_MB;
229         uint8_t LBA_L_M_LB;
230         uint8_t LBA_L_L_MB;
231         uint8_t LBA_L_L_LB;
232
233         uint8_t Misc2;
234
235         uint8_t ALC_MB;
236         uint8_t ALC_LB;
237
238         uint8_t Control;
239 public:
240
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) {
245         }
246
247         CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
248         Opcode(_Opcode), Service_Action(0), LUN(_LUN),
249         LBA_L_M_MB(BGRAB3(_LBA)), LBA_L_M_LB(BGRAB2(_LBA)), LBA_L_L_MB(BGRAB1(_LBA)), LBA_L_L_LB(BGRAB0(_LBA)),
250         Misc2(0), ALC_MB(BGRAB1(xflen)), ALC_LB(BGRAB0(xflen)), Control(0) {
251         }
252 } __attribute__((packed));
253
254 typedef CDB10 CDB10_t;
255
256 struct CDB12 {
257         uint8_t Opcode;
258
259         unsigned Service_Action : 5;
260         unsigned Misc : 3;
261
262         uint8_t LBA_L_M_LB;
263         uint8_t LBA_L_L_MB;
264         uint8_t LBA_L_L_LB;
265
266         uint8_t ALC_M_LB;
267         uint8_t ALC_L_MB;
268         uint8_t ALC_L_LB;
269         uint8_t Control;
270 } __attribute__((packed));
271
272 typedef CDB12 CDB12_t;
273
274 struct CDB_LBA32_16 {
275         uint8_t Opcode;
276
277         unsigned Service_Action : 5;
278         unsigned Misc : 3;
279
280         uint8_t LBA_L_M_MB;
281         uint8_t LBA_L_M_LB;
282         uint8_t LBA_L_L_MB;
283         uint8_t LBA_L_L_LB;
284
285         uint8_t A_M_M_MB;
286         uint8_t A_M_M_LB;
287         uint8_t A_M_L_MB;
288         uint8_t A_M_L_LB;
289
290         uint8_t ALC_M_MB;
291         uint8_t ALC_M_LB;
292         uint8_t ALC_L_MB;
293         uint8_t ALC_L_LB;
294
295         uint8_t Misc2;
296         uint8_t Control;
297 } __attribute__((packed));
298
299 struct CDB_LBA64_16 {
300         uint8_t Opcode;
301         uint8_t Misc;
302
303         uint8_t LBA_M_M_MB;
304         uint8_t LBA_M_M_LB;
305         uint8_t LBA_M_L_MB;
306         uint8_t LBA_M_L_LB;
307
308         uint8_t LBA_L_M_MB;
309         uint8_t LBA_L_M_LB;
310         uint8_t LBA_L_L_MB;
311         uint8_t LBA_L_L_LB;
312
313         uint8_t ALC_M_MB;
314         uint8_t ALC_M_LB;
315         uint8_t ALC_L_MB;
316         uint8_t ALC_L_LB;
317
318         uint8_t Misc2;
319         uint8_t Control;
320 } __attribute__((packed));
321
322 struct InquiryResponse {
323         uint8_t DeviceType : 5;
324         uint8_t PeripheralQualifier : 3;
325
326         unsigned Reserved : 7;
327         unsigned Removable : 1;
328
329         uint8_t Version;
330
331         unsigned ResponseDataFormat : 4;
332         unsigned HISUP : 1;
333         unsigned NormACA : 1;
334         unsigned TrmTsk : 1;
335         unsigned AERC : 1;
336
337         uint8_t AdditionalLength;
338         //uint8_t Reserved3[2];
339
340         unsigned PROTECT : 1;
341         unsigned Res : 2;
342         unsigned ThreePC : 1;
343         unsigned TPGS : 2;
344         unsigned ACC : 1;
345         unsigned SCCS : 1;
346
347         unsigned ADDR16 : 1;
348         unsigned R1 : 1;
349         unsigned R2 : 1;
350         unsigned MCHNGR : 1;
351         unsigned MULTIP : 1;
352         unsigned VS : 1;
353         unsigned ENCSERV : 1;
354         unsigned BQUE : 1;
355
356         unsigned SoftReset : 1;
357         unsigned CmdQue : 1;
358         unsigned Reserved4 : 1;
359         unsigned Linked : 1;
360         unsigned Sync : 1;
361         unsigned WideBus16Bit : 1;
362         unsigned WideBus32Bit : 1;
363         unsigned RelAddr : 1;
364
365         uint8_t VendorID[8];
366         uint8_t ProductID[16];
367         uint8_t RevisionID[4];
368 } __attribute__((packed));
369
370 struct CommandBlockWrapperBase {
371         uint32_t dCBWSignature;
372         uint32_t dCBWTag;
373         uint32_t dCBWDataTransferLength;
374         uint8_t bmCBWFlags;
375 public:
376
377         CommandBlockWrapperBase() {
378         }
379
380         CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
381         dCBWSignature(MASS_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
382         }
383 } __attribute__((packed));
384
385 struct CommandBlockWrapper : public CommandBlockWrapperBase {
386
387         struct {
388                 uint8_t bmCBWLUN : 4;
389                 uint8_t bmReserved1 : 4;
390         };
391
392         struct {
393                 uint8_t bmCBWCBLength : 4;
394                 uint8_t bmReserved2 : 4;
395         };
396
397         uint8_t CBWCB[16];
398
399 public:
400         // All zeroed.
401
402         CommandBlockWrapper() :
403         CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
404                 for(int i = 0; i < 16; i++) CBWCB[i] = 0;
405         }
406
407         // Generic Wrap, CDB zeroed.
408
409         CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
410         CommandBlockWrapperBase(tag, xflen, flgs),
411         bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
412                 for(int i = 0; i < 16; i++) CBWCB[i] = 0;
413                 // Type punning can cause optimization problems and bugs.
414                 // Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
415                 //(((BASICCDB_t *) CBWCB)->LUN) = cmd;
416                 BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
417                 x->LUN = cmd;
418         }
419
420         // Wrap for CDB of 6
421
422         CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
423         CommandBlockWrapperBase(tag, xflen, dir),
424         bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
425                 memcpy(&CBWCB, cdb, 6);
426         }
427         // Wrap for CDB of 10
428
429         CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
430         CommandBlockWrapperBase(tag, xflen, dir),
431         bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
432                 memcpy(&CBWCB, cdb, 10);
433         }
434 } __attribute__((packed));
435
436 struct CommandStatusWrapper {
437         uint32_t dCSWSignature;
438         uint32_t dCSWTag;
439         uint32_t dCSWDataResidue;
440         uint8_t bCSWStatus;
441 } __attribute__((packed));
442
443 struct RequestSenseResponce {
444         uint8_t bResponseCode;
445         uint8_t bSegmentNumber;
446
447         uint8_t bmSenseKey : 4;
448         uint8_t bmReserved : 1;
449         uint8_t bmILI : 1;
450         uint8_t bmEOM : 1;
451         uint8_t bmFileMark : 1;
452
453         uint8_t Information[4];
454         uint8_t bAdditionalLength;
455         uint8_t CmdSpecificInformation[4];
456         uint8_t bAdditionalSenseCode;
457         uint8_t bAdditionalSenseQualifier;
458         uint8_t bFieldReplaceableUnitCode;
459         uint8_t SenseKeySpecific[3];
460 } __attribute__((packed));
461
462 class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
463 protected:
464         static const uint8_t epDataInIndex; // DataIn endpoint index
465         static const uint8_t epDataOutIndex; // DataOUT endpoint index
466         static const uint8_t epInterruptInIndex; // InterruptIN  endpoint index
467
468         USB *pUsb;
469         uint8_t bAddress;
470         uint8_t bConfNum; // configuration number
471         uint8_t bIface; // interface value
472         uint8_t bNumEP; // total number of EP in the configuration
473         uint32_t qNextPollTime; // next poll time
474         bool bPollEnable; // poll enable flag
475
476         EpInfo epInfo[MASS_MAX_ENDPOINTS];
477
478         uint32_t dCBWTag; // Tag
479         //uint32_t dCBWDataTransferLength; // Data Transfer Length
480         uint8_t bLastUsbError; // Last USB error
481         uint8_t bMaxLUN; // Max LUN
482         uint8_t bTheLUN; // Active LUN
483         uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
484         uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
485         bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
486         bool WriteOk[MASS_MAX_SUPPORTED_LUN];
487         void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
488
489
490         // Additional Initialization Method for Subclasses
491
492         virtual uint8_t OnInit() {
493                 return 0;
494         };
495 public:
496         BulkOnly(USB *p);
497
498         uint8_t GetLastUsbError() {
499                 return bLastUsbError;
500         };
501
502         uint8_t GetbMaxLUN() {
503                 return bMaxLUN; // Max LUN
504         }
505
506         uint8_t GetbTheLUN() {
507                 return bTheLUN; // Active LUN
508         }
509
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);
516
517         bool LUNIsGood(uint8_t lun);
518         uint32_t GetCapacity(uint8_t lun);
519         uint16_t GetSectorSize(uint8_t lun);
520
521         // USBDeviceConfig implementation
522         uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
523         uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
524
525         uint8_t Release();
526         uint8_t Poll();
527
528         virtual uint8_t GetAddress() {
529                 return bAddress;
530         };
531
532         // UsbConfigXtracter implementation
533         void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
534
535         virtual bool DEVCLASSOK(uint8_t klass) {
536                 return (klass == USB_CLASS_MASS_STORAGE);
537         }
538
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);
541
542 private:
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);
549         void Reset();
550         uint8_t ResetRecovery();
551         uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
552         void ClearAllEP();
553         void CheckMedia();
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);
558
559         bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
560
561         uint8_t ClearEpHalt(uint8_t index);
562 #if MS_WANT_PARSER
563         uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
564 #endif
565         uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
566         uint8_t HandleUsbError(uint8_t error, uint8_t index);
567         uint8_t HandleSCSIError(uint8_t status);
568
569 };
570
571 #endif // __MASSTORAGE_H__