Lines Matching refs:qh
294 struct ehci_qh *qh; /* Q_TYPE_QH */ member
1030 static void oxu_qh_free(struct oxu_hcd *oxu, struct ehci_qh *qh) in oxu_qh_free() argument
1036 index = qh - &oxu->mem->qh_pool[0]; in oxu_qh_free()
1044 struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref); in qh_destroy() local
1045 struct oxu_hcd *oxu = qh->oxu; in qh_destroy()
1048 if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) { in qh_destroy()
1052 if (qh->dummy) in qh_destroy()
1053 oxu_qtd_free(oxu, qh->dummy); in qh_destroy()
1054 oxu_qh_free(oxu, qh); in qh_destroy()
1060 struct ehci_qh *qh = NULL; in oxu_qh_alloc() local
1069 qh = (struct ehci_qh *) &oxu->mem->qh_pool[i]; in oxu_qh_alloc()
1070 memset(qh, 0, sizeof *qh); in oxu_qh_alloc()
1072 kref_init(&qh->kref); in oxu_qh_alloc()
1073 qh->oxu = oxu; in oxu_qh_alloc()
1074 qh->qh_dma = virt_to_phys(qh); in oxu_qh_alloc()
1075 INIT_LIST_HEAD(&qh->qtd_list); in oxu_qh_alloc()
1078 qh->dummy = ehci_qtd_alloc(oxu); in oxu_qh_alloc()
1079 if (qh->dummy == NULL) { in oxu_qh_alloc()
1082 qh = NULL; in oxu_qh_alloc()
1091 return qh; in oxu_qh_alloc()
1095 static inline struct ehci_qh *qh_get(struct ehci_qh *qh) in qh_get() argument
1097 kref_get(&qh->kref); in qh_get()
1098 return qh; in qh_get()
1101 static inline void qh_put(struct ehci_qh *qh) in qh_put() argument
1103 kref_put(&qh->kref, qh_destroy); in qh_put()
1245 struct ehci_qh *qh, struct ehci_qtd *qtd) in qh_update() argument
1248 BUG_ON(qh->qh_state != QH_STATE_IDLE); in qh_update()
1250 qh->hw_qtd_next = QTD_NEXT(qtd->qtd_dma); in qh_update()
1251 qh->hw_alt_next = EHCI_LIST_END; in qh_update()
1258 if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) { in qh_update()
1262 epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; in qh_update()
1263 if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { in qh_update()
1264 qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE); in qh_update()
1265 usb_settoggle(qh->dev, epnum, is_out, 1); in qh_update()
1271 qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); in qh_update()
1278 static void qh_refresh(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_refresh() argument
1282 if (list_empty(&qh->qtd_list)) in qh_refresh()
1283 qtd = qh->dummy; in qh_refresh()
1285 qtd = list_entry(qh->qtd_list.next, in qh_refresh()
1288 if (cpu_to_le32(qtd->qtd_dma) == qh->hw_current) in qh_refresh()
1293 qh_update(oxu, qh, qtd); in qh_refresh()
1353 struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; in ehci_urb_done() local
1356 if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) { in ehci_urb_done()
1361 qh_put(qh); in ehci_urb_done()
1395 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
1396 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
1398 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
1399 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
1407 static unsigned qh_completions(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_completions() argument
1409 struct ehci_qtd *last = NULL, *end = qh->dummy; in qh_completions()
1417 if (unlikely(list_empty(&qh->qtd_list))) in qh_completions()
1426 state = qh->qh_state; in qh_completions()
1427 qh->qh_state = QH_STATE_COMPLETING; in qh_completions()
1435 list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) { in qh_completions()
1512 == qh->hw_current) in qh_completions()
1513 token = le32_to_cpu(qh->hw_token); in qh_completions()
1519 if ((HALT_BIT & qh->hw_token) == 0) { in qh_completions()
1521 qh->hw_token |= HALT_BIT; in qh_completions()
1536 if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { in qh_completions()
1563 qh->qh_state = state; in qh_completions()
1569 if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) { in qh_completions()
1572 qh_refresh(oxu, qh); in qh_completions()
1579 & qh->hw_info2) != 0) { in qh_completions()
1580 intr_deschedule(oxu, qh); in qh_completions()
1581 (void) qh_schedule(oxu, qh); in qh_completions()
1583 unlink_async(oxu, qh); in qh_completions()
1783 struct ehci_qh *qh = oxu_qh_alloc(oxu); in qh_make() local
1788 if (!qh) in qh_make()
1789 return qh; in qh_make()
1810 qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, in qh_make()
1813 qh->start = NO_FRAME; in qh_make()
1816 qh->c_usecs = 0; in qh_make()
1817 qh->gap_uf = 0; in qh_make()
1819 qh->period = urb->interval >> 3; in qh_make()
1820 if (qh->period == 0 && urb->interval != 1) { in qh_make()
1834 qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed, in qh_make()
1839 qh->c_usecs = qh->usecs + HS_USECS(0); in qh_make()
1840 qh->usecs = HS_USECS(1); in qh_make()
1842 qh->usecs += HS_USECS(1); in qh_make()
1843 qh->c_usecs = HS_USECS(0); in qh_make()
1847 qh->tt_usecs = NS_TO_US(think_time + in qh_make()
1850 qh->period = urb->interval; in qh_make()
1855 qh->dev = urb->dev; in qh_make()
1899 qh_put(qh); in qh_make()
1906 qh->qh_state = QH_STATE_IDLE; in qh_make()
1907 qh->hw_info1 = cpu_to_le32(info1); in qh_make()
1908 qh->hw_info2 = cpu_to_le32(info2); in qh_make()
1910 qh_refresh(oxu, qh); in qh_make()
1911 return qh; in qh_make()
1916 static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_async() argument
1918 __le32 dma = QH_NEXT(qh->qh_dma); in qh_link_async()
1924 if (!head->qh_next.qh) { in qh_link_async()
1939 if (qh->qh_state == QH_STATE_IDLE) in qh_link_async()
1940 qh_refresh(oxu, qh); in qh_link_async()
1943 qh->qh_next = head->qh_next; in qh_link_async()
1944 qh->hw_next = head->hw_next; in qh_link_async()
1947 head->qh_next.qh = qh; in qh_link_async()
1950 qh->qh_state = QH_STATE_LINKED; in qh_link_async()
1966 struct ehci_qh *qh = NULL; in qh_append_tds() local
1968 qh = (struct ehci_qh *) *ptr; in qh_append_tds()
1969 if (unlikely(qh == NULL)) { in qh_append_tds()
1971 qh = qh_make(oxu, urb, GFP_ATOMIC); in qh_append_tds()
1972 *ptr = qh; in qh_append_tds()
1974 if (likely(qh != NULL)) { in qh_append_tds()
1988 qh->hw_info1 &= ~QH_ADDR_MASK; in qh_append_tds()
2007 dummy = qh->dummy; in qh_append_tds()
2015 list_splice(qtd_list, qh->qtd_list.prev); in qh_append_tds()
2018 qh->dummy = qtd; in qh_append_tds()
2022 qtd = list_entry(qh->qtd_list.prev, in qh_append_tds()
2031 urb->hcpriv = qh_get(qh); in qh_append_tds()
2034 return qh; in qh_append_tds()
2042 struct ehci_qh *qh = NULL; in submit_async() local
2062 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in submit_async()
2063 if (unlikely(qh == NULL)) { in submit_async()
2071 if (likely(qh->qh_state == QH_STATE_IDLE)) in submit_async()
2072 qh_link_async(oxu, qh_get(qh)); in submit_async()
2075 if (unlikely(qh == NULL)) in submit_async()
2084 struct ehci_qh *qh = oxu->reclaim; in end_unlink_async() local
2089 qh->qh_state = QH_STATE_IDLE; in end_unlink_async()
2090 qh->qh_next.qh = NULL; in end_unlink_async()
2091 qh_put(qh); /* refcount from reclaim */ in end_unlink_async()
2094 next = qh->reclaim; in end_unlink_async()
2097 qh->reclaim = NULL; in end_unlink_async()
2099 qh_completions(oxu, qh); in end_unlink_async()
2101 if (!list_empty(&qh->qtd_list) in end_unlink_async()
2103 qh_link_async(oxu, qh); in end_unlink_async()
2105 qh_put(qh); /* refcount from async list */ in end_unlink_async()
2111 && oxu->async->qh_next.qh == NULL) in end_unlink_async()
2124 static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in start_unlink_async() argument
2131 BUG_ON(oxu->reclaim || (qh->qh_state != QH_STATE_LINKED in start_unlink_async()
2132 && qh->qh_state != QH_STATE_UNLINK_WAIT)); in start_unlink_async()
2136 if (unlikely(qh == oxu->async)) { in start_unlink_async()
2149 qh->qh_state = QH_STATE_UNLINK; in start_unlink_async()
2150 oxu->reclaim = qh = qh_get(qh); in start_unlink_async()
2153 while (prev->qh_next.qh != qh) in start_unlink_async()
2154 prev = prev->qh_next.qh; in start_unlink_async()
2156 prev->hw_next = qh->hw_next; in start_unlink_async()
2157 prev->qh_next = qh->qh_next; in start_unlink_async()
2177 struct ehci_qh *qh; in scan_async() local
2184 qh = oxu->async->qh_next.qh; in scan_async()
2185 if (likely(qh != NULL)) { in scan_async()
2188 if (!list_empty(&qh->qtd_list) in scan_async()
2189 && qh->stamp != oxu->stamp) { in scan_async()
2197 qh = qh_get(qh); in scan_async()
2198 qh->stamp = oxu->stamp; in scan_async()
2199 temp = qh_completions(oxu, qh); in scan_async()
2200 qh_put(qh); in scan_async()
2211 if (list_empty(&qh->qtd_list)) { in scan_async()
2212 if (qh->stamp == oxu->stamp) in scan_async()
2215 && qh->qh_state == QH_STATE_LINKED) in scan_async()
2216 start_unlink_async(oxu, qh); in scan_async()
2219 qh = qh->qh_next.qh; in scan_async()
2220 } while (qh); in scan_async()
2237 return &periodic->qh->qh_next; in periodic_next_shadow()
2278 if (q->qh->hw_info2 & cpu_to_le32(1 << uframe)) in periodic_usecs()
2279 usecs += q->qh->usecs; in periodic_usecs()
2281 if (q->qh->hw_info2 & cpu_to_le32(1 << (8 + uframe))) in periodic_usecs()
2282 usecs += q->qh->c_usecs; in periodic_usecs()
2283 hw_p = &q->qh->hw_next; in periodic_usecs()
2284 q = &q->qh->qh_next; in periodic_usecs()
2351 static int qh_link_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_link_periodic() argument
2354 unsigned period = qh->period; in qh_link_periodic()
2356 dev_dbg(&qh->dev->dev, in qh_link_periodic()
2358 period, le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_link_periodic()
2359 qh, qh->start, qh->usecs, qh->c_usecs); in qh_link_periodic()
2365 for (i = qh->start; i < oxu->periodic_size; i += period) { in qh_link_periodic()
2377 hw_p = &here.qh->hw_next; in qh_link_periodic()
2384 while (here.ptr && qh != here.qh) { in qh_link_periodic()
2385 if (qh->period > here.qh->period) in qh_link_periodic()
2387 prev = &here.qh->qh_next; in qh_link_periodic()
2388 hw_p = &here.qh->hw_next; in qh_link_periodic()
2392 if (qh != here.qh) { in qh_link_periodic()
2393 qh->qh_next = here; in qh_link_periodic()
2394 if (here.qh) in qh_link_periodic()
2395 qh->hw_next = *hw_p; in qh_link_periodic()
2397 prev->qh = qh; in qh_link_periodic()
2398 *hw_p = QH_NEXT(qh->qh_dma); in qh_link_periodic()
2401 qh->qh_state = QH_STATE_LINKED; in qh_link_periodic()
2402 qh_get(qh); in qh_link_periodic()
2405 oxu_to_hcd(oxu)->self.bandwidth_allocated += qh->period in qh_link_periodic()
2406 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_link_periodic()
2407 : (qh->usecs * 8); in qh_link_periodic()
2416 static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_unlink_periodic() argument
2430 period = qh->period; in qh_unlink_periodic()
2434 for (i = qh->start; i < oxu->periodic_size; i += period) in qh_unlink_periodic()
2435 periodic_unlink(oxu, i, qh); in qh_unlink_periodic()
2438 oxu_to_hcd(oxu)->self.bandwidth_allocated -= qh->period in qh_unlink_periodic()
2439 ? ((qh->usecs + qh->c_usecs) / qh->period) in qh_unlink_periodic()
2440 : (qh->usecs * 8); in qh_unlink_periodic()
2442 dev_dbg(&qh->dev->dev, in qh_unlink_periodic()
2444 qh->period, in qh_unlink_periodic()
2445 le32_to_cpup(&qh->hw_info2) & (QH_CMASK | QH_SMASK), in qh_unlink_periodic()
2446 qh, qh->start, qh->usecs, qh->c_usecs); in qh_unlink_periodic()
2449 qh->qh_state = QH_STATE_UNLINK; in qh_unlink_periodic()
2450 qh->qh_next.ptr = NULL; in qh_unlink_periodic()
2451 qh_put(qh); in qh_unlink_periodic()
2459 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in intr_deschedule() argument
2463 qh_unlink_periodic(oxu, qh); in intr_deschedule()
2470 if (list_empty(&qh->qtd_list) in intr_deschedule()
2471 || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) in intr_deschedule()
2477 qh->qh_state = QH_STATE_IDLE; in intr_deschedule()
2478 qh->hw_next = EHCI_LIST_END; in intr_deschedule()
2526 const struct ehci_qh *qh, __le32 *c_maskp) in check_intr_schedule() argument
2530 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ in check_intr_schedule()
2533 if (!check_period(oxu, frame, uframe, qh->period, qh->usecs)) in check_intr_schedule()
2535 if (!qh->c_usecs) { in check_intr_schedule()
2548 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh) in qh_schedule() argument
2555 qh_refresh(oxu, qh); in qh_schedule()
2556 qh->hw_next = EHCI_LIST_END; in qh_schedule()
2557 frame = qh->start; in qh_schedule()
2560 if (frame < qh->period) { in qh_schedule()
2561 uframe = ffs(le32_to_cpup(&qh->hw_info2) & QH_SMASK); in qh_schedule()
2563 qh, &c_mask); in qh_schedule()
2575 if (qh->period) { in qh_schedule()
2576 frame = qh->period - 1; in qh_schedule()
2580 frame, uframe, qh, in qh_schedule()
2590 status = check_intr_schedule(oxu, 0, 0, qh, &c_mask); in qh_schedule()
2594 qh->start = frame; in qh_schedule()
2597 qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK)); in qh_schedule()
2598 qh->hw_info2 |= qh->period in qh_schedule()
2601 qh->hw_info2 |= c_mask; in qh_schedule()
2603 oxu_dbg(oxu, "reused qh %p schedule\n", qh); in qh_schedule()
2606 status = qh_link_periodic(oxu, qh); in qh_schedule()
2616 struct ehci_qh *qh; in intr_submit() local
2632 qh = qh_append_tds(oxu, urb, &empty, epnum, &urb->ep->hcpriv); in intr_submit()
2633 if (qh == NULL) { in intr_submit()
2637 if (qh->qh_state == QH_STATE_IDLE) { in intr_submit()
2638 status = qh_schedule(oxu, qh); in intr_submit()
2644 qh = qh_append_tds(oxu, urb, qtd_list, epnum, &urb->ep->hcpriv); in intr_submit()
2645 BUG_ON(qh == NULL); in intr_submit()
2716 temp.qh = qh_get(q.qh); in scan_periodic()
2717 type = Q_NEXT_TYPE(q.qh->hw_next); in scan_periodic()
2718 q = q.qh->qh_next; in scan_periodic()
2719 modified = qh_completions(oxu, temp.qh); in scan_periodic()
2720 if (unlikely(list_empty(&temp.qh->qtd_list))) in scan_periodic()
2721 intr_deschedule(oxu, temp.qh); in scan_periodic()
2722 qh_put(temp.qh); in scan_periodic()
2828 static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) in unlink_async() argument
2831 if (qh->qh_state == QH_STATE_LINKED in unlink_async()
2840 qh->qh_state = QH_STATE_UNLINK_WAIT; in unlink_async()
2841 last->reclaim = qh; in unlink_async()
2848 if (qh->qh_state == QH_STATE_LINKED) in unlink_async()
2849 start_unlink_async(oxu, qh); in unlink_async()
3047 oxu->async->qh_next.qh = NULL; in oxu_hcd_init()
3359 struct ehci_qh *qh; in oxu_urb_dequeue() local
3367 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
3368 if (!qh) in oxu_urb_dequeue()
3370 unlink_async(oxu, qh); in oxu_urb_dequeue()
3374 qh = (struct ehci_qh *) urb->hcpriv; in oxu_urb_dequeue()
3375 if (!qh) in oxu_urb_dequeue()
3377 switch (qh->qh_state) { in oxu_urb_dequeue()
3379 intr_deschedule(oxu, qh); in oxu_urb_dequeue()
3382 qh_completions(oxu, qh); in oxu_urb_dequeue()
3386 qh, qh->qh_state); in oxu_urb_dequeue()
3391 if (!list_empty(&qh->qtd_list) in oxu_urb_dequeue()
3395 status = qh_schedule(oxu, qh); in oxu_urb_dequeue()
3403 "can't reschedule qh %p, err %d\n", qh, in oxu_urb_dequeue()
3421 struct ehci_qh *qh, *tmp; in oxu_endpoint_disable() local
3428 qh = ep->hcpriv; in oxu_endpoint_disable()
3429 if (!qh) in oxu_endpoint_disable()
3435 if (qh->hw_info1 == 0) { in oxu_endpoint_disable()
3441 qh->qh_state = QH_STATE_IDLE; in oxu_endpoint_disable()
3442 switch (qh->qh_state) { in oxu_endpoint_disable()
3444 for (tmp = oxu->async->qh_next.qh; in oxu_endpoint_disable()
3445 tmp && tmp != qh; in oxu_endpoint_disable()
3446 tmp = tmp->qh_next.qh) in oxu_endpoint_disable()
3451 unlink_async(oxu, qh); in oxu_endpoint_disable()
3459 if (list_empty(&qh->qtd_list)) { in oxu_endpoint_disable()
3460 qh_put(qh); in oxu_endpoint_disable()
3470 qh, ep->desc.bEndpointAddress, qh->qh_state, in oxu_endpoint_disable()
3471 list_empty(&qh->qtd_list) ? "" : "(has tds)"); in oxu_endpoint_disable()
3992 if (oxu->async->qh_next.qh) in oxu_bus_resume()