My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

masstorage.h 18KB

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