mstorage.c 31 KB

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