mstorage.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2012-10-01 Yi Qiu first version
  9. * 2012-11-25 Heyuanjie87 reduce the memory consumption
  10. * 2012-12-09 Heyuanjie87 change function and endpoint handler
  11. * 2013-07-25 Yi Qiu update for USB CV test
  12. */
  13. #include <rtthread.h>
  14. #include "drivers/usb_device.h"
  15. #include "mstorage.h"
  16. #ifdef RT_USING_DFS_MNTTABLE
  17. #include "dfs_fs.h"
  18. #endif
  19. #ifdef RT_USB_DEVICE_MSTORAGE
  20. enum STAT
  21. {
  22. STAT_CBW,
  23. STAT_CMD,
  24. STAT_CSW,
  25. STAT_RECEIVE,
  26. STAT_SEND,
  27. };
  28. typedef enum
  29. {
  30. FIXED,
  31. COUNT,
  32. BLOCK_COUNT,
  33. }CB_SIZE_TYPE;
  34. typedef enum
  35. {
  36. DIR_IN,
  37. DIR_OUT,
  38. DIR_NONE,
  39. }CB_DIR;
  40. typedef rt_size_t (*cbw_handler)(ufunction_t func, ustorage_cbw_t cbw);
  41. struct scsi_cmd
  42. {
  43. rt_uint16_t cmd;
  44. cbw_handler handler;
  45. rt_size_t cmd_len;
  46. CB_SIZE_TYPE type;
  47. rt_size_t data_size;
  48. CB_DIR dir;
  49. };
  50. struct mstorage
  51. {
  52. struct ustorage_csw csw_response;
  53. uep_t ep_in;
  54. uep_t ep_out;
  55. int status;
  56. rt_uint32_t cb_data_size;
  57. rt_device_t disk;
  58. rt_uint32_t block;
  59. rt_int32_t count;
  60. rt_int32_t size;
  61. struct scsi_cmd* processing;
  62. struct rt_device_blk_geometry geometry;
  63. };
  64. ALIGN(4)
  65. static struct udevice_descriptor dev_desc =
  66. {
  67. USB_DESC_LENGTH_DEVICE, //bLength;
  68. USB_DESC_TYPE_DEVICE, //type;
  69. USB_BCD_VERSION, //bcdUSB;
  70. USB_CLASS_MASS_STORAGE, //bDeviceClass;
  71. 0x06, //bDeviceSubClass;
  72. 0x50, //bDeviceProtocol;
  73. 0x40, //bMaxPacketSize0;
  74. _VENDOR_ID, //idVendor;
  75. _PRODUCT_ID, //idProduct;
  76. USB_BCD_DEVICE, //bcdDevice;
  77. USB_STRING_MANU_INDEX, //iManufacturer;
  78. USB_STRING_PRODUCT_INDEX, //iProduct;
  79. USB_STRING_SERIAL_INDEX, //iSerialNumber;
  80. USB_DYNAMIC, //bNumConfigurations;
  81. };
  82. //FS and HS needed
  83. ALIGN(4)
  84. static struct usb_qualifier_descriptor dev_qualifier =
  85. {
  86. sizeof(dev_qualifier), //bLength
  87. USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
  88. 0x0200, //bcdUSB
  89. USB_CLASS_MASS_STORAGE, //bDeviceClass
  90. 0x06, //bDeviceSubClass
  91. 0x50, //bDeviceProtocol
  92. 64, //bMaxPacketSize0
  93. 0x01, //bNumConfigurations
  94. 0,
  95. };
  96. ALIGN(4)
  97. const static struct umass_descriptor _mass_desc =
  98. {
  99. #ifdef RT_USB_DEVICE_COMPOSITE
  100. /* Interface Association Descriptor */
  101. {
  102. USB_DESC_LENGTH_IAD,
  103. USB_DESC_TYPE_IAD,
  104. USB_DYNAMIC,
  105. 0x01,
  106. USB_CLASS_MASS_STORAGE,
  107. 0x06,
  108. 0x50,
  109. 0x00,
  110. },
  111. #endif
  112. {
  113. USB_DESC_LENGTH_INTERFACE, //bLength;
  114. USB_DESC_TYPE_INTERFACE, //type;
  115. USB_DYNAMIC, //bInterfaceNumber;
  116. 0x00, //bAlternateSetting;
  117. 0x02, //bNumEndpoints
  118. USB_CLASS_MASS_STORAGE, //bInterfaceClass;
  119. 0x06, //bInterfaceSubClass;
  120. 0x50, //bInterfaceProtocol;
  121. 0x00, //iInterface;
  122. },
  123. {
  124. USB_DESC_LENGTH_ENDPOINT, //bLength;
  125. USB_DESC_TYPE_ENDPOINT, //type;
  126. USB_DYNAMIC | USB_DIR_OUT, //bEndpointAddress;
  127. USB_EP_ATTR_BULK, //bmAttributes;
  128. USB_DYNAMIC, //wMaxPacketSize;
  129. 0x00, //bInterval;
  130. },
  131. {
  132. USB_DESC_LENGTH_ENDPOINT, //bLength;
  133. USB_DESC_TYPE_ENDPOINT, //type;
  134. USB_DYNAMIC | USB_DIR_IN, //bEndpointAddress;
  135. USB_EP_ATTR_BULK, //bmAttributes;
  136. USB_DYNAMIC, //wMaxPacketSize;
  137. 0x00, //bInterval;
  138. },
  139. };
  140. ALIGN(4)
  141. const static char* _ustring[] =
  142. {
  143. "Language",
  144. "RT-Thread Team.",
  145. "RTT Mass Storage",
  146. "320219198301",
  147. "Configuration",
  148. "Interface",
  149. };
  150. static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw);
  151. static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw);
  152. static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw);
  153. static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw);
  154. static rt_size_t _start_stop(ufunction_t func, ustorage_cbw_t cbw);
  155. static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw);
  156. static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw);
  157. static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw);
  158. static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw);
  159. static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw);
  160. static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw);
  161. ALIGN(4)
  162. static struct scsi_cmd cmd_data[] =
  163. {
  164. {SCSI_TEST_UNIT_READY, _test_unit_ready, 6, FIXED, 0, DIR_NONE},
  165. {SCSI_REQUEST_SENSE, _request_sense, 6, COUNT, 0, DIR_IN},
  166. {SCSI_INQUIRY_CMD, _inquiry_cmd, 6, COUNT, 0, DIR_IN},
  167. {SCSI_ALLOW_REMOVAL, _allow_removal, 6, FIXED, 0, DIR_NONE},
  168. {SCSI_MODE_SENSE_6, _mode_sense_6, 6, COUNT, 0, DIR_IN},
  169. {SCSI_START_STOP, _start_stop, 6, FIXED, 0, DIR_NONE},
  170. {SCSI_READ_CAPACITIES, _read_capacities, 10, COUNT, 0, DIR_NONE},
  171. {SCSI_READ_CAPACITY, _read_capacity, 10, FIXED, 8, DIR_IN},
  172. {SCSI_READ_10, _read_10, 10, BLOCK_COUNT, 0, DIR_IN},
  173. {SCSI_WRITE_10, _write_10, 10, BLOCK_COUNT, 0, DIR_OUT},
  174. {SCSI_VERIFY_10, _verify_10, 10, FIXED, 0, DIR_NONE},
  175. };
  176. static void _send_status(ufunction_t func)
  177. {
  178. struct mstorage *data;
  179. RT_ASSERT(func != RT_NULL);
  180. RT_DEBUG_LOG(RT_DEBUG_USB, ("_send_status\n"));
  181. data = (struct mstorage*)func->user_data;
  182. data->ep_in->request.buffer = (rt_uint8_t*)&data->csw_response;
  183. data->ep_in->request.size = SIZEOF_CSW;
  184. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  185. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  186. data->status = STAT_CSW;
  187. }
  188. static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw)
  189. {
  190. struct mstorage *data;
  191. RT_ASSERT(func != RT_NULL);
  192. RT_ASSERT(func->device != RT_NULL);
  193. RT_DEBUG_LOG(RT_DEBUG_USB, ("_test_unit_ready\n"));
  194. data = (struct mstorage*)func->user_data;
  195. data->csw_response.status = 0;
  196. return 0;
  197. }
  198. static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw)
  199. {
  200. struct mstorage *data;
  201. RT_ASSERT(func != RT_NULL);
  202. RT_ASSERT(func->device != RT_NULL);
  203. RT_DEBUG_LOG(RT_DEBUG_USB, ("_allow_removal\n"));
  204. data = (struct mstorage*)func->user_data;
  205. data->csw_response.status = 0;
  206. return 0;
  207. }
  208. /**
  209. * This function will handle inquiry command request.
  210. *
  211. * @param func the usb function object.
  212. * @param cbw the command block wrapper.
  213. *
  214. * @return RT_EOK on successful.
  215. */
  216. static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw)
  217. {
  218. struct mstorage *data;
  219. rt_uint8_t *buf;
  220. RT_ASSERT(func != RT_NULL);
  221. RT_ASSERT(func->device != RT_NULL);
  222. RT_ASSERT(cbw != RT_NULL);
  223. RT_DEBUG_LOG(RT_DEBUG_USB, ("_inquiry_cmd\n"));
  224. data = (struct mstorage*)func->user_data;
  225. buf = data->ep_in->buffer;
  226. *(rt_uint32_t*)&buf[0] = 0x0 | (0x80 << 8);
  227. *(rt_uint32_t*)&buf[4] = 31;
  228. rt_memset(&buf[8], 0x20, 28);
  229. rt_memcpy(&buf[8], "RTT", 3);
  230. rt_memcpy(&buf[16], "USB Disk", 8);
  231. data->cb_data_size = MIN(data->cb_data_size, SIZEOF_INQUIRY_CMD);
  232. data->ep_in->request.buffer = buf;
  233. data->ep_in->request.size = data->cb_data_size;
  234. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  235. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  236. data->status = STAT_CMD;
  237. return data->cb_data_size;
  238. }
  239. /**
  240. * This function will handle sense request.
  241. *
  242. * @param func the usb function object.
  243. * @param cbw the command block wrapper.
  244. *
  245. * @return RT_EOK on successful.
  246. */
  247. static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw)
  248. {
  249. struct mstorage *data;
  250. struct request_sense_data *buf;
  251. RT_ASSERT(func != RT_NULL);
  252. RT_ASSERT(func->device != RT_NULL);
  253. RT_ASSERT(cbw != RT_NULL);
  254. RT_DEBUG_LOG(RT_DEBUG_USB, ("_request_sense\n"));
  255. data = (struct mstorage*)func->user_data;
  256. buf = (struct request_sense_data *)data->ep_in->buffer;
  257. buf->ErrorCode = 0x70;
  258. buf->Valid = 0;
  259. buf->SenseKey = 2;
  260. buf->Information[0] = 0;
  261. buf->Information[1] = 0;
  262. buf->Information[2] = 0;
  263. buf->Information[3] = 0;
  264. buf->AdditionalSenseLength = 0x0a;
  265. buf->AdditionalSenseCode = 0x3a;
  266. buf->AdditionalSenseCodeQualifier = 0;
  267. data->cb_data_size = MIN(data->cb_data_size, SIZEOF_REQUEST_SENSE);
  268. data->ep_in->request.buffer = (rt_uint8_t*)data->ep_in->buffer;
  269. data->ep_in->request.size = data->cb_data_size;
  270. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  271. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  272. data->status = STAT_CMD;
  273. return data->cb_data_size;
  274. }
  275. /**
  276. * This function will handle mode_sense_6 request.
  277. *
  278. * @param func the usb function object.
  279. * @param cbw the command block wrapper.
  280. *
  281. * @return RT_EOK on successful.
  282. */
  283. static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw)
  284. {
  285. struct mstorage *data;
  286. rt_uint8_t *buf;
  287. RT_ASSERT(func != RT_NULL);
  288. RT_ASSERT(func->device != RT_NULL);
  289. RT_ASSERT(cbw != RT_NULL);
  290. RT_DEBUG_LOG(RT_DEBUG_USB, ("_mode_sense_6\n"));
  291. data = (struct mstorage*)func->user_data;
  292. buf = data->ep_in->buffer;
  293. buf[0] = 3;
  294. buf[1] = 0;
  295. buf[2] = 0;
  296. buf[3] = 0;
  297. data->cb_data_size = MIN(data->cb_data_size, SIZEOF_MODE_SENSE_6);
  298. data->ep_in->request.buffer = buf;
  299. data->ep_in->request.size = data->cb_data_size;
  300. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  301. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  302. data->status = STAT_CMD;
  303. return data->cb_data_size;
  304. }
  305. /**
  306. * This function will handle read_capacities request.
  307. *
  308. * @param func the usb function object.
  309. * @param cbw the command block wrapper.
  310. *
  311. * @return RT_EOK on successful.
  312. */
  313. static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw)
  314. {
  315. struct mstorage *data;
  316. rt_uint8_t *buf;
  317. rt_uint32_t sector_count, sector_size;
  318. RT_ASSERT(func != RT_NULL);
  319. RT_ASSERT(func->device != RT_NULL);
  320. RT_ASSERT(cbw != RT_NULL);
  321. RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacities\n"));
  322. data = (struct mstorage*)func->user_data;
  323. buf = data->ep_in->buffer;
  324. sector_count = data->geometry.sector_count;
  325. sector_size = data->geometry.bytes_per_sector;
  326. *(rt_uint32_t*)&buf[0] = 0x08000000;
  327. buf[4] = sector_count >> 24;
  328. buf[5] = 0xff & (sector_count >> 16);
  329. buf[6] = 0xff & (sector_count >> 8);
  330. buf[7] = 0xff & (sector_count);
  331. buf[8] = 0x02;
  332. buf[9] = 0xff & (sector_size >> 16);
  333. buf[10] = 0xff & (sector_size >> 8);
  334. buf[11] = 0xff & sector_size;
  335. data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITIES);
  336. data->ep_in->request.buffer = buf;
  337. data->ep_in->request.size = data->cb_data_size;
  338. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  339. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  340. data->status = STAT_CMD;
  341. return data->cb_data_size;
  342. }
  343. /**
  344. * This function will handle read_capacity request.
  345. *
  346. * @param func the usb function object.
  347. * @param cbw the command block wapper.
  348. *
  349. * @return RT_EOK on successful.
  350. */
  351. static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw)
  352. {
  353. struct mstorage *data;
  354. rt_uint8_t *buf;
  355. rt_uint32_t sector_count, sector_size;
  356. RT_ASSERT(func != RT_NULL);
  357. RT_ASSERT(func->device != RT_NULL);
  358. RT_ASSERT(cbw != RT_NULL);
  359. RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacity\n"));
  360. data = (struct mstorage*)func->user_data;
  361. buf = data->ep_in->buffer;
  362. sector_count = data->geometry.sector_count - 1; /* Last Logical Block Address */
  363. sector_size = data->geometry.bytes_per_sector;
  364. buf[0] = sector_count >> 24;
  365. buf[1] = 0xff & (sector_count >> 16);
  366. buf[2] = 0xff & (sector_count >> 8);
  367. buf[3] = 0xff & (sector_count);
  368. buf[4] = 0x0;
  369. buf[5] = 0xff & (sector_size >> 16);
  370. buf[6] = 0xff & (sector_size >> 8);
  371. buf[7] = 0xff & sector_size;
  372. data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITY);
  373. data->ep_in->request.buffer = buf;
  374. data->ep_in->request.size = data->cb_data_size;
  375. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  376. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  377. data->status = STAT_CMD;
  378. return data->cb_data_size;
  379. }
  380. /**
  381. * This function will handle read_10 request.
  382. *
  383. * @param func the usb function object.
  384. * @param cbw the command block wrapper.
  385. *
  386. * @return RT_EOK on successful.
  387. */
  388. static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw)
  389. {
  390. struct mstorage *data;
  391. rt_size_t size;
  392. RT_ASSERT(func != RT_NULL);
  393. RT_ASSERT(func->device != RT_NULL);
  394. RT_ASSERT(cbw != RT_NULL);
  395. data = (struct mstorage*)func->user_data;
  396. data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 |
  397. cbw->cb[5]<<0;
  398. data->count = cbw->cb[7]<<8 | cbw->cb[8]<<0;
  399. RT_ASSERT(data->count < data->geometry.sector_count);
  400. data->csw_response.data_reside = data->cb_data_size;
  401. size = rt_device_read(data->disk, data->block, data->ep_in->buffer, 1);
  402. if(size == 0)
  403. {
  404. rt_kprintf("read data error\n");
  405. }
  406. data->ep_in->request.buffer = data->ep_in->buffer;
  407. data->ep_in->request.size = data->geometry.bytes_per_sector;
  408. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  409. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  410. data->status = STAT_SEND;
  411. return data->geometry.bytes_per_sector;
  412. }
  413. /**
  414. * This function will handle write_10 request.
  415. *
  416. * @param func the usb function object.
  417. * @param cbw the command block wrapper.
  418. *
  419. * @return RT_EOK on successful.
  420. */
  421. static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw)
  422. {
  423. struct mstorage *data;
  424. RT_ASSERT(func != RT_NULL);
  425. RT_ASSERT(func->device != RT_NULL);
  426. RT_ASSERT(cbw != RT_NULL);
  427. data = (struct mstorage*)func->user_data;
  428. data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 |
  429. cbw->cb[5]<<0;
  430. data->count = cbw->cb[7]<<8 | cbw->cb[8];
  431. data->csw_response.data_reside = cbw->xfer_len;
  432. data->size = data->count * data->geometry.bytes_per_sector;
  433. RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x block 0x%x 0x%x\n",
  434. data->count, data->block, data->geometry.sector_count));
  435. data->csw_response.data_reside = data->cb_data_size;
  436. data->ep_out->request.buffer = data->ep_out->buffer;
  437. data->ep_out->request.size = data->geometry.bytes_per_sector;
  438. data->ep_out->request.req_type = UIO_REQUEST_READ_FULL;
  439. rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
  440. data->status = STAT_RECEIVE;
  441. return data->geometry.bytes_per_sector;
  442. }
  443. /**
  444. * This function will handle verify_10 request.
  445. *
  446. * @param func the usb function object.
  447. *
  448. * @return RT_EOK on successful.
  449. */
  450. static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw)
  451. {
  452. struct mstorage *data;
  453. RT_ASSERT(func != RT_NULL);
  454. RT_ASSERT(func->device != RT_NULL);
  455. RT_DEBUG_LOG(RT_DEBUG_USB, ("_verify_10\n"));
  456. data = (struct mstorage*)func->user_data;
  457. data->csw_response.status = 0;
  458. return 0;
  459. }
  460. static rt_size_t _start_stop(ufunction_t func,
  461. ustorage_cbw_t cbw)
  462. {
  463. struct mstorage *data;
  464. RT_ASSERT(func != RT_NULL);
  465. RT_ASSERT(func->device != RT_NULL);
  466. RT_DEBUG_LOG(RT_DEBUG_USB, ("_start_stop\n"));
  467. data = (struct mstorage*)func->user_data;
  468. data->csw_response.status = 0;
  469. return 0;
  470. }
  471. static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
  472. {
  473. struct mstorage *data;
  474. RT_ASSERT(func != RT_NULL);
  475. RT_ASSERT(func->device != RT_NULL);
  476. RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_in_handler\n"));
  477. data = (struct mstorage*)func->user_data;
  478. switch(data->status)
  479. {
  480. case STAT_CSW:
  481. if(data->ep_in->request.size != SIZEOF_CSW)
  482. {
  483. rt_kprintf("Size of csw command error\n");
  484. rt_usbd_ep_set_stall(func->device, data->ep_in);
  485. }
  486. else
  487. {
  488. RT_DEBUG_LOG(RT_DEBUG_USB, ("return to cbw status\n"));
  489. data->ep_out->request.buffer = data->ep_out->buffer;
  490. data->ep_out->request.size = SIZEOF_CBW;
  491. data->ep_out->request.req_type = UIO_REQUEST_READ_FULL;
  492. rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
  493. data->status = STAT_CBW;
  494. }
  495. break;
  496. case STAT_CMD:
  497. if(data->csw_response.data_reside == 0xFF)
  498. {
  499. data->csw_response.data_reside = 0;
  500. }
  501. else
  502. {
  503. data->csw_response.data_reside -= data->ep_in->request.size;
  504. if(data->csw_response.data_reside != 0)
  505. {
  506. RT_DEBUG_LOG(RT_DEBUG_USB, ("data_reside %d, request %d\n",
  507. data->csw_response.data_reside, data->ep_in->request.size));
  508. if(data->processing->dir == DIR_OUT)
  509. {
  510. rt_usbd_ep_set_stall(func->device, data->ep_out);
  511. }
  512. else
  513. {
  514. //rt_kprintf("warning:in stall path but not stall\n");
  515. /* FIXME: Disable the operation or the disk cannot work. */
  516. //rt_usbd_ep_set_stall(func->device, data->ep_in);
  517. }
  518. data->csw_response.data_reside = 0;
  519. }
  520. }
  521. _send_status(func);
  522. break;
  523. case STAT_SEND:
  524. data->csw_response.data_reside -= data->ep_in->request.size;
  525. data->count--;
  526. data->block++;
  527. if(data->count > 0 && data->csw_response.data_reside > 0)
  528. {
  529. if(rt_device_read(data->disk, data->block, data->ep_in->buffer, 1) == 0)
  530. {
  531. rt_kprintf("disk read error\n");
  532. rt_usbd_ep_set_stall(func->device, data->ep_in);
  533. return -RT_ERROR;
  534. }
  535. data->ep_in->request.buffer = data->ep_in->buffer;
  536. data->ep_in->request.size = data->geometry.bytes_per_sector;
  537. data->ep_in->request.req_type = UIO_REQUEST_WRITE;
  538. rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
  539. }
  540. else
  541. {
  542. _send_status(func);
  543. }
  544. break;
  545. }
  546. return RT_EOK;
  547. }
  548. #ifdef MASS_CBW_DUMP
  549. static void cbw_dump(struct ustorage_cbw* cbw)
  550. {
  551. RT_ASSERT(cbw != RT_NULL);
  552. RT_DEBUG_LOG(RT_DEBUG_USB, ("signature 0x%x\n", cbw->signature));
  553. RT_DEBUG_LOG(RT_DEBUG_USB, ("tag 0x%x\n", cbw->tag));
  554. RT_DEBUG_LOG(RT_DEBUG_USB, ("xfer_len 0x%x\n", cbw->xfer_len));
  555. RT_DEBUG_LOG(RT_DEBUG_USB, ("dflags 0x%x\n", cbw->dflags));
  556. RT_DEBUG_LOG(RT_DEBUG_USB, ("lun 0x%x\n", cbw->lun));
  557. RT_DEBUG_LOG(RT_DEBUG_USB, ("cb_len 0x%x\n", cbw->cb_len));
  558. RT_DEBUG_LOG(RT_DEBUG_USB, ("cb[0] 0x%x\n", cbw->cb[0]));
  559. }
  560. #endif
  561. static struct scsi_cmd* _find_cbw_command(rt_uint16_t cmd)
  562. {
  563. int i;
  564. for(i=0; i<sizeof(cmd_data)/sizeof(struct scsi_cmd); i++)
  565. {
  566. if(cmd_data[i].cmd == cmd)
  567. return &cmd_data[i];
  568. }
  569. return RT_NULL;
  570. }
  571. static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd,
  572. ustorage_cbw_t cbw)
  573. {
  574. struct mstorage *data;
  575. RT_ASSERT(func != RT_NULL);
  576. RT_ASSERT(cmd != RT_NULL);
  577. RT_ASSERT(cbw != RT_NULL);
  578. data = (struct mstorage*)func->user_data;
  579. if(cmd->cmd_len == 6)
  580. {
  581. switch(cmd->type)
  582. {
  583. case COUNT:
  584. data->cb_data_size = cbw->cb[4];
  585. break;
  586. case BLOCK_COUNT:
  587. data->cb_data_size = cbw->cb[4] * data->geometry.bytes_per_sector;
  588. break;
  589. case FIXED:
  590. data->cb_data_size = cmd->data_size;
  591. break;
  592. default:
  593. break;
  594. }
  595. }
  596. else if(cmd->cmd_len == 10)
  597. {
  598. switch(cmd->type)
  599. {
  600. case COUNT:
  601. data->cb_data_size = cbw->cb[7]<<8 | cbw->cb[8];
  602. break;
  603. case BLOCK_COUNT:
  604. data->cb_data_size = (cbw->cb[7]<<8 | cbw->cb[8]) *
  605. data->geometry.bytes_per_sector;
  606. break;
  607. case FIXED:
  608. data->cb_data_size = cmd->data_size;
  609. break;
  610. default:
  611. break;
  612. }
  613. }
  614. //workaround: for stability in full-speed mode
  615. else if(cmd->cmd_len == 12)
  616. {
  617. switch(cmd->type)
  618. {
  619. case COUNT:
  620. data->cb_data_size = cbw->cb[4];
  621. break;
  622. default:
  623. break;
  624. }
  625. }
  626. else
  627. {
  628. rt_kprintf("cmd_len error %d\n", cmd->cmd_len);
  629. }
  630. }
  631. static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd,
  632. ustorage_cbw_t cbw)
  633. {
  634. struct mstorage *data;
  635. RT_ASSERT(cmd != RT_NULL);
  636. RT_ASSERT(cbw != RT_NULL);
  637. RT_ASSERT(func != RT_NULL);
  638. data = (struct mstorage*)func->user_data;
  639. if(cmd->cmd_len != cbw->cb_len)
  640. {
  641. rt_kprintf("cb_len error\n");
  642. cmd->cmd_len = cbw->cb_len;
  643. }
  644. if(cbw->xfer_len > 0 && data->cb_data_size == 0)
  645. {
  646. rt_kprintf("xfer_len > 0 && data_size == 0\n");
  647. return RT_FALSE;
  648. }
  649. if(cbw->xfer_len == 0 && data->cb_data_size > 0)
  650. {
  651. rt_kprintf("xfer_len == 0 && data_size > 0");
  652. return RT_FALSE;
  653. }
  654. if(((cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_OUT)) ||
  655. (!(cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_IN)))
  656. {
  657. rt_kprintf("dir error\n");
  658. return RT_FALSE;
  659. }
  660. if(cbw->xfer_len > data->cb_data_size)
  661. {
  662. rt_kprintf("xfer_len > data_size\n");
  663. return RT_FALSE;
  664. }
  665. if(cbw->xfer_len < data->cb_data_size)
  666. {
  667. rt_kprintf("xfer_len < data_size\n");
  668. data->cb_data_size = cbw->xfer_len;
  669. data->csw_response.status = 1;
  670. }
  671. return RT_TRUE;
  672. }
  673. static rt_size_t _cbw_handler(ufunction_t func, struct scsi_cmd* cmd,
  674. ustorage_cbw_t cbw)
  675. {
  676. struct mstorage *data;
  677. RT_ASSERT(func != RT_NULL);
  678. RT_ASSERT(cbw != RT_NULL);
  679. RT_ASSERT(cmd->handler != RT_NULL);
  680. data = (struct mstorage*)func->user_data;
  681. data->processing = cmd;
  682. return cmd->handler(func, cbw);
  683. }
  684. /**
  685. * This function will handle mass storage bulk out endpoint request.
  686. *
  687. * @param func the usb function object.
  688. * @param size request size.
  689. *
  690. * @return RT_EOK.
  691. */
  692. static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
  693. {
  694. struct mstorage *data;
  695. struct scsi_cmd* cmd;
  696. rt_size_t len;
  697. struct ustorage_cbw* cbw;
  698. RT_ASSERT(func != RT_NULL);
  699. RT_ASSERT(func->device != RT_NULL);
  700. RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_out_handler %d\n", size));
  701. data = (struct mstorage*)func->user_data;
  702. cbw = (struct ustorage_cbw*)data->ep_out->buffer;
  703. if(data->status == STAT_CBW)
  704. {
  705. /* dump cbw information */
  706. if(cbw->signature != CBW_SIGNATURE || size != SIZEOF_CBW)
  707. {
  708. goto exit;
  709. }
  710. data->csw_response.signature = CSW_SIGNATURE;
  711. data->csw_response.tag = cbw->tag;
  712. data->csw_response.data_reside = cbw->xfer_len;
  713. data->csw_response.status = 0;
  714. RT_DEBUG_LOG(RT_DEBUG_USB, ("ep_out reside %d\n", data->csw_response.data_reside));
  715. cmd = _find_cbw_command(cbw->cb[0]);
  716. if(cmd == RT_NULL)
  717. {
  718. rt_kprintf("can't find cbw command\n");
  719. goto exit;
  720. }
  721. _cb_len_calc(func, cmd, cbw);
  722. if(!_cbw_verify(func, cmd, cbw))
  723. {
  724. goto exit;
  725. }
  726. len = _cbw_handler(func, cmd, cbw);
  727. if(len == 0)
  728. {
  729. _send_status(func);
  730. }
  731. return RT_EOK;
  732. }
  733. else if(data->status == STAT_RECEIVE)
  734. {
  735. RT_DEBUG_LOG(RT_DEBUG_USB, ("\nwrite size %d block 0x%x oount 0x%x\n",
  736. size, data->block, data->size));
  737. data->size -= size;
  738. data->csw_response.data_reside -= size;
  739. rt_device_write(data->disk, data->block, data->ep_out->buffer, 1);
  740. if(data->csw_response.data_reside != 0)
  741. {
  742. data->ep_out->request.buffer = data->ep_out->buffer;
  743. data->ep_out->request.size = data->geometry.bytes_per_sector;
  744. data->ep_out->request.req_type = UIO_REQUEST_READ_FULL;
  745. rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
  746. data->block ++;
  747. }
  748. else
  749. {
  750. _send_status(func);
  751. }
  752. return RT_EOK;
  753. }
  754. exit:
  755. if(data->csw_response.data_reside)
  756. {
  757. if(cbw->dflags & USB_DIR_IN)
  758. {
  759. rt_usbd_ep_set_stall(func->device, data->ep_in);
  760. }
  761. else
  762. {
  763. rt_usbd_ep_set_stall(func->device, data->ep_in);
  764. rt_usbd_ep_set_stall(func->device, data->ep_out);
  765. }
  766. }
  767. data->csw_response.status = 1;
  768. _send_status(func);
  769. return -RT_ERROR;
  770. }
  771. /**
  772. * This function will handle mass storage interface request.
  773. *
  774. * @param func the usb function object.
  775. * @param setup the setup request.
  776. *
  777. * @return RT_EOK on successful.
  778. */
  779. static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
  780. {
  781. rt_uint8_t lun = 0;
  782. RT_ASSERT(func != RT_NULL);
  783. RT_ASSERT(func->device != RT_NULL);
  784. RT_ASSERT(setup != RT_NULL);
  785. RT_DEBUG_LOG(RT_DEBUG_USB, ("mstorage_interface_handler\n"));
  786. switch(setup->bRequest)
  787. {
  788. case USBREQ_GET_MAX_LUN:
  789. RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_GET_MAX_LUN\n"));
  790. if(setup->wValue || setup->wLength != 1)
  791. {
  792. rt_usbd_ep0_set_stall(func->device);
  793. }
  794. else
  795. {
  796. rt_usbd_ep0_write(func->device, &lun, setup->wLength);
  797. }
  798. break;
  799. case USBREQ_MASS_STORAGE_RESET:
  800. RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_MASS_STORAGE_RESET\n"));
  801. if(setup->wValue || setup->wLength != 0)
  802. {
  803. rt_usbd_ep0_set_stall(func->device);
  804. }
  805. else
  806. {
  807. dcd_ep0_send_status(func->device->dcd);
  808. }
  809. break;
  810. default:
  811. rt_kprintf("unknown interface request\n");
  812. break;
  813. }
  814. return RT_EOK;
  815. }
  816. /**
  817. * This function will run mass storage function, it will be called on handle set configuration request.
  818. *
  819. * @param func the usb function object.
  820. *
  821. * @return RT_EOK on successful.
  822. */
  823. static rt_err_t _function_enable(ufunction_t func)
  824. {
  825. struct mstorage *data;
  826. RT_ASSERT(func != RT_NULL);
  827. RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function enabled\n"));
  828. data = (struct mstorage*)func->user_data;
  829. data->disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME);
  830. if(data->disk == RT_NULL)
  831. {
  832. rt_kprintf("no data->disk named %s\n", RT_USB_MSTORAGE_DISK_NAME);
  833. return -RT_ERROR;
  834. }
  835. #ifdef RT_USING_DFS_MNTTABLE
  836. dfs_unmount_device(data->disk);
  837. #endif
  838. if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
  839. {
  840. rt_kprintf("disk open error\n");
  841. return -RT_ERROR;
  842. }
  843. if(rt_device_control(data->disk, RT_DEVICE_CTRL_BLK_GETGEOME,
  844. (void*)&data->geometry) != RT_EOK)
  845. {
  846. rt_kprintf("get disk info error\n");
  847. return -RT_ERROR;
  848. }
  849. data->ep_in->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector);
  850. if(data->ep_in->buffer == RT_NULL)
  851. {
  852. rt_kprintf("no memory\n");
  853. return -RT_ENOMEM;
  854. }
  855. data->ep_out->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector);
  856. if(data->ep_out->buffer == RT_NULL)
  857. {
  858. rt_free(data->ep_in->buffer);
  859. rt_kprintf("no memory\n");
  860. return -RT_ENOMEM;
  861. }
  862. /* prepare to read CBW request */
  863. data->ep_out->request.buffer = data->ep_out->buffer;
  864. data->ep_out->request.size = SIZEOF_CBW;
  865. data->ep_out->request.req_type = UIO_REQUEST_READ_FULL;
  866. rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
  867. return RT_EOK;
  868. }
  869. /**
  870. * This function will stop mass storage function, it will be called on handle set configuration request.
  871. *
  872. * @param device the usb device object.
  873. *
  874. * @return RT_EOK on successful.
  875. */
  876. static rt_err_t _function_disable(ufunction_t func)
  877. {
  878. struct mstorage *data;
  879. RT_ASSERT(func != RT_NULL);
  880. RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function disabled\n"));
  881. data = (struct mstorage*)func->user_data;
  882. if(data->ep_in->buffer != RT_NULL)
  883. {
  884. rt_free(data->ep_in->buffer);
  885. data->ep_in->buffer = RT_NULL;
  886. }
  887. if(data->ep_out->buffer != RT_NULL)
  888. {
  889. rt_free(data->ep_out->buffer);
  890. data->ep_out->buffer = RT_NULL;
  891. }
  892. if(data->disk != RT_NULL)
  893. {
  894. rt_device_close(data->disk);
  895. #ifdef RT_USING_DFS_MNTTABLE
  896. dfs_mount_device(data->disk);
  897. #endif
  898. data->disk = RT_NULL;
  899. }
  900. data->status = STAT_CBW;
  901. return RT_EOK;
  902. }
  903. static struct ufunction_ops ops =
  904. {
  905. _function_enable,
  906. _function_disable,
  907. RT_NULL,
  908. };
  909. static rt_err_t _mstorage_descriptor_config(umass_desc_t desc, rt_uint8_t cintf_nr, rt_uint8_t device_is_hs)
  910. {
  911. #ifdef RT_USB_DEVICE_COMPOSITE
  912. desc->iad_desc.bFirstInterface = cintf_nr;
  913. #endif
  914. desc->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
  915. desc->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
  916. return RT_EOK;
  917. }
  918. /**
  919. * This function will create a mass storage function instance.
  920. *
  921. * @param device the usb device object.
  922. *
  923. * @return RT_EOK on successful.
  924. */
  925. ufunction_t rt_usbd_function_mstorage_create(udevice_t device)
  926. {
  927. uintf_t intf;
  928. struct mstorage *data;
  929. ufunction_t func;
  930. ualtsetting_t setting;
  931. umass_desc_t mass_desc;
  932. /* parameter check */
  933. RT_ASSERT(device != RT_NULL);
  934. /* set usb device string description */
  935. rt_usbd_device_set_string(device, _ustring);
  936. /* create a mass storage function */
  937. func = rt_usbd_function_new(device, &dev_desc, &ops);
  938. device->dev_qualifier = &dev_qualifier;
  939. /* allocate memory for mass storage function data */
  940. data = (struct mstorage*)rt_malloc(sizeof(struct mstorage));
  941. rt_memset(data, 0, sizeof(struct mstorage));
  942. func->user_data = (void*)data;
  943. /* create an interface object */
  944. intf = rt_usbd_interface_new(device, _interface_handler);
  945. /* create an alternate setting object */
  946. setting = rt_usbd_altsetting_new(sizeof(struct umass_descriptor));
  947. /* config desc in alternate setting */
  948. rt_usbd_altsetting_config_descriptor(setting, &_mass_desc, (rt_off_t)&((umass_desc_t)0)->intf_desc);
  949. /* configure the msc interface descriptor */
  950. _mstorage_descriptor_config(setting->desc, intf->intf_num, device->dcd->device_is_hs);
  951. /* create a bulk out and a bulk in endpoint */
  952. mass_desc = (umass_desc_t)setting->desc;
  953. data->ep_in = rt_usbd_endpoint_new(&mass_desc->ep_in_desc, _ep_in_handler);
  954. data->ep_out = rt_usbd_endpoint_new(&mass_desc->ep_out_desc, _ep_out_handler);
  955. /* add the bulk out and bulk in endpoint to the alternate setting */
  956. rt_usbd_altsetting_add_endpoint(setting, data->ep_out);
  957. rt_usbd_altsetting_add_endpoint(setting, data->ep_in);
  958. /* add the alternate setting to the interface, then set default setting */
  959. rt_usbd_interface_add_altsetting(intf, setting);
  960. rt_usbd_set_altsetting(intf, 0);
  961. /* add the interface to the mass storage function */
  962. rt_usbd_function_add_interface(func, intf);
  963. return func;
  964. }
  965. struct udclass msc_class =
  966. {
  967. .rt_usbd_function_create = rt_usbd_function_mstorage_create
  968. };
  969. int rt_usbd_msc_class_register(void)
  970. {
  971. rt_usbd_class_register(&msc_class);
  972. return 0;
  973. }
  974. INIT_PREV_EXPORT(rt_usbd_msc_class_register);
  975. #endif