You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
19 KiB

  1. /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
  2. This software may be distributed and modified under the terms of the GNU
  3. General Public License version 2 (GPL2) as published by the Free Software
  4. Foundation and appearing in the file GPL2.TXT included in the packaging of
  5. this file. Please note that GPL2 Section 2[b] requires that all works based
  6. on this software must also be made publicly available under the terms of
  7. the GPL2 ("Copyleft").
  8. Contact information
  9. -------------------
  10. Circuits At Home, LTD
  11. Web : http://www.circuitsathome.com
  12. e-mail : support@circuitsathome.com
  13. */
  14. #if !defined(__MASSTORAGE_H__)
  15. #define __MASSTORAGE_H__
  16. // Cruft removal, makes driver smaller, faster.
  17. #ifndef MS_WANT_PARSER
  18. #define MS_WANT_PARSER 0
  19. #endif
  20. #include "Usb.h"
  21. #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
  22. #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
  23. // Mass Storage Subclass Constants
  24. #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
  25. #define MASS_SUBCLASS_RBC 0x01
  26. #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
  27. #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
  28. #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
  29. #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
  30. #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
  31. #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
  32. #define MASS_SUBCLASS_IEEE1667 0x08
  33. // Mass Storage Class Protocols
  34. #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
  35. #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
  36. #define MASS_PROTO_OBSOLETE 0x02
  37. #define MASS_PROTO_BBB 0x50 // Bulk Only Transport
  38. #define MASS_PROTO_UAS 0x62
  39. // Request Codes
  40. #define MASS_REQ_ADSC 0x00
  41. #define MASS_REQ_GET 0xFC
  42. #define MASS_REQ_PUT 0xFD
  43. #define MASS_REQ_GET_MAX_LUN 0xFE
  44. #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
  45. #define MASS_CBW_SIGNATURE 0x43425355
  46. #define MASS_CSW_SIGNATURE 0x53425355
  47. #define MASS_CMD_DIR_OUT 0 // (0 << 7)
  48. #define MASS_CMD_DIR_IN 0x80 //(1 << 7)
  49. /*
  50. * Reference documents from T10 (http://www.t10.org)
  51. * SCSI Primary Commands - 3 (SPC-3)
  52. * SCSI Block Commands - 2 (SBC-2)
  53. * Multi-Media Commands - 5 (MMC-5)
  54. */
  55. /* Group 1 commands (CDB's here are should all be 6-bytes) */
  56. #define SCSI_CMD_TEST_UNIT_READY 0x00
  57. #define SCSI_CMD_REQUEST_SENSE 0x03
  58. #define SCSI_CMD_FORMAT_UNIT 0x04
  59. #define SCSI_CMD_READ_6 0x08
  60. #define SCSI_CMD_WRITE_6 0x0A
  61. #define SCSI_CMD_INQUIRY 0x12
  62. #define SCSI_CMD_MODE_SELECT_6 0x15
  63. #define SCSI_CMD_MODE_SENSE_6 0x1A
  64. #define SCSI_CMD_START_STOP_UNIT 0x1B
  65. #define SCSI_CMD_PREVENT_REMOVAL 0x1E
  66. /* Group 2 Commands (CDB's here are 10-bytes) */
  67. #define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23
  68. #define SCSI_CMD_READ_CAPACITY_10 0x25
  69. #define SCSI_CMD_READ_10 0x28
  70. #define SCSI_CMD_WRITE_10 0x2A
  71. #define SCSI_CMD_SEEK_10 0x2B
  72. #define SCSI_CMD_ERASE_10 0x2C
  73. #define SCSI_CMD_WRITE_AND_VERIFY_10 0x2E
  74. #define SCSI_CMD_VERIFY_10 0x2F
  75. #define SCSI_CMD_SYNCHRONIZE_CACHE 0x35
  76. #define SCSI_CMD_WRITE_BUFFER 0x3B
  77. #define SCSI_CMD_READ_BUFFER 0x3C
  78. #define SCSI_CMD_READ_SUBCHANNEL 0x42
  79. #define SCSI_CMD_READ_TOC 0x43
  80. #define SCSI_CMD_READ_HEADER 0x44
  81. #define SCSI_CMD_PLAY_AUDIO_10 0x45
  82. #define SCSI_CMD_GET_CONFIGURATION 0x46
  83. #define SCSI_CMD_PLAY_AUDIO_MSF 0x47
  84. #define SCSI_CMD_PLAY_AUDIO_TI 0x48
  85. #define SCSI_CMD_PLAY_TRACK_REL_10 0x49
  86. #define SCSI_CMD_GET_EVENT_STATUS 0x4A
  87. #define SCSI_CMD_PAUSE_RESUME 0x4B
  88. #define SCSI_CMD_READ_DISC_INFORMATION 0x51
  89. #define SCSI_CMD_READ_TRACK_INFORMATION 0x52
  90. #define SCSI_CMD_RESERVE_TRACK 0x53
  91. #define SCSI_CMD_SEND_OPC_INFORMATION 0x54
  92. #define SCSI_CMD_MODE_SELECT_10 0x55
  93. #define SCSI_CMD_REPAIR_TRACK 0x58
  94. #define SCSI_CMD_MODE_SENSE_10 0x5A
  95. #define SCSI_CMD_CLOSE_TRACK_SESSION 0x5B
  96. #define SCSI_CMD_READ_BUFFER_CAPACITY 0x5C
  97. #define SCSI_CMD_SEND_CUE_SHEET 0x5D
  98. /* Group 5 Commands (CDB's here are 12-bytes) */
  99. #define SCSI_CMD_REPORT_LUNS 0xA0
  100. #define SCSI_CMD_BLANK 0xA1
  101. #define SCSI_CMD_SECURITY_PROTOCOL_IN 0xA2
  102. #define SCSI_CMD_SEND_KEY 0xA3
  103. #define SCSI_CMD_REPORT_KEY 0xA4
  104. #define SCSI_CMD_PLAY_AUDIO_12 0xA5
  105. #define SCSI_CMD_LOAD_UNLOAD 0xA6
  106. #define SCSI_CMD_SET_READ_AHEAD 0xA7
  107. #define SCSI_CMD_READ_12 0xA8
  108. #define SCSI_CMD_PLAY_TRACK_REL_12 0xA9
  109. #define SCSI_CMD_WRITE_12 0xAA
  110. #define SCSI_CMD_READ_MEDIA_SERIAL_12 0xAB
  111. #define SCSI_CMD_GET_PERFORMANCE 0xAC
  112. #define SCSI_CMD_READ_DVD_STRUCTURE 0xAD
  113. #define SCSI_CMD_SECURITY_PROTOCOL_OUT 0xB5
  114. #define SCSI_CMD_SET_STREAMING 0xB6
  115. #define SCSI_CMD_READ_MSF 0xB9
  116. #define SCSI_CMD_SET_SPEED 0xBB
  117. #define SCSI_CMD_MECHANISM_STATUS 0xBD
  118. #define SCSI_CMD_READ_CD 0xBE
  119. #define SCSI_CMD_SEND_DISC_STRUCTURE 0xBF
  120. /* Vendor-unique Commands, included for completeness */
  121. #define SCSI_CMD_CD_PLAYBACK_STATUS 0xC4 /* SONY unique */
  122. #define SCSI_CMD_PLAYBACK_CONTROL 0xC9 /* SONY unique */
  123. #define SCSI_CMD_READ_CDDA 0xD8 /* Vendor unique */
  124. #define SCSI_CMD_READ_CDXA 0xDB /* Vendor unique */
  125. #define SCSI_CMD_READ_ALL_SUBCODES 0xDF /* Vendor unique */
  126. /* SCSI error codes */
  127. #define SCSI_S_NOT_READY 0x02
  128. #define SCSI_S_MEDIUM_ERROR 0x03
  129. #define SCSI_S_ILLEGAL_REQUEST 0x05
  130. #define SCSI_S_UNIT_ATTENTION 0x06
  131. #define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
  132. #define SCSI_ASC_MEDIA_CHANGED 0x28
  133. #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
  134. /* USB error codes */
  135. #define MASS_ERR_SUCCESS 0x00
  136. #define MASS_ERR_PHASE_ERROR 0x02
  137. #define MASS_ERR_UNIT_NOT_READY 0x03
  138. #define MASS_ERR_UNIT_BUSY 0x04
  139. #define MASS_ERR_STALL 0x05
  140. #define MASS_ERR_CMD_NOT_SUPPORTED 0x06
  141. #define MASS_ERR_INVALID_CSW 0x07
  142. #define MASS_ERR_NO_MEDIA 0x08
  143. #define MASS_ERR_BAD_LBA 0x09
  144. #define MASS_ERR_MEDIA_CHANGED 0x0A
  145. #define MASS_ERR_DEVICE_DISCONNECTED 0x11
  146. #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
  147. #define MASS_ERR_INVALID_LUN 0x13
  148. #define MASS_ERR_WRITE_STALL 0x14
  149. #define MASS_ERR_READ_NAKS 0x15
  150. #define MASS_ERR_WRITE_NAKS 0x16
  151. #define MASS_ERR_WRITE_PROTECTED 0x17
  152. #define MASS_ERR_NOT_IMPLEMENTED 0xFD
  153. #define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
  154. #define MASS_ERR_GENERAL_USB_ERROR 0xFF
  155. #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
  159. #define MASS_MAX_ENDPOINTS 3
  160. struct Capacity {
  161. uint8_t data[8];
  162. //uint32_t dwBlockAddress;
  163. //uint32_t dwBlockLength;
  164. } __attribute__((packed));
  165. struct BASICCDB {
  166. uint8_t Opcode;
  167. unsigned unused : 5;
  168. unsigned LUN : 3;
  169. uint8_t info[12];
  170. } __attribute__((packed));
  171. typedef BASICCDB BASICCDB_t;
  172. struct CDB6 {
  173. uint8_t Opcode;
  174. unsigned LBAMSB : 5;
  175. unsigned LUN : 3;
  176. uint8_t LBAHB;
  177. uint8_t LBALB;
  178. uint8_t AllocationLength;
  179. uint8_t Control;
  180. public:
  181. CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
  182. Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
  183. AllocationLength(_AllocationLength), Control(_Control) {
  184. }
  185. CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
  186. Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
  187. AllocationLength(_AllocationLength), Control(_Control) {
  188. }
  189. } __attribute__((packed));
  190. typedef CDB6 CDB6_t;
  191. struct CDB10 {
  192. uint8_t Opcode;
  193. unsigned Service_Action : 5;
  194. unsigned LUN : 3;
  195. uint8_t LBA_L_M_MB;
  196. uint8_t LBA_L_M_LB;
  197. uint8_t LBA_L_L_MB;
  198. uint8_t LBA_L_L_LB;
  199. uint8_t Misc2;
  200. uint8_t ALC_MB;
  201. uint8_t ALC_LB;
  202. uint8_t Control;
  203. public:
  204. CDB10(uint8_t _Opcode, uint8_t _LUN) :
  205. Opcode(_Opcode), Service_Action(0), LUN(_LUN),
  206. LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
  207. Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
  208. }
  209. CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
  210. Opcode(_Opcode), Service_Action(0), LUN(_LUN),
  211. LBA_L_M_MB(BGRAB3(_LBA)), LBA_L_M_LB(BGRAB2(_LBA)), LBA_L_L_MB(BGRAB1(_LBA)), LBA_L_L_LB(BGRAB0(_LBA)),
  212. Misc2(0), ALC_MB(BGRAB1(xflen)), ALC_LB(BGRAB0(xflen)), Control(0) {
  213. }
  214. } __attribute__((packed));
  215. typedef CDB10 CDB10_t;
  216. struct CDB12 {
  217. uint8_t Opcode;
  218. unsigned Service_Action : 5;
  219. unsigned Misc : 3;
  220. uint8_t LBA_L_M_LB;
  221. uint8_t LBA_L_L_MB;
  222. uint8_t LBA_L_L_LB;
  223. uint8_t ALC_M_LB;
  224. uint8_t ALC_L_MB;
  225. uint8_t ALC_L_LB;
  226. uint8_t Control;
  227. } __attribute__((packed));
  228. typedef CDB12 CDB12_t;
  229. struct CDB_LBA32_16 {
  230. uint8_t Opcode;
  231. unsigned Service_Action : 5;
  232. unsigned Misc : 3;
  233. uint8_t LBA_L_M_MB;
  234. uint8_t LBA_L_M_LB;
  235. uint8_t LBA_L_L_MB;
  236. uint8_t LBA_L_L_LB;
  237. uint8_t A_M_M_MB;
  238. uint8_t A_M_M_LB;
  239. uint8_t A_M_L_MB;
  240. uint8_t A_M_L_LB;
  241. uint8_t ALC_M_MB;
  242. uint8_t ALC_M_LB;
  243. uint8_t ALC_L_MB;
  244. uint8_t ALC_L_LB;
  245. uint8_t Misc2;
  246. uint8_t Control;
  247. } __attribute__((packed));
  248. struct CDB_LBA64_16 {
  249. uint8_t Opcode;
  250. uint8_t Misc;
  251. uint8_t LBA_M_M_MB;
  252. uint8_t LBA_M_M_LB;
  253. uint8_t LBA_M_L_MB;
  254. uint8_t LBA_M_L_LB;
  255. uint8_t LBA_L_M_MB;
  256. uint8_t LBA_L_M_LB;
  257. uint8_t LBA_L_L_MB;
  258. uint8_t LBA_L_L_LB;
  259. uint8_t ALC_M_MB;
  260. uint8_t ALC_M_LB;
  261. uint8_t ALC_L_MB;
  262. uint8_t ALC_L_LB;
  263. uint8_t Misc2;
  264. uint8_t Control;
  265. } __attribute__((packed));
  266. struct InquiryResponse {
  267. uint8_t DeviceType : 5;
  268. uint8_t PeripheralQualifier : 3;
  269. unsigned Reserved : 7;
  270. unsigned Removable : 1;
  271. uint8_t Version;
  272. unsigned ResponseDataFormat : 4;
  273. unsigned HISUP : 1;
  274. unsigned NormACA : 1;
  275. unsigned TrmTsk : 1;
  276. unsigned AERC : 1;
  277. uint8_t AdditionalLength;
  278. //uint8_t Reserved3[2];
  279. unsigned PROTECT : 1;
  280. unsigned Res : 2;
  281. unsigned ThreePC : 1;
  282. unsigned TPGS : 2;
  283. unsigned ACC : 1;
  284. unsigned SCCS : 1;
  285. unsigned ADDR16 : 1;
  286. unsigned R1 : 1;
  287. unsigned R2 : 1;
  288. unsigned MCHNGR : 1;
  289. unsigned MULTIP : 1;
  290. unsigned VS : 1;
  291. unsigned ENCSERV : 1;
  292. unsigned BQUE : 1;
  293. unsigned SoftReset : 1;
  294. unsigned CmdQue : 1;
  295. unsigned Reserved4 : 1;
  296. unsigned Linked : 1;
  297. unsigned Sync : 1;
  298. unsigned WideBus16Bit : 1;
  299. unsigned WideBus32Bit : 1;
  300. unsigned RelAddr : 1;
  301. uint8_t VendorID[8];
  302. uint8_t ProductID[16];
  303. uint8_t RevisionID[4];
  304. } __attribute__((packed));
  305. struct CommandBlockWrapperBase {
  306. uint32_t dCBWSignature;
  307. uint32_t dCBWTag;
  308. uint32_t dCBWDataTransferLength;
  309. uint8_t bmCBWFlags;
  310. public:
  311. CommandBlockWrapperBase() {
  312. }
  313. CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
  314. dCBWSignature(MASS_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
  315. }
  316. } __attribute__((packed));
  317. struct CommandBlockWrapper : public CommandBlockWrapperBase {
  318. struct {
  319. uint8_t bmCBWLUN : 4;
  320. uint8_t bmReserved1 : 4;
  321. };
  322. struct {
  323. uint8_t bmCBWCBLength : 4;
  324. uint8_t bmReserved2 : 4;
  325. };
  326. uint8_t CBWCB[16];
  327. public:
  328. // All zeroed.
  329. CommandBlockWrapper() :
  330. CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
  331. for(int i = 0; i < 16; i++) CBWCB[i] = 0;
  332. }
  333. // Generic Wrap, CDB zeroed.
  334. CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
  335. CommandBlockWrapperBase(tag, xflen, flgs),
  336. bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
  337. for(int i = 0; i < 16; i++) CBWCB[i] = 0;
  338. // Type punning can cause optimization problems and bugs.
  339. // Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
  340. //(((BASICCDB_t *) CBWCB)->LUN) = cmd;
  341. BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
  342. x->LUN = cmd;
  343. }
  344. // Wrap for CDB of 6
  345. CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
  346. CommandBlockWrapperBase(tag, xflen, dir),
  347. bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
  348. memcpy(&CBWCB, cdb, 6);
  349. }
  350. // Wrap for CDB of 10
  351. CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
  352. CommandBlockWrapperBase(tag, xflen, dir),
  353. bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
  354. memcpy(&CBWCB, cdb, 10);
  355. }
  356. } __attribute__((packed));
  357. struct CommandStatusWrapper {
  358. uint32_t dCSWSignature;
  359. uint32_t dCSWTag;
  360. uint32_t dCSWDataResidue;
  361. uint8_t bCSWStatus;
  362. } __attribute__((packed));
  363. struct RequestSenseResponce {
  364. uint8_t bResponseCode;
  365. uint8_t bSegmentNumber;
  366. uint8_t bmSenseKey : 4;
  367. uint8_t bmReserved : 1;
  368. uint8_t bmILI : 1;
  369. uint8_t bmEOM : 1;
  370. uint8_t bmFileMark : 1;
  371. uint8_t Information[4];
  372. uint8_t bAdditionalLength;
  373. uint8_t CmdSpecificInformation[4];
  374. uint8_t bAdditionalSenseCode;
  375. uint8_t bAdditionalSenseQualifier;
  376. uint8_t bFieldReplaceableUnitCode;
  377. uint8_t SenseKeySpecific[3];
  378. } __attribute__((packed));
  379. class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
  380. protected:
  381. static const uint8_t epDataInIndex; // DataIn endpoint index
  382. static const uint8_t epDataOutIndex; // DataOUT endpoint index
  383. static const uint8_t epInterruptInIndex; // InterruptIN endpoint index
  384. USB *pUsb;
  385. uint8_t bAddress;
  386. uint8_t bConfNum; // configuration number
  387. uint8_t bIface; // interface value
  388. uint8_t bNumEP; // total number of EP in the configuration
  389. uint32_t qNextPollTime; // next poll time
  390. bool bPollEnable; // poll enable flag
  391. EpInfo epInfo[MASS_MAX_ENDPOINTS];
  392. uint32_t dCBWTag; // Tag
  393. //uint32_t dCBWDataTransferLength; // Data Transfer Length
  394. uint8_t bLastUsbError; // Last USB error
  395. uint8_t bMaxLUN; // Max LUN
  396. uint8_t bTheLUN; // Active LUN
  397. uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
  398. uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
  399. bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
  400. bool WriteOk[MASS_MAX_SUPPORTED_LUN];
  401. void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
  402. // Additional Initialization Method for Subclasses
  403. virtual uint8_t OnInit() {
  404. return 0;
  405. };
  406. public:
  407. BulkOnly(USB *p);
  408. uint8_t GetLastUsbError() {
  409. return bLastUsbError;
  410. };
  411. uint8_t GetbMaxLUN() {
  412. return bMaxLUN; // Max LUN
  413. }
  414. uint8_t GetbTheLUN() {
  415. return bTheLUN; // Active LUN
  416. }
  417. bool WriteProtected(uint8_t lun);
  418. uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
  419. uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
  420. uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser *prs);
  421. uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
  422. uint8_t LockMedia(uint8_t lun, uint8_t lock);
  423. bool LUNIsGood(uint8_t lun);
  424. uint32_t GetCapacity(uint8_t lun);
  425. uint16_t GetSectorSize(uint8_t lun);
  426. // USBDeviceConfig implementation
  427. uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
  428. uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
  429. uint8_t Release();
  430. uint8_t Poll();
  431. virtual uint8_t GetAddress() {
  432. return bAddress;
  433. };
  434. // UsbConfigXtracter implementation
  435. void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
  436. virtual bool DEVCLASSOK(uint8_t klass) {
  437. return (klass == USB_CLASS_MASS_STORAGE);
  438. }
  439. uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
  440. uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
  441. private:
  442. uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
  443. uint8_t TestUnitReady(uint8_t lun);
  444. uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
  445. uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
  446. uint8_t GetMaxLUN(uint8_t *max_lun);
  447. uint8_t SetCurLUN(uint8_t lun);
  448. void Reset();
  449. uint8_t ResetRecovery();
  450. uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
  451. void ClearAllEP();
  452. void CheckMedia();
  453. bool CheckLUN(uint8_t lun);
  454. uint8_t Page3F(uint8_t lun);
  455. bool IsValidCBW(uint8_t size, uint8_t *pcbw);
  456. bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
  457. bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
  458. uint8_t ClearEpHalt(uint8_t index);
  459. #if MS_WANT_PARSER
  460. uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
  461. #endif
  462. uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
  463. uint8_t HandleUsbError(uint8_t error, uint8_t index);
  464. uint8_t HandleSCSIError(uint8_t status);
  465. };
  466. #endif // __MASSTORAGE_H__