mstorage.c 31 KB

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