mstorage.c 31 KB

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