ark_dwc2.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. #include "usb_os_adapter.h"
  2. #include "trace.h"
  3. #include <asm/dma-mapping.h>
  4. #include <linux/usb/ch9.h>
  5. #include <linux/usb/gadget.h>
  6. #include "core.h"
  7. #include "hcd.h"
  8. #include "ark_dwc2.h"
  9. #include "semphr.h"
  10. #include "timers.h"
  11. #include "usbroothubdes.h"
  12. #include "sysctl.h"
  13. #include "board.h"
  14. struct dwc2_host_data {
  15. struct dwc2_hsotg *host;
  16. struct usb_hcd hcd;
  17. enum usb_device_speed host_speed;
  18. int root_hub_devnum;
  19. struct usb_host_endpoint hep_in[16];
  20. struct usb_host_endpoint hep_out[16];
  21. struct hc_driver *dw2_hc_driver;
  22. List_t free_urb_list;
  23. spinlock_t lock;
  24. };
  25. struct urb_user_ctx {
  26. struct usb_device* dev;
  27. struct usb_host_endpoint *hep;
  28. unsigned long pipe;
  29. void *buffer;
  30. int length;
  31. int num_iso_packets;
  32. int interval;
  33. int alloc_flag;
  34. };
  35. int dwc2_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
  36. int dwc2_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
  37. extern int dwc2_driver_init(struct dwc2_hsotg **dev, struct usb_hcd *hcd);
  38. extern int dwc2_driver_uninit(struct dwc2_hsotg *hsotg);
  39. extern struct hc_driver* dwc2_get_driver();
  40. static int dwc_otg_submit_rh_msg(struct usb_device *dev,
  41. unsigned long pipe, void *buffer, int txlen,
  42. struct devrequest *cmd);
  43. struct dwc2_host_data dwc2_host;
  44. struct urb_user_ctx urb_user_handle[8];
  45. void *alloc_urb_user_ctx()
  46. {
  47. int i;
  48. struct urb_user_ctx* handle = NULL;
  49. for (i = 0; i < 8; i++) {
  50. handle = &urb_user_handle[i];
  51. if (handle->alloc_flag == 0) {
  52. handle->alloc_flag = 1;
  53. break;
  54. }
  55. }
  56. return handle;
  57. }
  58. void free_urb_user_ctx(void *ctx)
  59. {
  60. struct urb_user_ctx* handle = (struct urb_user_ctx*)ctx;
  61. handle->alloc_flag = 0;
  62. }
  63. static void dwc2_host_complete_urb(struct urb *urb)
  64. {
  65. if (urb->status != 0) {
  66. printf("#urb transfer err:%d\r\n", urb->status);
  67. }
  68. urb->dev->status &= ~USB_ST_NOT_PROC;
  69. urb->dev->act_len = urb->actual_length;
  70. //printf("actual_length:%d\r\n", urb->actual_length);
  71. xQueueSendFromISR((QueueHandle_t)urb->queueHandle, NULL, 0);
  72. }
  73. static void usb_urb_release(struct urb *urb)
  74. {
  75. if (NULL == urb)
  76. return;
  77. spin_lock(&dwc2_host.lock);
  78. list_add_tail(&urb->urb_list, &dwc2_host.free_urb_list);
  79. spin_unlock(&dwc2_host.lock);
  80. }
  81. static struct urb *usb_urb_alloc(struct dwc2_host_data *ctx,
  82. int iso_desc_count,
  83. gfp_t mem_flags)
  84. {
  85. struct urb *urb = NULL;
  86. QueueHandle_t complete;
  87. u32 size = sizeof(*urb) + iso_desc_count *
  88. sizeof(struct usb_iso_packet_descriptor);
  89. ListItem_t *pxListItem = NULL;
  90. int found = 0, flags;
  91. spin_lock_irqsave(&ctx->lock, flags);
  92. list_for_each_entry(pxListItem, urb, &ctx->free_urb_list) {
  93. if (urb->number_of_packets == iso_desc_count) {
  94. found = 1;
  95. break;
  96. }
  97. }
  98. if (found) {
  99. void *queueHandle = urb->queueHandle;
  100. list_del_init(&urb->urb_list);
  101. spin_unlock_irqrestore(&ctx->lock, flags);
  102. memset(urb, 0, sizeof(struct urb));
  103. urb->number_of_packets = iso_desc_count;
  104. INIT_LIST_ITEM(&urb->urb_list);
  105. listSET_LIST_ITEM_OWNER(&urb->urb_list, urb);
  106. urb->queueHandle = queueHandle;
  107. xQueueReset(urb->queueHandle);
  108. return urb;
  109. }
  110. spin_unlock_irqrestore(&ctx->lock, flags);
  111. urb = (struct urb *)kzalloc(size, mem_flags);
  112. if (urb) {
  113. urb->number_of_packets = iso_desc_count;
  114. INIT_LIST_ITEM(&urb->urb_list);
  115. listSET_LIST_ITEM_OWNER(&urb->urb_list, urb);
  116. complete = xQueueCreate(1, 0);
  117. urb->queueHandle = complete;
  118. }
  119. return urb;
  120. }
  121. static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep,
  122. struct usb_device *dev, int endpoint_type,
  123. unsigned long pipe, void *buffer, int len,
  124. struct devrequest *setup, int interval)
  125. {
  126. int epnum = usb_pipeendpoint(pipe);
  127. int is_in = usb_pipein(pipe);
  128. INIT_LIST_HEAD(&hep->urb_list);
  129. #ifndef NO_GNU
  130. INIT_LIST_HEAD(&urb->urb_list);
  131. #else
  132. INIT_LIST_ITEM(&urb->urb_list);
  133. urb->urb_list.pvOwner = (void *)urb;
  134. #endif
  135. urb->ep = hep;
  136. urb->complete = dwc2_host_complete_urb;
  137. urb->status = -EINPROGRESS;
  138. urb->dev = dev;
  139. urb->pipe = pipe;
  140. urb->transfer_buffer = buffer;
  141. urb->transfer_dma = (dma_addr_t)buffer;
  142. urb->transfer_buffer_length = len;
  143. urb->setup_packet = (unsigned char *)setup;
  144. urb->setup_dma = (dma_addr_t)setup;
  145. urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |
  146. URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |
  147. URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
  148. URB_DMA_SG_COMBINED);
  149. urb->transfer_flags |= (is_in ? URB_DIR_IN : URB_DIR_OUT);
  150. urb->ep->desc.wMaxPacketSize =
  151. __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
  152. dev->epmaxpacketout[epnum]);
  153. urb->ep->desc.bmAttributes = endpoint_type;
  154. urb->ep->desc.bEndpointAddress =
  155. (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
  156. urb->ep->desc.bInterval = interval;
  157. }
  158. static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
  159. {
  160. int ret;
  161. ret = dwc2_urb_enqueue(hcd, urb, 0);
  162. if (ret < 0) {
  163. printf("Failed to enqueue URB to controller ret=%d \r\n", ret);
  164. return ret;
  165. }
  166. return ret;
  167. }
  168. static int _dwc2_submit_control_msg(struct dwc2_host_data *host,
  169. struct usb_device *dev, unsigned long pipe,
  170. void *buffer, int len, struct devrequest *setup, int timeout)
  171. {
  172. struct urb *urb = NULL;
  173. struct usb_host_endpoint *hep = NULL;
  174. int epnum = usb_pipeendpoint(pipe);
  175. int is_in = usb_pipein(pipe);
  176. int ret = 0;
  177. if (epnum > 8 || epnum < 0)
  178. return -EINVAL;
  179. if (is_in) {
  180. hep = &host->hep_in[epnum];
  181. } else {
  182. hep = &host->hep_out[epnum];
  183. }
  184. urb = usb_urb_alloc(host, 0, IRQ_NONE);
  185. if (urb == NULL)
  186. return -ENOMEM;
  187. construct_urb(urb, hep, dev, USB_ENDPOINT_XFER_CONTROL,
  188. pipe, buffer, len, setup, 0);
  189. /* Fix speed for non hub-attached devices */
  190. if (!usb_dev_get_parent(dev))
  191. dev->speed = host->host_speed;
  192. //unsigned char *a = urb->setup_packet;
  193. //if (a)
  194. //printf("setup-->%02x %02x %02x %02x %02x %02x %02x %02x\r\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
  195. ret = submit_urb(&host->hcd, urb);
  196. if (ret < 0) {
  197. printf("%s:%d\r\n", __func__, __LINE__);
  198. //dwc2_urb_dequeue(&host->hcd, urb, 0);
  199. //printf("%s:%d\r\n", __func__, __LINE__);
  200. goto exit;
  201. }
  202. ret = xQueueReceive((QueueHandle_t)urb->queueHandle, NULL, timeout);
  203. if (ret != pdTRUE || 0 != urb->status) {//timeout
  204. printf("%s:%d\r\n", __func__, __LINE__);
  205. ret = urb->status;
  206. dwc2_urb_dequeue(&host->hcd, urb, 0);
  207. printf("%s:%d\r\n", __func__, __LINE__);
  208. if (0 != urb->status)
  209. printf("usb control urb error:%d\r\n", urb->status);
  210. } else {
  211. ret = urb->actual_length;
  212. }
  213. exit:
  214. usb_urb_release(urb);
  215. return ret;
  216. }
  217. int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int *actual_length, int timeout)
  218. {
  219. struct urb *urb = NULL;
  220. struct usb_host_endpoint *hep = NULL;
  221. int epnum = usb_pipeendpoint(pipe);
  222. int is_in = usb_pipein(pipe);
  223. int ret = 0;
  224. struct dwc2_host_data *host = &dwc2_host;
  225. if (epnum > 8 || epnum < 0)
  226. return -EINVAL;
  227. if (is_in) {
  228. hep = &host->hep_in[epnum];
  229. } else {
  230. hep = &host->hep_out[epnum];
  231. }
  232. urb = usb_urb_alloc(host, 0, IRQ_NONE);
  233. if (urb == NULL)
  234. return -ENOMEM;
  235. construct_urb(urb, hep, dev, USB_ENDPOINT_XFER_BULK,
  236. pipe, buffer, transfer_len, NULL, 0);
  237. ret = submit_urb(&host->hcd, urb);
  238. if (ret < 0) {
  239. printf("%s:%d\r\n", __func__, __LINE__);
  240. //dwc2_urb_dequeue(&host->hcd, urb, 0);
  241. //printf("%s:%d\r\n", __func__, __LINE__);
  242. goto exit;
  243. }
  244. ret = xQueueReceive((QueueHandle_t)urb->queueHandle, NULL, timeout);
  245. if (ret != pdTRUE || 0 != urb->status) {//timeout
  246. printf("%s:%d\r\n", __func__, __LINE__);
  247. ret = urb->status;
  248. dwc2_urb_dequeue(&host->hcd, urb, 0);
  249. printf("%s:%d\r\n", __func__, __LINE__);
  250. if (actual_length)
  251. *actual_length = 0;
  252. if (0 != urb->status)
  253. printf("usb bulk urb error:%d\r\n", urb->status);
  254. } else {
  255. if (actual_length)
  256. *actual_length = urb->actual_length;
  257. }
  258. exit:
  259. usb_urb_release(urb);
  260. return ret;
  261. }
  262. static int _dwc2_submit_int_msg(struct dwc2_host_data *host, struct usb_device *dev, unsigned long pipe, void *buffer, int len, int interval, int timeout)
  263. {
  264. struct urb *urb = NULL;
  265. struct usb_host_endpoint *hep = NULL;
  266. int epnum = usb_pipeendpoint(pipe);
  267. int is_in = usb_pipein(pipe);
  268. int ret = 0;
  269. if (epnum > 8 || epnum < 0)
  270. return -EINVAL;
  271. if (is_in) {
  272. hep = &host->hep_in[epnum];
  273. } else {
  274. hep = &host->hep_out[epnum];
  275. }
  276. urb = usb_urb_alloc(host, 0, IRQ_NONE);
  277. if (urb == NULL)
  278. return -ENOMEM;
  279. construct_urb(urb, hep, dev, USB_ENDPOINT_XFER_INT,
  280. pipe, buffer, len, NULL, interval);
  281. ret = submit_urb(&host->hcd, urb);
  282. if (ret < 0) {
  283. dwc2_urb_dequeue(&host->hcd, urb, 0);
  284. goto exit;
  285. }
  286. ret = xQueueReceive((QueueHandle_t)urb->queueHandle, NULL, timeout);
  287. if (ret != pdTRUE) {//timeout
  288. dwc2_urb_dequeue(&host->hcd, urb, 0);
  289. }
  290. exit:
  291. usb_urb_release(urb);
  292. return ret;
  293. }
  294. #if 0
  295. static int _dwc2_reset_root_port(struct dwc2_host_data *host,
  296. struct usb_device *dev)
  297. {
  298. mdelay(50);
  299. host->host_speed = USB_SPEED_HIGH;
  300. mdelay((host->host_speed == USB_SPEED_LOW) ? 200 : 50);
  301. return 0;
  302. }
  303. #endif
  304. void usb_reset_endpoint()
  305. {
  306. int i;
  307. struct dwc2_host_data *host = &dwc2_host;
  308. if ((NULL == host->dw2_hc_driver) || (NULL == host->dw2_hc_driver->endpoint_reset))
  309. return;
  310. for (i = 0; i < 16; i++) {
  311. host->dw2_hc_driver->endpoint_reset(&(host->hcd), &host->hep_in[i]);
  312. host->dw2_hc_driver->endpoint_reset(&(host->hcd), &host->hep_out[i]);
  313. }
  314. }
  315. void usb_disable_endpoint()
  316. {
  317. int i;
  318. struct dwc2_host_data *host = &dwc2_host;
  319. if ((NULL == host->dw2_hc_driver) || (NULL == host->dw2_hc_driver->endpoint_disable))
  320. return;
  321. for (i = 0; i < 16; i++) {
  322. host->dw2_hc_driver->endpoint_disable(&(host->hcd), &host->hep_in[i]);
  323. host->dw2_hc_driver->endpoint_disable(&(host->hcd), &host->hep_out[i]);
  324. }
  325. }
  326. void reset_usb_phy()
  327. {
  328. vSysctlConfigure(SYS_SOFTRESET_CTL1, 22, 1, 0); //usb phy softreset
  329. mdelay(10);
  330. vSysctlConfigure(SYS_SOFTRESET_CTL1, 22, 1, 1);
  331. }
  332. void usb_sysctrl_init()
  333. {
  334. vSysctlConfigure(SYS_SOFTRESET_CTL1, 22, 1, 0); //usb phy softreset
  335. vSysctlConfigure(SYS_SOFTRESET_CTL, 3, 1, 0); //usb softreset.
  336. vSysctlConfigure(SYS_SOFTRESET_CTL1, 5, 1, 0); //usb utmi softreset(usb phy interface).
  337. mdelay(10);
  338. vSysctlConfigure(SYS_SOFTRESET_CTL1, 22, 1, 1);
  339. vSysctlConfigure(SYS_SOFTRESET_CTL, 3, 1, 1);
  340. vSysctlConfigure(SYS_SOFTRESET_CTL1, 5, 1, 1);
  341. if (!get_usb_mode())
  342. vSysctlConfigure(SYS_ANA_CFG, 4, 3, 0); //usb host(bit[5]]=0)
  343. else
  344. vSysctlConfigure(SYS_ANA_CFG, 4, 3, 2); //usb dev(bit[5]]=1)
  345. mdelay(10);
  346. }
  347. int hub_status_data(char buf[8])
  348. {
  349. int ret = 1;
  350. struct dwc2_host_data *host = &dwc2_host;
  351. //printf("prvUsbPortScanTimerCallback\r\n");
  352. ret = host->dw2_hc_driver->hub_status_data(&(host->hcd), buf);
  353. if (ret != 0) {
  354. //printf("state:%d usb state changed now!\r\n", buf[0]);
  355. }
  356. return ret;
  357. }
  358. void usb_dwc2_lowlevel_restart()
  359. {
  360. struct dwc2_host_data *host = &dwc2_host;
  361. if (host->dw2_hc_driver && host->dw2_hc_driver->stop) {
  362. host->dw2_hc_driver->stop(&(host->hcd));
  363. }
  364. msleep(50);
  365. if (host->dw2_hc_driver && host->dw2_hc_driver->start) {
  366. host->dw2_hc_driver->start(&(host->hcd));
  367. }
  368. }
  369. int usb_dwc2_reset(int inIrq, int isDev)
  370. {
  371. struct dwc2_hsotg *hsotg = dwc2_host.host;
  372. struct wq_msg *pmsg = &hsotg->xmsg;
  373. if (isDev)
  374. pmsg->id = OTG_WQ_MSG_ID_DEV_RESET;
  375. else
  376. pmsg->id = OTG_WQ_MSG_ID_HOST_RESET;
  377. pmsg->delay = 50;
  378. if (inIrq) {
  379. xQueueSendFromISR(hsotg->wq_otg, (void*)pmsg, 0);
  380. } else {
  381. xQueueSend(hsotg->wq_otg, (void*)pmsg, 0);
  382. }
  383. return 0;
  384. }
  385. //#define mainTIMER_SCAN_FREQUENCY_MS pdMS_TO_TICKS( 1000UL )
  386. int usb_dwc2_lowlevel_init()
  387. {
  388. struct dwc2_host_data *host = &dwc2_host;
  389. int ret;
  390. INIT_LIST_HEAD(&host->free_urb_list);
  391. spin_lock_init(&host->lock);
  392. ret = dwc2_driver_init(&host->host, &(host->hcd));
  393. if (!host->host) {
  394. printf("MUSB host is not registered\n");
  395. return -ENODEV;
  396. }
  397. host->dw2_hc_driver = dwc2_get_driver();
  398. return ret;
  399. }
  400. int usb_dwc2_lowlevel_uninit()
  401. {
  402. if (!dwc2_host.host) {
  403. printf("MUSB host is not registered\n");
  404. return -ENODEV;
  405. }
  406. dwc2_driver_uninit(dwc2_host.host);
  407. return 0;
  408. }
  409. int submit_control_msg(struct usb_device *dev, unsigned long pipe,
  410. void *buffer, int length, struct devrequest *setup, int timeout)
  411. {
  412. if (dev->parent == NULL) {
  413. return dwc_otg_submit_rh_msg(dev, pipe, buffer, length, setup);
  414. } else {
  415. return _dwc2_submit_control_msg(&dwc2_host, dev, pipe, buffer, length, setup, timeout);
  416. }
  417. }
  418. int submit_int_msg(struct usb_device *dev, unsigned long pipe,
  419. void *buffer, int length, int interval)
  420. {
  421. return _dwc2_submit_int_msg(&dwc2_host, dev, pipe, buffer, length, interval, 0);
  422. }
  423. static void construct_iso_urb(struct urb *urb, struct usb_host_endpoint *hep,
  424. struct usb_device *dev, int endpoint_type,
  425. unsigned long pipe, void *buffer, int len,
  426. int num_iso_packets, int interval)
  427. {
  428. int epnum = usb_pipeendpoint(pipe);
  429. int is_in = usb_pipein(pipe);
  430. int i;
  431. int psize = 512;
  432. INIT_LIST_HEAD(&hep->urb_list);
  433. #ifndef NO_GNU
  434. INIT_LIST_HEAD(&urb->urb_list);
  435. #else
  436. INIT_LIST_ITEM(&urb->urb_list);
  437. urb->urb_list.pvOwner = (void *)urb;
  438. #endif
  439. urb->ep = hep;
  440. urb->complete = dwc2_host_complete_urb;
  441. urb->status = -EINPROGRESS;
  442. urb->dev = dev;
  443. urb->pipe = pipe;
  444. urb->transfer_buffer = buffer;
  445. urb->transfer_dma = (dma_addr_t)buffer;
  446. urb->transfer_buffer_length = len;
  447. urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |
  448. URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |
  449. URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
  450. URB_DMA_SG_COMBINED);
  451. urb->transfer_flags |= (is_in ? URB_DIR_IN : URB_DIR_OUT);
  452. urb->ep->desc.wMaxPacketSize =
  453. __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
  454. dev->epmaxpacketout[epnum]);
  455. urb->ep->desc.bmAttributes = endpoint_type;
  456. urb->ep->desc.bEndpointAddress =
  457. (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
  458. urb->ep->desc.bInterval = interval;
  459. if (num_iso_packets > 0)
  460. psize = len / num_iso_packets;
  461. for (i = 0; i < num_iso_packets; ++i) {
  462. urb->iso_frame_desc[i].offset = i * psize;
  463. urb->iso_frame_desc[i].length = psize;
  464. }
  465. }
  466. int submit_iso_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int *actual_length, int timeout)
  467. {
  468. struct urb *urb = NULL;
  469. struct usb_host_endpoint *hep = NULL;
  470. int epnum = usb_pipeendpoint(pipe);
  471. int is_in = usb_pipein(pipe);
  472. int ret = 0;
  473. struct dwc2_host_data *host = &dwc2_host;
  474. int num_iso_packets = 1;
  475. if (epnum > 8 || epnum < 0)
  476. return -EINVAL;
  477. if (is_in) {
  478. hep = &host->hep_in[epnum];
  479. } else {
  480. hep = &host->hep_out[epnum];
  481. }
  482. urb = usb_urb_alloc(host, num_iso_packets, IRQ_NONE);
  483. if (urb == NULL)
  484. return -ENOMEM;
  485. construct_iso_urb(urb, hep, dev, USB_ENDPOINT_XFER_ISOC,
  486. pipe, buffer, transfer_len, num_iso_packets, 0);
  487. ret = submit_urb(&host->hcd, urb);
  488. if (ret < 0) {
  489. dwc2_urb_dequeue(&host->hcd, urb, 0);
  490. if (actual_length)
  491. *actual_length = 0;
  492. goto exit;
  493. }
  494. ret = xQueueReceive((QueueHandle_t)urb->queueHandle, NULL, timeout);
  495. if (ret != pdTRUE || 0 != urb->status) {
  496. ret = urb->status;
  497. dwc2_urb_dequeue(&host->hcd, urb, 0);
  498. if (actual_length)
  499. *actual_length = 0;
  500. if (0 != urb->status)
  501. printf("usb iso urb error:%d\r\n", urb->status);
  502. } else {
  503. if (actual_length) {
  504. int i, tmp_len = 0;
  505. for (i = 0; i < urb->number_of_packets; i++) {
  506. tmp_len += urb->iso_frame_desc[i].actual_length;
  507. }
  508. *actual_length = tmp_len;
  509. }
  510. }
  511. exit:
  512. usb_urb_release(urb);
  513. return ret;
  514. }
  515. /*
  516. * DWC2 to USB API interface
  517. */
  518. /* Direction: In ; Request: Status */
  519. static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer,
  520. int txlen, struct devrequest *cmd)
  521. {
  522. int len = 0;
  523. int stat = 0;
  524. switch (cmd->requesttype & ~USB_DIR_IN) {
  525. case 0:
  526. *(uint16_t *)buffer = cpu_to_le16(1);
  527. len = 2;
  528. break;
  529. case USB_RECIP_INTERFACE:
  530. case USB_RECIP_ENDPOINT:
  531. *(uint16_t *)buffer = cpu_to_le16(0);
  532. len = 2;
  533. break;
  534. case USB_TYPE_CLASS:
  535. *(uint32_t *)buffer = cpu_to_le32(0);
  536. len = 4;
  537. break;
  538. case USB_RECIP_OTHER | USB_TYPE_CLASS:
  539. len = 4;
  540. stat = dwc2_host.dw2_hc_driver->hub_control(&dwc2_host.hcd, (cmd->requesttype << 8) | (cmd->request),
  541. cmd->value, cmd->index, (char*)buffer, len);
  542. break;
  543. default:
  544. //puts("unsupported root hub command\n");
  545. stat = USB_ST_STALLED;
  546. }
  547. dev->act_len = min(len, txlen);
  548. dev->status = stat;
  549. return stat;
  550. }
  551. /* Direction: In ; Request: Descriptor */
  552. /* roothub.a masks */
  553. #define RH_A_NDP (0xff << 0) /* number of downstream ports */
  554. #define RH_A_PSM (1 << 8) /* power switching mode */
  555. #define RH_A_NPS (1 << 9) /* no power switching */
  556. #define RH_A_DT (1 << 10) /* device type (mbz) */
  557. #define RH_A_OCPM (1 << 11) /* over current protection mode */
  558. #define RH_A_NOCP (1 << 12) /* no over current protection */
  559. #define RH_A_POTPGT (0xffUL << 24) /* power on to power good time */
  560. /* roothub.b masks */
  561. #define RH_B_DR 0x0000ffff /* device removable flags */
  562. #define RH_B_PPCM 0xffff0000 /* port power control mask */
  563. static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev,
  564. void *buffer, int txlen,
  565. struct devrequest *cmd)
  566. {
  567. unsigned char data[32];
  568. uint32_t dsc;
  569. int len = 0;
  570. int stat = 0;
  571. uint16_t wValue = cpu_to_le16(cmd->value);
  572. uint16_t wLength = cpu_to_le16(cmd->length);
  573. switch (cmd->requesttype & ~USB_DIR_IN) {
  574. case 0:
  575. {
  576. switch (wValue & 0xff00) {
  577. case 0x0100: /* device descriptor */
  578. len = min3(txlen, (int)sizeof(root_hub_dev_des), (int)wLength);
  579. memcpy(buffer, root_hub_dev_des, len);
  580. break;
  581. case 0x0200: /* configuration descriptor */
  582. len = min3(txlen, (int)sizeof(root_hub_config_des), (int)wLength);
  583. memcpy(buffer, root_hub_config_des, len);
  584. break;
  585. case 0x0300: /* string descriptors */
  586. switch (wValue & 0xff) {
  587. case 0x00:
  588. len = min3(txlen, (int)sizeof(root_hub_str_index0),
  589. (int)wLength);
  590. memcpy(buffer, root_hub_str_index0, len);
  591. break;
  592. case 0x01:
  593. len = min3(txlen, (int)sizeof(root_hub_str_index1),
  594. (int)wLength);
  595. memcpy(buffer, root_hub_str_index1, len);
  596. break;
  597. }
  598. break;
  599. default:
  600. stat = USB_ST_STALLED;
  601. }
  602. break;
  603. }
  604. case USB_TYPE_CLASS:
  605. /* Root port config, set 1 port and nothing else. */
  606. dsc = 0x00000001;
  607. data[0] = 9; /* min length; */
  608. data[1] = 0x29;
  609. data[2] = dsc & RH_A_NDP;
  610. data[3] = 0;
  611. if (dsc & RH_A_PSM)
  612. data[3] |= 0x1;
  613. if (dsc & RH_A_NOCP)
  614. data[3] |= 0x10;
  615. else if (dsc & RH_A_OCPM)
  616. data[3] |= 0x8;
  617. /* corresponds to data[4-7] */
  618. data[5] = (dsc & RH_A_POTPGT) >> 24;
  619. data[7] = dsc & RH_B_DR;
  620. if (data[2] < 7) {
  621. data[8] = 0xff;
  622. } else {
  623. data[0] += 2;
  624. data[8] = (dsc & RH_B_DR) >> 8;
  625. data[9] = 0xff;
  626. data[10] = data[9];
  627. }
  628. len = min3(txlen, (int)data[0], (int)wLength);
  629. memcpy(buffer, data, len);
  630. break;
  631. default:
  632. //puts("unsupported root hub command\n");
  633. stat = USB_ST_STALLED;
  634. }
  635. dev->act_len = min(len, txlen);
  636. dev->status = stat;
  637. return stat;
  638. }
  639. /* Direction: In ; Request: Configuration */
  640. static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev,
  641. void *buffer, int txlen,
  642. struct devrequest *cmd)
  643. {
  644. int len = 0;
  645. int stat = 0;
  646. switch (cmd->requesttype & ~USB_DIR_IN) {
  647. case 0:
  648. *(uint8_t *)buffer = 0x01;
  649. len = 1;
  650. break;
  651. default:
  652. //puts("unsupported root hub command\n");
  653. stat = USB_ST_STALLED;
  654. }
  655. dev->act_len = min(len, txlen);
  656. dev->status = stat;
  657. return stat;
  658. }
  659. /* Direction: In */
  660. static int dwc_otg_submit_rh_msg_in(
  661. struct usb_device *dev, void *buffer,
  662. int txlen, struct devrequest *cmd)
  663. {
  664. switch (cmd->request) {
  665. case USB_REQ_GET_STATUS:
  666. return dwc_otg_submit_rh_msg_in_status(dev, buffer,
  667. txlen, cmd);
  668. case USB_REQ_GET_DESCRIPTOR:
  669. return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer,
  670. txlen, cmd);
  671. case USB_REQ_GET_CONFIGURATION:
  672. return dwc_otg_submit_rh_msg_in_configuration(dev, buffer,
  673. txlen, cmd);
  674. default:
  675. //puts("unsupported root hub command\n");
  676. return USB_ST_STALLED;
  677. }
  678. }
  679. /* Direction: Out */
  680. static int dwc_otg_submit_rh_msg_out(
  681. struct usb_device *dev,
  682. void *buffer, int txlen,
  683. struct devrequest *cmd)
  684. {
  685. int len = 0;
  686. int stat = 0;
  687. uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8);
  688. uint16_t wValue = cpu_to_le16(cmd->value);
  689. switch (bmrtype_breq & ~USB_DIR_IN) {
  690. case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT:
  691. case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS:
  692. break;
  693. case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
  694. case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
  695. dwc2_host.dw2_hc_driver->hub_control(&dwc2_host.hcd, (cmd->requesttype << 8) | (cmd->request),
  696. cmd->value, cmd->index, (char*)buffer, txlen);
  697. break;
  698. case (USB_REQ_SET_ADDRESS << 8):
  699. dwc2_host.root_hub_devnum = wValue;
  700. dwc2_host.dw2_hc_driver->hub_control(&dwc2_host.hcd, (cmd->requesttype << 8) | (cmd->request),
  701. cmd->value, cmd->index, (char*)buffer, txlen);
  702. break;
  703. case (USB_REQ_SET_CONFIGURATION << 8):
  704. break;
  705. default:
  706. //puts("unsupported root hub command\n");
  707. stat = USB_ST_STALLED;
  708. }
  709. len = min(len, txlen);
  710. dev->act_len = len;
  711. dev->status = stat;
  712. return stat;
  713. }
  714. static int dwc_otg_submit_rh_msg(struct usb_device *dev,
  715. unsigned long pipe, void *buffer, int txlen,
  716. struct devrequest *cmd)
  717. {
  718. int stat = 0;
  719. if (usb_pipeint(pipe)) {
  720. //puts("Root-Hub submit IRQ: NOT implemented\n");
  721. return 0;
  722. }
  723. if (cmd->requesttype & USB_DIR_IN)
  724. stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd);
  725. else
  726. stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd);
  727. stat = dev->act_len;
  728. return stat;
  729. }