Lines Matching refs:qh

269 	struct ehci_qh		*qh;		/* Q_TYPE_QH */  member
1005 static void oxu_qh_free(struct oxu_hcd *oxu, struct ehci_qh *qh) in oxu_qh_free() argument
1011 index = qh - &oxu->mem->qh_pool[0]; in oxu_qh_free()
1019 struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref); in qh_destroy() local
1020 struct oxu_hcd *oxu = qh->oxu; in qh_destroy()
1023 if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) { in qh_destroy()
1027 if (qh->dummy) in qh_destroy()
1028 oxu_qtd_free(oxu, qh->dummy); in qh_destroy()
1029 oxu_qh_free(oxu, qh); in qh_destroy()
1035 struct ehci_qh *qh = NULL; in oxu_qh_alloc() local
1044 qh = (struct ehci_qh *) &oxu->mem->qh_pool[i]; in oxu_qh_alloc()
1045 memset(qh, 0, sizeof *qh); in oxu_qh_alloc()
1047 kref_init(&qh->kref); in oxu_qh_alloc()
1048 qh->oxu = oxu; in oxu_qh_alloc()
1049 qh->qh_dma = virt_to_phys(qh); in oxu_qh_alloc()
1050 INIT_LIST_HEAD(&qh->qtd_list); in oxu_qh_alloc()
1053 qh->dummy = ehci_qtd_alloc(oxu); in oxu_qh_alloc()
1054 if (qh->dummy == NULL) { in oxu_qh_alloc()
1057 qh = NULL; in oxu_qh_alloc()
1066 return qh; in oxu_qh_alloc()
1070 static inline struct ehci_qh *qh_get(struct ehci_qh *qh) in qh_get() argument
1072 kref_get(&qh->kref); in qh_get()
1073 return qh; in qh_get()
1076 static inline void qh_put(struct ehci_qh *qh) in qh_put() argument
1078 kref_put(&qh->kref, qh_destroy); in qh_put()
1220 struct ehci_qh *qh, struct ehci_qtd *qtd) in qh_update() argument
1223 BUG_ON(qh->qh_state != QH_STATE_IDLE); in qh_update()
1225 qh->hw_qtd_next = QTD_NEXT(qtd->qtd_dma); in qh_update()
1226 qh->hw_alt_next = EHCI_LIST_END; in qh_update()
1233 if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) { in qh_update()
1237 epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; in qh_update()
1238 if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { in qh_update()
1239 qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE); in qh_update()
1240 usb_settoggle(qh->dev, epnum, is_out, 1); in qh_update()
1246 qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); in qh_update()
1253 static void qh_refresh(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_refresh() argument
1257 if (list_empty(&qh->qtd_list)) in qh_refresh()
1258 qtd = qh->dummy; in qh_refresh()
1260 qtd = list_entry(qh->qtd_list.next, in qh_refresh()
1263 if (cpu_to_le32(qtd->qtd_dma) == qh->hw_current) in qh_refresh()
1268 qh_update(oxu, qh, qtd); in qh_refresh()
1328 struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; in ehci_urb_done() local
1331 if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) { in ehci_urb_done()
1336 qh_put(qh); in ehci_urb_done()
1370 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
1371 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
1373 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
1374 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
1382 static unsigned qh_completions(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_completions() argument
1384 struct ehci_qtd *last = NULL, *end = qh->dummy; in qh_completions()
1392 if (unlikely(list_empty(&qh->qtd_list))) in qh_completions()
1401 state = qh->qh_state; in qh_completions()
1402 qh->qh_state = QH_STATE_COMPLETING; in qh_completions()
1410 list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) { in qh_completions()
1487 == qh->hw_current) in qh_completions()
1488 token = le32_to_cpu(qh->hw_token); in qh_completions()
1494 if ((HALT_BIT & qh->hw_token) == 0) { in qh_completions()
1496 qh->hw_token |= HALT_BIT; in qh_completions()
1511 if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { in qh_completions()
1538 qh->qh_state = state; in qh_completions()
1544 if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) { in qh_completions()
1547 qh_refresh(oxu, qh); in qh_completions()
1554 & qh->hw_info2) != 0) { in qh_completions()
1555 intr_deschedule(oxu, qh); in qh_completions()
1556 (void) qh_schedule(oxu, qh); in qh_completions()
1558 unlink_async(oxu, qh); in qh_completions()
1758 struct ehci_qh *qh = oxu_qh_alloc(oxu); in qh_make() local
1763 if (!qh) in qh_make()
1764 return qh; in qh_make()
1785 qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, in qh_make()
1788 qh->start = NO_FRAME; in qh_make()
1791 qh->c_usecs = 0; in qh_make()
1792 qh->gap_uf = 0; in qh_make()
1794 qh->period = urb->interval >> 3; in qh_make()
1795 if (qh->period == 0 && urb->interval != 1) { in qh_make()
1809 qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed, in qh_make()
1814 qh->c_usecs = qh->usecs + HS_USECS(0); in qh_make()
1815 qh->usecs = HS_USECS(1); in qh_make()
1817 qh->usecs += HS_USECS(1); in qh_make()
1818 qh->c_usecs = HS_USECS(0); in qh_make()
1822 qh->tt_usecs = NS_TO_US(think_time + in qh_make()
1825 qh->period = urb->interval; in qh_make()
1830 qh->dev = urb->dev; in qh_make()
1874 qh_put(qh); in qh_make()
1881 qh->qh_state = QH_STATE_IDLE; in qh_make()
1882 qh->hw_info1 = cpu_to_le32(info1); in qh_make()
1883 qh->hw_info2 = cpu_to_le32(info2); in qh_make()
1885 qh_refresh(oxu, qh); in qh_make()
1886 return qh; in qh_make()
1891 static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_async() argument
1893 __le32 dma = QH_NEXT(qh->qh_dma); in qh_link_async()
1899 if (!head->qh_next.qh) { in qh_link_async()
1914 if (qh->qh_state == QH_STATE_IDLE) in qh_link_async()
1915 qh_refresh(oxu, qh); in qh_link_async()
1918 qh->qh_next = head->qh_next; in qh_link_async()
1919 qh->hw_next = head->hw_next; in qh_link_async()
1922 head->qh_next.qh = qh; in qh_link_async()
1925 qh->qh_state = QH_STATE_LINKED; in qh_link_async()
1941 struct ehci_qh *qh = NULL; in qh_append_tds() local
1943 qh = (struct ehci_qh *) *ptr; in qh_append_tds()
1944 if (unlikely(qh == NULL)) { in qh_append_tds()
1946 qh = qh_make(oxu, urb, GFP_ATOMIC); in qh_append_tds()
1947 *ptr = qh; in qh_append_tds()
1949 if (likely(qh != NULL)) { in qh_append_tds()
1963 qh->hw_info1 &= ~QH_ADDR_MASK; in qh_append_tds()
1982 dummy = qh->dummy; in qh_append_tds()
1990 list_splice(qtd_list, qh->qtd_list.prev); in qh_append_tds()
1993 qh->dummy = qtd; in qh_append_tds()
1997 qtd = list_entry(qh->qtd_list.prev, in qh_append_tds()
2006 urb->hcpriv = qh_get(qh); in qh_append_tds()
2009 return qh; in qh_append_tds()
2017 struct ehci_qh *qh = NULL; in submit_async() local
2037 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in submit_async()
2038 if (unlikely(qh == NULL)) { in submit_async()
2046 if (likely(qh->qh_state == QH_STATE_IDLE)) in submit_async()
2047 qh_link_async(oxu, qh_get(qh)); in submit_async()
2050 if (unlikely(qh == NULL)) in submit_async()
2059 struct ehci_qh *qh = oxu->reclaim; in end_unlink_async() local
2064 qh->qh_state = QH_STATE_IDLE; in end_unlink_async()
2065 qh->qh_next.qh = NULL; in end_unlink_async()
2066 qh_put(qh); /* refcount from reclaim */ in end_unlink_async()
2069 next = qh->reclaim; in end_unlink_async()
2072 qh->reclaim = NULL; in end_unlink_async()
2074 qh_completions(oxu, qh); in end_unlink_async()
2076 if (!list_empty(&qh->qtd_list) in end_unlink_async()
2078 qh_link_async(oxu, qh); in end_unlink_async()
2080 qh_put(qh); /* refcount from async list */ in end_unlink_async()
2086 && oxu->async->qh_next.qh == NULL) in end_unlink_async()
2099 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in start_unlink_async() argument
2106 BUG_ON(oxu->reclaim || (qh->qh_state != QH_STATE_LINKED in start_unlink_async()
2107 && qh->qh_state != QH_STATE_UNLINK_WAIT)); in start_unlink_async()
2111 if (unlikely(qh == oxu->async)) { in start_unlink_async()
2124 qh->qh_state = QH_STATE_UNLINK; in start_unlink_async()
2125 oxu->reclaim = qh = qh_get(qh); in start_unlink_async()
2128 while (prev->qh_next.qh != qh) in start_unlink_async()
2129 prev = prev->qh_next.qh; in start_unlink_async()
2131 prev->hw_next = qh->hw_next; in start_unlink_async()
2132 prev->qh_next = qh->qh_next; in start_unlink_async()
2152 struct ehci_qh *qh; in scan_async() local
2159 qh = oxu->async->qh_next.qh; in scan_async()
2160 if (likely(qh != NULL)) { in scan_async()
2163 if (!list_empty(&qh->qtd_list) in scan_async()
2164 && qh->stamp != oxu->stamp) { in scan_async()
2172 qh = qh_get(qh); in scan_async()
2173 qh->stamp = oxu->stamp; in scan_async()
2174 temp = qh_completions(oxu, qh); in scan_async()
2175 qh_put(qh); in scan_async()
2186 if (list_empty(&qh->qtd_list)) { in scan_async()
2187 if (qh->stamp == oxu->stamp) in scan_async()
2190 && qh->qh_state == QH_STATE_LINKED) in scan_async()
2191 start_unlink_async(oxu, qh); in scan_async()
2194 qh = qh->qh_next.qh; in scan_async()
2195 } while (qh); in scan_async()
2212 return &periodic->qh->qh_next; in periodic_next_shadow()
2253 if (q->qh->hw_info2 & cpu_to_le32(1 << uframe)) in periodic_usecs()
2254 usecs += q->qh->usecs; in periodic_usecs()
2256 if (q->qh->hw_info2 & cpu_to_le32(1 << (8 + uframe))) in periodic_usecs()
2257 usecs += q->qh->c_usecs; in periodic_usecs()
2258 hw_p = &q->qh->hw_next; in periodic_usecs()
2259 q = &q->qh->qh_next; in periodic_usecs()
2326 static int qh_link_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_periodic() argument
2329 unsigned period = qh->period; in qh_link_periodic()
2331 dev_dbg(&qh->dev->dev, in qh_link_periodic()
2333 period, le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_link_periodic()
2334 qh, qh->start, qh->usecs, qh->c_usecs); in qh_link_periodic()
2340 for (i = qh->start; i < oxu->periodic_size; i += period) { in qh_link_periodic()
2352 hw_p = &here.qh->hw_next; in qh_link_periodic()
2359 while (here.ptr && qh != here.qh) { in qh_link_periodic()
2360 if (qh->period > here.qh->period) in qh_link_periodic()
2362 prev = &here.qh->qh_next; in qh_link_periodic()
2363 hw_p = &here.qh->hw_next; in qh_link_periodic()
2367 if (qh != here.qh) { in qh_link_periodic()
2368 qh->qh_next = here; in qh_link_periodic()
2369 if (here.qh) in qh_link_periodic()
2370 qh->hw_next = *hw_p; in qh_link_periodic()
2372 prev->qh = qh; in qh_link_periodic()
2373 *hw_p = QH_NEXT(qh->qh_dma); in qh_link_periodic()
2376 qh->qh_state = QH_STATE_LINKED; in qh_link_periodic()
2377 qh_get(qh); in qh_link_periodic()
2380 oxu_to_hcd(oxu)->self.bandwidth_allocated += qh->period in qh_link_periodic()
2381 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_link_periodic()
2382 : (qh->usecs * 8); in qh_link_periodic()
2391 static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_unlink_periodic() argument
2405 period = qh->period; in qh_unlink_periodic()
2409 for (i = qh->start; i < oxu->periodic_size; i += period) in qh_unlink_periodic()
2410 periodic_unlink(oxu, i, qh); in qh_unlink_periodic()
2413 oxu_to_hcd(oxu)->self.bandwidth_allocated -= qh->period in qh_unlink_periodic()
2414 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_unlink_periodic()
2415 : (qh->usecs * 8); in qh_unlink_periodic()
2417 dev_dbg(&qh->dev->dev, in qh_unlink_periodic()
2419 qh->period, in qh_unlink_periodic()
2420 le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_unlink_periodic()
2421 qh, qh->start, qh->usecs, qh->c_usecs); in qh_unlink_periodic()
2424 qh->qh_state = QH_STATE_UNLINK; in qh_unlink_periodic()
2425 qh->qh_next.ptr = NULL; in qh_unlink_periodic()
2426 qh_put(qh); in qh_unlink_periodic()
2434 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in intr_deschedule() argument
2438 qh_unlink_periodic(oxu, qh); in intr_deschedule()
2445 if (list_empty(&qh->qtd_list) in intr_deschedule()
2446 || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) in intr_deschedule()
2452 qh->qh_state = QH_STATE_IDLE; in intr_deschedule()
2453 qh->hw_next = EHCI_LIST_END; in intr_deschedule()
2501 const struct ehci_qh *qh, __le32 *c_maskp) in check_intr_schedule() argument
2505 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ in check_intr_schedule()
2508 if (!check_period(oxu, frame, uframe, qh->period, qh->usecs)) in check_intr_schedule()
2510 if (!qh->c_usecs) { in check_intr_schedule()
2523 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_schedule() argument
2530 qh_refresh(oxu, qh); in qh_schedule()
2531 qh->hw_next = EHCI_LIST_END; in qh_schedule()
2532 frame = qh->start; in qh_schedule()
2535 if (frame < qh->period) { in qh_schedule()
2536 uframe = ffs(le32_to_cpup(&qh->hw_info2) & QH_SMASK); in qh_schedule()
2538 qh, &c_mask); in qh_schedule()
2550 if (qh->period) { in qh_schedule()
2551 frame = qh->period - 1; in qh_schedule()
2555 frame, uframe, qh, in qh_schedule()
2565 status = check_intr_schedule(oxu, 0, 0, qh, &c_mask); in qh_schedule()
2569 qh->start = frame; in qh_schedule()
2572 qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK)); in qh_schedule()
2573 qh->hw_info2 |= qh->period in qh_schedule()
2576 qh->hw_info2 |= c_mask; in qh_schedule()
2578 oxu_dbg(oxu, "reused qh %p schedule\n", qh); in qh_schedule()
2581 status = qh_link_periodic(oxu, qh); in qh_schedule()
2591 struct ehci_qh *qh; in intr_submit() local
2607 qh = qh_append_tds(oxu, urb, &empty, epnum, &urb->ep->hcpriv); in intr_submit()
2608 if (qh == NULL) { in intr_submit()
2612 if (qh->qh_state == QH_STATE_IDLE) { in intr_submit()
2613 status = qh_schedule(oxu, qh); in intr_submit()
2619 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in intr_submit()
2620 BUG_ON(qh == NULL); in intr_submit()
2691 temp.qh = qh_get(q.qh); in scan_periodic()
2692 type = Q_NEXT_TYPE(q.qh->hw_next); in scan_periodic()
2693 q = q.qh->qh_next; in scan_periodic()
2694 modified = qh_completions(oxu, temp.qh); in scan_periodic()
2695 if (unlikely(list_empty(&temp.qh->qtd_list))) in scan_periodic()
2696 intr_deschedule(oxu, temp.qh); in scan_periodic()
2697 qh_put(temp.qh); in scan_periodic()
2803 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in unlink_async() argument
2806 if (qh->qh_state == QH_STATE_LINKED in unlink_async()
2815 qh->qh_state = QH_STATE_UNLINK_WAIT; in unlink_async()
2816 last->reclaim = qh; in unlink_async()
2823 if (qh->qh_state == QH_STATE_LINKED) in unlink_async()
2824 start_unlink_async(oxu, qh); in unlink_async()
3022 oxu->async->qh_next.qh = NULL; in oxu_hcd_init()
3334 struct ehci_qh *qh; in oxu_urb_dequeue() local
3342 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
3343 if (!qh) in oxu_urb_dequeue()
3345 unlink_async(oxu, qh); in oxu_urb_dequeue()
3349 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
3350 if (!qh) in oxu_urb_dequeue()
3352 switch (qh->qh_state) { in oxu_urb_dequeue()
3354 intr_deschedule(oxu, qh); in oxu_urb_dequeue()
3357 qh_completions(oxu, qh); in oxu_urb_dequeue()
3361 qh, qh->qh_state); in oxu_urb_dequeue()
3366 if (!list_empty(&qh->qtd_list) in oxu_urb_dequeue()
3370 status = qh_schedule(oxu, qh); in oxu_urb_dequeue()
3378 "can't reschedule qh %p, err %d\n", qh, in oxu_urb_dequeue()
3396 struct ehci_qh *qh, *tmp; in oxu_endpoint_disable() local
3403 qh = ep->hcpriv; in oxu_endpoint_disable()
3404 if (!qh) in oxu_endpoint_disable()
3410 if (qh->hw_info1 == 0) { in oxu_endpoint_disable()
3416 qh->qh_state = QH_STATE_IDLE; in oxu_endpoint_disable()
3417 switch (qh->qh_state) { in oxu_endpoint_disable()
3419 for (tmp = oxu->async->qh_next.qh; in oxu_endpoint_disable()
3420 tmp && tmp != qh; in oxu_endpoint_disable()
3421 tmp = tmp->qh_next.qh) in oxu_endpoint_disable()
3426 unlink_async(oxu, qh); in oxu_endpoint_disable()
3434 if (list_empty(&qh->qtd_list)) { in oxu_endpoint_disable()
3435 qh_put(qh); in oxu_endpoint_disable()
3445 qh, ep->desc.bEndpointAddress, qh->qh_state, in oxu_endpoint_disable()
3446 list_empty(&qh->qtd_list) ? "" : "(has tds)"); in oxu_endpoint_disable()
3969 if (oxu->async->qh_next.qh) in oxu_bus_resume()