dwc_otg_hcd_queue.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /* ==========================================================================
  2. * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $
  3. * $Revision: #44 $
  4. * $Date: 2011/10/26 $
  5. * $Change: 1873028 $
  6. *
  7. * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  8. * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  9. * otherwise expressly agreed to in writing between Synopsys and you.
  10. *
  11. * The Software IS NOT an item of Licensed Software or Licensed Product under
  12. * any End User Software License Agreement or Agreement for Licensed Product
  13. * with Synopsys or any supplement thereto. You are permitted to use and
  14. * redistribute this Software in source and binary forms, with or without
  15. * modification, provided that redistributions of source code must retain this
  16. * notice. You may not view, use, disclose, copy or distribute this file or
  17. * any information contained herein except pursuant to this license grant from
  18. * Synopsys. If you do not agree with this notice, including the disclaimer
  19. * below, then you are not authorized to use the Software.
  20. *
  21. * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  25. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  31. * DAMAGE.
  32. * ========================================================================== */
  33. #ifndef DWC_DEVICE_ONLY
  34. /**
  35. * @file
  36. *
  37. * This file contains the functions to manage Queue Heads and Queue
  38. * Transfer Descriptors.
  39. */
  40. #include "dwc_otg_hcd.h"
  41. #include "dwc_otg_regs.h"
  42. /**
  43. * Free each QTD in the QH's QTD-list then free the QH. QH should already be
  44. * removed from a list. QTD list should already be empty if called from URB
  45. * Dequeue.
  46. *
  47. * @param hcd HCD instance.
  48. * @param qh The QH to free.
  49. */
  50. void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  51. {
  52. dwc_otg_qtd_t *qtd, *qtd_tmp;
  53. /* Free each QTD in the QTD list */
  54. DWC_SPINLOCK(hcd->lock);
  55. DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) {
  56. DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry);
  57. dwc_otg_hcd_qtd_free(qtd);
  58. }
  59. if (hcd->core_if->dma_desc_enable) {
  60. dwc_otg_hcd_qh_free_ddma(hcd, qh);
  61. } else if (qh->dw_align_buf) {
  62. uint32_t buf_size;
  63. if (qh->ep_type == UE_ISOCHRONOUS) {
  64. buf_size = 4096;
  65. } else {
  66. buf_size = hcd->core_if->core_params->max_transfer_size;
  67. }
  68. DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma);
  69. }
  70. DWC_FREE(qh);
  71. DWC_SPINUNLOCK(hcd->lock);
  72. return;
  73. }
  74. #define BitStuffTime(bytecount) ((8 * 7* bytecount) / 6)
  75. #define HS_HOST_DELAY 5 /* nanoseconds */
  76. #define FS_LS_HOST_DELAY 1000 /* nanoseconds */
  77. #define HUB_LS_SETUP 333 /* nanoseconds */
  78. #define NS_TO_US(ns) ((ns + 500) / 1000)
  79. /* convert & round nanoseconds to microseconds */
  80. static uint32_t calc_bus_time(int speed, int is_in, int is_isoc, int bytecount)
  81. {
  82. unsigned long retval;
  83. switch (speed) {
  84. case USB_SPEED_HIGH:
  85. if (is_isoc) {
  86. retval =
  87. ((38 * 8 * 2083) +
  88. (2083 * (3 + BitStuffTime(bytecount)))) / 1000 +
  89. HS_HOST_DELAY;
  90. } else {
  91. retval =
  92. ((55 * 8 * 2083) +
  93. (2083 * (3 + BitStuffTime(bytecount)))) / 1000 +
  94. HS_HOST_DELAY;
  95. }
  96. break;
  97. case USB_SPEED_FULL:
  98. if (is_isoc) {
  99. retval =
  100. (8354 * (31 + 10 * BitStuffTime(bytecount))) / 1000;
  101. if (is_in) {
  102. retval = 7268 + FS_LS_HOST_DELAY + retval;
  103. } else {
  104. retval = 6265 + FS_LS_HOST_DELAY + retval;
  105. }
  106. } else {
  107. retval =
  108. (8354 * (31 + 10 * BitStuffTime(bytecount))) / 1000;
  109. retval = 9107 + FS_LS_HOST_DELAY + retval;
  110. }
  111. break;
  112. case USB_SPEED_LOW:
  113. if (is_in) {
  114. retval =
  115. (67667 * (31 + 10 * BitStuffTime(bytecount))) /
  116. 1000;
  117. retval =
  118. 64060 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY +
  119. retval;
  120. } else {
  121. retval =
  122. (66700 * (31 + 10 * BitStuffTime(bytecount))) /
  123. 1000;
  124. retval =
  125. 64107 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY +
  126. retval;
  127. }
  128. break;
  129. default:
  130. DWC_WARN("Unknown device speed\n");
  131. retval = -1;
  132. }
  133. return NS_TO_US(retval);
  134. }
  135. /**
  136. * Initializes a QH structure.
  137. *
  138. * @param hcd The HCD state structure for the DWC OTG controller.
  139. * @param qh The QH to init.
  140. * @param urb Holds the information about the device/endpoint that we need
  141. * to initialize the QH.
  142. */
  143. #define SCHEDULE_SLOP 10
  144. void qh_init(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, dwc_otg_hcd_urb_t * urb)
  145. {
  146. char *speed, *type;
  147. int dev_speed;
  148. uint32_t hub_addr, hub_port;
  149. dwc_memset(qh, 0, sizeof(dwc_otg_qh_t));
  150. /* Initialize QH */
  151. qh->ep_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info);
  152. qh->ep_is_in = dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? 1 : 0;
  153. qh->data_toggle = DWC_OTG_HC_PID_DATA0;
  154. qh->maxp = dwc_otg_hcd_get_mps(&urb->pipe_info);
  155. DWC_CIRCLEQ_INIT(&qh->qtd_list);
  156. DWC_LIST_INIT(&qh->qh_list_entry);
  157. qh->channel = NULL;
  158. /* FS/LS Enpoint on HS Hub
  159. * NOT virtual root hub */
  160. dev_speed = hcd->fops->speed(hcd, urb->priv);
  161. hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &hub_port);
  162. qh->do_split = 0;
  163. if (((dev_speed == USB_SPEED_LOW) ||
  164. (dev_speed == USB_SPEED_FULL)) &&
  165. (hub_addr != 0 && hub_addr != 1)) {
  166. DWC_DEBUGPL(DBG_HCD,
  167. "QH init: EP %d: TT found at hub addr %d, for port %d\n",
  168. dwc_otg_hcd_get_ep_num(&urb->pipe_info), hub_addr,
  169. hub_port);
  170. qh->do_split = 1;
  171. }
  172. if (qh->ep_type == UE_INTERRUPT || qh->ep_type == UE_ISOCHRONOUS) {
  173. /* Compute scheduling parameters once and save them. */
  174. hprt0_data_t hprt;
  175. /** @todo Account for split transfers in the bus time. */
  176. int bytecount =
  177. dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp);
  178. qh->usecs =
  179. calc_bus_time((qh->do_split ? USB_SPEED_HIGH : dev_speed),
  180. qh->ep_is_in, (qh->ep_type == UE_ISOCHRONOUS),
  181. bytecount);
  182. /* Start in a slightly future (micro)frame. */
  183. qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
  184. SCHEDULE_SLOP);
  185. qh->interval = urb->interval;
  186. #if 0
  187. /* Increase interrupt polling rate for debugging. */
  188. if (qh->ep_type == UE_INTERRUPT) {
  189. qh->interval = 8;
  190. }
  191. #endif
  192. hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0);
  193. if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
  194. ((dev_speed == USB_SPEED_LOW) ||
  195. (dev_speed == USB_SPEED_FULL))) {
  196. qh->interval *= 8;
  197. qh->sched_frame |= 0x7;
  198. qh->start_split_frame = qh->sched_frame;
  199. }
  200. }
  201. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
  202. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh);
  203. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
  204. dwc_otg_hcd_get_dev_addr(&urb->pipe_info));
  205. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
  206. dwc_otg_hcd_get_ep_num(&urb->pipe_info),
  207. dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT");
  208. switch (dev_speed) {
  209. case USB_SPEED_LOW:
  210. qh->dev_speed = DWC_OTG_EP_SPEED_LOW;
  211. speed = "low";
  212. break;
  213. case USB_SPEED_FULL:
  214. qh->dev_speed = DWC_OTG_EP_SPEED_FULL;
  215. speed = "full";
  216. break;
  217. case USB_SPEED_HIGH:
  218. qh->dev_speed = DWC_OTG_EP_SPEED_HIGH;
  219. speed = "high";
  220. break;
  221. default:
  222. speed = "?";
  223. break;
  224. }
  225. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", speed);
  226. switch (qh->ep_type) {
  227. case UE_ISOCHRONOUS:
  228. type = "isochronous";
  229. break;
  230. case UE_INTERRUPT:
  231. type = "interrupt";
  232. break;
  233. case UE_CONTROL:
  234. type = "control";
  235. break;
  236. case UE_BULK:
  237. type = "bulk";
  238. break;
  239. default:
  240. type = "?";
  241. break;
  242. }
  243. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n", type);
  244. #ifdef DEBUG
  245. if (qh->ep_type == UE_INTERRUPT) {
  246. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
  247. qh->usecs);
  248. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
  249. qh->interval);
  250. }
  251. #endif
  252. }
  253. /**
  254. * This function allocates and initializes a QH.
  255. *
  256. * @param hcd The HCD state structure for the DWC OTG controller.
  257. * @param urb Holds the information about the device/endpoint that we need
  258. * to initialize the QH.
  259. * @param atomic_alloc Flag to do atomic allocation if needed
  260. *
  261. * @return Returns pointer to the newly allocated QH, or NULL on error. */
  262. dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t * hcd,
  263. dwc_otg_hcd_urb_t * urb, int atomic_alloc)
  264. {
  265. dwc_otg_qh_t *qh;
  266. /* Allocate memory */
  267. /** @todo add memflags argument */
  268. qh = dwc_otg_hcd_qh_alloc(atomic_alloc);
  269. if (qh == NULL) {
  270. DWC_ERROR("qh allocation failed");
  271. return NULL;
  272. }
  273. qh_init(hcd, qh, urb);
  274. if (hcd->core_if->dma_desc_enable
  275. && (dwc_otg_hcd_qh_init_ddma(hcd, qh) < 0)) {
  276. dwc_otg_hcd_qh_free(hcd, qh);
  277. return NULL;
  278. }
  279. return qh;
  280. }
  281. /**
  282. * Checks that a channel is available for a periodic transfer.
  283. *
  284. * @return 0 if successful, negative error code otherise.
  285. */
  286. static int periodic_channel_available(dwc_otg_hcd_t * hcd)
  287. {
  288. /*
  289. * Currently assuming that there is a dedicated host channnel for each
  290. * periodic transaction plus at least one host channel for
  291. * non-periodic transactions.
  292. */
  293. int status;
  294. int num_channels;
  295. num_channels = hcd->core_if->core_params->host_channels;
  296. if ((hcd->periodic_channels + hcd->non_periodic_channels < num_channels)
  297. && (hcd->periodic_channels < num_channels - 1)) {
  298. status = 0;
  299. } else {
  300. DWC_INFO("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
  301. __func__, num_channels, hcd->periodic_channels, hcd->non_periodic_channels); //NOTICE
  302. status = -DWC_E_NO_SPACE;
  303. }
  304. return status;
  305. }
  306. /**
  307. * Checks that there is sufficient bandwidth for the specified QH in the
  308. * periodic schedule. For simplicity, this calculation assumes that all the
  309. * transfers in the periodic schedule may occur in the same (micro)frame.
  310. *
  311. * @param hcd The HCD state structure for the DWC OTG controller.
  312. * @param qh QH containing periodic bandwidth required.
  313. *
  314. * @return 0 if successful, negative error code otherwise.
  315. */
  316. static int check_periodic_bandwidth(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  317. {
  318. int status;
  319. int16_t max_claimed_usecs;
  320. status = 0;
  321. if ((qh->dev_speed == DWC_OTG_EP_SPEED_HIGH) || qh->do_split) {
  322. /*
  323. * High speed mode.
  324. * Max periodic usecs is 80% x 125 usec = 100 usec.
  325. */
  326. max_claimed_usecs = 100 - qh->usecs;
  327. } else {
  328. /*
  329. * Full speed mode.
  330. * Max periodic usecs is 90% x 1000 usec = 900 usec.
  331. */
  332. max_claimed_usecs = 900 - qh->usecs;
  333. }
  334. if (hcd->periodic_usecs > max_claimed_usecs) {
  335. DWC_INFO("%s: already claimed usecs %d, required usecs %d\n", __func__, hcd->periodic_usecs, qh->usecs); //NOTICE
  336. status = -DWC_E_NO_SPACE;
  337. }
  338. return status;
  339. }
  340. /**
  341. * Checks that the max transfer size allowed in a host channel is large enough
  342. * to handle the maximum data transfer in a single (micro)frame for a periodic
  343. * transfer.
  344. *
  345. * @param hcd The HCD state structure for the DWC OTG controller.
  346. * @param qh QH for a periodic endpoint.
  347. *
  348. * @return 0 if successful, negative error code otherwise.
  349. */
  350. static int check_max_xfer_size(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  351. {
  352. int status;
  353. uint32_t max_xfer_size;
  354. uint32_t max_channel_xfer_size;
  355. status = 0;
  356. max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp);
  357. max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size;
  358. if (max_xfer_size > max_channel_xfer_size) {
  359. DWC_INFO("%s: Periodic xfer length %d > " "max xfer length for channel %d\n",
  360. __func__, max_xfer_size, max_channel_xfer_size); //NOTICE
  361. status = -DWC_E_NO_SPACE;
  362. }
  363. return status;
  364. }
  365. /**
  366. * Schedules an interrupt or isochronous transfer in the periodic schedule.
  367. *
  368. * @param hcd The HCD state structure for the DWC OTG controller.
  369. * @param qh QH for the periodic transfer. The QH should already contain the
  370. * scheduling information.
  371. *
  372. * @return 0 if successful, negative error code otherwise.
  373. */
  374. static int schedule_periodic(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  375. {
  376. int status = 0;
  377. status = periodic_channel_available(hcd);
  378. if (status) {
  379. DWC_INFO("%s: No host channel available for periodic " "transfer.\n", __func__); //NOTICE
  380. return status;
  381. }
  382. status = check_periodic_bandwidth(hcd, qh);
  383. if (status) {
  384. DWC_INFO("%s: Insufficient periodic bandwidth for " "periodic transfer.\n", __func__); //NOTICE
  385. return status;
  386. }
  387. status = check_max_xfer_size(hcd, qh);
  388. if (status) {
  389. DWC_INFO("%s: Channel max transfer size too small " "for periodic transfer.\n", __func__); //NOTICE
  390. return status;
  391. }
  392. if (hcd->core_if->dma_desc_enable) {
  393. /* Don't rely on SOF and start in ready schedule */
  394. DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_ready, &qh->qh_list_entry);
  395. }
  396. else {
  397. /* Always start in the inactive schedule. */
  398. DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_inactive, &qh->qh_list_entry);
  399. }
  400. /* Reserve the periodic channel. */
  401. hcd->periodic_channels++;
  402. /* Update claimed usecs per (micro)frame. */
  403. hcd->periodic_usecs += qh->usecs;
  404. return status;
  405. }
  406. /**
  407. * This function adds a QH to either the non periodic or periodic schedule if
  408. * it is not already in the schedule. If the QH is already in the schedule, no
  409. * action is taken.
  410. *
  411. * @return 0 if successful, negative error code otherwise.
  412. */
  413. int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  414. {
  415. int status = 0;
  416. gintmsk_data_t intr_mask = {.d32 = 0 };
  417. if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) {
  418. /* QH already in a schedule. */
  419. return status;
  420. }
  421. /* Add the new QH to the appropriate schedule */
  422. if (dwc_qh_is_non_per(qh)) {
  423. /* Always start in the inactive schedule. */
  424. DWC_LIST_INSERT_TAIL(&hcd->non_periodic_sched_inactive,
  425. &qh->qh_list_entry);
  426. } else {
  427. status = schedule_periodic(hcd, qh);
  428. if ( !hcd->periodic_qh_count ) {
  429. intr_mask.b.sofintr = 1;
  430. DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->gintmsk,
  431. intr_mask.d32, intr_mask.d32);
  432. }
  433. hcd->periodic_qh_count++;
  434. }
  435. return status;
  436. }
  437. /**
  438. * Removes an interrupt or isochronous transfer from the periodic schedule.
  439. *
  440. * @param hcd The HCD state structure for the DWC OTG controller.
  441. * @param qh QH for the periodic transfer.
  442. */
  443. static void deschedule_periodic(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  444. {
  445. DWC_LIST_REMOVE_INIT(&qh->qh_list_entry);
  446. /* Release the periodic channel reservation. */
  447. hcd->periodic_channels--;
  448. /* Update claimed usecs per (micro)frame. */
  449. hcd->periodic_usecs -= qh->usecs;
  450. }
  451. /**
  452. * Removes a QH from either the non-periodic or periodic schedule. Memory is
  453. * not freed.
  454. *
  455. * @param hcd The HCD state structure.
  456. * @param qh QH to remove from schedule. */
  457. void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  458. {
  459. gintmsk_data_t intr_mask = {.d32 = 0 };
  460. if (DWC_LIST_EMPTY(&qh->qh_list_entry)) {
  461. /* QH is not in a schedule. */
  462. return;
  463. }
  464. if (dwc_qh_is_non_per(qh)) {
  465. if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) {
  466. hcd->non_periodic_qh_ptr =
  467. hcd->non_periodic_qh_ptr->next;
  468. }
  469. DWC_LIST_REMOVE_INIT(&qh->qh_list_entry);
  470. } else {
  471. deschedule_periodic(hcd, qh);
  472. hcd->periodic_qh_count--;
  473. if( !hcd->periodic_qh_count ) {
  474. intr_mask.b.sofintr = 1;
  475. DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->gintmsk,
  476. intr_mask.d32, 0);
  477. }
  478. }
  479. }
  480. /**
  481. * Deactivates a QH. For non-periodic QHs, removes the QH from the active
  482. * non-periodic schedule. The QH is added to the inactive non-periodic
  483. * schedule if any QTDs are still attached to the QH.
  484. *
  485. * For periodic QHs, the QH is removed from the periodic queued schedule. If
  486. * there are any QTDs still attached to the QH, the QH is added to either the
  487. * periodic inactive schedule or the periodic ready schedule and its next
  488. * scheduled frame is calculated. The QH is placed in the ready schedule if
  489. * the scheduled frame has been reached already. Otherwise it's placed in the
  490. * inactive schedule. If there are no QTDs attached to the QH, the QH is
  491. * completely removed from the periodic schedule.
  492. */
  493. void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh,
  494. int sched_next_periodic_split)
  495. {
  496. if (dwc_qh_is_non_per(qh)) {
  497. dwc_otg_hcd_qh_remove(hcd, qh);
  498. if (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
  499. /* Add back to inactive non-periodic schedule. */
  500. dwc_otg_hcd_qh_add(hcd, qh);
  501. }
  502. } else {
  503. uint16_t frame_number = dwc_otg_hcd_get_frame_number(hcd);
  504. if (qh->do_split) {
  505. /* Schedule the next continuing periodic split transfer */
  506. if (sched_next_periodic_split) {
  507. qh->sched_frame = frame_number;
  508. if (dwc_frame_num_le(frame_number,
  509. dwc_frame_num_inc
  510. (qh->start_split_frame,
  511. 1))) {
  512. /*
  513. * Allow one frame to elapse after start
  514. * split microframe before scheduling
  515. * complete split, but DONT if we are
  516. * doing the next start split in the
  517. * same frame for an ISOC out.
  518. */
  519. if ((qh->ep_type != UE_ISOCHRONOUS) ||
  520. (qh->ep_is_in != 0)) {
  521. qh->sched_frame =
  522. dwc_frame_num_inc(qh->sched_frame, 1);
  523. }
  524. }
  525. } else {
  526. qh->sched_frame =
  527. dwc_frame_num_inc(qh->start_split_frame,
  528. qh->interval);
  529. if (dwc_frame_num_le
  530. (qh->sched_frame, frame_number)) {
  531. qh->sched_frame = frame_number;
  532. }
  533. qh->sched_frame |= 0x7;
  534. qh->start_split_frame = qh->sched_frame;
  535. }
  536. } else {
  537. qh->sched_frame =
  538. dwc_frame_num_inc(qh->sched_frame, qh->interval);
  539. if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
  540. qh->sched_frame = frame_number;
  541. }
  542. }
  543. if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
  544. dwc_otg_hcd_qh_remove(hcd, qh);
  545. } else {
  546. /*
  547. * Remove from periodic_sched_queued and move to
  548. * appropriate queue.
  549. */
  550. if (qh->sched_frame == frame_number) {
  551. DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready,
  552. &qh->qh_list_entry);
  553. } else {
  554. DWC_LIST_MOVE_HEAD
  555. (&hcd->periodic_sched_inactive,
  556. &qh->qh_list_entry);
  557. }
  558. }
  559. }
  560. }
  561. /**
  562. * This function allocates and initializes a QTD.
  563. *
  564. * @param urb The URB to create a QTD from. Each URB-QTD pair will end up
  565. * pointing to each other so each pair should have a unique correlation.
  566. * @param atomic_alloc Flag to do atomic alloc if needed
  567. *
  568. * @return Returns pointer to the newly allocated QTD, or NULL on error. */
  569. dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb, int atomic_alloc)
  570. {
  571. dwc_otg_qtd_t *qtd;
  572. qtd = dwc_otg_hcd_qtd_alloc(atomic_alloc);
  573. if (qtd == NULL) {
  574. return NULL;
  575. }
  576. dwc_otg_hcd_qtd_init(qtd, urb);
  577. return qtd;
  578. }
  579. /**
  580. * Initializes a QTD structure.
  581. *
  582. * @param qtd The QTD to initialize.
  583. * @param urb The URB to use for initialization. */
  584. void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb)
  585. {
  586. dwc_memset(qtd, 0, sizeof(dwc_otg_qtd_t));
  587. qtd->urb = urb;
  588. if (dwc_otg_hcd_get_pipe_type(&urb->pipe_info) == UE_CONTROL) {
  589. /*
  590. * The only time the QTD data toggle is used is on the data
  591. * phase of control transfers. This phase always starts with
  592. * DATA1.
  593. */
  594. qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
  595. qtd->control_phase = DWC_OTG_CONTROL_SETUP;
  596. }
  597. /* start split */
  598. qtd->complete_split = 0;
  599. qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
  600. qtd->isoc_split_offset = 0;
  601. qtd->in_process = 0;
  602. /* Store the qtd ptr in the urb to reference what QTD. */
  603. urb->qtd = qtd;
  604. return;
  605. }
  606. /**
  607. * This function adds a QTD to the QTD-list of a QH. It will find the correct
  608. * QH to place the QTD into. If it does not find a QH, then it will create a
  609. * new QH. If the QH to which the QTD is added is not currently scheduled, it
  610. * is placed into the proper schedule based on its EP type.
  611. *
  612. * @param[in] qtd The QTD to add
  613. * @param[in] hcd The DWC HCD structure
  614. * @param[out] qh out parameter to return queue head
  615. * @param atomic_alloc Flag to do atomic alloc if needed
  616. *
  617. * @return 0 if successful, negative error code otherwise.
  618. */
  619. int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd,
  620. dwc_otg_hcd_t * hcd, dwc_otg_qh_t ** qh, int atomic_alloc)
  621. {
  622. int retval = 0;
  623. dwc_irqflags_t flags;
  624. dwc_otg_hcd_urb_t *urb = qtd->urb;
  625. /*
  626. * Get the QH which holds the QTD-list to insert to. Create QH if it
  627. * doesn't exist.
  628. */
  629. if (*qh == NULL) {
  630. *qh = dwc_otg_hcd_qh_create(hcd, urb, atomic_alloc);
  631. if (*qh == NULL) {
  632. retval = -1;
  633. goto done;
  634. }
  635. }
  636. DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
  637. retval = dwc_otg_hcd_qh_add(hcd, *qh);
  638. if (retval == 0) {
  639. qtd->qh = *qh;
  640. DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd,
  641. qtd_list_entry);
  642. }
  643. DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
  644. done:
  645. return retval;
  646. }
  647. #endif /* DWC_DEVICE_ONLY */