Lines Matching refs:qh
606 static void oxu_qh_free(struct oxu_hcd *oxu, struct ehci_qh *qh) in oxu_qh_free() argument
612 index = qh - &oxu->mem->qh_pool[0]; in oxu_qh_free()
620 struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref); in qh_destroy() local
621 struct oxu_hcd *oxu = qh->oxu; in qh_destroy()
624 if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) { in qh_destroy()
628 if (qh->dummy) in qh_destroy()
629 oxu_qtd_free(oxu, qh->dummy); in qh_destroy()
630 oxu_qh_free(oxu, qh); in qh_destroy()
636 struct ehci_qh *qh = NULL; in oxu_qh_alloc() local
645 qh = (struct ehci_qh *) &oxu->mem->qh_pool[i]; in oxu_qh_alloc()
646 memset(qh, 0, sizeof *qh); in oxu_qh_alloc()
648 kref_init(&qh->kref); in oxu_qh_alloc()
649 qh->oxu = oxu; in oxu_qh_alloc()
650 qh->qh_dma = virt_to_phys(qh); in oxu_qh_alloc()
651 INIT_LIST_HEAD(&qh->qtd_list); in oxu_qh_alloc()
654 qh->dummy = ehci_qtd_alloc(oxu); in oxu_qh_alloc()
655 if (qh->dummy == NULL) { in oxu_qh_alloc()
658 qh = NULL; in oxu_qh_alloc()
667 return qh; in oxu_qh_alloc()
671 static inline struct ehci_qh *qh_get(struct ehci_qh *qh) in qh_get() argument
673 kref_get(&qh->kref); in qh_get()
674 return qh; in qh_get()
677 static inline void qh_put(struct ehci_qh *qh) in qh_put() argument
679 kref_put(&qh->kref, qh_destroy); in qh_put()
821 struct ehci_qh *qh, struct ehci_qtd *qtd) in qh_update() argument
824 BUG_ON(qh->qh_state != QH_STATE_IDLE); in qh_update()
826 qh->hw_qtd_next = QTD_NEXT(qtd->qtd_dma); in qh_update()
827 qh->hw_alt_next = EHCI_LIST_END; in qh_update()
834 if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) { in qh_update()
838 epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; in qh_update()
839 if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { in qh_update()
840 qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE); in qh_update()
841 usb_settoggle(qh->dev, epnum, is_out, 1); in qh_update()
847 qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); in qh_update()
854 static void qh_refresh(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_refresh() argument
858 if (list_empty(&qh->qtd_list)) in qh_refresh()
859 qtd = qh->dummy; in qh_refresh()
861 qtd = list_entry(qh->qtd_list.next, in qh_refresh()
864 if (cpu_to_le32(qtd->qtd_dma) == qh->hw_current) in qh_refresh()
869 qh_update(oxu, qh, qtd); in qh_refresh()
929 struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; in ehci_urb_done() local
932 if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) { in ehci_urb_done()
937 qh_put(qh); in ehci_urb_done()
970 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
971 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
973 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
974 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
982 static unsigned qh_completions(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_completions() argument
984 struct ehci_qtd *last = NULL, *end = qh->dummy; in qh_completions()
992 if (unlikely(list_empty(&qh->qtd_list))) in qh_completions()
1001 state = qh->qh_state; in qh_completions()
1002 qh->qh_state = QH_STATE_COMPLETING; in qh_completions()
1010 list_for_each_safe(entry, tmp, &qh->qtd_list) { in qh_completions()
1089 == qh->hw_current) in qh_completions()
1090 token = le32_to_cpu(qh->hw_token); in qh_completions()
1096 if ((HALT_BIT & qh->hw_token) == 0) { in qh_completions()
1098 qh->hw_token |= HALT_BIT; in qh_completions()
1113 if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { in qh_completions()
1140 qh->qh_state = state; in qh_completions()
1146 if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) { in qh_completions()
1149 qh_refresh(oxu, qh); in qh_completions()
1156 & qh->hw_info2) != 0) { in qh_completions()
1157 intr_deschedule(oxu, qh); in qh_completions()
1158 (void) qh_schedule(oxu, qh); in qh_completions()
1160 unlink_async(oxu, qh); in qh_completions()
1363 struct ehci_qh *qh = oxu_qh_alloc(oxu); in qh_make() local
1368 if (!qh) in qh_make()
1369 return qh; in qh_make()
1390 qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, in qh_make()
1393 qh->start = NO_FRAME; in qh_make()
1396 qh->c_usecs = 0; in qh_make()
1397 qh->gap_uf = 0; in qh_make()
1399 qh->period = urb->interval >> 3; in qh_make()
1400 if (qh->period == 0 && urb->interval != 1) { in qh_make()
1414 qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed, in qh_make()
1419 qh->c_usecs = qh->usecs + HS_USECS(0); in qh_make()
1420 qh->usecs = HS_USECS(1); in qh_make()
1422 qh->usecs += HS_USECS(1); in qh_make()
1423 qh->c_usecs = HS_USECS(0); in qh_make()
1427 qh->tt_usecs = NS_TO_US(think_time + in qh_make()
1430 qh->period = urb->interval; in qh_make()
1435 qh->dev = urb->dev; in qh_make()
1479 qh_put(qh); in qh_make()
1486 qh->qh_state = QH_STATE_IDLE; in qh_make()
1487 qh->hw_info1 = cpu_to_le32(info1); in qh_make()
1488 qh->hw_info2 = cpu_to_le32(info2); in qh_make()
1490 qh_refresh(oxu, qh); in qh_make()
1491 return qh; in qh_make()
1496 static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_async() argument
1498 __le32 dma = QH_NEXT(qh->qh_dma); in qh_link_async()
1504 if (!head->qh_next.qh) { in qh_link_async()
1519 if (qh->qh_state == QH_STATE_IDLE) in qh_link_async()
1520 qh_refresh(oxu, qh); in qh_link_async()
1523 qh->qh_next = head->qh_next; in qh_link_async()
1524 qh->hw_next = head->hw_next; in qh_link_async()
1527 head->qh_next.qh = qh; in qh_link_async()
1530 qh->qh_state = QH_STATE_LINKED; in qh_link_async()
1546 struct ehci_qh *qh = NULL; in qh_append_tds() local
1548 qh = (struct ehci_qh *) *ptr; in qh_append_tds()
1549 if (unlikely(qh == NULL)) { in qh_append_tds()
1551 qh = qh_make(oxu, urb, GFP_ATOMIC); in qh_append_tds()
1552 *ptr = qh; in qh_append_tds()
1554 if (likely(qh != NULL)) { in qh_append_tds()
1568 qh->hw_info1 &= ~QH_ADDR_MASK; in qh_append_tds()
1587 dummy = qh->dummy; in qh_append_tds()
1595 list_splice(qtd_list, qh->qtd_list.prev); in qh_append_tds()
1598 qh->dummy = qtd; in qh_append_tds()
1602 qtd = list_entry(qh->qtd_list.prev, in qh_append_tds()
1611 urb->hcpriv = qh_get(qh); in qh_append_tds()
1614 return qh; in qh_append_tds()
1623 struct ehci_qh *qh = NULL; in submit_async() local
1643 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in submit_async()
1644 if (unlikely(qh == NULL)) { in submit_async()
1652 if (likely(qh->qh_state == QH_STATE_IDLE)) in submit_async()
1653 qh_link_async(oxu, qh_get(qh)); in submit_async()
1656 if (unlikely(qh == NULL)) in submit_async()
1665 struct ehci_qh *qh = oxu->reclaim; in end_unlink_async() local
1670 qh->qh_state = QH_STATE_IDLE; in end_unlink_async()
1671 qh->qh_next.qh = NULL; in end_unlink_async()
1672 qh_put(qh); /* refcount from reclaim */ in end_unlink_async()
1675 next = qh->reclaim; in end_unlink_async()
1678 qh->reclaim = NULL; in end_unlink_async()
1680 qh_completions(oxu, qh); in end_unlink_async()
1682 if (!list_empty(&qh->qtd_list) in end_unlink_async()
1684 qh_link_async(oxu, qh); in end_unlink_async()
1686 qh_put(qh); /* refcount from async list */ in end_unlink_async()
1692 && oxu->async->qh_next.qh == NULL) in end_unlink_async()
1705 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in start_unlink_async() argument
1712 if (oxu->reclaim || (qh->qh_state != QH_STATE_LINKED in start_unlink_async()
1713 && qh->qh_state != QH_STATE_UNLINK_WAIT)) in start_unlink_async()
1718 if (unlikely(qh == oxu->async)) { in start_unlink_async()
1731 qh->qh_state = QH_STATE_UNLINK; in start_unlink_async()
1732 oxu->reclaim = qh = qh_get(qh); in start_unlink_async()
1735 while (prev->qh_next.qh != qh) in start_unlink_async()
1736 prev = prev->qh_next.qh; in start_unlink_async()
1738 prev->hw_next = qh->hw_next; in start_unlink_async()
1739 prev->qh_next = qh->qh_next; in start_unlink_async()
1759 struct ehci_qh *qh; in scan_async() local
1766 qh = oxu->async->qh_next.qh; in scan_async()
1767 if (likely(qh != NULL)) { in scan_async()
1770 if (!list_empty(&qh->qtd_list) in scan_async()
1771 && qh->stamp != oxu->stamp) { in scan_async()
1779 qh = qh_get(qh); in scan_async()
1780 qh->stamp = oxu->stamp; in scan_async()
1781 temp = qh_completions(oxu, qh); in scan_async()
1782 qh_put(qh); in scan_async()
1793 if (list_empty(&qh->qtd_list)) { in scan_async()
1794 if (qh->stamp == oxu->stamp) in scan_async()
1797 && qh->qh_state == QH_STATE_LINKED) in scan_async()
1798 start_unlink_async(oxu, qh); in scan_async()
1801 qh = qh->qh_next.qh; in scan_async()
1802 } while (qh); in scan_async()
1819 return &periodic->qh->qh_next; in periodic_next_shadow()
1860 if (q->qh->hw_info2 & cpu_to_le32(1 << uframe)) in periodic_usecs()
1861 usecs += q->qh->usecs; in periodic_usecs()
1863 if (q->qh->hw_info2 & cpu_to_le32(1 << (8 + uframe))) in periodic_usecs()
1864 usecs += q->qh->c_usecs; in periodic_usecs()
1865 hw_p = &q->qh->hw_next; in periodic_usecs()
1866 q = &q->qh->qh_next; in periodic_usecs()
1933 static int qh_link_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_periodic() argument
1936 unsigned period = qh->period; in qh_link_periodic()
1938 dev_dbg(&qh->dev->dev, in qh_link_periodic()
1940 period, le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_link_periodic()
1941 qh, qh->start, qh->usecs, qh->c_usecs); in qh_link_periodic()
1947 for (i = qh->start; i < oxu->periodic_size; i += period) { in qh_link_periodic()
1959 hw_p = &here.qh->hw_next; in qh_link_periodic()
1966 while (here.ptr && qh != here.qh) { in qh_link_periodic()
1967 if (qh->period > here.qh->period) in qh_link_periodic()
1969 prev = &here.qh->qh_next; in qh_link_periodic()
1970 hw_p = &here.qh->hw_next; in qh_link_periodic()
1974 if (qh != here.qh) { in qh_link_periodic()
1975 qh->qh_next = here; in qh_link_periodic()
1976 if (here.qh) in qh_link_periodic()
1977 qh->hw_next = *hw_p; in qh_link_periodic()
1979 prev->qh = qh; in qh_link_periodic()
1980 *hw_p = QH_NEXT(qh->qh_dma); in qh_link_periodic()
1983 qh->qh_state = QH_STATE_LINKED; in qh_link_periodic()
1984 qh_get(qh); in qh_link_periodic()
1987 oxu_to_hcd(oxu)->self.bandwidth_allocated += qh->period in qh_link_periodic()
1988 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_link_periodic()
1989 : (qh->usecs * 8); in qh_link_periodic()
1998 static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_unlink_periodic() argument
2012 period = qh->period; in qh_unlink_periodic()
2016 for (i = qh->start; i < oxu->periodic_size; i += period) in qh_unlink_periodic()
2017 periodic_unlink(oxu, i, qh); in qh_unlink_periodic()
2020 oxu_to_hcd(oxu)->self.bandwidth_allocated -= qh->period in qh_unlink_periodic()
2021 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_unlink_periodic()
2022 : (qh->usecs * 8); in qh_unlink_periodic()
2024 dev_dbg(&qh->dev->dev, in qh_unlink_periodic()
2026 qh->period, in qh_unlink_periodic()
2027 le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_unlink_periodic()
2028 qh, qh->start, qh->usecs, qh->c_usecs); in qh_unlink_periodic()
2031 qh->qh_state = QH_STATE_UNLINK; in qh_unlink_periodic()
2032 qh->qh_next.ptr = NULL; in qh_unlink_periodic()
2033 qh_put(qh); in qh_unlink_periodic()
2041 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in intr_deschedule() argument
2045 qh_unlink_periodic(oxu, qh); in intr_deschedule()
2052 if (list_empty(&qh->qtd_list) in intr_deschedule()
2053 || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) in intr_deschedule()
2059 qh->qh_state = QH_STATE_IDLE; in intr_deschedule()
2060 qh->hw_next = EHCI_LIST_END; in intr_deschedule()
2108 const struct ehci_qh *qh, __le32 *c_maskp) in check_intr_schedule() argument
2112 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ in check_intr_schedule()
2115 if (!check_period(oxu, frame, uframe, qh->period, qh->usecs)) in check_intr_schedule()
2117 if (!qh->c_usecs) { in check_intr_schedule()
2130 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_schedule() argument
2137 qh_refresh(oxu, qh); in qh_schedule()
2138 qh->hw_next = EHCI_LIST_END; in qh_schedule()
2139 frame = qh->start; in qh_schedule()
2142 if (frame < qh->period) { in qh_schedule()
2143 uframe = ffs(le32_to_cpup(&qh->hw_info2) & QH_SMASK); in qh_schedule()
2145 qh, &c_mask); in qh_schedule()
2157 if (qh->period) { in qh_schedule()
2158 frame = qh->period - 1; in qh_schedule()
2162 frame, uframe, qh, in qh_schedule()
2172 status = check_intr_schedule(oxu, 0, 0, qh, &c_mask); in qh_schedule()
2176 qh->start = frame; in qh_schedule()
2179 qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK)); in qh_schedule()
2180 qh->hw_info2 |= qh->period in qh_schedule()
2183 qh->hw_info2 |= c_mask; in qh_schedule()
2185 oxu_dbg(oxu, "reused qh %p schedule\n", qh); in qh_schedule()
2188 status = qh_link_periodic(oxu, qh); in qh_schedule()
2198 struct ehci_qh *qh; in intr_submit() local
2214 qh = qh_append_tds(oxu, urb, &empty, epnum, &urb->ep->hcpriv); in intr_submit()
2215 if (qh == NULL) { in intr_submit()
2219 if (qh->qh_state == QH_STATE_IDLE) { in intr_submit()
2220 status = qh_schedule(oxu, qh); in intr_submit()
2226 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in intr_submit()
2227 BUG_ON(qh == NULL); in intr_submit()
2304 temp.qh = qh_get(q.qh); in scan_periodic()
2305 type = Q_NEXT_TYPE(q.qh->hw_next); in scan_periodic()
2306 q = q.qh->qh_next; in scan_periodic()
2307 modified = qh_completions(oxu, temp.qh); in scan_periodic()
2308 if (unlikely(list_empty(&temp.qh->qtd_list))) in scan_periodic()
2309 intr_deschedule(oxu, temp.qh); in scan_periodic()
2310 qh_put(temp.qh); in scan_periodic()
2412 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in unlink_async() argument
2415 if (qh->qh_state == QH_STATE_LINKED in unlink_async()
2424 qh->qh_state = QH_STATE_UNLINK_WAIT; in unlink_async()
2425 last->reclaim = qh; in unlink_async()
2432 if (qh->qh_state == QH_STATE_LINKED) in unlink_async()
2433 start_unlink_async(oxu, qh); in unlink_async()
2631 oxu->async->qh_next.qh = NULL; in oxu_hcd_init()
2948 struct ehci_qh *qh; in oxu_urb_dequeue() local
2956 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
2957 if (!qh) in oxu_urb_dequeue()
2959 unlink_async(oxu, qh); in oxu_urb_dequeue()
2963 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
2964 if (!qh) in oxu_urb_dequeue()
2966 switch (qh->qh_state) { in oxu_urb_dequeue()
2968 intr_deschedule(oxu, qh); in oxu_urb_dequeue()
2971 qh_completions(oxu, qh); in oxu_urb_dequeue()
2975 qh, qh->qh_state); in oxu_urb_dequeue()
2980 if (!list_empty(&qh->qtd_list) in oxu_urb_dequeue()
2984 status = qh_schedule(oxu, qh); in oxu_urb_dequeue()
2992 "can't reschedule qh %p, err %d\n", qh, in oxu_urb_dequeue()
3010 struct ehci_qh *qh, *tmp; in oxu_endpoint_disable() local
3017 qh = ep->hcpriv; in oxu_endpoint_disable()
3018 if (!qh) in oxu_endpoint_disable()
3024 if (qh->hw_info1 == 0) { in oxu_endpoint_disable()
3030 qh->qh_state = QH_STATE_IDLE; in oxu_endpoint_disable()
3031 switch (qh->qh_state) { in oxu_endpoint_disable()
3033 for (tmp = oxu->async->qh_next.qh; in oxu_endpoint_disable()
3034 tmp && tmp != qh; in oxu_endpoint_disable()
3035 tmp = tmp->qh_next.qh) in oxu_endpoint_disable()
3040 unlink_async(oxu, qh); in oxu_endpoint_disable()
3048 if (list_empty(&qh->qtd_list)) { in oxu_endpoint_disable()
3049 qh_put(qh); in oxu_endpoint_disable()
3059 qh, ep->desc.bEndpointAddress, qh->qh_state, in oxu_endpoint_disable()
3060 list_empty(&qh->qtd_list) ? "" : "(has tds)"); in oxu_endpoint_disable()
3581 if (oxu->async->qh_next.qh) in oxu_bus_resume()