mstorage.c 32 KB

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