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.

mscuser.cpp 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /*----------------------------------------------------------------------------
  2. * U S B - K e r n e l
  3. *----------------------------------------------------------------------------
  4. * Name: MSCUSER.C
  5. * Purpose: Mass Storage Class Custom User Module
  6. * Version: V1.10
  7. *----------------------------------------------------------------------------
  8. * This software is supplied "AS IS" without any warranties, express,
  9. * implied or statutory, including but not limited to the implied
  10. * warranties of fitness for purpose, satisfactory quality and
  11. * noninfringement. Keil extends you a royalty-free right to reproduce
  12. * and distribute executable files created using this software for use
  13. * on NXP Semiconductors LPC family microcontroller devices only. Nothing
  14. * else gives you the right to use this software.
  15. *
  16. * Copyright (c) 2005-2009 Keil Software.
  17. *---------------------------------------------------------------------------*/
  18. extern "C" {
  19. #include "LPC17xx.h"
  20. #include "lpc_types.h"
  21. }
  22. #include "usb.h"
  23. #include "msc.h"
  24. #include "usbcfg.h"
  25. #include "usbhw.h"
  26. #include "usbcore.h"
  27. #include "mscuser.h"
  28. #include "lpc17xx_wdt.h"
  29. #include "../chanfs/diskio.h"
  30. #include <debug_frmwrk.h>
  31. DWORD MSC_BlockCount = 0;
  32. uint32_t MemOK; /* Memory OK */
  33. DWORD lba; /* start block */
  34. DWORD transfer_count; /* blocks to transfer */
  35. DWORD length;
  36. uint32_t block_offset; /* current block offset*/
  37. uint8_t BulkStage; /* Bulk Stage */
  38. uint8_t BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */
  39. uint8_t block_cache[MSC_BLOCK_SIZE];
  40. uint8_t BulkLen; /* Bulk In/Out Length */
  41. Sense sense_data;
  42. MSC_CBW CBW; /* Command Block Wrapper */
  43. MSC_CSW CSW; /* Command Status Wrapper */
  44. volatile uint8_t media_lock = 0;
  45. volatile bool device_wants_lock = false;
  46. #define NO_LOCK 0
  47. #define HOST_LOCK 1
  48. #define DEVICE_LOCK 2
  49. extern uint32_t millis();
  50. extern void _delay_ms(int delay);
  51. uint32_t MSC_Aquire_Lock() {
  52. NVIC_DisableIRQ(USB_IRQn);
  53. device_wants_lock = true;
  54. uint32_t end_millis = millis() + 1000;
  55. if(media_lock == HOST_LOCK) {
  56. NVIC_EnableIRQ(USB_IRQn);
  57. while(media_lock == HOST_LOCK) {
  58. if(((long)(end_millis - (millis())) < 0)) {
  59. _DBG("No signal from Host, Assume success\n");
  60. break;
  61. }
  62. WDT_Feed();
  63. }
  64. }
  65. NVIC_DisableIRQ(USB_IRQn);
  66. media_lock = DEVICE_LOCK;
  67. NVIC_EnableIRQ(USB_IRQn);
  68. _DBG("Device MSC Lock\n");
  69. device_wants_lock = false;
  70. return 0;
  71. }
  72. uint32_t MSC_Release_Lock() {
  73. if(media_lock != DEVICE_LOCK) {
  74. return 0; // Didn't have lock
  75. }
  76. media_lock = NO_LOCK;
  77. if(disk_status(0) != STA_NOINIT) disk_ioctl(0, GET_SECTOR_COUNT, (void *)(&MSC_BlockCount));
  78. _DBG("Device MSC Unlock\n");
  79. NVIC_DisableIRQ(USB_IRQn);
  80. sense_data.set(Sense_KEY::UNIT_ATTENTION, Sense_ASC::MEDIA_CHANGED);
  81. NVIC_EnableIRQ(USB_IRQn);
  82. return 0; // Released
  83. }
  84. uint32_t MSC_SD_Lock() {
  85. if(media_lock == DEVICE_LOCK || (device_wants_lock && CBW.CB[4])) {
  86. CSW.bStatus = CSW_CMD_FAILED;
  87. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::LOGICAL_UNIT_NOT_READY, Sense_ASCQ::DEVICE_IS_BUSY);
  88. MSC_SetCSW();
  89. _DBG("Device has Lock (or is waiting for lock) cannot Lock..\n");
  90. return 1;
  91. }
  92. if(CBW.CB[4]) {
  93. media_lock = HOST_LOCK;
  94. _DBG("OS MSC Lock\n");
  95. } else {
  96. media_lock = NO_LOCK;
  97. _DBG("OS MSC Unlock\n");
  98. }
  99. // logical_unit = CBW.CB[1] & 0xE0;
  100. CSW.bStatus = CSW_CMD_PASSED;
  101. MSC_SetCSW();
  102. return 0;
  103. }
  104. uint32_t MSC_SD_Release(uint8_t pdrv) {
  105. MSC_BlockCount = 0;
  106. return 0;
  107. }
  108. uint32_t MSC_SD_Init(uint8_t pdrv) {
  109. DSTATUS ret = disk_initialize(pdrv);
  110. if(ret) return ret;
  111. if(disk_ioctl (pdrv, GET_SECTOR_COUNT, (void *)(&MSC_BlockCount))) return 1;
  112. return 0;
  113. }
  114. #define STARTSTOP_STOPMOTOR 0x0
  115. #define STARTSTOP_STARTMOTOR 0x1
  116. #define STARTSTOP_EJECT 0x2
  117. #define STARTSTOP_LOAD 0x3
  118. void MSC_StartStopUnit() {
  119. switch (CBW.CB[4] & 0x03) {
  120. case STARTSTOP_EJECT:
  121. MSC_SD_Release(0);
  122. media_lock = NO_LOCK;
  123. _DBG("OS Media Ejected UNLOCK\n");
  124. break;
  125. case STARTSTOP_LOAD:
  126. if(MSC_BlockCount == 0) {
  127. if(MSC_SD_Init(0) != 0) {
  128. CSW.bStatus = CSW_CMD_FAILED;
  129. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::MANUAL_INTERVENTION_REQUIRED);
  130. MSC_SetCSW();
  131. return;
  132. }
  133. }
  134. media_lock = HOST_LOCK;
  135. _DBG("OS Media Mount LOCKED\n");
  136. break;
  137. default:
  138. _DBG("MSC_StartStopUnit unknown startstopunit sub command: ");
  139. _DBH(CBW.CB[4] & 0x03);
  140. _DBG("\n");
  141. }
  142. CSW.bStatus = CSW_CMD_PASSED;
  143. sense_data.reset();
  144. MSC_SetCSW();
  145. }
  146. /*
  147. * MSC Mass Storage Reset Request Callback
  148. * Called automatically on Mass Storage Reset Request
  149. * Parameters: None (global SetupPacket and EP0Buf)
  150. * Return Value: TRUE - Success, FALSE - Error
  151. */
  152. uint32_t MSC_Reset (void) {
  153. BulkStage = MSC_BS_CBW;
  154. return (TRUE);
  155. }
  156. /*
  157. * MSC Get Max LUN Request Callback
  158. * Called automatically on Get Max LUN Request
  159. * Parameters: None (global SetupPacket and EP0Buf)
  160. * Return Value: TRUE - Success, FALSE - Error
  161. */
  162. uint32_t MSC_GetMaxLUN (void) {
  163. EP0Buf[0] = 0; /* No LUN associated with this device */
  164. return (TRUE);
  165. }
  166. bool host_get_lock(void) {
  167. if(media_lock != DEVICE_LOCK && !device_wants_lock) {
  168. media_lock = HOST_LOCK;
  169. return true;
  170. } else {
  171. CSW.bStatus = CSW_CMD_FAILED;
  172. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::LOGICAL_UNIT_NOT_READY, Sense_ASCQ::DEVICE_IS_BUSY);
  173. MSC_SetCSW();
  174. return false;
  175. }
  176. }
  177. /*
  178. * MSC Memory Read Callback
  179. * Called automatically on Memory Read Event
  180. * Parameters: None (global variables)
  181. * Return Value: None
  182. */
  183. void MSC_MemoryRead (void) {
  184. if(!host_get_lock()) {
  185. _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
  186. return;
  187. }
  188. WDT_Feed();
  189. uint32_t n = (length > MSC_MAX_PACKET) ? MSC_MAX_PACKET : length;
  190. if (lba > MSC_BlockCount) {
  191. n = (MSC_BlockCount - lba) * MSC_BLOCK_SIZE + block_offset;
  192. BulkStage = MSC_BS_ERROR;
  193. }
  194. if(block_offset == 0) {
  195. disk_read (0, block_cache, lba, 1);
  196. }
  197. USB_WriteEP(MSC_EP_IN, &block_cache[block_offset], n);
  198. block_offset += n;
  199. length -= n;
  200. CSW.dDataResidue -= n;
  201. if(block_offset >= MSC_BLOCK_SIZE) {
  202. block_offset = 0;
  203. ++lba;
  204. }
  205. if (length == 0) {
  206. BulkStage = MSC_BS_DATA_IN_LAST;
  207. }
  208. if (BulkStage != MSC_BS_DATA_IN) {
  209. CSW.bStatus = CSW_CMD_PASSED;
  210. sense_data.reset();
  211. }
  212. }
  213. /*
  214. * MSC Memory Write Callback
  215. * Called automatically on Memory Write Event
  216. * Parameters: None (global variables)
  217. * Return Value: None
  218. */
  219. void MSC_MemoryWrite (void) {
  220. if(!host_get_lock()) {
  221. _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
  222. return;
  223. }
  224. WDT_Feed();
  225. for (uint32_t n = 0; n < BulkLen; n++) {
  226. block_cache[block_offset + n] = BulkBuf[n];
  227. }
  228. if(block_offset + BulkLen >= MSC_BLOCK_SIZE) {
  229. if(!(disk_status(0) & STA_PROTECT)){
  230. disk_write(0, block_cache, lba, 1);
  231. }
  232. }
  233. block_offset += BulkLen;
  234. length -= BulkLen;
  235. CSW.dDataResidue -= BulkLen;
  236. if(block_offset >= MSC_BLOCK_SIZE) {
  237. block_offset = 0;
  238. ++lba;
  239. }
  240. if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
  241. CSW.bStatus = CSW_CMD_PASSED;
  242. sense_data.reset();
  243. MSC_SetCSW();
  244. }
  245. }
  246. /*
  247. * MSC Memory Verify Callback
  248. * Called automatically on Memory Verify Event
  249. * Parameters: None (global variables)
  250. * Return Value: None
  251. */
  252. void MSC_MemoryVerify (void) {
  253. if(!host_get_lock()) {
  254. _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
  255. return;
  256. }
  257. WDT_Feed();
  258. if(!block_offset) {
  259. disk_read(0, block_cache, lba, 1);
  260. }
  261. for (uint32_t n = 0; n < BulkLen; n++) {
  262. if (block_cache[block_offset + n] != BulkBuf[n]) {
  263. MemOK = FALSE;
  264. break;
  265. }
  266. }
  267. block_offset += BulkLen;
  268. length -= BulkLen;
  269. CSW.dDataResidue -= BulkLen;
  270. if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
  271. if(MemOK) {
  272. CSW.bStatus = CSW_CMD_PASSED;
  273. sense_data.reset();
  274. } else {
  275. CSW.bStatus = CSW_CMD_FAILED;
  276. sense_data.set(Sense_KEY::MEDIUM_ERROR);
  277. }
  278. MSC_SetCSW();
  279. }
  280. }
  281. /*
  282. * MSC SCSI Read/Write Setup Callback
  283. * Parameters: None (global variables)
  284. * Return Value: TRUE - Success, FALSE - Error
  285. */
  286. uint32_t MSC_RWSetup (void) {
  287. uint32_t n;
  288. /* Logical Block Address of First Block */
  289. lba = (CBW.CB[2] << 24) |
  290. (CBW.CB[3] << 16) |
  291. (CBW.CB[4] << 8) |
  292. (CBW.CB[5] << 0);
  293. /* Number of Blocks to transfer */
  294. transfer_count = (CBW.CB[7] << 8) |
  295. (CBW.CB[8] << 0);
  296. block_offset = 0;
  297. length = transfer_count * MSC_BLOCK_SIZE;
  298. if (CBW.dDataLength != (transfer_count * MSC_BLOCK_SIZE)) {
  299. USB_SetStallEP(MSC_EP_IN);
  300. USB_SetStallEP(MSC_EP_OUT);
  301. CSW.bStatus = CSW_PHASE_ERROR;
  302. MSC_SetCSW();
  303. return (FALSE);
  304. }
  305. return (TRUE);
  306. }
  307. /*
  308. * Check Data IN Format
  309. * Parameters: None (global variables)
  310. * Return Value: TRUE - Success, FALSE - Error
  311. */
  312. uint32_t DataInFormat (void) {
  313. if (CBW.dDataLength == 0) {
  314. CSW.bStatus = CSW_PHASE_ERROR;
  315. MSC_SetCSW();
  316. return (FALSE);
  317. }
  318. if ((CBW.bmFlags & 0x80) == 0) {
  319. USB_SetStallEP(MSC_EP_OUT);
  320. CSW.bStatus = CSW_PHASE_ERROR;
  321. MSC_SetCSW();
  322. return (FALSE);
  323. }
  324. return (TRUE);
  325. }
  326. /*
  327. * Perform Data IN Transfer
  328. * Parameters: None (global variables)
  329. * Return Value: TRUE - Success, FALSE - Error
  330. */
  331. void DataInTransfer (void) {
  332. if (BulkLen > CBW.dDataLength) {
  333. BulkLen = CBW.dDataLength;
  334. }
  335. USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen);
  336. BulkStage = MSC_BS_DATA_IN_LAST;
  337. CSW.dDataResidue -= BulkLen;
  338. CSW.bStatus = CSW_CMD_PASSED;
  339. }
  340. /*
  341. * MSC SCSI Test Unit Ready Callback
  342. * Parameters: None (global variables)
  343. * Return Value: None
  344. */
  345. void MSC_TestUnitReady (void) {
  346. if (CBW.dDataLength != 0) {
  347. if ((CBW.bmFlags & 0x80) != 0) {
  348. USB_SetStallEP(MSC_EP_IN);
  349. } else {
  350. USB_SetStallEP(MSC_EP_OUT);
  351. }
  352. }
  353. if(device_wants_lock) {
  354. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::REASON_UNKNOWN);
  355. CSW.bStatus = CSW_CMD_FAILED;
  356. } else if(MSC_BlockCount > 0) {
  357. sense_data.reset();
  358. CSW.bStatus = CSW_CMD_PASSED;
  359. } else {
  360. CSW.bStatus = CSW_CMD_FAILED;
  361. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::LOADABLE);
  362. }
  363. MSC_SetCSW();
  364. }
  365. /*
  366. * MSC SCSI Request Sense Callback
  367. * Parameters: None (global variables)
  368. * Return Value: None
  369. */
  370. void MSC_RequestSense (void) {
  371. if (!DataInFormat()) return;
  372. if(media_lock == DEVICE_LOCK || device_wants_lock) {
  373. sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::REASON_UNKNOWN);
  374. }
  375. BulkBuf[ 0] = 0x70; /* Response Code */
  376. BulkBuf[ 1] = 0x00;
  377. BulkBuf[ 2] = static_cast<uint8_t>(sense_data.key);
  378. BulkBuf[ 3] = 0x00;
  379. BulkBuf[ 4] = 0x00;
  380. BulkBuf[ 5] = 0x00;
  381. BulkBuf[ 6] = 0x00;
  382. BulkBuf[ 7] = 0x0A; /* Additional Length */
  383. BulkBuf[ 8] = 0x00;
  384. BulkBuf[ 9] = 0x00;
  385. BulkBuf[10] = 0x00;
  386. BulkBuf[11] = 0x00;
  387. BulkBuf[12] = static_cast<uint8_t>(sense_data.asc);
  388. BulkBuf[13] = static_cast<uint8_t>(sense_data.ascq);
  389. BulkBuf[14] = 0x00;
  390. BulkBuf[15] = 0x00;
  391. BulkBuf[16] = 0x00;
  392. BulkBuf[17] = 0x00;
  393. if(sense_data.has_sense()){
  394. _DBG("Sent Response to SenseRequest: ");
  395. _DBH(static_cast<uint8_t>(sense_data.key));
  396. _DBG("\n");
  397. }
  398. BulkLen = 18;
  399. DataInTransfer();
  400. }
  401. /*
  402. * MSC SCSI Inquiry Callback
  403. * Parameters: None (global variables)
  404. * Return Value: None
  405. */
  406. void MSC_Inquiry (void) {
  407. if (!DataInFormat()) return;
  408. BulkBuf[ 0] = 0x00; /* Direct Access Device */
  409. BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */
  410. BulkBuf[ 2] = 0x00; /* Version: No conformance claim to standard */
  411. BulkBuf[ 3] = 0x01;
  412. BulkBuf[ 4] = 36-4; /* Additional Length */
  413. BulkBuf[ 5] = 0x80; /* SCCS = 1: Storage Controller Component */
  414. BulkBuf[ 6] = 0x00;
  415. BulkBuf[ 7] = 0x00;
  416. BulkBuf[ 8] = 'M'; /* Vendor Identification */
  417. BulkBuf[ 9] = 'a';
  418. BulkBuf[10] = 'r';
  419. BulkBuf[11] = 'l';
  420. BulkBuf[12] = 'i';
  421. BulkBuf[13] = 'n';
  422. BulkBuf[14] = ' ';
  423. BulkBuf[15] = ' ';
  424. BulkBuf[16] = 'R'; /* Product Identification */
  425. BulkBuf[17] = 'e';
  426. BulkBuf[18] = '-';
  427. BulkBuf[19] = 'A';
  428. BulkBuf[20] = 'R';
  429. BulkBuf[21] = 'M';
  430. BulkBuf[22] = ' ';
  431. BulkBuf[23] = 'S';
  432. BulkBuf[24] = 'D';
  433. BulkBuf[25] = 'C';
  434. BulkBuf[26] = 'a';
  435. BulkBuf[27] = 'r';
  436. BulkBuf[28] = 'd';
  437. BulkBuf[29] = ' ';
  438. BulkBuf[30] = '0';
  439. BulkBuf[31] = '1';
  440. BulkBuf[32] = '1'; /* Product Revision Level */
  441. BulkBuf[33] = '.';
  442. BulkBuf[34] = '0';
  443. BulkBuf[35] = ' ';
  444. BulkLen = 36;
  445. DataInTransfer();
  446. }
  447. /*
  448. * MSC SCSI Mode Sense (6-Byte) Callback
  449. * Parameters: None (global variables)
  450. * Return Value: None
  451. */
  452. void MSC_ModeSense6 (void) {
  453. if (!DataInFormat()) return;
  454. BulkBuf[ 0] = 0x03;
  455. BulkBuf[ 1] = 0x00;
  456. BulkBuf[ 2] = 0x00;
  457. BulkBuf[ 3] = 0x00;
  458. BulkLen = 4;
  459. DataInTransfer();
  460. }
  461. /*
  462. * MSC SCSI Mode Sense (10-Byte) Callback
  463. * Parameters: None (global variables)
  464. * Return Value: None
  465. */
  466. void MSC_ModeSense10 (void) {
  467. if (!DataInFormat()) return;
  468. BulkBuf[ 0] = 0x00;
  469. BulkBuf[ 1] = 0x06;
  470. BulkBuf[ 2] = 0x00;
  471. BulkBuf[ 3] = 0x00;
  472. BulkBuf[ 4] = 0x00;
  473. BulkBuf[ 5] = 0x00;
  474. BulkBuf[ 6] = 0x00;
  475. BulkBuf[ 7] = 0x00;
  476. BulkLen = 8;
  477. DataInTransfer();
  478. }
  479. /*
  480. * MSC SCSI Read Capacity Callback
  481. * Parameters: None (global variables)
  482. * Return Value: None
  483. */
  484. void MSC_ReadCapacity (void) {
  485. if (!DataInFormat()) return;
  486. /* Last Logical Block */
  487. BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;
  488. BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;
  489. BulkBuf[ 2] = ((MSC_BlockCount - 1) >> 8) & 0xFF;
  490. BulkBuf[ 3] = ((MSC_BlockCount - 1) >> 0) & 0xFF;
  491. /* Block Length */
  492. BulkBuf[ 4] = (MSC_BLOCK_SIZE >> 24) & 0xFF;
  493. BulkBuf[ 5] = (MSC_BLOCK_SIZE >> 16) & 0xFF;
  494. BulkBuf[ 6] = (MSC_BLOCK_SIZE >> 8) & 0xFF;
  495. BulkBuf[ 7] = (MSC_BLOCK_SIZE >> 0) & 0xFF;
  496. BulkLen = 8;
  497. DataInTransfer();
  498. }
  499. /*
  500. * MSC SCSI Read Format Capacity Callback
  501. * Parameters: None (global variables)
  502. * Return Value: None
  503. */
  504. void MSC_ReadFormatCapacity (void) {
  505. if (!DataInFormat()) return;
  506. BulkBuf[ 0] = 0x00;
  507. BulkBuf[ 1] = 0x00;
  508. BulkBuf[ 2] = 0x00;
  509. BulkBuf[ 3] = 0x08; /* Capacity List Length */
  510. /* Block Count */
  511. BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF;
  512. BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF;
  513. BulkBuf[ 6] = (MSC_BlockCount >> 8) & 0xFF;
  514. BulkBuf[ 7] = (MSC_BlockCount >> 0) & 0xFF;
  515. /* Block Length */
  516. BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */
  517. BulkBuf[ 9] = (MSC_BLOCK_SIZE >> 16) & 0xFF;
  518. BulkBuf[10] = (MSC_BLOCK_SIZE >> 8) & 0xFF;
  519. BulkBuf[11] = (MSC_BLOCK_SIZE >> 0) & 0xFF;
  520. BulkLen = 12;
  521. DataInTransfer();
  522. }
  523. /*
  524. * MSC Get Command Block Wrapper Callback
  525. * Parameters: None (global variables)
  526. * Return Value: None
  527. */
  528. void MSC_GetCBW (void) {
  529. uint32_t n;
  530. for (n = 0; n < BulkLen; n++) {
  531. *((uint8_t *)&CBW + n) = BulkBuf[n];
  532. }
  533. if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) {
  534. /* Valid CBW */
  535. CSW.dTag = CBW.dTag;
  536. CSW.dDataResidue = CBW.dDataLength;
  537. if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) {
  538. fail: CSW.bStatus = CSW_CMD_FAILED;
  539. sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
  540. MSC_SetCSW();
  541. _DBG("Unsupported SCSI OP code ");
  542. _DBH(CBW.CB[0]);
  543. _DBG("\n");
  544. } else {
  545. switch (CBW.CB[0]) {
  546. case SCSI_TEST_UNIT_READY:
  547. MSC_TestUnitReady();
  548. break;
  549. case SCSI_REQUEST_SENSE:
  550. MSC_RequestSense();
  551. break;
  552. case SCSI_FORMAT_UNIT:
  553. goto fail;
  554. case SCSI_INQUIRY:
  555. MSC_Inquiry();
  556. break;
  557. case SCSI_START_STOP_UNIT:
  558. MSC_StartStopUnit();
  559. break;
  560. case SCSI_MEDIA_REMOVAL:
  561. MSC_SD_Lock();
  562. break;
  563. case SCSI_MODE_SELECT6:
  564. goto fail;
  565. case SCSI_MODE_SENSE6:
  566. MSC_ModeSense6();
  567. break;
  568. case SCSI_MODE_SELECT10:
  569. goto fail;
  570. case SCSI_MODE_SENSE10:
  571. MSC_ModeSense10();
  572. break;
  573. case SCSI_READ_FORMAT_CAPACITIES:
  574. MSC_ReadFormatCapacity();
  575. break;
  576. case SCSI_READ_CAPACITY:
  577. MSC_ReadCapacity();
  578. break;
  579. case SCSI_READ10:
  580. if (MSC_RWSetup()) {
  581. if ((CBW.bmFlags & 0x80) != 0) {
  582. BulkStage = MSC_BS_DATA_IN;
  583. MSC_MemoryRead();
  584. } else {
  585. USB_SetStallEP(MSC_EP_OUT);
  586. CSW.bStatus = CSW_PHASE_ERROR;
  587. MSC_SetCSW();
  588. }
  589. }
  590. break;
  591. case SCSI_WRITE10:
  592. if (MSC_RWSetup()) {
  593. if ((CBW.bmFlags & 0x80) == 0) {
  594. BulkStage = MSC_BS_DATA_OUT;
  595. } else {
  596. USB_SetStallEP(MSC_EP_IN);
  597. CSW.bStatus = CSW_PHASE_ERROR;
  598. MSC_SetCSW();
  599. }
  600. }
  601. break;
  602. case SCSI_VERIFY10:
  603. if (MSC_RWSetup()) {
  604. if ((CBW.bmFlags & 0x80) == 0) {
  605. BulkStage = MSC_BS_DATA_OUT;
  606. MemOK = TRUE;
  607. } else {
  608. USB_SetStallEP(MSC_EP_IN);
  609. CSW.bStatus = CSW_PHASE_ERROR;
  610. MSC_SetCSW();
  611. }
  612. }
  613. break;
  614. case 0x35: // SCSI_SYNCHRONIZECACHE10
  615. _DBG("SCSI_SYNCHRONIZECACHE10 Unsupported\n");
  616. CSW.bStatus = CSW_CMD_FAILED;
  617. sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
  618. MSC_SetCSW();
  619. break;
  620. case 0x9E: // SCSI_SERVICEACTIONIN16
  621. _DBG("ServiceAction(16) Action: ");
  622. _DBH(CBW.CB[1]);
  623. _DBG(" Unsupported\n");
  624. CSW.bStatus = CSW_CMD_FAILED;
  625. sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
  626. MSC_SetCSW();
  627. break;
  628. default:
  629. goto fail;
  630. }
  631. }
  632. } else {
  633. /* Invalid CBW */
  634. USB_SetStallEP(MSC_EP_IN);
  635. USB_SetStallEP(MSC_EP_OUT);
  636. BulkStage = MSC_BS_ERROR;
  637. }
  638. }
  639. /*
  640. * MSC Set Command Status Wrapper Callback
  641. * Parameters: None (global variables)
  642. * Return Value: None
  643. */
  644. void MSC_SetCSW (void) {
  645. CSW.dSignature = MSC_CSW_Signature;
  646. USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
  647. BulkStage = MSC_BS_CSW;
  648. }
  649. /*
  650. * MSC Bulk In Callback
  651. * Parameters: None (global variables)
  652. * Return Value: None
  653. */
  654. void MSC_BulkIn (void) {
  655. switch (BulkStage) {
  656. case MSC_BS_DATA_IN:
  657. switch (CBW.CB[0]) {
  658. case SCSI_READ10:
  659. MSC_MemoryRead();
  660. break;
  661. }
  662. break;
  663. case MSC_BS_DATA_IN_LAST:
  664. MSC_SetCSW();
  665. break;
  666. case MSC_BS_DATA_IN_LAST_STALL:
  667. USB_SetStallEP(MSC_EP_IN);
  668. MSC_SetCSW();
  669. break;
  670. case MSC_BS_CSW:
  671. BulkStage = MSC_BS_CBW;
  672. break;
  673. }
  674. }
  675. /*
  676. * MSC Bulk Out Callback
  677. * Parameters: None (global variables)
  678. * Return Value: None
  679. */
  680. void MSC_BulkOut (void) {
  681. BulkLen = (uint8_t)USB_ReadEP(MSC_EP_OUT, BulkBuf);
  682. switch (BulkStage) {
  683. case MSC_BS_CBW:
  684. MSC_GetCBW();
  685. break;
  686. case MSC_BS_DATA_OUT:
  687. switch (CBW.CB[0]) {
  688. case SCSI_WRITE10:
  689. MSC_MemoryWrite();
  690. break;
  691. case SCSI_VERIFY10:
  692. MSC_MemoryVerify();
  693. break;
  694. }
  695. break;
  696. default:
  697. USB_SetStallEP(MSC_EP_OUT);
  698. CSW.bStatus = CSW_PHASE_ERROR;
  699. MSC_SetCSW();
  700. break;
  701. }
  702. }