11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Universal Host Controller Interface driver for USB. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Maintainer: Alan Stern <stern@rowland.harvard.edu> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * (C) Copyright 1999 Linus Torvalds 71da177e4SLinus Torvalds * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 81da177e4SLinus Torvalds * (C) Copyright 1999 Randy Dunlap 91da177e4SLinus Torvalds * (C) Copyright 1999 Georg Acher, acher@in.tum.de 101da177e4SLinus Torvalds * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de 111da177e4SLinus Torvalds * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch 121da177e4SLinus Torvalds * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at 131da177e4SLinus Torvalds * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 141da177e4SLinus Torvalds * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 151da177e4SLinus Torvalds * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 16b761d9d8SAlan Stern * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu 171da177e4SLinus Torvalds */ 181da177e4SLinus Torvalds 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /* 211da177e4SLinus Torvalds * Technically, updating td->status here is a race, but it's not really a 221da177e4SLinus Torvalds * problem. The worst that can happen is that we set the IOC bit again 231da177e4SLinus Torvalds * generating a spurious interrupt. We could fix this by creating another 241da177e4SLinus Torvalds * QH and leaving the IOC bit always set, but then we would have to play 251da177e4SLinus Torvalds * games with the FSBR code to make sure we get the correct order in all 261da177e4SLinus Torvalds * the cases. I don't think it's worth the effort 271da177e4SLinus Torvalds */ 28dccf4a48SAlan Stern static void uhci_set_next_interrupt(struct uhci_hcd *uhci) 291da177e4SLinus Torvalds { 306c1b445cSAlan Stern if (uhci->is_stopped) 311f09df8bSAlan Stern mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); 321da177e4SLinus Torvalds uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 331da177e4SLinus Torvalds } 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) 361da177e4SLinus Torvalds { 371da177e4SLinus Torvalds uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); 381da177e4SLinus Torvalds } 391da177e4SLinus Torvalds 4084afddd7SAlan Stern 4184afddd7SAlan Stern /* 4284afddd7SAlan Stern * Full-Speed Bandwidth Reclamation (FSBR). 4384afddd7SAlan Stern * We turn on FSBR whenever a queue that wants it is advancing, 4484afddd7SAlan Stern * and leave it on for a short time thereafter. 4584afddd7SAlan Stern */ 4684afddd7SAlan Stern static void uhci_fsbr_on(struct uhci_hcd *uhci) 4784afddd7SAlan Stern { 4884afddd7SAlan Stern uhci->fsbr_is_on = 1; 4984afddd7SAlan Stern uhci->skel_term_qh->link = cpu_to_le32( 5084afddd7SAlan Stern uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; 5184afddd7SAlan Stern } 5284afddd7SAlan Stern 5384afddd7SAlan Stern static void uhci_fsbr_off(struct uhci_hcd *uhci) 5484afddd7SAlan Stern { 5584afddd7SAlan Stern uhci->fsbr_is_on = 0; 5684afddd7SAlan Stern uhci->skel_term_qh->link = UHCI_PTR_TERM; 5784afddd7SAlan Stern } 5884afddd7SAlan Stern 5984afddd7SAlan Stern static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) 6084afddd7SAlan Stern { 6184afddd7SAlan Stern struct urb_priv *urbp = urb->hcpriv; 6284afddd7SAlan Stern 6384afddd7SAlan Stern if (!(urb->transfer_flags & URB_NO_FSBR)) 6484afddd7SAlan Stern urbp->fsbr = 1; 6584afddd7SAlan Stern } 6684afddd7SAlan Stern 67c5e3b741SAlan Stern static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp) 6884afddd7SAlan Stern { 6984afddd7SAlan Stern if (urbp->fsbr) { 70c5e3b741SAlan Stern uhci->fsbr_is_wanted = 1; 7184afddd7SAlan Stern if (!uhci->fsbr_is_on) 7284afddd7SAlan Stern uhci_fsbr_on(uhci); 73c5e3b741SAlan Stern else if (uhci->fsbr_expiring) { 74c5e3b741SAlan Stern uhci->fsbr_expiring = 0; 75c5e3b741SAlan Stern del_timer(&uhci->fsbr_timer); 7684afddd7SAlan Stern } 7784afddd7SAlan Stern } 78c5e3b741SAlan Stern } 79c5e3b741SAlan Stern 80c5e3b741SAlan Stern static void uhci_fsbr_timeout(unsigned long _uhci) 81c5e3b741SAlan Stern { 82c5e3b741SAlan Stern struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci; 83c5e3b741SAlan Stern unsigned long flags; 84c5e3b741SAlan Stern 85c5e3b741SAlan Stern spin_lock_irqsave(&uhci->lock, flags); 86c5e3b741SAlan Stern if (uhci->fsbr_expiring) { 87c5e3b741SAlan Stern uhci->fsbr_expiring = 0; 88c5e3b741SAlan Stern uhci_fsbr_off(uhci); 89c5e3b741SAlan Stern } 90c5e3b741SAlan Stern spin_unlock_irqrestore(&uhci->lock, flags); 91c5e3b741SAlan Stern } 9284afddd7SAlan Stern 9384afddd7SAlan Stern 942532178aSAlan Stern static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) 951da177e4SLinus Torvalds { 961da177e4SLinus Torvalds dma_addr_t dma_handle; 971da177e4SLinus Torvalds struct uhci_td *td; 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); 1001da177e4SLinus Torvalds if (!td) 1011da177e4SLinus Torvalds return NULL; 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds td->dma_handle = dma_handle; 1041da177e4SLinus Torvalds td->frame = -1; 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds INIT_LIST_HEAD(&td->list); 1071da177e4SLinus Torvalds INIT_LIST_HEAD(&td->fl_list); 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds return td; 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds 112dccf4a48SAlan Stern static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) 113dccf4a48SAlan Stern { 114dccf4a48SAlan Stern if (!list_empty(&td->list)) 115dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); 116dccf4a48SAlan Stern if (!list_empty(&td->fl_list)) 117dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 118dccf4a48SAlan Stern 119dccf4a48SAlan Stern dma_pool_free(uhci->td_pool, td, td->dma_handle); 120dccf4a48SAlan Stern } 121dccf4a48SAlan Stern 1221da177e4SLinus Torvalds static inline void uhci_fill_td(struct uhci_td *td, u32 status, 1231da177e4SLinus Torvalds u32 token, u32 buffer) 1241da177e4SLinus Torvalds { 1251da177e4SLinus Torvalds td->status = cpu_to_le32(status); 1261da177e4SLinus Torvalds td->token = cpu_to_le32(token); 1271da177e4SLinus Torvalds td->buffer = cpu_to_le32(buffer); 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 13004538a25SAlan Stern static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp) 13104538a25SAlan Stern { 13204538a25SAlan Stern list_add_tail(&td->list, &urbp->td_list); 13304538a25SAlan Stern } 13404538a25SAlan Stern 13504538a25SAlan Stern static void uhci_remove_td_from_urbp(struct uhci_td *td) 13604538a25SAlan Stern { 13704538a25SAlan Stern list_del_init(&td->list); 13804538a25SAlan Stern } 13904538a25SAlan Stern 1401da177e4SLinus Torvalds /* 141687f5f34SAlan Stern * We insert Isochronous URBs directly into the frame list at the beginning 1421da177e4SLinus Torvalds */ 143dccf4a48SAlan Stern static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, 144dccf4a48SAlan Stern struct uhci_td *td, unsigned framenum) 1451da177e4SLinus Torvalds { 1461da177e4SLinus Torvalds framenum &= (UHCI_NUMFRAMES - 1); 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds td->frame = framenum; 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds /* Is there a TD already mapped there? */ 151a1d59ce8SAlan Stern if (uhci->frame_cpu[framenum]) { 1521da177e4SLinus Torvalds struct uhci_td *ftd, *ltd; 1531da177e4SLinus Torvalds 154a1d59ce8SAlan Stern ftd = uhci->frame_cpu[framenum]; 1551da177e4SLinus Torvalds ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds list_add_tail(&td->fl_list, &ftd->fl_list); 1581da177e4SLinus Torvalds 1591da177e4SLinus Torvalds td->link = ltd->link; 1601da177e4SLinus Torvalds wmb(); 1611da177e4SLinus Torvalds ltd->link = cpu_to_le32(td->dma_handle); 1621da177e4SLinus Torvalds } else { 163a1d59ce8SAlan Stern td->link = uhci->frame[framenum]; 1641da177e4SLinus Torvalds wmb(); 165a1d59ce8SAlan Stern uhci->frame[framenum] = cpu_to_le32(td->dma_handle); 166a1d59ce8SAlan Stern uhci->frame_cpu[framenum] = td; 1671da177e4SLinus Torvalds } 1681da177e4SLinus Torvalds } 1691da177e4SLinus Torvalds 170dccf4a48SAlan Stern static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, 171b81d3436SAlan Stern struct uhci_td *td) 1721da177e4SLinus Torvalds { 1731da177e4SLinus Torvalds /* If it's not inserted, don't remove it */ 174b81d3436SAlan Stern if (td->frame == -1) { 175b81d3436SAlan Stern WARN_ON(!list_empty(&td->fl_list)); 1761da177e4SLinus Torvalds return; 177b81d3436SAlan Stern } 1781da177e4SLinus Torvalds 179b81d3436SAlan Stern if (uhci->frame_cpu[td->frame] == td) { 1801da177e4SLinus Torvalds if (list_empty(&td->fl_list)) { 181a1d59ce8SAlan Stern uhci->frame[td->frame] = td->link; 182a1d59ce8SAlan Stern uhci->frame_cpu[td->frame] = NULL; 1831da177e4SLinus Torvalds } else { 1841da177e4SLinus Torvalds struct uhci_td *ntd; 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); 187a1d59ce8SAlan Stern uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); 188a1d59ce8SAlan Stern uhci->frame_cpu[td->frame] = ntd; 1891da177e4SLinus Torvalds } 1901da177e4SLinus Torvalds } else { 1911da177e4SLinus Torvalds struct uhci_td *ptd; 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list); 1941da177e4SLinus Torvalds ptd->link = td->link; 1951da177e4SLinus Torvalds } 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds list_del_init(&td->fl_list); 1981da177e4SLinus Torvalds td->frame = -1; 1991da177e4SLinus Torvalds } 2001da177e4SLinus Torvalds 201c8155cc5SAlan Stern static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci, 202c8155cc5SAlan Stern unsigned int framenum) 203c8155cc5SAlan Stern { 204c8155cc5SAlan Stern struct uhci_td *ftd, *ltd; 205c8155cc5SAlan Stern 206c8155cc5SAlan Stern framenum &= (UHCI_NUMFRAMES - 1); 207c8155cc5SAlan Stern 208c8155cc5SAlan Stern ftd = uhci->frame_cpu[framenum]; 209c8155cc5SAlan Stern if (ftd) { 210c8155cc5SAlan Stern ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); 211c8155cc5SAlan Stern uhci->frame[framenum] = ltd->link; 212c8155cc5SAlan Stern uhci->frame_cpu[framenum] = NULL; 213c8155cc5SAlan Stern 214c8155cc5SAlan Stern while (!list_empty(&ftd->fl_list)) 215c8155cc5SAlan Stern list_del_init(ftd->fl_list.prev); 216c8155cc5SAlan Stern } 217c8155cc5SAlan Stern } 218c8155cc5SAlan Stern 219dccf4a48SAlan Stern /* 220dccf4a48SAlan Stern * Remove all the TDs for an Isochronous URB from the frame list 221dccf4a48SAlan Stern */ 222dccf4a48SAlan Stern static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) 223b81d3436SAlan Stern { 224b81d3436SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 225b81d3436SAlan Stern struct uhci_td *td; 226b81d3436SAlan Stern 227b81d3436SAlan Stern list_for_each_entry(td, &urbp->td_list, list) 228dccf4a48SAlan Stern uhci_remove_td_from_frame_list(uhci, td); 229b81d3436SAlan Stern } 230b81d3436SAlan Stern 231dccf4a48SAlan Stern static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, 232dccf4a48SAlan Stern struct usb_device *udev, struct usb_host_endpoint *hep) 2331da177e4SLinus Torvalds { 2341da177e4SLinus Torvalds dma_addr_t dma_handle; 2351da177e4SLinus Torvalds struct uhci_qh *qh; 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); 2381da177e4SLinus Torvalds if (!qh) 2391da177e4SLinus Torvalds return NULL; 2401da177e4SLinus Torvalds 24159e29ed9SAlan Stern memset(qh, 0, sizeof(*qh)); 2421da177e4SLinus Torvalds qh->dma_handle = dma_handle; 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds qh->element = UHCI_PTR_TERM; 2451da177e4SLinus Torvalds qh->link = UHCI_PTR_TERM; 2461da177e4SLinus Torvalds 247dccf4a48SAlan Stern INIT_LIST_HEAD(&qh->queue); 248dccf4a48SAlan Stern INIT_LIST_HEAD(&qh->node); 2491da177e4SLinus Torvalds 250dccf4a48SAlan Stern if (udev) { /* Normal QH */ 251*85a975d0SAlan Stern qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 252*85a975d0SAlan Stern if (qh->type != USB_ENDPOINT_XFER_ISOC) { 253af0bb599SAlan Stern qh->dummy_td = uhci_alloc_td(uhci); 254af0bb599SAlan Stern if (!qh->dummy_td) { 255af0bb599SAlan Stern dma_pool_free(uhci->qh_pool, qh, dma_handle); 256af0bb599SAlan Stern return NULL; 257af0bb599SAlan Stern } 258*85a975d0SAlan Stern } 259dccf4a48SAlan Stern qh->state = QH_STATE_IDLE; 260dccf4a48SAlan Stern qh->hep = hep; 261dccf4a48SAlan Stern qh->udev = udev; 262dccf4a48SAlan Stern hep->hcpriv = qh; 2631da177e4SLinus Torvalds 264dccf4a48SAlan Stern } else { /* Skeleton QH */ 265dccf4a48SAlan Stern qh->state = QH_STATE_ACTIVE; 2664de7d2c2SAlan Stern qh->type = -1; 267dccf4a48SAlan Stern } 2681da177e4SLinus Torvalds return qh; 2691da177e4SLinus Torvalds } 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 2721da177e4SLinus Torvalds { 273dccf4a48SAlan Stern WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); 274dccf4a48SAlan Stern if (!list_empty(&qh->queue)) 2751da177e4SLinus Torvalds dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh); 2761da177e4SLinus Torvalds 277dccf4a48SAlan Stern list_del(&qh->node); 278dccf4a48SAlan Stern if (qh->udev) { 279dccf4a48SAlan Stern qh->hep->hcpriv = NULL; 280*85a975d0SAlan Stern if (qh->dummy_td) 281af0bb599SAlan Stern uhci_free_td(uhci, qh->dummy_td); 282dccf4a48SAlan Stern } 2831da177e4SLinus Torvalds dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); 2841da177e4SLinus Torvalds } 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds /* 287a0b458b6SAlan Stern * When a queue is stopped and a dequeued URB is given back, adjust 288a0b458b6SAlan Stern * the previous TD link (if the URB isn't first on the queue) or 289a0b458b6SAlan Stern * save its toggle value (if it is first and is currently executing). 29010b8e47dSAlan Stern * 29110b8e47dSAlan Stern * Returns 0 if the URB should not yet be given back, 1 otherwise. 2920ed8fee1SAlan Stern */ 29310b8e47dSAlan Stern static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, 294a0b458b6SAlan Stern struct urb *urb) 2950ed8fee1SAlan Stern { 296a0b458b6SAlan Stern struct urb_priv *urbp = urb->hcpriv; 2970ed8fee1SAlan Stern struct uhci_td *td; 29810b8e47dSAlan Stern int ret = 1; 2990ed8fee1SAlan Stern 300a0b458b6SAlan Stern /* Isochronous pipes don't use toggles and their TD link pointers 30110b8e47dSAlan Stern * get adjusted during uhci_urb_dequeue(). But since their queues 30210b8e47dSAlan Stern * cannot truly be stopped, we have to watch out for dequeues 30310b8e47dSAlan Stern * occurring after the nominal unlink frame. */ 30410b8e47dSAlan Stern if (qh->type == USB_ENDPOINT_XFER_ISOC) { 30510b8e47dSAlan Stern ret = (uhci->frame_number + uhci->is_stopped != 30610b8e47dSAlan Stern qh->unlink_frame); 307c5e3b741SAlan Stern goto done; 30810b8e47dSAlan Stern } 309a0b458b6SAlan Stern 310a0b458b6SAlan Stern /* If the URB isn't first on its queue, adjust the link pointer 311a0b458b6SAlan Stern * of the last TD in the previous URB. The toggle doesn't need 312a0b458b6SAlan Stern * to be saved since this URB can't be executing yet. */ 313a0b458b6SAlan Stern if (qh->queue.next != &urbp->node) { 314a0b458b6SAlan Stern struct urb_priv *purbp; 315a0b458b6SAlan Stern struct uhci_td *ptd; 316a0b458b6SAlan Stern 317a0b458b6SAlan Stern purbp = list_entry(urbp->node.prev, struct urb_priv, node); 318a0b458b6SAlan Stern WARN_ON(list_empty(&purbp->td_list)); 319a0b458b6SAlan Stern ptd = list_entry(purbp->td_list.prev, struct uhci_td, 320a0b458b6SAlan Stern list); 321a0b458b6SAlan Stern td = list_entry(urbp->td_list.prev, struct uhci_td, 322a0b458b6SAlan Stern list); 323a0b458b6SAlan Stern ptd->link = td->link; 324c5e3b741SAlan Stern goto done; 325a0b458b6SAlan Stern } 326a0b458b6SAlan Stern 3270ed8fee1SAlan Stern /* If the QH element pointer is UHCI_PTR_TERM then then currently 3280ed8fee1SAlan Stern * executing URB has already been unlinked, so this one isn't it. */ 329a0b458b6SAlan Stern if (qh_element(qh) == UHCI_PTR_TERM) 330c5e3b741SAlan Stern goto done; 3310ed8fee1SAlan Stern qh->element = UHCI_PTR_TERM; 3320ed8fee1SAlan Stern 333*85a975d0SAlan Stern /* Control pipes don't have to worry about toggles */ 334a0b458b6SAlan Stern if (qh->type == USB_ENDPOINT_XFER_CONTROL) 335c5e3b741SAlan Stern goto done; 3360ed8fee1SAlan Stern 337a0b458b6SAlan Stern /* Save the next toggle value */ 33859e29ed9SAlan Stern WARN_ON(list_empty(&urbp->td_list)); 33959e29ed9SAlan Stern td = list_entry(urbp->td_list.next, struct uhci_td, list); 3400ed8fee1SAlan Stern qh->needs_fixup = 1; 3410ed8fee1SAlan Stern qh->initial_toggle = uhci_toggle(td_token(td)); 342c5e3b741SAlan Stern 343c5e3b741SAlan Stern done: 34410b8e47dSAlan Stern return ret; 3450ed8fee1SAlan Stern } 3460ed8fee1SAlan Stern 3470ed8fee1SAlan Stern /* 3480ed8fee1SAlan Stern * Fix up the data toggles for URBs in a queue, when one of them 3490ed8fee1SAlan Stern * terminates early (short transfer, error, or dequeued). 3500ed8fee1SAlan Stern */ 3510ed8fee1SAlan Stern static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) 3520ed8fee1SAlan Stern { 3530ed8fee1SAlan Stern struct urb_priv *urbp = NULL; 3540ed8fee1SAlan Stern struct uhci_td *td; 3550ed8fee1SAlan Stern unsigned int toggle = qh->initial_toggle; 3560ed8fee1SAlan Stern unsigned int pipe; 3570ed8fee1SAlan Stern 3580ed8fee1SAlan Stern /* Fixups for a short transfer start with the second URB in the 3590ed8fee1SAlan Stern * queue (the short URB is the first). */ 3600ed8fee1SAlan Stern if (skip_first) 3610ed8fee1SAlan Stern urbp = list_entry(qh->queue.next, struct urb_priv, node); 3620ed8fee1SAlan Stern 3630ed8fee1SAlan Stern /* When starting with the first URB, if the QH element pointer is 3640ed8fee1SAlan Stern * still valid then we know the URB's toggles are okay. */ 3650ed8fee1SAlan Stern else if (qh_element(qh) != UHCI_PTR_TERM) 3660ed8fee1SAlan Stern toggle = 2; 3670ed8fee1SAlan Stern 3680ed8fee1SAlan Stern /* Fix up the toggle for the URBs in the queue. Normally this 3690ed8fee1SAlan Stern * loop won't run more than once: When an error or short transfer 3700ed8fee1SAlan Stern * occurs, the queue usually gets emptied. */ 3711393adb2SAlan Stern urbp = list_prepare_entry(urbp, &qh->queue, node); 3720ed8fee1SAlan Stern list_for_each_entry_continue(urbp, &qh->queue, node) { 3730ed8fee1SAlan Stern 3740ed8fee1SAlan Stern /* If the first TD has the right toggle value, we don't 3750ed8fee1SAlan Stern * need to change any toggles in this URB */ 3760ed8fee1SAlan Stern td = list_entry(urbp->td_list.next, struct uhci_td, list); 3770ed8fee1SAlan Stern if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { 378db59b464SAlan Stern td = list_entry(urbp->td_list.prev, struct uhci_td, 3790ed8fee1SAlan Stern list); 3800ed8fee1SAlan Stern toggle = uhci_toggle(td_token(td)) ^ 1; 3810ed8fee1SAlan Stern 3820ed8fee1SAlan Stern /* Otherwise all the toggles in the URB have to be switched */ 3830ed8fee1SAlan Stern } else { 3840ed8fee1SAlan Stern list_for_each_entry(td, &urbp->td_list, list) { 3850ed8fee1SAlan Stern td->token ^= __constant_cpu_to_le32( 3860ed8fee1SAlan Stern TD_TOKEN_TOGGLE); 3870ed8fee1SAlan Stern toggle ^= 1; 3880ed8fee1SAlan Stern } 3890ed8fee1SAlan Stern } 3900ed8fee1SAlan Stern } 3910ed8fee1SAlan Stern 3920ed8fee1SAlan Stern wmb(); 3930ed8fee1SAlan Stern pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe; 3940ed8fee1SAlan Stern usb_settoggle(qh->udev, usb_pipeendpoint(pipe), 3950ed8fee1SAlan Stern usb_pipeout(pipe), toggle); 3960ed8fee1SAlan Stern qh->needs_fixup = 0; 3970ed8fee1SAlan Stern } 3980ed8fee1SAlan Stern 3990ed8fee1SAlan Stern /* 400dccf4a48SAlan Stern * Put a QH on the schedule in both hardware and software 4011da177e4SLinus Torvalds */ 402dccf4a48SAlan Stern static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 4031da177e4SLinus Torvalds { 4041da177e4SLinus Torvalds struct uhci_qh *pqh; 4051da177e4SLinus Torvalds 406dccf4a48SAlan Stern WARN_ON(list_empty(&qh->queue)); 407dccf4a48SAlan Stern 408dccf4a48SAlan Stern /* Set the element pointer if it isn't set already. 409dccf4a48SAlan Stern * This isn't needed for Isochronous queues, but it doesn't hurt. */ 410dccf4a48SAlan Stern if (qh_element(qh) == UHCI_PTR_TERM) { 411dccf4a48SAlan Stern struct urb_priv *urbp = list_entry(qh->queue.next, 412dccf4a48SAlan Stern struct urb_priv, node); 413dccf4a48SAlan Stern struct uhci_td *td = list_entry(urbp->td_list.next, 414dccf4a48SAlan Stern struct uhci_td, list); 415dccf4a48SAlan Stern 416dccf4a48SAlan Stern qh->element = cpu_to_le32(td->dma_handle); 417dccf4a48SAlan Stern } 418dccf4a48SAlan Stern 41984afddd7SAlan Stern /* Treat the queue as if it has just advanced */ 42084afddd7SAlan Stern qh->wait_expired = 0; 42184afddd7SAlan Stern qh->advance_jiffies = jiffies; 42284afddd7SAlan Stern 423dccf4a48SAlan Stern if (qh->state == QH_STATE_ACTIVE) 4241da177e4SLinus Torvalds return; 425dccf4a48SAlan Stern qh->state = QH_STATE_ACTIVE; 426dccf4a48SAlan Stern 427dccf4a48SAlan Stern /* Move the QH from its old list to the end of the appropriate 428dccf4a48SAlan Stern * skeleton's list */ 4290ed8fee1SAlan Stern if (qh == uhci->next_qh) 4300ed8fee1SAlan Stern uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, 4310ed8fee1SAlan Stern node); 432dccf4a48SAlan Stern list_move_tail(&qh->node, &qh->skel->node); 433dccf4a48SAlan Stern 434dccf4a48SAlan Stern /* Link it into the schedule */ 435dccf4a48SAlan Stern pqh = list_entry(qh->node.prev, struct uhci_qh, node); 436dccf4a48SAlan Stern qh->link = pqh->link; 437dccf4a48SAlan Stern wmb(); 438dccf4a48SAlan Stern pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); 439dccf4a48SAlan Stern } 4401da177e4SLinus Torvalds 4411da177e4SLinus Torvalds /* 442dccf4a48SAlan Stern * Take a QH off the hardware schedule 4431da177e4SLinus Torvalds */ 444dccf4a48SAlan Stern static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 445dccf4a48SAlan Stern { 446dccf4a48SAlan Stern struct uhci_qh *pqh; 4471da177e4SLinus Torvalds 448dccf4a48SAlan Stern if (qh->state == QH_STATE_UNLINKING) 449dccf4a48SAlan Stern return; 450dccf4a48SAlan Stern WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev); 451dccf4a48SAlan Stern qh->state = QH_STATE_UNLINKING; 4521da177e4SLinus Torvalds 453dccf4a48SAlan Stern /* Unlink the QH from the schedule and record when we did it */ 454dccf4a48SAlan Stern pqh = list_entry(qh->node.prev, struct uhci_qh, node); 455dccf4a48SAlan Stern pqh->link = qh->link; 456dccf4a48SAlan Stern mb(); 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 459dccf4a48SAlan Stern qh->unlink_frame = uhci->frame_number; 4601da177e4SLinus Torvalds 461dccf4a48SAlan Stern /* Force an interrupt so we know when the QH is fully unlinked */ 462dccf4a48SAlan Stern if (list_empty(&uhci->skel_unlink_qh->node)) 4631da177e4SLinus Torvalds uhci_set_next_interrupt(uhci); 4641da177e4SLinus Torvalds 465dccf4a48SAlan Stern /* Move the QH from its old list to the end of the unlinking list */ 4660ed8fee1SAlan Stern if (qh == uhci->next_qh) 4670ed8fee1SAlan Stern uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, 4680ed8fee1SAlan Stern node); 469dccf4a48SAlan Stern list_move_tail(&qh->node, &uhci->skel_unlink_qh->node); 4701da177e4SLinus Torvalds } 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds /* 473dccf4a48SAlan Stern * When we and the controller are through with a QH, it becomes IDLE. 474dccf4a48SAlan Stern * This happens when a QH has been off the schedule (on the unlinking 475dccf4a48SAlan Stern * list) for more than one frame, or when an error occurs while adding 476dccf4a48SAlan Stern * the first URB onto a new QH. 4771da177e4SLinus Torvalds */ 478dccf4a48SAlan Stern static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) 479dccf4a48SAlan Stern { 480dccf4a48SAlan Stern WARN_ON(qh->state == QH_STATE_ACTIVE); 481dccf4a48SAlan Stern 4820ed8fee1SAlan Stern if (qh == uhci->next_qh) 4830ed8fee1SAlan Stern uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, 4840ed8fee1SAlan Stern node); 485dccf4a48SAlan Stern list_move(&qh->node, &uhci->idle_qh_list); 486dccf4a48SAlan Stern qh->state = QH_STATE_IDLE; 487dccf4a48SAlan Stern 48859e29ed9SAlan Stern /* Now that the QH is idle, its post_td isn't being used */ 48959e29ed9SAlan Stern if (qh->post_td) { 49059e29ed9SAlan Stern uhci_free_td(uhci, qh->post_td); 49159e29ed9SAlan Stern qh->post_td = NULL; 49259e29ed9SAlan Stern } 49359e29ed9SAlan Stern 494dccf4a48SAlan Stern /* If anyone is waiting for a QH to become idle, wake them up */ 495dccf4a48SAlan Stern if (uhci->num_waiting) 496dccf4a48SAlan Stern wake_up_all(&uhci->waitqh); 4971da177e4SLinus Torvalds } 4981da177e4SLinus Torvalds 499dccf4a48SAlan Stern static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, 500dccf4a48SAlan Stern struct urb *urb) 5011da177e4SLinus Torvalds { 5021da177e4SLinus Torvalds struct urb_priv *urbp; 5031da177e4SLinus Torvalds 50454e6ecb2SChristoph Lameter urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC); 5051da177e4SLinus Torvalds if (!urbp) 5061da177e4SLinus Torvalds return NULL; 5071da177e4SLinus Torvalds 5081da177e4SLinus Torvalds memset((void *)urbp, 0, sizeof(*urbp)); 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvalds urbp->urb = urb; 5111da177e4SLinus Torvalds urb->hcpriv = urbp; 512dccf4a48SAlan Stern 513dccf4a48SAlan Stern INIT_LIST_HEAD(&urbp->node); 514dccf4a48SAlan Stern INIT_LIST_HEAD(&urbp->td_list); 5151da177e4SLinus Torvalds 5161da177e4SLinus Torvalds return urbp; 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 519dccf4a48SAlan Stern static void uhci_free_urb_priv(struct uhci_hcd *uhci, 520dccf4a48SAlan Stern struct urb_priv *urbp) 5211da177e4SLinus Torvalds { 5221da177e4SLinus Torvalds struct uhci_td *td, *tmp; 5231da177e4SLinus Torvalds 524dccf4a48SAlan Stern if (!list_empty(&urbp->node)) 525dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", 526dccf4a48SAlan Stern urbp->urb); 5271da177e4SLinus Torvalds 5281da177e4SLinus Torvalds list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { 52904538a25SAlan Stern uhci_remove_td_from_urbp(td); 53004538a25SAlan Stern uhci_free_td(uhci, td); 5311da177e4SLinus Torvalds } 5321da177e4SLinus Torvalds 533dccf4a48SAlan Stern urbp->urb->hcpriv = NULL; 5341da177e4SLinus Torvalds kmem_cache_free(uhci_up_cachep, urbp); 5351da177e4SLinus Torvalds } 5361da177e4SLinus Torvalds 5371da177e4SLinus Torvalds /* 5381da177e4SLinus Torvalds * Map status to standard result codes 5391da177e4SLinus Torvalds * 5401da177e4SLinus Torvalds * <status> is (td_status(td) & 0xF60000), a.k.a. 5411da177e4SLinus Torvalds * uhci_status_bits(td_status(td)). 5421da177e4SLinus Torvalds * Note: <status> does not include the TD_CTRL_NAK bit. 5431da177e4SLinus Torvalds * <dir_out> is True for output TDs and False for input TDs. 5441da177e4SLinus Torvalds */ 5451da177e4SLinus Torvalds static int uhci_map_status(int status, int dir_out) 5461da177e4SLinus Torvalds { 5471da177e4SLinus Torvalds if (!status) 5481da177e4SLinus Torvalds return 0; 5491da177e4SLinus Torvalds if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */ 5501da177e4SLinus Torvalds return -EPROTO; 5511da177e4SLinus Torvalds if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */ 5521da177e4SLinus Torvalds if (dir_out) 5531da177e4SLinus Torvalds return -EPROTO; 5541da177e4SLinus Torvalds else 5551da177e4SLinus Torvalds return -EILSEQ; 5561da177e4SLinus Torvalds } 5571da177e4SLinus Torvalds if (status & TD_CTRL_BABBLE) /* Babble */ 5581da177e4SLinus Torvalds return -EOVERFLOW; 5591da177e4SLinus Torvalds if (status & TD_CTRL_DBUFERR) /* Buffer error */ 5601da177e4SLinus Torvalds return -ENOSR; 5611da177e4SLinus Torvalds if (status & TD_CTRL_STALLED) /* Stalled */ 5621da177e4SLinus Torvalds return -EPIPE; 5631da177e4SLinus Torvalds return 0; 5641da177e4SLinus Torvalds } 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds /* 5671da177e4SLinus Torvalds * Control transfers 5681da177e4SLinus Torvalds */ 569dccf4a48SAlan Stern static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, 570dccf4a48SAlan Stern struct uhci_qh *qh) 5711da177e4SLinus Torvalds { 5721da177e4SLinus Torvalds struct uhci_td *td; 5731da177e4SLinus Torvalds unsigned long destination, status; 574dccf4a48SAlan Stern int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 5751da177e4SLinus Torvalds int len = urb->transfer_buffer_length; 5761da177e4SLinus Torvalds dma_addr_t data = urb->transfer_dma; 577dccf4a48SAlan Stern __le32 *plink; 57804538a25SAlan Stern struct urb_priv *urbp = urb->hcpriv; 5791da177e4SLinus Torvalds 5801da177e4SLinus Torvalds /* The "pipe" thing contains the destination in bits 8--18 */ 5811da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 5821da177e4SLinus Torvalds 583af0bb599SAlan Stern /* 3 errors, dummy TD remains inactive */ 584af0bb599SAlan Stern status = uhci_maxerr(3); 5851da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 5861da177e4SLinus Torvalds status |= TD_CTRL_LS; 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds /* 5891da177e4SLinus Torvalds * Build the TD for the control request setup packet 5901da177e4SLinus Torvalds */ 591af0bb599SAlan Stern td = qh->dummy_td; 59204538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 593fa346568SAlan Stern uhci_fill_td(td, status, destination | uhci_explen(8), 5941da177e4SLinus Torvalds urb->setup_dma); 595dccf4a48SAlan Stern plink = &td->link; 596af0bb599SAlan Stern status |= TD_CTRL_ACTIVE; 5971da177e4SLinus Torvalds 5981da177e4SLinus Torvalds /* 5991da177e4SLinus Torvalds * If direction is "send", change the packet ID from SETUP (0x2D) 6001da177e4SLinus Torvalds * to OUT (0xE1). Else change it from SETUP to IN (0x69) and 6011da177e4SLinus Torvalds * set Short Packet Detect (SPD) for all data packets. 6021da177e4SLinus Torvalds */ 6031da177e4SLinus Torvalds if (usb_pipeout(urb->pipe)) 6041da177e4SLinus Torvalds destination ^= (USB_PID_SETUP ^ USB_PID_OUT); 6051da177e4SLinus Torvalds else { 6061da177e4SLinus Torvalds destination ^= (USB_PID_SETUP ^ USB_PID_IN); 6071da177e4SLinus Torvalds status |= TD_CTRL_SPD; 6081da177e4SLinus Torvalds } 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds /* 611687f5f34SAlan Stern * Build the DATA TDs 6121da177e4SLinus Torvalds */ 6131da177e4SLinus Torvalds while (len > 0) { 614dccf4a48SAlan Stern int pktsze = min(len, maxsze); 6151da177e4SLinus Torvalds 6162532178aSAlan Stern td = uhci_alloc_td(uhci); 6171da177e4SLinus Torvalds if (!td) 618af0bb599SAlan Stern goto nomem; 619dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 6201da177e4SLinus Torvalds 6211da177e4SLinus Torvalds /* Alternate Data0/1 (start with Data1) */ 6221da177e4SLinus Torvalds destination ^= TD_TOKEN_TOGGLE; 6231da177e4SLinus Torvalds 62404538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 625fa346568SAlan Stern uhci_fill_td(td, status, destination | uhci_explen(pktsze), 6261da177e4SLinus Torvalds data); 627dccf4a48SAlan Stern plink = &td->link; 6281da177e4SLinus Torvalds 6291da177e4SLinus Torvalds data += pktsze; 6301da177e4SLinus Torvalds len -= pktsze; 6311da177e4SLinus Torvalds } 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds /* 6341da177e4SLinus Torvalds * Build the final TD for control status 6351da177e4SLinus Torvalds */ 6362532178aSAlan Stern td = uhci_alloc_td(uhci); 6371da177e4SLinus Torvalds if (!td) 638af0bb599SAlan Stern goto nomem; 639dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds /* 6421da177e4SLinus Torvalds * It's IN if the pipe is an output pipe or we're not expecting 6431da177e4SLinus Torvalds * data back. 6441da177e4SLinus Torvalds */ 6451da177e4SLinus Torvalds destination &= ~TD_TOKEN_PID_MASK; 6461da177e4SLinus Torvalds if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) 6471da177e4SLinus Torvalds destination |= USB_PID_IN; 6481da177e4SLinus Torvalds else 6491da177e4SLinus Torvalds destination |= USB_PID_OUT; 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds status &= ~TD_CTRL_SPD; 6541da177e4SLinus Torvalds 65504538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 6561da177e4SLinus Torvalds uhci_fill_td(td, status | TD_CTRL_IOC, 657fa346568SAlan Stern destination | uhci_explen(0), 0); 658af0bb599SAlan Stern plink = &td->link; 659af0bb599SAlan Stern 660af0bb599SAlan Stern /* 661af0bb599SAlan Stern * Build the new dummy TD and activate the old one 662af0bb599SAlan Stern */ 663af0bb599SAlan Stern td = uhci_alloc_td(uhci); 664af0bb599SAlan Stern if (!td) 665af0bb599SAlan Stern goto nomem; 666af0bb599SAlan Stern *plink = cpu_to_le32(td->dma_handle); 667af0bb599SAlan Stern 668af0bb599SAlan Stern uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 669af0bb599SAlan Stern wmb(); 670af0bb599SAlan Stern qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 671af0bb599SAlan Stern qh->dummy_td = td; 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* Low-speed transfers get a different queue, and won't hog the bus. 6741da177e4SLinus Torvalds * Also, some devices enumerate better without FSBR; the easiest way 6751da177e4SLinus Torvalds * to do that is to put URBs on the low-speed queue while the device 676630aa3cfSAlan Stern * isn't in the CONFIGURED state. */ 6771da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW || 678630aa3cfSAlan Stern urb->dev->state != USB_STATE_CONFIGURED) 679dccf4a48SAlan Stern qh->skel = uhci->skel_ls_control_qh; 6801da177e4SLinus Torvalds else { 681dccf4a48SAlan Stern qh->skel = uhci->skel_fs_control_qh; 68284afddd7SAlan Stern uhci_add_fsbr(uhci, urb); 6831da177e4SLinus Torvalds } 68459e29ed9SAlan Stern 68559e29ed9SAlan Stern urb->actual_length = -8; /* Account for the SETUP packet */ 686dccf4a48SAlan Stern return 0; 687af0bb599SAlan Stern 688af0bb599SAlan Stern nomem: 689af0bb599SAlan Stern /* Remove the dummy TD from the td_list so it doesn't get freed */ 69004538a25SAlan Stern uhci_remove_td_from_urbp(qh->dummy_td); 691af0bb599SAlan Stern return -ENOMEM; 6921da177e4SLinus Torvalds } 6931da177e4SLinus Torvalds 6941da177e4SLinus Torvalds /* 6951da177e4SLinus Torvalds * Common submit for bulk and interrupt 6961da177e4SLinus Torvalds */ 697dccf4a48SAlan Stern static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, 698dccf4a48SAlan Stern struct uhci_qh *qh) 6991da177e4SLinus Torvalds { 7001da177e4SLinus Torvalds struct uhci_td *td; 7011da177e4SLinus Torvalds unsigned long destination, status; 702dccf4a48SAlan Stern int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 7031da177e4SLinus Torvalds int len = urb->transfer_buffer_length; 7041da177e4SLinus Torvalds dma_addr_t data = urb->transfer_dma; 705af0bb599SAlan Stern __le32 *plink; 70604538a25SAlan Stern struct urb_priv *urbp = urb->hcpriv; 707af0bb599SAlan Stern unsigned int toggle; 7081da177e4SLinus Torvalds 7091da177e4SLinus Torvalds if (len < 0) 7101da177e4SLinus Torvalds return -EINVAL; 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds /* The "pipe" thing contains the destination in bits 8--18 */ 7131da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 714af0bb599SAlan Stern toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), 715af0bb599SAlan Stern usb_pipeout(urb->pipe)); 7161da177e4SLinus Torvalds 717af0bb599SAlan Stern /* 3 errors, dummy TD remains inactive */ 718af0bb599SAlan Stern status = uhci_maxerr(3); 7191da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 7201da177e4SLinus Torvalds status |= TD_CTRL_LS; 7211da177e4SLinus Torvalds if (usb_pipein(urb->pipe)) 7221da177e4SLinus Torvalds status |= TD_CTRL_SPD; 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds /* 725687f5f34SAlan Stern * Build the DATA TDs 7261da177e4SLinus Torvalds */ 727af0bb599SAlan Stern plink = NULL; 728af0bb599SAlan Stern td = qh->dummy_td; 7291da177e4SLinus Torvalds do { /* Allow zero length packets */ 7301da177e4SLinus Torvalds int pktsze = maxsze; 7311da177e4SLinus Torvalds 732dccf4a48SAlan Stern if (len <= pktsze) { /* The last packet */ 7331da177e4SLinus Torvalds pktsze = len; 7341da177e4SLinus Torvalds if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) 7351da177e4SLinus Torvalds status &= ~TD_CTRL_SPD; 7361da177e4SLinus Torvalds } 7371da177e4SLinus Torvalds 738af0bb599SAlan Stern if (plink) { 7392532178aSAlan Stern td = uhci_alloc_td(uhci); 7401da177e4SLinus Torvalds if (!td) 741af0bb599SAlan Stern goto nomem; 742dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 743af0bb599SAlan Stern } 74404538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 745dccf4a48SAlan Stern uhci_fill_td(td, status, 746dccf4a48SAlan Stern destination | uhci_explen(pktsze) | 747af0bb599SAlan Stern (toggle << TD_TOKEN_TOGGLE_SHIFT), 7481da177e4SLinus Torvalds data); 749dccf4a48SAlan Stern plink = &td->link; 750af0bb599SAlan Stern status |= TD_CTRL_ACTIVE; 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds data += pktsze; 7531da177e4SLinus Torvalds len -= maxsze; 754af0bb599SAlan Stern toggle ^= 1; 7551da177e4SLinus Torvalds } while (len > 0); 7561da177e4SLinus Torvalds 7571da177e4SLinus Torvalds /* 7581da177e4SLinus Torvalds * URB_ZERO_PACKET means adding a 0-length packet, if direction 7591da177e4SLinus Torvalds * is OUT and the transfer_length was an exact multiple of maxsze, 7601da177e4SLinus Torvalds * hence (len = transfer_length - N * maxsze) == 0 7611da177e4SLinus Torvalds * however, if transfer_length == 0, the zero packet was already 7621da177e4SLinus Torvalds * prepared above. 7631da177e4SLinus Torvalds */ 764dccf4a48SAlan Stern if ((urb->transfer_flags & URB_ZERO_PACKET) && 765dccf4a48SAlan Stern usb_pipeout(urb->pipe) && len == 0 && 766dccf4a48SAlan Stern urb->transfer_buffer_length > 0) { 7672532178aSAlan Stern td = uhci_alloc_td(uhci); 7681da177e4SLinus Torvalds if (!td) 769af0bb599SAlan Stern goto nomem; 770dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 7711da177e4SLinus Torvalds 77204538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 773af0bb599SAlan Stern uhci_fill_td(td, status, 774af0bb599SAlan Stern destination | uhci_explen(0) | 775af0bb599SAlan Stern (toggle << TD_TOKEN_TOGGLE_SHIFT), 7761da177e4SLinus Torvalds data); 777af0bb599SAlan Stern plink = &td->link; 7781da177e4SLinus Torvalds 779af0bb599SAlan Stern toggle ^= 1; 7801da177e4SLinus Torvalds } 7811da177e4SLinus Torvalds 7821da177e4SLinus Torvalds /* Set the interrupt-on-completion flag on the last packet. 7831da177e4SLinus Torvalds * A more-or-less typical 4 KB URB (= size of one memory page) 7841da177e4SLinus Torvalds * will require about 3 ms to transfer; that's a little on the 7851da177e4SLinus Torvalds * fast side but not enough to justify delaying an interrupt 7861da177e4SLinus Torvalds * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT 7871da177e4SLinus Torvalds * flag setting. */ 788dccf4a48SAlan Stern td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 7891da177e4SLinus Torvalds 790af0bb599SAlan Stern /* 791af0bb599SAlan Stern * Build the new dummy TD and activate the old one 792af0bb599SAlan Stern */ 793af0bb599SAlan Stern td = uhci_alloc_td(uhci); 794af0bb599SAlan Stern if (!td) 795af0bb599SAlan Stern goto nomem; 796af0bb599SAlan Stern *plink = cpu_to_le32(td->dma_handle); 797af0bb599SAlan Stern 798af0bb599SAlan Stern uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 799af0bb599SAlan Stern wmb(); 800af0bb599SAlan Stern qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 801af0bb599SAlan Stern qh->dummy_td = td; 802caf3827aSAlan Stern qh->period = urb->interval; 803af0bb599SAlan Stern 804af0bb599SAlan Stern usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 805af0bb599SAlan Stern usb_pipeout(urb->pipe), toggle); 806dccf4a48SAlan Stern return 0; 807af0bb599SAlan Stern 808af0bb599SAlan Stern nomem: 809af0bb599SAlan Stern /* Remove the dummy TD from the td_list so it doesn't get freed */ 81004538a25SAlan Stern uhci_remove_td_from_urbp(qh->dummy_td); 811af0bb599SAlan Stern return -ENOMEM; 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds 814dccf4a48SAlan Stern static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, 815dccf4a48SAlan Stern struct uhci_qh *qh) 8161da177e4SLinus Torvalds { 8171da177e4SLinus Torvalds int ret; 8181da177e4SLinus Torvalds 8191da177e4SLinus Torvalds /* Can't have low-speed bulk transfers */ 8201da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 8211da177e4SLinus Torvalds return -EINVAL; 8221da177e4SLinus Torvalds 823dccf4a48SAlan Stern qh->skel = uhci->skel_bulk_qh; 824dccf4a48SAlan Stern ret = uhci_submit_common(uhci, urb, qh); 825dccf4a48SAlan Stern if (ret == 0) 82684afddd7SAlan Stern uhci_add_fsbr(uhci, urb); 8271da177e4SLinus Torvalds return ret; 8281da177e4SLinus Torvalds } 8291da177e4SLinus Torvalds 830caf3827aSAlan Stern static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, 831dccf4a48SAlan Stern struct uhci_qh *qh) 8321da177e4SLinus Torvalds { 833caf3827aSAlan Stern int exponent; 834caf3827aSAlan Stern 835dccf4a48SAlan Stern /* USB 1.1 interrupt transfers only involve one packet per interval. 836dccf4a48SAlan Stern * Drivers can submit URBs of any length, but longer ones will need 837dccf4a48SAlan Stern * multiple intervals to complete. 8381da177e4SLinus Torvalds */ 839caf3827aSAlan Stern 840caf3827aSAlan Stern /* Figure out which power-of-two queue to use */ 841caf3827aSAlan Stern for (exponent = 7; exponent >= 0; --exponent) { 842caf3827aSAlan Stern if ((1 << exponent) <= urb->interval) 843caf3827aSAlan Stern break; 844caf3827aSAlan Stern } 845caf3827aSAlan Stern if (exponent < 0) 846caf3827aSAlan Stern return -EINVAL; 847caf3827aSAlan Stern urb->interval = 1 << exponent; 848caf3827aSAlan Stern 849caf3827aSAlan Stern if (qh->period == 0) 850caf3827aSAlan Stern qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; 851caf3827aSAlan Stern else if (qh->period != urb->interval) 852caf3827aSAlan Stern return -EINVAL; /* Can't change the period */ 853caf3827aSAlan Stern 854dccf4a48SAlan Stern return uhci_submit_common(uhci, urb, qh); 8551da177e4SLinus Torvalds } 8561da177e4SLinus Torvalds 8571da177e4SLinus Torvalds /* 858b1869000SAlan Stern * Fix up the data structures following a short transfer 859b1869000SAlan Stern */ 860b1869000SAlan Stern static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, 86159e29ed9SAlan Stern struct uhci_qh *qh, struct urb_priv *urbp) 862b1869000SAlan Stern { 863b1869000SAlan Stern struct uhci_td *td; 86459e29ed9SAlan Stern struct list_head *tmp; 86559e29ed9SAlan Stern int ret; 866b1869000SAlan Stern 867b1869000SAlan Stern td = list_entry(urbp->td_list.prev, struct uhci_td, list); 868b1869000SAlan Stern if (qh->type == USB_ENDPOINT_XFER_CONTROL) { 869b1869000SAlan Stern 870b1869000SAlan Stern /* When a control transfer is short, we have to restart 871b1869000SAlan Stern * the queue at the status stage transaction, which is 872b1869000SAlan Stern * the last TD. */ 87359e29ed9SAlan Stern WARN_ON(list_empty(&urbp->td_list)); 874b1869000SAlan Stern qh->element = cpu_to_le32(td->dma_handle); 87559e29ed9SAlan Stern tmp = td->list.prev; 876b1869000SAlan Stern ret = -EINPROGRESS; 877b1869000SAlan Stern 87859e29ed9SAlan Stern } else { 879b1869000SAlan Stern 880b1869000SAlan Stern /* When a bulk/interrupt transfer is short, we have to 881b1869000SAlan Stern * fix up the toggles of the following URBs on the queue 882b1869000SAlan Stern * before restarting the queue at the next URB. */ 88359e29ed9SAlan Stern qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1; 884b1869000SAlan Stern uhci_fixup_toggles(qh, 1); 885b1869000SAlan Stern 88659e29ed9SAlan Stern if (list_empty(&urbp->td_list)) 88759e29ed9SAlan Stern td = qh->post_td; 888b1869000SAlan Stern qh->element = td->link; 88959e29ed9SAlan Stern tmp = urbp->td_list.prev; 89059e29ed9SAlan Stern ret = 0; 891b1869000SAlan Stern } 892b1869000SAlan Stern 89359e29ed9SAlan Stern /* Remove all the TDs we skipped over, from tmp back to the start */ 89459e29ed9SAlan Stern while (tmp != &urbp->td_list) { 89559e29ed9SAlan Stern td = list_entry(tmp, struct uhci_td, list); 89659e29ed9SAlan Stern tmp = tmp->prev; 89759e29ed9SAlan Stern 89804538a25SAlan Stern uhci_remove_td_from_urbp(td); 89904538a25SAlan Stern uhci_free_td(uhci, td); 90059e29ed9SAlan Stern } 901b1869000SAlan Stern return ret; 902b1869000SAlan Stern } 903b1869000SAlan Stern 904b1869000SAlan Stern /* 905b1869000SAlan Stern * Common result for control, bulk, and interrupt 906b1869000SAlan Stern */ 907b1869000SAlan Stern static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) 908b1869000SAlan Stern { 909b1869000SAlan Stern struct urb_priv *urbp = urb->hcpriv; 910b1869000SAlan Stern struct uhci_qh *qh = urbp->qh; 91159e29ed9SAlan Stern struct uhci_td *td, *tmp; 912b1869000SAlan Stern unsigned status; 913b1869000SAlan Stern int ret = 0; 914b1869000SAlan Stern 91559e29ed9SAlan Stern list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { 916b1869000SAlan Stern unsigned int ctrlstat; 917b1869000SAlan Stern int len; 918b1869000SAlan Stern 919b1869000SAlan Stern ctrlstat = td_status(td); 920b1869000SAlan Stern status = uhci_status_bits(ctrlstat); 921b1869000SAlan Stern if (status & TD_CTRL_ACTIVE) 922b1869000SAlan Stern return -EINPROGRESS; 923b1869000SAlan Stern 924b1869000SAlan Stern len = uhci_actual_length(ctrlstat); 925b1869000SAlan Stern urb->actual_length += len; 926b1869000SAlan Stern 927b1869000SAlan Stern if (status) { 928b1869000SAlan Stern ret = uhci_map_status(status, 929b1869000SAlan Stern uhci_packetout(td_token(td))); 930b1869000SAlan Stern if ((debug == 1 && ret != -EPIPE) || debug > 1) { 931b1869000SAlan Stern /* Some debugging code */ 932be3cbc5fSDavid Brownell dev_dbg(&urb->dev->dev, 933b1869000SAlan Stern "%s: failed with status %x\n", 934b1869000SAlan Stern __FUNCTION__, status); 935b1869000SAlan Stern 936b1869000SAlan Stern if (debug > 1 && errbuf) { 937b1869000SAlan Stern /* Print the chain for debugging */ 938b1869000SAlan Stern uhci_show_qh(urbp->qh, errbuf, 939b1869000SAlan Stern ERRBUF_LEN, 0); 940b1869000SAlan Stern lprintk(errbuf); 941b1869000SAlan Stern } 942b1869000SAlan Stern } 943b1869000SAlan Stern 944b1869000SAlan Stern } else if (len < uhci_expected_length(td_token(td))) { 945b1869000SAlan Stern 946b1869000SAlan Stern /* We received a short packet */ 947b1869000SAlan Stern if (urb->transfer_flags & URB_SHORT_NOT_OK) 948b1869000SAlan Stern ret = -EREMOTEIO; 949f443ddf1SAlan Stern 950f443ddf1SAlan Stern /* Fixup needed only if this isn't the URB's last TD */ 951f443ddf1SAlan Stern else if (&td->list != urbp->td_list.prev) 952b1869000SAlan Stern ret = 1; 953b1869000SAlan Stern } 954b1869000SAlan Stern 95504538a25SAlan Stern uhci_remove_td_from_urbp(td); 95659e29ed9SAlan Stern if (qh->post_td) 95704538a25SAlan Stern uhci_free_td(uhci, qh->post_td); 95859e29ed9SAlan Stern qh->post_td = td; 95959e29ed9SAlan Stern 960b1869000SAlan Stern if (ret != 0) 961b1869000SAlan Stern goto err; 962b1869000SAlan Stern } 963b1869000SAlan Stern return ret; 964b1869000SAlan Stern 965b1869000SAlan Stern err: 966b1869000SAlan Stern if (ret < 0) { 967b1869000SAlan Stern /* In case a control transfer gets an error 968b1869000SAlan Stern * during the setup stage */ 969b1869000SAlan Stern urb->actual_length = max(urb->actual_length, 0); 970b1869000SAlan Stern 971b1869000SAlan Stern /* Note that the queue has stopped and save 972b1869000SAlan Stern * the next toggle value */ 973b1869000SAlan Stern qh->element = UHCI_PTR_TERM; 974b1869000SAlan Stern qh->is_stopped = 1; 975b1869000SAlan Stern qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); 976b1869000SAlan Stern qh->initial_toggle = uhci_toggle(td_token(td)) ^ 977b1869000SAlan Stern (ret == -EREMOTEIO); 978b1869000SAlan Stern 979b1869000SAlan Stern } else /* Short packet received */ 98059e29ed9SAlan Stern ret = uhci_fixup_short_transfer(uhci, qh, urbp); 981b1869000SAlan Stern return ret; 982b1869000SAlan Stern } 983b1869000SAlan Stern 984b1869000SAlan Stern /* 9851da177e4SLinus Torvalds * Isochronous transfers 9861da177e4SLinus Torvalds */ 987dccf4a48SAlan Stern static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, 988dccf4a48SAlan Stern struct uhci_qh *qh) 9891da177e4SLinus Torvalds { 990dccf4a48SAlan Stern struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */ 9910ed8fee1SAlan Stern int i, frame; 992dccf4a48SAlan Stern unsigned long destination, status; 993b81d3436SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 9941da177e4SLinus Torvalds 995caf3827aSAlan Stern /* Values must not be too big (could overflow below) */ 996caf3827aSAlan Stern if (urb->interval >= UHCI_NUMFRAMES || 997caf3827aSAlan Stern urb->number_of_packets >= UHCI_NUMFRAMES) 998caf3827aSAlan Stern return -EFBIG; 999caf3827aSAlan Stern 1000caf3827aSAlan Stern /* Check the period and figure out the starting frame number */ 1001caf3827aSAlan Stern if (qh->period == 0) { 1002caf3827aSAlan Stern if (urb->transfer_flags & URB_ISO_ASAP) { 1003c8155cc5SAlan Stern uhci_get_current_frame_number(uhci); 1004caf3827aSAlan Stern urb->start_frame = uhci->frame_number + 10; 1005caf3827aSAlan Stern } else { 1006c8155cc5SAlan Stern i = urb->start_frame - uhci->last_iso_frame; 1007caf3827aSAlan Stern if (i <= 0 || i >= UHCI_NUMFRAMES) 1008caf3827aSAlan Stern return -EINVAL; 1009caf3827aSAlan Stern } 1010caf3827aSAlan Stern } else if (qh->period != urb->interval) { 1011caf3827aSAlan Stern return -EINVAL; /* Can't change the period */ 1012caf3827aSAlan Stern 1013caf3827aSAlan Stern } else { /* Pick up where the last URB leaves off */ 1014caf3827aSAlan Stern if (list_empty(&qh->queue)) { 1015c8155cc5SAlan Stern frame = qh->iso_frame; 1016caf3827aSAlan Stern } else { 1017caf3827aSAlan Stern struct urb *lurb; 1018caf3827aSAlan Stern 1019caf3827aSAlan Stern lurb = list_entry(qh->queue.prev, 1020caf3827aSAlan Stern struct urb_priv, node)->urb; 1021caf3827aSAlan Stern frame = lurb->start_frame + 1022caf3827aSAlan Stern lurb->number_of_packets * 1023caf3827aSAlan Stern lurb->interval; 1024caf3827aSAlan Stern } 1025caf3827aSAlan Stern if (urb->transfer_flags & URB_ISO_ASAP) 1026caf3827aSAlan Stern urb->start_frame = frame; 1027c8155cc5SAlan Stern else if (urb->start_frame != frame) 1028c8155cc5SAlan Stern return -EINVAL; 1029caf3827aSAlan Stern } 1030caf3827aSAlan Stern 1031caf3827aSAlan Stern /* Make sure we won't have to go too far into the future */ 1032c8155cc5SAlan Stern if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES, 1033caf3827aSAlan Stern urb->start_frame + urb->number_of_packets * 1034caf3827aSAlan Stern urb->interval)) 10350ed8fee1SAlan Stern return -EFBIG; 10360ed8fee1SAlan Stern 10371da177e4SLinus Torvalds status = TD_CTRL_ACTIVE | TD_CTRL_IOS; 10381da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 10391da177e4SLinus Torvalds 1040b81d3436SAlan Stern for (i = 0; i < urb->number_of_packets; i++) { 10412532178aSAlan Stern td = uhci_alloc_td(uhci); 10421da177e4SLinus Torvalds if (!td) 10431da177e4SLinus Torvalds return -ENOMEM; 10441da177e4SLinus Torvalds 104504538a25SAlan Stern uhci_add_td_to_urbp(td, urbp); 1046dccf4a48SAlan Stern uhci_fill_td(td, status, destination | 1047dccf4a48SAlan Stern uhci_explen(urb->iso_frame_desc[i].length), 1048dccf4a48SAlan Stern urb->transfer_dma + 1049dccf4a48SAlan Stern urb->iso_frame_desc[i].offset); 1050b81d3436SAlan Stern } 10511da177e4SLinus Torvalds 1052dccf4a48SAlan Stern /* Set the interrupt-on-completion flag on the last packet. */ 1053dccf4a48SAlan Stern td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 1054dccf4a48SAlan Stern 1055dccf4a48SAlan Stern qh->skel = uhci->skel_iso_qh; 1056caf3827aSAlan Stern qh->period = urb->interval; 1057dccf4a48SAlan Stern 1058dccf4a48SAlan Stern /* Add the TDs to the frame list */ 1059b81d3436SAlan Stern frame = urb->start_frame; 1060b81d3436SAlan Stern list_for_each_entry(td, &urbp->td_list, list) { 1061dccf4a48SAlan Stern uhci_insert_td_in_frame_list(uhci, td, frame); 1062c8155cc5SAlan Stern frame += qh->period; 1063c8155cc5SAlan Stern } 1064c8155cc5SAlan Stern 1065c8155cc5SAlan Stern if (list_empty(&qh->queue)) { 1066c8155cc5SAlan Stern qh->iso_packet_desc = &urb->iso_frame_desc[0]; 1067c8155cc5SAlan Stern qh->iso_frame = urb->start_frame; 1068c8155cc5SAlan Stern qh->iso_status = 0; 10691da177e4SLinus Torvalds } 10701da177e4SLinus Torvalds 1071dccf4a48SAlan Stern return 0; 10721da177e4SLinus Torvalds } 10731da177e4SLinus Torvalds 10741da177e4SLinus Torvalds static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) 10751da177e4SLinus Torvalds { 1076c8155cc5SAlan Stern struct uhci_td *td, *tmp; 1077c8155cc5SAlan Stern struct urb_priv *urbp = urb->hcpriv; 1078c8155cc5SAlan Stern struct uhci_qh *qh = urbp->qh; 1079c8155cc5SAlan Stern 1080c8155cc5SAlan Stern list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { 1081c8155cc5SAlan Stern unsigned int ctrlstat; 10821da177e4SLinus Torvalds int status; 10831da177e4SLinus Torvalds int actlength; 10841da177e4SLinus Torvalds 1085c8155cc5SAlan Stern if (uhci_frame_before_eq(uhci->cur_iso_frame, qh->iso_frame)) 10861da177e4SLinus Torvalds return -EINPROGRESS; 10871da177e4SLinus Torvalds 1088c8155cc5SAlan Stern uhci_remove_tds_from_frame(uhci, qh->iso_frame); 10891da177e4SLinus Torvalds 1090c8155cc5SAlan Stern ctrlstat = td_status(td); 1091c8155cc5SAlan Stern if (ctrlstat & TD_CTRL_ACTIVE) { 1092c8155cc5SAlan Stern status = -EXDEV; /* TD was added too late? */ 1093c8155cc5SAlan Stern } else { 10941da177e4SLinus Torvalds status = uhci_map_status(uhci_status_bits(ctrlstat), 10951da177e4SLinus Torvalds usb_pipeout(urb->pipe)); 1096c8155cc5SAlan Stern actlength = uhci_actual_length(ctrlstat); 1097c8155cc5SAlan Stern 1098c8155cc5SAlan Stern urb->actual_length += actlength; 1099c8155cc5SAlan Stern qh->iso_packet_desc->actual_length = actlength; 1100c8155cc5SAlan Stern qh->iso_packet_desc->status = status; 1101c8155cc5SAlan Stern } 1102c8155cc5SAlan Stern 11031da177e4SLinus Torvalds if (status) { 11041da177e4SLinus Torvalds urb->error_count++; 1105c8155cc5SAlan Stern qh->iso_status = status; 11061da177e4SLinus Torvalds } 11071da177e4SLinus Torvalds 1108c8155cc5SAlan Stern uhci_remove_td_from_urbp(td); 1109c8155cc5SAlan Stern uhci_free_td(uhci, td); 1110c8155cc5SAlan Stern qh->iso_frame += qh->period; 1111c8155cc5SAlan Stern ++qh->iso_packet_desc; 11121da177e4SLinus Torvalds } 1113c8155cc5SAlan Stern return qh->iso_status; 11141da177e4SLinus Torvalds } 11151da177e4SLinus Torvalds 11161da177e4SLinus Torvalds static int uhci_urb_enqueue(struct usb_hcd *hcd, 1117dccf4a48SAlan Stern struct usb_host_endpoint *hep, 111855016f10SAl Viro struct urb *urb, gfp_t mem_flags) 11191da177e4SLinus Torvalds { 11201da177e4SLinus Torvalds int ret; 11211da177e4SLinus Torvalds struct uhci_hcd *uhci = hcd_to_uhci(hcd); 11221da177e4SLinus Torvalds unsigned long flags; 1123dccf4a48SAlan Stern struct urb_priv *urbp; 1124dccf4a48SAlan Stern struct uhci_qh *qh; 11251da177e4SLinus Torvalds int bustime; 11261da177e4SLinus Torvalds 11271da177e4SLinus Torvalds spin_lock_irqsave(&uhci->lock, flags); 11281da177e4SLinus Torvalds 11291da177e4SLinus Torvalds ret = urb->status; 11301da177e4SLinus Torvalds if (ret != -EINPROGRESS) /* URB already unlinked! */ 1131dccf4a48SAlan Stern goto done; 11321da177e4SLinus Torvalds 11331da177e4SLinus Torvalds ret = -ENOMEM; 1134dccf4a48SAlan Stern urbp = uhci_alloc_urb_priv(uhci, urb); 1135dccf4a48SAlan Stern if (!urbp) 1136dccf4a48SAlan Stern goto done; 1137dccf4a48SAlan Stern 1138dccf4a48SAlan Stern if (hep->hcpriv) 1139dccf4a48SAlan Stern qh = (struct uhci_qh *) hep->hcpriv; 1140dccf4a48SAlan Stern else { 1141dccf4a48SAlan Stern qh = uhci_alloc_qh(uhci, urb->dev, hep); 1142dccf4a48SAlan Stern if (!qh) 1143dccf4a48SAlan Stern goto err_no_qh; 11441da177e4SLinus Torvalds } 1145dccf4a48SAlan Stern urbp->qh = qh; 11461da177e4SLinus Torvalds 11474de7d2c2SAlan Stern switch (qh->type) { 11484de7d2c2SAlan Stern case USB_ENDPOINT_XFER_CONTROL: 1149dccf4a48SAlan Stern ret = uhci_submit_control(uhci, urb, qh); 1150dccf4a48SAlan Stern break; 11514de7d2c2SAlan Stern case USB_ENDPOINT_XFER_BULK: 1152dccf4a48SAlan Stern ret = uhci_submit_bulk(uhci, urb, qh); 11531da177e4SLinus Torvalds break; 11544de7d2c2SAlan Stern case USB_ENDPOINT_XFER_INT: 1155dccf4a48SAlan Stern if (list_empty(&qh->queue)) { 11561da177e4SLinus Torvalds bustime = usb_check_bandwidth(urb->dev, urb); 11571da177e4SLinus Torvalds if (bustime < 0) 11581da177e4SLinus Torvalds ret = bustime; 11591da177e4SLinus Torvalds else { 1160dccf4a48SAlan Stern ret = uhci_submit_interrupt(uhci, urb, qh); 1161dccf4a48SAlan Stern if (ret == 0) 11621da177e4SLinus Torvalds usb_claim_bandwidth(urb->dev, urb, bustime, 0); 11631da177e4SLinus Torvalds } 11641da177e4SLinus Torvalds } else { /* inherit from parent */ 1165dccf4a48SAlan Stern struct urb_priv *eurbp; 1166dccf4a48SAlan Stern 1167dccf4a48SAlan Stern eurbp = list_entry(qh->queue.prev, struct urb_priv, 1168dccf4a48SAlan Stern node); 1169dccf4a48SAlan Stern urb->bandwidth = eurbp->urb->bandwidth; 1170dccf4a48SAlan Stern ret = uhci_submit_interrupt(uhci, urb, qh); 11711da177e4SLinus Torvalds } 11721da177e4SLinus Torvalds break; 11734de7d2c2SAlan Stern case USB_ENDPOINT_XFER_ISOC: 1174c8155cc5SAlan Stern urb->error_count = 0; 11751da177e4SLinus Torvalds bustime = usb_check_bandwidth(urb->dev, urb); 11761da177e4SLinus Torvalds if (bustime < 0) { 11771da177e4SLinus Torvalds ret = bustime; 11781da177e4SLinus Torvalds break; 11791da177e4SLinus Torvalds } 11801da177e4SLinus Torvalds 1181dccf4a48SAlan Stern ret = uhci_submit_isochronous(uhci, urb, qh); 1182dccf4a48SAlan Stern if (ret == 0) 11831da177e4SLinus Torvalds usb_claim_bandwidth(urb->dev, urb, bustime, 1); 11841da177e4SLinus Torvalds break; 11851da177e4SLinus Torvalds } 1186dccf4a48SAlan Stern if (ret != 0) 1187dccf4a48SAlan Stern goto err_submit_failed; 11881da177e4SLinus Torvalds 1189dccf4a48SAlan Stern /* Add this URB to the QH */ 1190dccf4a48SAlan Stern urbp->qh = qh; 1191dccf4a48SAlan Stern list_add_tail(&urbp->node, &qh->queue); 11921da177e4SLinus Torvalds 1193dccf4a48SAlan Stern /* If the new URB is the first and only one on this QH then either 1194dccf4a48SAlan Stern * the QH is new and idle or else it's unlinked and waiting to 11952775562aSAlan Stern * become idle, so we can activate it right away. But only if the 11962775562aSAlan Stern * queue isn't stopped. */ 119784afddd7SAlan Stern if (qh->queue.next == &urbp->node && !qh->is_stopped) { 1198dccf4a48SAlan Stern uhci_activate_qh(uhci, qh); 1199c5e3b741SAlan Stern uhci_urbp_wants_fsbr(uhci, urbp); 120084afddd7SAlan Stern } 1201dccf4a48SAlan Stern goto done; 1202dccf4a48SAlan Stern 1203dccf4a48SAlan Stern err_submit_failed: 1204dccf4a48SAlan Stern if (qh->state == QH_STATE_IDLE) 1205dccf4a48SAlan Stern uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ 1206dccf4a48SAlan Stern 1207dccf4a48SAlan Stern err_no_qh: 1208dccf4a48SAlan Stern uhci_free_urb_priv(uhci, urbp); 1209dccf4a48SAlan Stern 1210dccf4a48SAlan Stern done: 12111da177e4SLinus Torvalds spin_unlock_irqrestore(&uhci->lock, flags); 12121da177e4SLinus Torvalds return ret; 12131da177e4SLinus Torvalds } 12141da177e4SLinus Torvalds 12151da177e4SLinus Torvalds static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 12161da177e4SLinus Torvalds { 12171da177e4SLinus Torvalds struct uhci_hcd *uhci = hcd_to_uhci(hcd); 12181da177e4SLinus Torvalds unsigned long flags; 12191da177e4SLinus Torvalds struct urb_priv *urbp; 122010b8e47dSAlan Stern struct uhci_qh *qh; 12211da177e4SLinus Torvalds 12221da177e4SLinus Torvalds spin_lock_irqsave(&uhci->lock, flags); 12231da177e4SLinus Torvalds urbp = urb->hcpriv; 12241da177e4SLinus Torvalds if (!urbp) /* URB was never linked! */ 12251da177e4SLinus Torvalds goto done; 122610b8e47dSAlan Stern qh = urbp->qh; 12271da177e4SLinus Torvalds 1228dccf4a48SAlan Stern /* Remove Isochronous TDs from the frame list ASAP */ 122910b8e47dSAlan Stern if (qh->type == USB_ENDPOINT_XFER_ISOC) { 1230dccf4a48SAlan Stern uhci_unlink_isochronous_tds(uhci, urb); 123110b8e47dSAlan Stern mb(); 123210b8e47dSAlan Stern 123310b8e47dSAlan Stern /* If the URB has already started, update the QH unlink time */ 123410b8e47dSAlan Stern uhci_get_current_frame_number(uhci); 123510b8e47dSAlan Stern if (uhci_frame_before_eq(urb->start_frame, uhci->frame_number)) 123610b8e47dSAlan Stern qh->unlink_frame = uhci->frame_number; 123710b8e47dSAlan Stern } 123810b8e47dSAlan Stern 123910b8e47dSAlan Stern uhci_unlink_qh(uhci, qh); 12401da177e4SLinus Torvalds 12411da177e4SLinus Torvalds done: 12421da177e4SLinus Torvalds spin_unlock_irqrestore(&uhci->lock, flags); 12431da177e4SLinus Torvalds return 0; 12441da177e4SLinus Torvalds } 12451da177e4SLinus Torvalds 12460ed8fee1SAlan Stern /* 12470ed8fee1SAlan Stern * Finish unlinking an URB and give it back 12480ed8fee1SAlan Stern */ 12490ed8fee1SAlan Stern static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, 12507d12e780SDavid Howells struct urb *urb) 12510ed8fee1SAlan Stern __releases(uhci->lock) 12520ed8fee1SAlan Stern __acquires(uhci->lock) 12531da177e4SLinus Torvalds { 12541da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 12551da177e4SLinus Torvalds 1256c8155cc5SAlan Stern /* When giving back the first URB in an Isochronous queue, 1257c8155cc5SAlan Stern * reinitialize the QH's iso-related members for the next URB. */ 1258c8155cc5SAlan Stern if (qh->type == USB_ENDPOINT_XFER_ISOC && 1259c8155cc5SAlan Stern urbp->node.prev == &qh->queue && 1260c8155cc5SAlan Stern urbp->node.next != &qh->queue) { 1261c8155cc5SAlan Stern struct urb *nurb = list_entry(urbp->node.next, 1262c8155cc5SAlan Stern struct urb_priv, node)->urb; 1263c8155cc5SAlan Stern 1264c8155cc5SAlan Stern qh->iso_packet_desc = &nurb->iso_frame_desc[0]; 1265c8155cc5SAlan Stern qh->iso_frame = nurb->start_frame; 1266c8155cc5SAlan Stern qh->iso_status = 0; 1267c8155cc5SAlan Stern } 12681da177e4SLinus Torvalds 12690ed8fee1SAlan Stern /* Take the URB off the QH's queue. If the queue is now empty, 12700ed8fee1SAlan Stern * this is a perfect time for a toggle fixup. */ 12710ed8fee1SAlan Stern list_del_init(&urbp->node); 12720ed8fee1SAlan Stern if (list_empty(&qh->queue) && qh->needs_fixup) { 12730ed8fee1SAlan Stern usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 12740ed8fee1SAlan Stern usb_pipeout(urb->pipe), qh->initial_toggle); 12750ed8fee1SAlan Stern qh->needs_fixup = 0; 12760ed8fee1SAlan Stern } 12770ed8fee1SAlan Stern 12780ed8fee1SAlan Stern uhci_free_urb_priv(uhci, urbp); 12790ed8fee1SAlan Stern 12804de7d2c2SAlan Stern switch (qh->type) { 12814de7d2c2SAlan Stern case USB_ENDPOINT_XFER_ISOC: 12820ed8fee1SAlan Stern /* Release bandwidth for Interrupt or Isoc. transfers */ 12830ed8fee1SAlan Stern if (urb->bandwidth) 12840ed8fee1SAlan Stern usb_release_bandwidth(urb->dev, urb, 1); 12850ed8fee1SAlan Stern break; 12864de7d2c2SAlan Stern case USB_ENDPOINT_XFER_INT: 12870ed8fee1SAlan Stern /* Release bandwidth for Interrupt or Isoc. transfers */ 12880ed8fee1SAlan Stern /* Make sure we don't release if we have a queued URB */ 12890ed8fee1SAlan Stern if (list_empty(&qh->queue) && urb->bandwidth) 12900ed8fee1SAlan Stern usb_release_bandwidth(urb->dev, urb, 0); 12910ed8fee1SAlan Stern else 12920ed8fee1SAlan Stern /* bandwidth was passed on to queued URB, */ 12930ed8fee1SAlan Stern /* so don't let usb_unlink_urb() release it */ 12940ed8fee1SAlan Stern urb->bandwidth = 0; 12950ed8fee1SAlan Stern break; 12960ed8fee1SAlan Stern } 12970ed8fee1SAlan Stern 12980ed8fee1SAlan Stern spin_unlock(&uhci->lock); 12997d12e780SDavid Howells usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); 13000ed8fee1SAlan Stern spin_lock(&uhci->lock); 13010ed8fee1SAlan Stern 13020ed8fee1SAlan Stern /* If the queue is now empty, we can unlink the QH and give up its 13030ed8fee1SAlan Stern * reserved bandwidth. */ 13040ed8fee1SAlan Stern if (list_empty(&qh->queue)) { 13050ed8fee1SAlan Stern uhci_unlink_qh(uhci, qh); 13060ed8fee1SAlan Stern 13070ed8fee1SAlan Stern /* Bandwidth stuff not yet implemented */ 1308caf3827aSAlan Stern qh->period = 0; 13090ed8fee1SAlan Stern } 13100ed8fee1SAlan Stern } 13110ed8fee1SAlan Stern 13120ed8fee1SAlan Stern /* 13130ed8fee1SAlan Stern * Scan the URBs in a QH's queue 13140ed8fee1SAlan Stern */ 13150ed8fee1SAlan Stern #define QH_FINISHED_UNLINKING(qh) \ 13160ed8fee1SAlan Stern (qh->state == QH_STATE_UNLINKING && \ 13170ed8fee1SAlan Stern uhci->frame_number + uhci->is_stopped != qh->unlink_frame) 13180ed8fee1SAlan Stern 13197d12e780SDavid Howells static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 13200ed8fee1SAlan Stern { 13210ed8fee1SAlan Stern struct urb_priv *urbp; 13220ed8fee1SAlan Stern struct urb *urb; 13230ed8fee1SAlan Stern int status; 13240ed8fee1SAlan Stern 13250ed8fee1SAlan Stern while (!list_empty(&qh->queue)) { 13260ed8fee1SAlan Stern urbp = list_entry(qh->queue.next, struct urb_priv, node); 13270ed8fee1SAlan Stern urb = urbp->urb; 13280ed8fee1SAlan Stern 1329b1869000SAlan Stern if (qh->type == USB_ENDPOINT_XFER_ISOC) 13300ed8fee1SAlan Stern status = uhci_result_isochronous(uhci, urb); 1331b1869000SAlan Stern else 13320ed8fee1SAlan Stern status = uhci_result_common(uhci, urb); 13330ed8fee1SAlan Stern if (status == -EINPROGRESS) 13340ed8fee1SAlan Stern break; 13350ed8fee1SAlan Stern 13360ed8fee1SAlan Stern spin_lock(&urb->lock); 13370ed8fee1SAlan Stern if (urb->status == -EINPROGRESS) /* Not dequeued */ 13380ed8fee1SAlan Stern urb->status = status; 13390ed8fee1SAlan Stern else 13402775562aSAlan Stern status = ECONNRESET; /* Not -ECONNRESET */ 13410ed8fee1SAlan Stern spin_unlock(&urb->lock); 13420ed8fee1SAlan Stern 13430ed8fee1SAlan Stern /* Dequeued but completed URBs can't be given back unless 13440ed8fee1SAlan Stern * the QH is stopped or has finished unlinking. */ 13452775562aSAlan Stern if (status == ECONNRESET) { 13462775562aSAlan Stern if (QH_FINISHED_UNLINKING(qh)) 13472775562aSAlan Stern qh->is_stopped = 1; 13482775562aSAlan Stern else if (!qh->is_stopped) 13490ed8fee1SAlan Stern return; 13502775562aSAlan Stern } 13510ed8fee1SAlan Stern 13527d12e780SDavid Howells uhci_giveback_urb(uhci, qh, urb); 13537ceb932fSAlan Stern if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) 13540ed8fee1SAlan Stern break; 13550ed8fee1SAlan Stern } 13560ed8fee1SAlan Stern 13570ed8fee1SAlan Stern /* If the QH is neither stopped nor finished unlinking (normal case), 13580ed8fee1SAlan Stern * our work here is done. */ 13592775562aSAlan Stern if (QH_FINISHED_UNLINKING(qh)) 13602775562aSAlan Stern qh->is_stopped = 1; 13612775562aSAlan Stern else if (!qh->is_stopped) 13620ed8fee1SAlan Stern return; 13630ed8fee1SAlan Stern 13640ed8fee1SAlan Stern /* Otherwise give back each of the dequeued URBs */ 13652775562aSAlan Stern restart: 13660ed8fee1SAlan Stern list_for_each_entry(urbp, &qh->queue, node) { 13670ed8fee1SAlan Stern urb = urbp->urb; 13680ed8fee1SAlan Stern if (urb->status != -EINPROGRESS) { 136910b8e47dSAlan Stern 137010b8e47dSAlan Stern /* Fix up the TD links and save the toggles for 137110b8e47dSAlan Stern * non-Isochronous queues. For Isochronous queues, 137210b8e47dSAlan Stern * test for too-recent dequeues. */ 137310b8e47dSAlan Stern if (!uhci_cleanup_queue(uhci, qh, urb)) { 137410b8e47dSAlan Stern qh->is_stopped = 0; 137510b8e47dSAlan Stern return; 137610b8e47dSAlan Stern } 13777d12e780SDavid Howells uhci_giveback_urb(uhci, qh, urb); 13780ed8fee1SAlan Stern goto restart; 13790ed8fee1SAlan Stern } 13800ed8fee1SAlan Stern } 13810ed8fee1SAlan Stern qh->is_stopped = 0; 13820ed8fee1SAlan Stern 13830ed8fee1SAlan Stern /* There are no more dequeued URBs. If there are still URBs on the 13840ed8fee1SAlan Stern * queue, the QH can now be re-activated. */ 13850ed8fee1SAlan Stern if (!list_empty(&qh->queue)) { 13860ed8fee1SAlan Stern if (qh->needs_fixup) 13870ed8fee1SAlan Stern uhci_fixup_toggles(qh, 0); 138884afddd7SAlan Stern 138984afddd7SAlan Stern /* If the first URB on the queue wants FSBR but its time 139084afddd7SAlan Stern * limit has expired, set the next TD to interrupt on 139184afddd7SAlan Stern * completion before reactivating the QH. */ 139284afddd7SAlan Stern urbp = list_entry(qh->queue.next, struct urb_priv, node); 139384afddd7SAlan Stern if (urbp->fsbr && qh->wait_expired) { 139484afddd7SAlan Stern struct uhci_td *td = list_entry(urbp->td_list.next, 139584afddd7SAlan Stern struct uhci_td, list); 139684afddd7SAlan Stern 139784afddd7SAlan Stern td->status |= __cpu_to_le32(TD_CTRL_IOC); 139884afddd7SAlan Stern } 139984afddd7SAlan Stern 14000ed8fee1SAlan Stern uhci_activate_qh(uhci, qh); 14010ed8fee1SAlan Stern } 14020ed8fee1SAlan Stern 14030ed8fee1SAlan Stern /* The queue is empty. The QH can become idle if it is fully 14040ed8fee1SAlan Stern * unlinked. */ 14050ed8fee1SAlan Stern else if (QH_FINISHED_UNLINKING(qh)) 14060ed8fee1SAlan Stern uhci_make_qh_idle(uhci, qh); 14071da177e4SLinus Torvalds } 14081da177e4SLinus Torvalds 14090ed8fee1SAlan Stern /* 141084afddd7SAlan Stern * Check for queues that have made some forward progress. 141184afddd7SAlan Stern * Returns 0 if the queue is not Isochronous, is ACTIVE, and 141284afddd7SAlan Stern * has not advanced since last examined; 1 otherwise. 1413b761d9d8SAlan Stern * 1414b761d9d8SAlan Stern * Early Intel controllers have a bug which causes qh->element sometimes 1415b761d9d8SAlan Stern * not to advance when a TD completes successfully. The queue remains 1416b761d9d8SAlan Stern * stuck on the inactive completed TD. We detect such cases and advance 1417b761d9d8SAlan Stern * the element pointer by hand. 141884afddd7SAlan Stern */ 141984afddd7SAlan Stern static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) 142084afddd7SAlan Stern { 142184afddd7SAlan Stern struct urb_priv *urbp = NULL; 142284afddd7SAlan Stern struct uhci_td *td; 142384afddd7SAlan Stern int ret = 1; 142484afddd7SAlan Stern unsigned status; 142584afddd7SAlan Stern 142684afddd7SAlan Stern if (qh->type == USB_ENDPOINT_XFER_ISOC) 1427c5e3b741SAlan Stern goto done; 142884afddd7SAlan Stern 142984afddd7SAlan Stern /* Treat an UNLINKING queue as though it hasn't advanced. 143084afddd7SAlan Stern * This is okay because reactivation will treat it as though 143184afddd7SAlan Stern * it has advanced, and if it is going to become IDLE then 143284afddd7SAlan Stern * this doesn't matter anyway. Furthermore it's possible 143384afddd7SAlan Stern * for an UNLINKING queue not to have any URBs at all, or 143484afddd7SAlan Stern * for its first URB not to have any TDs (if it was dequeued 143584afddd7SAlan Stern * just as it completed). So it's not easy in any case to 143684afddd7SAlan Stern * test whether such queues have advanced. */ 143784afddd7SAlan Stern if (qh->state != QH_STATE_ACTIVE) { 143884afddd7SAlan Stern urbp = NULL; 143984afddd7SAlan Stern status = 0; 144084afddd7SAlan Stern 144184afddd7SAlan Stern } else { 144284afddd7SAlan Stern urbp = list_entry(qh->queue.next, struct urb_priv, node); 144384afddd7SAlan Stern td = list_entry(urbp->td_list.next, struct uhci_td, list); 144484afddd7SAlan Stern status = td_status(td); 144584afddd7SAlan Stern if (!(status & TD_CTRL_ACTIVE)) { 144684afddd7SAlan Stern 144784afddd7SAlan Stern /* We're okay, the queue has advanced */ 144884afddd7SAlan Stern qh->wait_expired = 0; 144984afddd7SAlan Stern qh->advance_jiffies = jiffies; 1450c5e3b741SAlan Stern goto done; 145184afddd7SAlan Stern } 145284afddd7SAlan Stern ret = 0; 145384afddd7SAlan Stern } 145484afddd7SAlan Stern 145584afddd7SAlan Stern /* The queue hasn't advanced; check for timeout */ 1456c5e3b741SAlan Stern if (qh->wait_expired) 1457c5e3b741SAlan Stern goto done; 1458c5e3b741SAlan Stern 1459c5e3b741SAlan Stern if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { 1460b761d9d8SAlan Stern 1461b761d9d8SAlan Stern /* Detect the Intel bug and work around it */ 1462b761d9d8SAlan Stern if (qh->post_td && qh_element(qh) == 1463b761d9d8SAlan Stern cpu_to_le32(qh->post_td->dma_handle)) { 1464b761d9d8SAlan Stern qh->element = qh->post_td->link; 1465b761d9d8SAlan Stern qh->advance_jiffies = jiffies; 1466c5e3b741SAlan Stern ret = 1; 1467c5e3b741SAlan Stern goto done; 1468b761d9d8SAlan Stern } 1469b761d9d8SAlan Stern 147084afddd7SAlan Stern qh->wait_expired = 1; 147184afddd7SAlan Stern 147284afddd7SAlan Stern /* If the current URB wants FSBR, unlink it temporarily 147384afddd7SAlan Stern * so that we can safely set the next TD to interrupt on 147484afddd7SAlan Stern * completion. That way we'll know as soon as the queue 147584afddd7SAlan Stern * starts moving again. */ 147684afddd7SAlan Stern if (urbp && urbp->fsbr && !(status & TD_CTRL_IOC)) 147784afddd7SAlan Stern uhci_unlink_qh(uhci, qh); 1478c5e3b741SAlan Stern 1479c5e3b741SAlan Stern } else { 1480c5e3b741SAlan Stern /* Unmoving but not-yet-expired queues keep FSBR alive */ 1481c5e3b741SAlan Stern if (urbp) 1482c5e3b741SAlan Stern uhci_urbp_wants_fsbr(uhci, urbp); 148384afddd7SAlan Stern } 1484c5e3b741SAlan Stern 1485c5e3b741SAlan Stern done: 148684afddd7SAlan Stern return ret; 148784afddd7SAlan Stern } 148884afddd7SAlan Stern 148984afddd7SAlan Stern /* 14900ed8fee1SAlan Stern * Process events in the schedule, but only in one thread at a time 14910ed8fee1SAlan Stern */ 14927d12e780SDavid Howells static void uhci_scan_schedule(struct uhci_hcd *uhci) 14931da177e4SLinus Torvalds { 14940ed8fee1SAlan Stern int i; 14950ed8fee1SAlan Stern struct uhci_qh *qh; 14961da177e4SLinus Torvalds 14971da177e4SLinus Torvalds /* Don't allow re-entrant calls */ 14981da177e4SLinus Torvalds if (uhci->scan_in_progress) { 14991da177e4SLinus Torvalds uhci->need_rescan = 1; 15001da177e4SLinus Torvalds return; 15011da177e4SLinus Torvalds } 15021da177e4SLinus Torvalds uhci->scan_in_progress = 1; 15031da177e4SLinus Torvalds rescan: 15041da177e4SLinus Torvalds uhci->need_rescan = 0; 1505c5e3b741SAlan Stern uhci->fsbr_is_wanted = 0; 15061da177e4SLinus Torvalds 15076c1b445cSAlan Stern uhci_clear_next_interrupt(uhci); 15081da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 1509c8155cc5SAlan Stern uhci->cur_iso_frame = uhci->frame_number; 15101da177e4SLinus Torvalds 15110ed8fee1SAlan Stern /* Go through all the QH queues and process the URBs in each one */ 15120ed8fee1SAlan Stern for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { 15130ed8fee1SAlan Stern uhci->next_qh = list_entry(uhci->skelqh[i]->node.next, 15140ed8fee1SAlan Stern struct uhci_qh, node); 15150ed8fee1SAlan Stern while ((qh = uhci->next_qh) != uhci->skelqh[i]) { 15160ed8fee1SAlan Stern uhci->next_qh = list_entry(qh->node.next, 15170ed8fee1SAlan Stern struct uhci_qh, node); 151884afddd7SAlan Stern 151984afddd7SAlan Stern if (uhci_advance_check(uhci, qh)) { 15207d12e780SDavid Howells uhci_scan_qh(uhci, qh); 1521c5e3b741SAlan Stern if (qh->state == QH_STATE_ACTIVE) { 1522c5e3b741SAlan Stern uhci_urbp_wants_fsbr(uhci, 1523c5e3b741SAlan Stern list_entry(qh->queue.next, struct urb_priv, node)); 1524c5e3b741SAlan Stern } 152584afddd7SAlan Stern } 15261da177e4SLinus Torvalds } 15270ed8fee1SAlan Stern } 15281da177e4SLinus Torvalds 1529c8155cc5SAlan Stern uhci->last_iso_frame = uhci->cur_iso_frame; 15301da177e4SLinus Torvalds if (uhci->need_rescan) 15311da177e4SLinus Torvalds goto rescan; 15321da177e4SLinus Torvalds uhci->scan_in_progress = 0; 15331da177e4SLinus Torvalds 1534c5e3b741SAlan Stern if (uhci->fsbr_is_on && !uhci->fsbr_is_wanted && 1535c5e3b741SAlan Stern !uhci->fsbr_expiring) { 1536c5e3b741SAlan Stern uhci->fsbr_expiring = 1; 1537c5e3b741SAlan Stern mod_timer(&uhci->fsbr_timer, jiffies + FSBR_OFF_DELAY); 1538c5e3b741SAlan Stern } 153984afddd7SAlan Stern 154004538a25SAlan Stern if (list_empty(&uhci->skel_unlink_qh->node)) 15411da177e4SLinus Torvalds uhci_clear_next_interrupt(uhci); 15421da177e4SLinus Torvalds else 15431da177e4SLinus Torvalds uhci_set_next_interrupt(uhci); 15441da177e4SLinus Torvalds } 1545