mstorage.c 32 KB

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