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) 16*dccf4a48SAlan Stern * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu 171da177e4SLinus Torvalds */ 181da177e4SLinus Torvalds 191da177e4SLinus Torvalds static void uhci_free_pending_tds(struct uhci_hcd *uhci); 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds /* 221da177e4SLinus Torvalds * Technically, updating td->status here is a race, but it's not really a 231da177e4SLinus Torvalds * problem. The worst that can happen is that we set the IOC bit again 241da177e4SLinus Torvalds * generating a spurious interrupt. We could fix this by creating another 251da177e4SLinus Torvalds * QH and leaving the IOC bit always set, but then we would have to play 261da177e4SLinus Torvalds * games with the FSBR code to make sure we get the correct order in all 271da177e4SLinus Torvalds * the cases. I don't think it's worth the effort 281da177e4SLinus Torvalds */ 29*dccf4a48SAlan Stern static void uhci_set_next_interrupt(struct uhci_hcd *uhci) 301da177e4SLinus Torvalds { 316c1b445cSAlan Stern if (uhci->is_stopped) 321f09df8bSAlan Stern mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); 331da177e4SLinus Torvalds uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 341da177e4SLinus Torvalds } 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) 371da177e4SLinus Torvalds { 381da177e4SLinus Torvalds uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); 391da177e4SLinus Torvalds } 401da177e4SLinus Torvalds 412532178aSAlan Stern static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) 421da177e4SLinus Torvalds { 431da177e4SLinus Torvalds dma_addr_t dma_handle; 441da177e4SLinus Torvalds struct uhci_td *td; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); 471da177e4SLinus Torvalds if (!td) 481da177e4SLinus Torvalds return NULL; 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds td->dma_handle = dma_handle; 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds td->link = UHCI_PTR_TERM; 531da177e4SLinus Torvalds td->buffer = 0; 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds td->frame = -1; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds INIT_LIST_HEAD(&td->list); 581da177e4SLinus Torvalds INIT_LIST_HEAD(&td->remove_list); 591da177e4SLinus Torvalds INIT_LIST_HEAD(&td->fl_list); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds return td; 621da177e4SLinus Torvalds } 631da177e4SLinus Torvalds 64*dccf4a48SAlan Stern static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) 65*dccf4a48SAlan Stern { 66*dccf4a48SAlan Stern if (!list_empty(&td->list)) 67*dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); 68*dccf4a48SAlan Stern if (!list_empty(&td->remove_list)) 69*dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td); 70*dccf4a48SAlan Stern if (!list_empty(&td->fl_list)) 71*dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 72*dccf4a48SAlan Stern 73*dccf4a48SAlan Stern dma_pool_free(uhci->td_pool, td, td->dma_handle); 74*dccf4a48SAlan Stern } 75*dccf4a48SAlan Stern 761da177e4SLinus Torvalds static inline void uhci_fill_td(struct uhci_td *td, u32 status, 771da177e4SLinus Torvalds u32 token, u32 buffer) 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds td->status = cpu_to_le32(status); 801da177e4SLinus Torvalds td->token = cpu_to_le32(token); 811da177e4SLinus Torvalds td->buffer = cpu_to_le32(buffer); 821da177e4SLinus Torvalds } 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds /* 85687f5f34SAlan Stern * We insert Isochronous URBs directly into the frame list at the beginning 861da177e4SLinus Torvalds */ 87*dccf4a48SAlan Stern static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, 88*dccf4a48SAlan Stern struct uhci_td *td, unsigned framenum) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds framenum &= (UHCI_NUMFRAMES - 1); 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds td->frame = framenum; 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds /* Is there a TD already mapped there? */ 95a1d59ce8SAlan Stern if (uhci->frame_cpu[framenum]) { 961da177e4SLinus Torvalds struct uhci_td *ftd, *ltd; 971da177e4SLinus Torvalds 98a1d59ce8SAlan Stern ftd = uhci->frame_cpu[framenum]; 991da177e4SLinus Torvalds ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds list_add_tail(&td->fl_list, &ftd->fl_list); 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds td->link = ltd->link; 1041da177e4SLinus Torvalds wmb(); 1051da177e4SLinus Torvalds ltd->link = cpu_to_le32(td->dma_handle); 1061da177e4SLinus Torvalds } else { 107a1d59ce8SAlan Stern td->link = uhci->frame[framenum]; 1081da177e4SLinus Torvalds wmb(); 109a1d59ce8SAlan Stern uhci->frame[framenum] = cpu_to_le32(td->dma_handle); 110a1d59ce8SAlan Stern uhci->frame_cpu[framenum] = td; 1111da177e4SLinus Torvalds } 1121da177e4SLinus Torvalds } 1131da177e4SLinus Torvalds 114*dccf4a48SAlan Stern static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, 115b81d3436SAlan Stern struct uhci_td *td) 1161da177e4SLinus Torvalds { 1171da177e4SLinus Torvalds /* If it's not inserted, don't remove it */ 118b81d3436SAlan Stern if (td->frame == -1) { 119b81d3436SAlan Stern WARN_ON(!list_empty(&td->fl_list)); 1201da177e4SLinus Torvalds return; 121b81d3436SAlan Stern } 1221da177e4SLinus Torvalds 123b81d3436SAlan Stern if (uhci->frame_cpu[td->frame] == td) { 1241da177e4SLinus Torvalds if (list_empty(&td->fl_list)) { 125a1d59ce8SAlan Stern uhci->frame[td->frame] = td->link; 126a1d59ce8SAlan Stern uhci->frame_cpu[td->frame] = NULL; 1271da177e4SLinus Torvalds } else { 1281da177e4SLinus Torvalds struct uhci_td *ntd; 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); 131a1d59ce8SAlan Stern uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); 132a1d59ce8SAlan Stern uhci->frame_cpu[td->frame] = ntd; 1331da177e4SLinus Torvalds } 1341da177e4SLinus Torvalds } else { 1351da177e4SLinus Torvalds struct uhci_td *ptd; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list); 1381da177e4SLinus Torvalds ptd->link = td->link; 1391da177e4SLinus Torvalds } 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds list_del_init(&td->fl_list); 1421da177e4SLinus Torvalds td->frame = -1; 1431da177e4SLinus Torvalds } 1441da177e4SLinus Torvalds 145*dccf4a48SAlan Stern /* 146*dccf4a48SAlan Stern * Remove all the TDs for an Isochronous URB from the frame list 147*dccf4a48SAlan Stern */ 148*dccf4a48SAlan Stern static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) 149b81d3436SAlan Stern { 150b81d3436SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 151b81d3436SAlan Stern struct uhci_td *td; 152b81d3436SAlan Stern 153b81d3436SAlan Stern list_for_each_entry(td, &urbp->td_list, list) 154*dccf4a48SAlan Stern uhci_remove_td_from_frame_list(uhci, td); 155b81d3436SAlan Stern wmb(); 156b81d3436SAlan Stern } 157b81d3436SAlan Stern 1581da177e4SLinus Torvalds /* 159*dccf4a48SAlan Stern * Remove an URB's TDs from the hardware schedule 1601da177e4SLinus Torvalds */ 161*dccf4a48SAlan Stern static void uhci_remove_tds_from_schedule(struct uhci_hcd *uhci, 162*dccf4a48SAlan Stern struct urb *urb, int status) 1631da177e4SLinus Torvalds { 1641da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 1651da177e4SLinus Torvalds 166*dccf4a48SAlan Stern /* Isochronous TDs get unlinked directly from the frame list */ 167*dccf4a48SAlan Stern if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { 168*dccf4a48SAlan Stern uhci_unlink_isochronous_tds(uhci, urb); 169*dccf4a48SAlan Stern return; 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 172*dccf4a48SAlan Stern /* If the URB isn't first on its queue, adjust the link pointer 173*dccf4a48SAlan Stern * of the last TD in the previous URB. */ 174*dccf4a48SAlan Stern if (urbp->node.prev != &urbp->qh->queue) { 175*dccf4a48SAlan Stern struct urb_priv *purbp; 176*dccf4a48SAlan Stern struct uhci_td *ptd, *ltd; 1771da177e4SLinus Torvalds 178*dccf4a48SAlan Stern if (status == -EINPROGRESS) 179*dccf4a48SAlan Stern status = 0; 180*dccf4a48SAlan Stern purbp = list_entry(urbp->node.prev, struct urb_priv, node); 181*dccf4a48SAlan Stern ptd = list_entry(purbp->td_list.prev, struct uhci_td, 182*dccf4a48SAlan Stern list); 183*dccf4a48SAlan Stern ltd = list_entry(urbp->td_list.prev, struct uhci_td, 184*dccf4a48SAlan Stern list); 185*dccf4a48SAlan Stern ptd->link = ltd->link; 1861da177e4SLinus Torvalds } 1871da177e4SLinus Torvalds 188*dccf4a48SAlan Stern /* If the URB completed with an error, then the QH element certainly 189*dccf4a48SAlan Stern * points to one of the URB's TDs. If it completed normally then 190*dccf4a48SAlan Stern * the QH element has certainly moved on to the next URB. And if 191*dccf4a48SAlan Stern * the URB is still in progress then it must have been dequeued. 192*dccf4a48SAlan Stern * The QH element either hasn't reached it yet or is somewhere in 193*dccf4a48SAlan Stern * the middle. If the URB wasn't first we can assume that it 194*dccf4a48SAlan Stern * hasn't started yet (see above): Otherwise all the preceding URBs 195*dccf4a48SAlan Stern * would have completed and been removed from the queue, so this one 196*dccf4a48SAlan Stern * _would_ be first. 197*dccf4a48SAlan Stern * 198*dccf4a48SAlan Stern * If the QH element is inside this URB, clear it. It will be 199*dccf4a48SAlan Stern * set properly when the QH is activated. 200*dccf4a48SAlan Stern */ 201*dccf4a48SAlan Stern if (status < 0) 202*dccf4a48SAlan Stern urbp->qh->element = UHCI_PTR_TERM; 203*dccf4a48SAlan Stern } 204*dccf4a48SAlan Stern 205*dccf4a48SAlan Stern static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, 206*dccf4a48SAlan Stern struct usb_device *udev, struct usb_host_endpoint *hep) 2071da177e4SLinus Torvalds { 2081da177e4SLinus Torvalds dma_addr_t dma_handle; 2091da177e4SLinus Torvalds struct uhci_qh *qh; 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); 2121da177e4SLinus Torvalds if (!qh) 2131da177e4SLinus Torvalds return NULL; 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds qh->dma_handle = dma_handle; 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds qh->element = UHCI_PTR_TERM; 2181da177e4SLinus Torvalds qh->link = UHCI_PTR_TERM; 2191da177e4SLinus Torvalds 220*dccf4a48SAlan Stern INIT_LIST_HEAD(&qh->queue); 221*dccf4a48SAlan Stern INIT_LIST_HEAD(&qh->node); 2221da177e4SLinus Torvalds 223*dccf4a48SAlan Stern if (udev) { /* Normal QH */ 224*dccf4a48SAlan Stern qh->state = QH_STATE_IDLE; 225*dccf4a48SAlan Stern qh->hep = hep; 226*dccf4a48SAlan Stern qh->udev = udev; 227*dccf4a48SAlan Stern hep->hcpriv = qh; 228*dccf4a48SAlan Stern usb_get_dev(udev); 2291da177e4SLinus Torvalds 230*dccf4a48SAlan Stern } else { /* Skeleton QH */ 231*dccf4a48SAlan Stern qh->state = QH_STATE_ACTIVE; 232*dccf4a48SAlan Stern qh->udev = NULL; 233*dccf4a48SAlan Stern } 2341da177e4SLinus Torvalds return qh; 2351da177e4SLinus Torvalds } 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 2381da177e4SLinus Torvalds { 239*dccf4a48SAlan Stern WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); 240*dccf4a48SAlan Stern if (!list_empty(&qh->queue)) 2411da177e4SLinus Torvalds dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh); 2421da177e4SLinus Torvalds 243*dccf4a48SAlan Stern list_del(&qh->node); 244*dccf4a48SAlan Stern if (qh->udev) { 245*dccf4a48SAlan Stern qh->hep->hcpriv = NULL; 246*dccf4a48SAlan Stern usb_put_dev(qh->udev); 247*dccf4a48SAlan Stern } 2481da177e4SLinus Torvalds dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds /* 252*dccf4a48SAlan Stern * Put a QH on the schedule in both hardware and software 2531da177e4SLinus Torvalds */ 254*dccf4a48SAlan Stern static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 2551da177e4SLinus Torvalds { 2561da177e4SLinus Torvalds struct uhci_qh *pqh; 2571da177e4SLinus Torvalds 258*dccf4a48SAlan Stern WARN_ON(list_empty(&qh->queue)); 259*dccf4a48SAlan Stern 260*dccf4a48SAlan Stern /* Set the element pointer if it isn't set already. 261*dccf4a48SAlan Stern * This isn't needed for Isochronous queues, but it doesn't hurt. */ 262*dccf4a48SAlan Stern if (qh_element(qh) == UHCI_PTR_TERM) { 263*dccf4a48SAlan Stern struct urb_priv *urbp = list_entry(qh->queue.next, 264*dccf4a48SAlan Stern struct urb_priv, node); 265*dccf4a48SAlan Stern struct uhci_td *td = list_entry(urbp->td_list.next, 266*dccf4a48SAlan Stern struct uhci_td, list); 267*dccf4a48SAlan Stern 268*dccf4a48SAlan Stern qh->element = cpu_to_le32(td->dma_handle); 269*dccf4a48SAlan Stern } 270*dccf4a48SAlan Stern 271*dccf4a48SAlan Stern if (qh->state == QH_STATE_ACTIVE) 2721da177e4SLinus Torvalds return; 273*dccf4a48SAlan Stern qh->state = QH_STATE_ACTIVE; 274*dccf4a48SAlan Stern 275*dccf4a48SAlan Stern /* Move the QH from its old list to the end of the appropriate 276*dccf4a48SAlan Stern * skeleton's list */ 277*dccf4a48SAlan Stern list_move_tail(&qh->node, &qh->skel->node); 278*dccf4a48SAlan Stern 279*dccf4a48SAlan Stern /* Link it into the schedule */ 280*dccf4a48SAlan Stern pqh = list_entry(qh->node.prev, struct uhci_qh, node); 281*dccf4a48SAlan Stern qh->link = pqh->link; 282*dccf4a48SAlan Stern wmb(); 283*dccf4a48SAlan Stern pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); 284*dccf4a48SAlan Stern } 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds /* 287*dccf4a48SAlan Stern * Take a QH off the hardware schedule 2881da177e4SLinus Torvalds */ 289*dccf4a48SAlan Stern static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 290*dccf4a48SAlan Stern { 291*dccf4a48SAlan Stern struct uhci_qh *pqh; 2921da177e4SLinus Torvalds 293*dccf4a48SAlan Stern if (qh->state == QH_STATE_UNLINKING) 294*dccf4a48SAlan Stern return; 295*dccf4a48SAlan Stern WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev); 296*dccf4a48SAlan Stern qh->state = QH_STATE_UNLINKING; 2971da177e4SLinus Torvalds 298*dccf4a48SAlan Stern /* Unlink the QH from the schedule and record when we did it */ 299*dccf4a48SAlan Stern pqh = list_entry(qh->node.prev, struct uhci_qh, node); 300*dccf4a48SAlan Stern pqh->link = qh->link; 301*dccf4a48SAlan Stern mb(); 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 304*dccf4a48SAlan Stern qh->unlink_frame = uhci->frame_number; 3051da177e4SLinus Torvalds 306*dccf4a48SAlan Stern /* Force an interrupt so we know when the QH is fully unlinked */ 307*dccf4a48SAlan Stern if (list_empty(&uhci->skel_unlink_qh->node)) 3081da177e4SLinus Torvalds uhci_set_next_interrupt(uhci); 3091da177e4SLinus Torvalds 310*dccf4a48SAlan Stern /* Move the QH from its old list to the end of the unlinking list */ 311*dccf4a48SAlan Stern list_move_tail(&qh->node, &uhci->skel_unlink_qh->node); 3121da177e4SLinus Torvalds } 3131da177e4SLinus Torvalds 3141da177e4SLinus Torvalds /* 315*dccf4a48SAlan Stern * When we and the controller are through with a QH, it becomes IDLE. 316*dccf4a48SAlan Stern * This happens when a QH has been off the schedule (on the unlinking 317*dccf4a48SAlan Stern * list) for more than one frame, or when an error occurs while adding 318*dccf4a48SAlan Stern * the first URB onto a new QH. 3191da177e4SLinus Torvalds */ 320*dccf4a48SAlan Stern static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) 321*dccf4a48SAlan Stern { 322*dccf4a48SAlan Stern WARN_ON(qh->state == QH_STATE_ACTIVE); 323*dccf4a48SAlan Stern 324*dccf4a48SAlan Stern list_move(&qh->node, &uhci->idle_qh_list); 325*dccf4a48SAlan Stern qh->state = QH_STATE_IDLE; 326*dccf4a48SAlan Stern 327*dccf4a48SAlan Stern /* If anyone is waiting for a QH to become idle, wake them up */ 328*dccf4a48SAlan Stern if (uhci->num_waiting) 329*dccf4a48SAlan Stern wake_up_all(&uhci->waitqh); 3301da177e4SLinus Torvalds } 3311da177e4SLinus Torvalds 332*dccf4a48SAlan Stern static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, 333*dccf4a48SAlan Stern struct urb *urb) 3341da177e4SLinus Torvalds { 3351da177e4SLinus Torvalds struct urb_priv *urbp; 3361da177e4SLinus Torvalds 3371da177e4SLinus Torvalds urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC); 3381da177e4SLinus Torvalds if (!urbp) 3391da177e4SLinus Torvalds return NULL; 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds memset((void *)urbp, 0, sizeof(*urbp)); 3421da177e4SLinus Torvalds 3431da177e4SLinus Torvalds urbp->urb = urb; 3441da177e4SLinus Torvalds urb->hcpriv = urbp; 345*dccf4a48SAlan Stern urbp->fsbrtime = jiffies; 346*dccf4a48SAlan Stern 347*dccf4a48SAlan Stern INIT_LIST_HEAD(&urbp->node); 348*dccf4a48SAlan Stern INIT_LIST_HEAD(&urbp->td_list); 349*dccf4a48SAlan Stern INIT_LIST_HEAD(&urbp->urb_list); 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvalds return urbp; 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds 3541da177e4SLinus Torvalds static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) 3551da177e4SLinus Torvalds { 3561da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds list_add_tail(&td->list, &urbp->td_list); 3591da177e4SLinus Torvalds } 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds static void uhci_remove_td_from_urb(struct uhci_td *td) 3621da177e4SLinus Torvalds { 3631da177e4SLinus Torvalds if (list_empty(&td->list)) 3641da177e4SLinus Torvalds return; 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds list_del_init(&td->list); 3671da177e4SLinus Torvalds } 3681da177e4SLinus Torvalds 369*dccf4a48SAlan Stern static void uhci_free_urb_priv(struct uhci_hcd *uhci, 370*dccf4a48SAlan Stern struct urb_priv *urbp) 3711da177e4SLinus Torvalds { 3721da177e4SLinus Torvalds struct uhci_td *td, *tmp; 3731da177e4SLinus Torvalds 3741da177e4SLinus Torvalds if (!list_empty(&urbp->urb_list)) 375*dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list!\n", 376*dccf4a48SAlan Stern urbp->urb); 377*dccf4a48SAlan Stern if (!list_empty(&urbp->node)) 378*dccf4a48SAlan Stern dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", 379*dccf4a48SAlan Stern urbp->urb); 3801da177e4SLinus Torvalds 3811da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 3821da177e4SLinus Torvalds if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) { 3831da177e4SLinus Torvalds uhci_free_pending_tds(uhci); 3841da177e4SLinus Torvalds uhci->td_remove_age = uhci->frame_number; 3851da177e4SLinus Torvalds } 3861da177e4SLinus Torvalds 3871da177e4SLinus Torvalds /* Check to see if the remove list is empty. Set the IOC bit */ 388*dccf4a48SAlan Stern /* to force an interrupt so we can remove the TDs. */ 3891da177e4SLinus Torvalds if (list_empty(&uhci->td_remove_list)) 3901da177e4SLinus Torvalds uhci_set_next_interrupt(uhci); 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { 3931da177e4SLinus Torvalds uhci_remove_td_from_urb(td); 3941da177e4SLinus Torvalds list_add(&td->remove_list, &uhci->td_remove_list); 3951da177e4SLinus Torvalds } 3961da177e4SLinus Torvalds 397*dccf4a48SAlan Stern urbp->urb->hcpriv = NULL; 3981da177e4SLinus Torvalds kmem_cache_free(uhci_up_cachep, urbp); 3991da177e4SLinus Torvalds } 4001da177e4SLinus Torvalds 4011da177e4SLinus Torvalds static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) 4021da177e4SLinus Torvalds { 4031da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 4041da177e4SLinus Torvalds 4051da177e4SLinus Torvalds if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) { 4061da177e4SLinus Torvalds urbp->fsbr = 1; 4071da177e4SLinus Torvalds if (!uhci->fsbr++ && !uhci->fsbrtimeout) 4081da177e4SLinus Torvalds uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; 4091da177e4SLinus Torvalds } 4101da177e4SLinus Torvalds } 4111da177e4SLinus Torvalds 4121da177e4SLinus Torvalds static void uhci_dec_fsbr(struct uhci_hcd *uhci, struct urb *urb) 4131da177e4SLinus Torvalds { 4141da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 4151da177e4SLinus Torvalds 4161da177e4SLinus Torvalds if ((!(urb->transfer_flags & URB_NO_FSBR)) && urbp->fsbr) { 4171da177e4SLinus Torvalds urbp->fsbr = 0; 4181da177e4SLinus Torvalds if (!--uhci->fsbr) 4191da177e4SLinus Torvalds uhci->fsbrtimeout = jiffies + FSBR_DELAY; 4201da177e4SLinus Torvalds } 4211da177e4SLinus Torvalds } 4221da177e4SLinus Torvalds 4231da177e4SLinus Torvalds /* 4241da177e4SLinus Torvalds * Map status to standard result codes 4251da177e4SLinus Torvalds * 4261da177e4SLinus Torvalds * <status> is (td_status(td) & 0xF60000), a.k.a. 4271da177e4SLinus Torvalds * uhci_status_bits(td_status(td)). 4281da177e4SLinus Torvalds * Note: <status> does not include the TD_CTRL_NAK bit. 4291da177e4SLinus Torvalds * <dir_out> is True for output TDs and False for input TDs. 4301da177e4SLinus Torvalds */ 4311da177e4SLinus Torvalds static int uhci_map_status(int status, int dir_out) 4321da177e4SLinus Torvalds { 4331da177e4SLinus Torvalds if (!status) 4341da177e4SLinus Torvalds return 0; 4351da177e4SLinus Torvalds if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */ 4361da177e4SLinus Torvalds return -EPROTO; 4371da177e4SLinus Torvalds if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */ 4381da177e4SLinus Torvalds if (dir_out) 4391da177e4SLinus Torvalds return -EPROTO; 4401da177e4SLinus Torvalds else 4411da177e4SLinus Torvalds return -EILSEQ; 4421da177e4SLinus Torvalds } 4431da177e4SLinus Torvalds if (status & TD_CTRL_BABBLE) /* Babble */ 4441da177e4SLinus Torvalds return -EOVERFLOW; 4451da177e4SLinus Torvalds if (status & TD_CTRL_DBUFERR) /* Buffer error */ 4461da177e4SLinus Torvalds return -ENOSR; 4471da177e4SLinus Torvalds if (status & TD_CTRL_STALLED) /* Stalled */ 4481da177e4SLinus Torvalds return -EPIPE; 4491da177e4SLinus Torvalds WARN_ON(status & TD_CTRL_ACTIVE); /* Active */ 4501da177e4SLinus Torvalds return 0; 4511da177e4SLinus Torvalds } 4521da177e4SLinus Torvalds 4531da177e4SLinus Torvalds /* 454*dccf4a48SAlan Stern * Fix up the data toggles for URBs in a queue, when one of them 455*dccf4a48SAlan Stern * terminates early (short transfer, error, or dequeued). 456*dccf4a48SAlan Stern */ 457*dccf4a48SAlan Stern static void uhci_fixup_toggles(struct urb *urb) 458*dccf4a48SAlan Stern { 459*dccf4a48SAlan Stern struct list_head *head; 460*dccf4a48SAlan Stern struct uhci_td *td; 461*dccf4a48SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 462*dccf4a48SAlan Stern int prevactive = 0; 463*dccf4a48SAlan Stern unsigned int toggle = 0; 464*dccf4a48SAlan Stern struct urb_priv *turbp, *list_end; 465*dccf4a48SAlan Stern 466*dccf4a48SAlan Stern /* 467*dccf4a48SAlan Stern * We need to find out what the last successful toggle was so 468*dccf4a48SAlan Stern * we can update the data toggles for the following transfers. 469*dccf4a48SAlan Stern * 470*dccf4a48SAlan Stern * There are 2 ways the last successful completed TD is found: 471*dccf4a48SAlan Stern * 472*dccf4a48SAlan Stern * 1) The TD is NOT active and the actual length < expected length 473*dccf4a48SAlan Stern * 2) The TD is NOT active and it's the last TD in the chain 474*dccf4a48SAlan Stern * 475*dccf4a48SAlan Stern * and a third way the first uncompleted TD is found: 476*dccf4a48SAlan Stern * 477*dccf4a48SAlan Stern * 3) The TD is active and the previous TD is NOT active 478*dccf4a48SAlan Stern */ 479*dccf4a48SAlan Stern head = &urbp->td_list; 480*dccf4a48SAlan Stern list_for_each_entry(td, head, list) { 481*dccf4a48SAlan Stern unsigned int ctrlstat = td_status(td); 482*dccf4a48SAlan Stern 483*dccf4a48SAlan Stern if (!(ctrlstat & TD_CTRL_ACTIVE) && 484*dccf4a48SAlan Stern (uhci_actual_length(ctrlstat) < 485*dccf4a48SAlan Stern uhci_expected_length(td_token(td)) || 486*dccf4a48SAlan Stern td->list.next == head)) 487*dccf4a48SAlan Stern toggle = uhci_toggle(td_token(td)) ^ 1; 488*dccf4a48SAlan Stern else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive) 489*dccf4a48SAlan Stern toggle = uhci_toggle(td_token(td)); 490*dccf4a48SAlan Stern 491*dccf4a48SAlan Stern prevactive = ctrlstat & TD_CTRL_ACTIVE; 492*dccf4a48SAlan Stern } 493*dccf4a48SAlan Stern 494*dccf4a48SAlan Stern /* 495*dccf4a48SAlan Stern * Fix up the toggle for the following URBs in the queue. 496*dccf4a48SAlan Stern * 497*dccf4a48SAlan Stern * We can stop as soon as we find an URB with toggles set correctly, 498*dccf4a48SAlan Stern * because then all the following URBs will be correct also. 499*dccf4a48SAlan Stern */ 500*dccf4a48SAlan Stern list_end = list_entry(&urbp->qh->queue, struct urb_priv, node); 501*dccf4a48SAlan Stern turbp = urbp; 502*dccf4a48SAlan Stern while ((turbp = list_entry(turbp->node.next, struct urb_priv, node)) 503*dccf4a48SAlan Stern != list_end) { 504*dccf4a48SAlan Stern td = list_entry(turbp->td_list.next, struct uhci_td, list); 505*dccf4a48SAlan Stern if (uhci_toggle(td_token(td)) == toggle) 506*dccf4a48SAlan Stern return; 507*dccf4a48SAlan Stern 508*dccf4a48SAlan Stern list_for_each_entry(td, &turbp->td_list, list) { 509*dccf4a48SAlan Stern td->token ^= __constant_cpu_to_le32(TD_TOKEN_TOGGLE); 510*dccf4a48SAlan Stern toggle ^= 1; 511*dccf4a48SAlan Stern } 512*dccf4a48SAlan Stern } 513*dccf4a48SAlan Stern 514*dccf4a48SAlan Stern usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 515*dccf4a48SAlan Stern usb_pipeout(urb->pipe), toggle); 516*dccf4a48SAlan Stern } 517*dccf4a48SAlan Stern 518*dccf4a48SAlan Stern /* 5191da177e4SLinus Torvalds * Control transfers 5201da177e4SLinus Torvalds */ 521*dccf4a48SAlan Stern static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, 522*dccf4a48SAlan Stern struct uhci_qh *qh) 5231da177e4SLinus Torvalds { 5241da177e4SLinus Torvalds struct uhci_td *td; 5251da177e4SLinus Torvalds unsigned long destination, status; 526*dccf4a48SAlan Stern int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 5271da177e4SLinus Torvalds int len = urb->transfer_buffer_length; 5281da177e4SLinus Torvalds dma_addr_t data = urb->transfer_dma; 529*dccf4a48SAlan Stern __le32 *plink; 5301da177e4SLinus Torvalds 5311da177e4SLinus Torvalds /* The "pipe" thing contains the destination in bits 8--18 */ 5321da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 5331da177e4SLinus Torvalds 5341da177e4SLinus Torvalds /* 3 errors */ 5351da177e4SLinus Torvalds status = TD_CTRL_ACTIVE | uhci_maxerr(3); 5361da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 5371da177e4SLinus Torvalds status |= TD_CTRL_LS; 5381da177e4SLinus Torvalds 5391da177e4SLinus Torvalds /* 5401da177e4SLinus Torvalds * Build the TD for the control request setup packet 5411da177e4SLinus Torvalds */ 5422532178aSAlan Stern td = uhci_alloc_td(uhci); 5431da177e4SLinus Torvalds if (!td) 5441da177e4SLinus Torvalds return -ENOMEM; 5451da177e4SLinus Torvalds 5461da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 547fa346568SAlan Stern uhci_fill_td(td, status, destination | uhci_explen(8), 5481da177e4SLinus Torvalds urb->setup_dma); 549*dccf4a48SAlan Stern plink = &td->link; 5501da177e4SLinus Torvalds 5511da177e4SLinus Torvalds /* 5521da177e4SLinus Torvalds * If direction is "send", change the packet ID from SETUP (0x2D) 5531da177e4SLinus Torvalds * to OUT (0xE1). Else change it from SETUP to IN (0x69) and 5541da177e4SLinus Torvalds * set Short Packet Detect (SPD) for all data packets. 5551da177e4SLinus Torvalds */ 5561da177e4SLinus Torvalds if (usb_pipeout(urb->pipe)) 5571da177e4SLinus Torvalds destination ^= (USB_PID_SETUP ^ USB_PID_OUT); 5581da177e4SLinus Torvalds else { 5591da177e4SLinus Torvalds destination ^= (USB_PID_SETUP ^ USB_PID_IN); 5601da177e4SLinus Torvalds status |= TD_CTRL_SPD; 5611da177e4SLinus Torvalds } 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds /* 564687f5f34SAlan Stern * Build the DATA TDs 5651da177e4SLinus Torvalds */ 5661da177e4SLinus Torvalds while (len > 0) { 567*dccf4a48SAlan Stern int pktsze = min(len, maxsze); 5681da177e4SLinus Torvalds 5692532178aSAlan Stern td = uhci_alloc_td(uhci); 5701da177e4SLinus Torvalds if (!td) 5711da177e4SLinus Torvalds return -ENOMEM; 572*dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 5731da177e4SLinus Torvalds 5741da177e4SLinus Torvalds /* Alternate Data0/1 (start with Data1) */ 5751da177e4SLinus Torvalds destination ^= TD_TOKEN_TOGGLE; 5761da177e4SLinus Torvalds 5771da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 578fa346568SAlan Stern uhci_fill_td(td, status, destination | uhci_explen(pktsze), 5791da177e4SLinus Torvalds data); 580*dccf4a48SAlan Stern plink = &td->link; 5811da177e4SLinus Torvalds 5821da177e4SLinus Torvalds data += pktsze; 5831da177e4SLinus Torvalds len -= pktsze; 5841da177e4SLinus Torvalds } 5851da177e4SLinus Torvalds 5861da177e4SLinus Torvalds /* 5871da177e4SLinus Torvalds * Build the final TD for control status 5881da177e4SLinus Torvalds */ 5892532178aSAlan Stern td = uhci_alloc_td(uhci); 5901da177e4SLinus Torvalds if (!td) 5911da177e4SLinus Torvalds return -ENOMEM; 592*dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds /* 5951da177e4SLinus Torvalds * It's IN if the pipe is an output pipe or we're not expecting 5961da177e4SLinus Torvalds * data back. 5971da177e4SLinus Torvalds */ 5981da177e4SLinus Torvalds destination &= ~TD_TOKEN_PID_MASK; 5991da177e4SLinus Torvalds if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) 6001da177e4SLinus Torvalds destination |= USB_PID_IN; 6011da177e4SLinus Torvalds else 6021da177e4SLinus Torvalds destination |= USB_PID_OUT; 6031da177e4SLinus Torvalds 6041da177e4SLinus Torvalds destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ 6051da177e4SLinus Torvalds 6061da177e4SLinus Torvalds status &= ~TD_CTRL_SPD; 6071da177e4SLinus Torvalds 6081da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 6091da177e4SLinus Torvalds uhci_fill_td(td, status | TD_CTRL_IOC, 610fa346568SAlan Stern destination | uhci_explen(0), 0); 6111da177e4SLinus Torvalds 6121da177e4SLinus Torvalds /* Low-speed transfers get a different queue, and won't hog the bus. 6131da177e4SLinus Torvalds * Also, some devices enumerate better without FSBR; the easiest way 6141da177e4SLinus Torvalds * to do that is to put URBs on the low-speed queue while the device 615630aa3cfSAlan Stern * isn't in the CONFIGURED state. */ 6161da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW || 617630aa3cfSAlan Stern urb->dev->state != USB_STATE_CONFIGURED) 618*dccf4a48SAlan Stern qh->skel = uhci->skel_ls_control_qh; 6191da177e4SLinus Torvalds else { 620*dccf4a48SAlan Stern qh->skel = uhci->skel_fs_control_qh; 6211da177e4SLinus Torvalds uhci_inc_fsbr(uhci, urb); 6221da177e4SLinus Torvalds } 6231da177e4SLinus Torvalds 624*dccf4a48SAlan Stern return 0; 6251da177e4SLinus Torvalds } 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds /* 6281da177e4SLinus Torvalds * If control-IN transfer was short, the status packet wasn't sent. 6291da177e4SLinus Torvalds * This routine changes the element pointer in the QH to point at the 6301da177e4SLinus Torvalds * status TD. It's safe to do this even while the QH is live, because 6311da177e4SLinus Torvalds * the hardware only updates the element pointer following a successful 6321da177e4SLinus Torvalds * transfer. The inactive TD for the short packet won't cause an update, 6331da177e4SLinus Torvalds * so the pointer won't get overwritten. The next time the controller 6341da177e4SLinus Torvalds * sees this QH, it will send the status packet. 6351da177e4SLinus Torvalds */ 6361da177e4SLinus Torvalds static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb) 6371da177e4SLinus Torvalds { 6381da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 6391da177e4SLinus Torvalds struct uhci_td *td; 6401da177e4SLinus Torvalds 641*dccf4a48SAlan Stern urbp->short_transfer = 1; 6421da177e4SLinus Torvalds 6431da177e4SLinus Torvalds td = list_entry(urbp->td_list.prev, struct uhci_td, list); 6441da177e4SLinus Torvalds urbp->qh->element = cpu_to_le32(td->dma_handle); 6451da177e4SLinus Torvalds 6461da177e4SLinus Torvalds return -EINPROGRESS; 6471da177e4SLinus Torvalds } 6481da177e4SLinus Torvalds 6491da177e4SLinus Torvalds 6501da177e4SLinus Torvalds static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) 6511da177e4SLinus Torvalds { 6521da177e4SLinus Torvalds struct list_head *tmp, *head; 6531da177e4SLinus Torvalds struct urb_priv *urbp = urb->hcpriv; 6541da177e4SLinus Torvalds struct uhci_td *td; 6551da177e4SLinus Torvalds unsigned int status; 6561da177e4SLinus Torvalds int ret = 0; 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds head = &urbp->td_list; 659*dccf4a48SAlan Stern if (urbp->short_transfer) { 6601da177e4SLinus Torvalds tmp = head->prev; 6611da177e4SLinus Torvalds goto status_stage; 6621da177e4SLinus Torvalds } 6631da177e4SLinus Torvalds 664*dccf4a48SAlan Stern urb->actual_length = 0; 665*dccf4a48SAlan Stern 6661da177e4SLinus Torvalds tmp = head->next; 6671da177e4SLinus Torvalds td = list_entry(tmp, struct uhci_td, list); 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds /* The first TD is the SETUP stage, check the status, but skip */ 6701da177e4SLinus Torvalds /* the count */ 6711da177e4SLinus Torvalds status = uhci_status_bits(td_status(td)); 6721da177e4SLinus Torvalds if (status & TD_CTRL_ACTIVE) 6731da177e4SLinus Torvalds return -EINPROGRESS; 6741da177e4SLinus Torvalds 6751da177e4SLinus Torvalds if (status) 6761da177e4SLinus Torvalds goto td_error; 6771da177e4SLinus Torvalds 678687f5f34SAlan Stern /* The rest of the TDs (but the last) are data */ 6791da177e4SLinus Torvalds tmp = tmp->next; 6801da177e4SLinus Torvalds while (tmp != head && tmp->next != head) { 6811da177e4SLinus Torvalds unsigned int ctrlstat; 6821da177e4SLinus Torvalds 6831da177e4SLinus Torvalds td = list_entry(tmp, struct uhci_td, list); 6841da177e4SLinus Torvalds tmp = tmp->next; 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds ctrlstat = td_status(td); 6871da177e4SLinus Torvalds status = uhci_status_bits(ctrlstat); 6881da177e4SLinus Torvalds if (status & TD_CTRL_ACTIVE) 6891da177e4SLinus Torvalds return -EINPROGRESS; 6901da177e4SLinus Torvalds 6911da177e4SLinus Torvalds urb->actual_length += uhci_actual_length(ctrlstat); 6921da177e4SLinus Torvalds 6931da177e4SLinus Torvalds if (status) 6941da177e4SLinus Torvalds goto td_error; 6951da177e4SLinus Torvalds 6961da177e4SLinus Torvalds /* Check to see if we received a short packet */ 6971da177e4SLinus Torvalds if (uhci_actual_length(ctrlstat) < 6981da177e4SLinus Torvalds uhci_expected_length(td_token(td))) { 6991da177e4SLinus Torvalds if (urb->transfer_flags & URB_SHORT_NOT_OK) { 7001da177e4SLinus Torvalds ret = -EREMOTEIO; 7011da177e4SLinus Torvalds goto err; 7021da177e4SLinus Torvalds } 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds return usb_control_retrigger_status(uhci, urb); 7051da177e4SLinus Torvalds } 7061da177e4SLinus Torvalds } 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds status_stage: 7091da177e4SLinus Torvalds td = list_entry(tmp, struct uhci_td, list); 7101da177e4SLinus Torvalds 7111da177e4SLinus Torvalds /* Control status stage */ 7121da177e4SLinus Torvalds status = td_status(td); 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds #ifdef I_HAVE_BUGGY_APC_BACKUPS 7151da177e4SLinus Torvalds /* APC BackUPS Pro kludge */ 7161da177e4SLinus Torvalds /* It tries to send all of the descriptor instead of the amount */ 7171da177e4SLinus Torvalds /* we requested */ 7181da177e4SLinus Torvalds if (status & TD_CTRL_IOC && /* IOC is masked out by uhci_status_bits */ 7191da177e4SLinus Torvalds status & TD_CTRL_ACTIVE && 7201da177e4SLinus Torvalds status & TD_CTRL_NAK) 7211da177e4SLinus Torvalds return 0; 7221da177e4SLinus Torvalds #endif 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds status = uhci_status_bits(status); 7251da177e4SLinus Torvalds if (status & TD_CTRL_ACTIVE) 7261da177e4SLinus Torvalds return -EINPROGRESS; 7271da177e4SLinus Torvalds 7281da177e4SLinus Torvalds if (status) 7291da177e4SLinus Torvalds goto td_error; 7301da177e4SLinus Torvalds 7311da177e4SLinus Torvalds return 0; 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds td_error: 7341da177e4SLinus Torvalds ret = uhci_map_status(status, uhci_packetout(td_token(td))); 7351da177e4SLinus Torvalds 7361da177e4SLinus Torvalds err: 7371da177e4SLinus Torvalds if ((debug == 1 && ret != -EPIPE) || debug > 1) { 7381da177e4SLinus Torvalds /* Some debugging code */ 7391da177e4SLinus Torvalds dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", 7401da177e4SLinus Torvalds __FUNCTION__, status); 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds if (errbuf) { 7431da177e4SLinus Torvalds /* Print the chain for debugging purposes */ 7441da177e4SLinus Torvalds uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); 7451da177e4SLinus Torvalds 7461da177e4SLinus Torvalds lprintk(errbuf); 7471da177e4SLinus Torvalds } 7481da177e4SLinus Torvalds } 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds return ret; 7511da177e4SLinus Torvalds } 7521da177e4SLinus Torvalds 7531da177e4SLinus Torvalds /* 7541da177e4SLinus Torvalds * Common submit for bulk and interrupt 7551da177e4SLinus Torvalds */ 756*dccf4a48SAlan Stern static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, 757*dccf4a48SAlan Stern struct uhci_qh *qh) 7581da177e4SLinus Torvalds { 7591da177e4SLinus Torvalds struct uhci_td *td; 7601da177e4SLinus Torvalds unsigned long destination, status; 761*dccf4a48SAlan Stern int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 7621da177e4SLinus Torvalds int len = urb->transfer_buffer_length; 7631da177e4SLinus Torvalds dma_addr_t data = urb->transfer_dma; 764*dccf4a48SAlan Stern __le32 *plink, fake_link; 7651da177e4SLinus Torvalds 7661da177e4SLinus Torvalds if (len < 0) 7671da177e4SLinus Torvalds return -EINVAL; 7681da177e4SLinus Torvalds 7691da177e4SLinus Torvalds /* The "pipe" thing contains the destination in bits 8--18 */ 7701da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 7711da177e4SLinus Torvalds 772*dccf4a48SAlan Stern /* 3 errors */ 773*dccf4a48SAlan Stern status = TD_CTRL_ACTIVE | uhci_maxerr(3); 7741da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 7751da177e4SLinus Torvalds status |= TD_CTRL_LS; 7761da177e4SLinus Torvalds if (usb_pipein(urb->pipe)) 7771da177e4SLinus Torvalds status |= TD_CTRL_SPD; 7781da177e4SLinus Torvalds 7791da177e4SLinus Torvalds /* 780687f5f34SAlan Stern * Build the DATA TDs 7811da177e4SLinus Torvalds */ 782*dccf4a48SAlan Stern plink = &fake_link; 7831da177e4SLinus Torvalds do { /* Allow zero length packets */ 7841da177e4SLinus Torvalds int pktsze = maxsze; 7851da177e4SLinus Torvalds 786*dccf4a48SAlan Stern if (len <= pktsze) { /* The last packet */ 7871da177e4SLinus Torvalds pktsze = len; 7881da177e4SLinus Torvalds if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) 7891da177e4SLinus Torvalds status &= ~TD_CTRL_SPD; 7901da177e4SLinus Torvalds } 7911da177e4SLinus Torvalds 7922532178aSAlan Stern td = uhci_alloc_td(uhci); 7931da177e4SLinus Torvalds if (!td) 7941da177e4SLinus Torvalds return -ENOMEM; 795*dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 7961da177e4SLinus Torvalds 7971da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 798*dccf4a48SAlan Stern uhci_fill_td(td, status, 799*dccf4a48SAlan Stern destination | uhci_explen(pktsze) | 8001da177e4SLinus Torvalds (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), 8011da177e4SLinus Torvalds usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), 8021da177e4SLinus Torvalds data); 803*dccf4a48SAlan Stern plink = &td->link; 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds data += pktsze; 8061da177e4SLinus Torvalds len -= maxsze; 8071da177e4SLinus Torvalds 8081da177e4SLinus Torvalds usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), 8091da177e4SLinus Torvalds usb_pipeout(urb->pipe)); 8101da177e4SLinus Torvalds } while (len > 0); 8111da177e4SLinus Torvalds 8121da177e4SLinus Torvalds /* 8131da177e4SLinus Torvalds * URB_ZERO_PACKET means adding a 0-length packet, if direction 8141da177e4SLinus Torvalds * is OUT and the transfer_length was an exact multiple of maxsze, 8151da177e4SLinus Torvalds * hence (len = transfer_length - N * maxsze) == 0 8161da177e4SLinus Torvalds * however, if transfer_length == 0, the zero packet was already 8171da177e4SLinus Torvalds * prepared above. 8181da177e4SLinus Torvalds */ 819*dccf4a48SAlan Stern if ((urb->transfer_flags & URB_ZERO_PACKET) && 820*dccf4a48SAlan Stern usb_pipeout(urb->pipe) && len == 0 && 821*dccf4a48SAlan Stern urb->transfer_buffer_length > 0) { 8222532178aSAlan Stern td = uhci_alloc_td(uhci); 8231da177e4SLinus Torvalds if (!td) 8241da177e4SLinus Torvalds return -ENOMEM; 825*dccf4a48SAlan Stern *plink = cpu_to_le32(td->dma_handle); 8261da177e4SLinus Torvalds 8271da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 828fa346568SAlan Stern uhci_fill_td(td, status, destination | uhci_explen(0) | 8291da177e4SLinus Torvalds (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), 8301da177e4SLinus Torvalds usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), 8311da177e4SLinus Torvalds data); 8321da177e4SLinus Torvalds 8331da177e4SLinus Torvalds usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), 8341da177e4SLinus Torvalds usb_pipeout(urb->pipe)); 8351da177e4SLinus Torvalds } 8361da177e4SLinus Torvalds 8371da177e4SLinus Torvalds /* Set the interrupt-on-completion flag on the last packet. 8381da177e4SLinus Torvalds * A more-or-less typical 4 KB URB (= size of one memory page) 8391da177e4SLinus Torvalds * will require about 3 ms to transfer; that's a little on the 8401da177e4SLinus Torvalds * fast side but not enough to justify delaying an interrupt 8411da177e4SLinus Torvalds * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT 8421da177e4SLinus Torvalds * flag setting. */ 843*dccf4a48SAlan Stern td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 8441da177e4SLinus Torvalds 845*dccf4a48SAlan Stern return 0; 8461da177e4SLinus Torvalds } 8471da177e4SLinus Torvalds 8481da177e4SLinus Torvalds /* 8491da177e4SLinus Torvalds * Common result for bulk and interrupt 8501da177e4SLinus Torvalds */ 8511da177e4SLinus Torvalds static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) 8521da177e4SLinus Torvalds { 8531da177e4SLinus Torvalds struct urb_priv *urbp = urb->hcpriv; 8541da177e4SLinus Torvalds struct uhci_td *td; 8551da177e4SLinus Torvalds unsigned int status = 0; 8561da177e4SLinus Torvalds int ret = 0; 8571da177e4SLinus Torvalds 8581da177e4SLinus Torvalds urb->actual_length = 0; 8591da177e4SLinus Torvalds 8601da177e4SLinus Torvalds list_for_each_entry(td, &urbp->td_list, list) { 8611da177e4SLinus Torvalds unsigned int ctrlstat = td_status(td); 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds status = uhci_status_bits(ctrlstat); 8641da177e4SLinus Torvalds if (status & TD_CTRL_ACTIVE) 8651da177e4SLinus Torvalds return -EINPROGRESS; 8661da177e4SLinus Torvalds 8671da177e4SLinus Torvalds urb->actual_length += uhci_actual_length(ctrlstat); 8681da177e4SLinus Torvalds 8691da177e4SLinus Torvalds if (status) 8701da177e4SLinus Torvalds goto td_error; 8711da177e4SLinus Torvalds 8721da177e4SLinus Torvalds if (uhci_actual_length(ctrlstat) < 8731da177e4SLinus Torvalds uhci_expected_length(td_token(td))) { 8741da177e4SLinus Torvalds if (urb->transfer_flags & URB_SHORT_NOT_OK) { 8751da177e4SLinus Torvalds ret = -EREMOTEIO; 8761da177e4SLinus Torvalds goto err; 877*dccf4a48SAlan Stern } 878*dccf4a48SAlan Stern 879*dccf4a48SAlan Stern /* 880*dccf4a48SAlan Stern * This URB stopped short of its end. We have to 881*dccf4a48SAlan Stern * fix up the toggles of the following URBs on the 882*dccf4a48SAlan Stern * queue and restart the queue. 883*dccf4a48SAlan Stern * 884*dccf4a48SAlan Stern * Do this only the first time we encounter the 885*dccf4a48SAlan Stern * short URB. 886*dccf4a48SAlan Stern */ 887*dccf4a48SAlan Stern if (!urbp->short_transfer) { 888*dccf4a48SAlan Stern urbp->short_transfer = 1; 889*dccf4a48SAlan Stern uhci_fixup_toggles(urb); 890*dccf4a48SAlan Stern td = list_entry(urbp->td_list.prev, 891*dccf4a48SAlan Stern struct uhci_td, list); 892*dccf4a48SAlan Stern urbp->qh->element = td->link; 893*dccf4a48SAlan Stern } 894*dccf4a48SAlan Stern break; 8951da177e4SLinus Torvalds } 8961da177e4SLinus Torvalds } 8971da177e4SLinus Torvalds 8981da177e4SLinus Torvalds return 0; 8991da177e4SLinus Torvalds 9001da177e4SLinus Torvalds td_error: 9011da177e4SLinus Torvalds ret = uhci_map_status(status, uhci_packetout(td_token(td))); 9021da177e4SLinus Torvalds 9031da177e4SLinus Torvalds err: 9041da177e4SLinus Torvalds /* 9051da177e4SLinus Torvalds * Enable this chunk of code if you want to see some more debugging. 9061da177e4SLinus Torvalds * But be careful, it has the tendancy to starve out khubd and prevent 9071da177e4SLinus Torvalds * disconnects from happening successfully if you have a slow debug 9081da177e4SLinus Torvalds * log interface (like a serial console. 9091da177e4SLinus Torvalds */ 9101da177e4SLinus Torvalds #if 0 9111da177e4SLinus Torvalds if ((debug == 1 && ret != -EPIPE) || debug > 1) { 9121da177e4SLinus Torvalds /* Some debugging code */ 9131da177e4SLinus Torvalds dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", 9141da177e4SLinus Torvalds __FUNCTION__, status); 9151da177e4SLinus Torvalds 9161da177e4SLinus Torvalds if (errbuf) { 9171da177e4SLinus Torvalds /* Print the chain for debugging purposes */ 9181da177e4SLinus Torvalds uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); 9191da177e4SLinus Torvalds 9201da177e4SLinus Torvalds lprintk(errbuf); 9211da177e4SLinus Torvalds } 9221da177e4SLinus Torvalds } 9231da177e4SLinus Torvalds #endif 9241da177e4SLinus Torvalds return ret; 9251da177e4SLinus Torvalds } 9261da177e4SLinus Torvalds 927*dccf4a48SAlan Stern static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, 928*dccf4a48SAlan Stern struct uhci_qh *qh) 9291da177e4SLinus Torvalds { 9301da177e4SLinus Torvalds int ret; 9311da177e4SLinus Torvalds 9321da177e4SLinus Torvalds /* Can't have low-speed bulk transfers */ 9331da177e4SLinus Torvalds if (urb->dev->speed == USB_SPEED_LOW) 9341da177e4SLinus Torvalds return -EINVAL; 9351da177e4SLinus Torvalds 936*dccf4a48SAlan Stern qh->skel = uhci->skel_bulk_qh; 937*dccf4a48SAlan Stern ret = uhci_submit_common(uhci, urb, qh); 938*dccf4a48SAlan Stern if (ret == 0) 9391da177e4SLinus Torvalds uhci_inc_fsbr(uhci, urb); 9401da177e4SLinus Torvalds return ret; 9411da177e4SLinus Torvalds } 9421da177e4SLinus Torvalds 943*dccf4a48SAlan Stern static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, 944*dccf4a48SAlan Stern struct uhci_qh *qh) 9451da177e4SLinus Torvalds { 946*dccf4a48SAlan Stern /* USB 1.1 interrupt transfers only involve one packet per interval. 947*dccf4a48SAlan Stern * Drivers can submit URBs of any length, but longer ones will need 948*dccf4a48SAlan Stern * multiple intervals to complete. 9491da177e4SLinus Torvalds */ 950*dccf4a48SAlan Stern qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)]; 951*dccf4a48SAlan Stern return uhci_submit_common(uhci, urb, qh); 9521da177e4SLinus Torvalds } 9531da177e4SLinus Torvalds 9541da177e4SLinus Torvalds /* 9551da177e4SLinus Torvalds * Isochronous transfers 9561da177e4SLinus Torvalds */ 9571da177e4SLinus Torvalds static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsigned int *start, unsigned int *end) 9581da177e4SLinus Torvalds { 9591da177e4SLinus Torvalds struct urb *last_urb = NULL; 9601da177e4SLinus Torvalds struct urb_priv *up; 9611da177e4SLinus Torvalds int ret = 0; 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds list_for_each_entry(up, &uhci->urb_list, urb_list) { 9641da177e4SLinus Torvalds struct urb *u = up->urb; 9651da177e4SLinus Torvalds 966687f5f34SAlan Stern /* look for pending URBs with identical pipe handle */ 9671da177e4SLinus Torvalds if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && 9681da177e4SLinus Torvalds (u->status == -EINPROGRESS) && (u != urb)) { 9691da177e4SLinus Torvalds if (!last_urb) 9701da177e4SLinus Torvalds *start = u->start_frame; 9711da177e4SLinus Torvalds last_urb = u; 9721da177e4SLinus Torvalds } 9731da177e4SLinus Torvalds } 9741da177e4SLinus Torvalds 9751da177e4SLinus Torvalds if (last_urb) { 9761da177e4SLinus Torvalds *end = (last_urb->start_frame + last_urb->number_of_packets * 9771da177e4SLinus Torvalds last_urb->interval) & (UHCI_NUMFRAMES-1); 9781da177e4SLinus Torvalds ret = 0; 9791da177e4SLinus Torvalds } else 9801da177e4SLinus Torvalds ret = -1; /* no previous urb found */ 9811da177e4SLinus Torvalds 9821da177e4SLinus Torvalds return ret; 9831da177e4SLinus Torvalds } 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds static int isochronous_find_start(struct uhci_hcd *uhci, struct urb *urb) 9861da177e4SLinus Torvalds { 9871da177e4SLinus Torvalds int limits; 9881da177e4SLinus Torvalds unsigned int start = 0, end = 0; 9891da177e4SLinus Torvalds 9901da177e4SLinus Torvalds if (urb->number_of_packets > 900) /* 900? Why? */ 9911da177e4SLinus Torvalds return -EFBIG; 9921da177e4SLinus Torvalds 9931da177e4SLinus Torvalds limits = isochronous_find_limits(uhci, urb, &start, &end); 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds if (urb->transfer_flags & URB_ISO_ASAP) { 9961da177e4SLinus Torvalds if (limits) { 9971da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 9981da177e4SLinus Torvalds urb->start_frame = (uhci->frame_number + 10) 9991da177e4SLinus Torvalds & (UHCI_NUMFRAMES - 1); 10001da177e4SLinus Torvalds } else 10011da177e4SLinus Torvalds urb->start_frame = end; 10021da177e4SLinus Torvalds } else { 10031da177e4SLinus Torvalds urb->start_frame &= (UHCI_NUMFRAMES - 1); 10041da177e4SLinus Torvalds /* FIXME: Sanity check */ 10051da177e4SLinus Torvalds } 10061da177e4SLinus Torvalds 10071da177e4SLinus Torvalds return 0; 10081da177e4SLinus Torvalds } 10091da177e4SLinus Torvalds 10101da177e4SLinus Torvalds /* 10111da177e4SLinus Torvalds * Isochronous transfers 10121da177e4SLinus Torvalds */ 1013*dccf4a48SAlan Stern static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, 1014*dccf4a48SAlan Stern struct uhci_qh *qh) 10151da177e4SLinus Torvalds { 1016*dccf4a48SAlan Stern struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */ 10171da177e4SLinus Torvalds int i, ret, frame; 1018*dccf4a48SAlan Stern unsigned long destination, status; 1019b81d3436SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 10201da177e4SLinus Torvalds 10211da177e4SLinus Torvalds status = TD_CTRL_ACTIVE | TD_CTRL_IOS; 10221da177e4SLinus Torvalds destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 10231da177e4SLinus Torvalds 10241da177e4SLinus Torvalds ret = isochronous_find_start(uhci, urb); 10251da177e4SLinus Torvalds if (ret) 10261da177e4SLinus Torvalds return ret; 10271da177e4SLinus Torvalds 1028b81d3436SAlan Stern for (i = 0; i < urb->number_of_packets; i++) { 10292532178aSAlan Stern td = uhci_alloc_td(uhci); 10301da177e4SLinus Torvalds if (!td) 10311da177e4SLinus Torvalds return -ENOMEM; 10321da177e4SLinus Torvalds 10331da177e4SLinus Torvalds uhci_add_td_to_urb(urb, td); 1034*dccf4a48SAlan Stern uhci_fill_td(td, status, destination | 1035*dccf4a48SAlan Stern uhci_explen(urb->iso_frame_desc[i].length), 1036*dccf4a48SAlan Stern urb->transfer_dma + 1037*dccf4a48SAlan Stern urb->iso_frame_desc[i].offset); 1038b81d3436SAlan Stern } 10391da177e4SLinus Torvalds 1040*dccf4a48SAlan Stern /* Set the interrupt-on-completion flag on the last packet. */ 1041*dccf4a48SAlan Stern td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 1042*dccf4a48SAlan Stern 1043*dccf4a48SAlan Stern qh->skel = uhci->skel_iso_qh; 1044*dccf4a48SAlan Stern 1045*dccf4a48SAlan Stern /* Add the TDs to the frame list */ 1046b81d3436SAlan Stern frame = urb->start_frame; 1047b81d3436SAlan Stern list_for_each_entry(td, &urbp->td_list, list) { 1048*dccf4a48SAlan Stern uhci_insert_td_in_frame_list(uhci, td, frame); 1049b81d3436SAlan Stern frame += urb->interval; 10501da177e4SLinus Torvalds } 10511da177e4SLinus Torvalds 1052*dccf4a48SAlan Stern return 0; 10531da177e4SLinus Torvalds } 10541da177e4SLinus Torvalds 10551da177e4SLinus Torvalds static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) 10561da177e4SLinus Torvalds { 10571da177e4SLinus Torvalds struct uhci_td *td; 10581da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 10591da177e4SLinus Torvalds int status; 10601da177e4SLinus Torvalds int i, ret = 0; 10611da177e4SLinus Torvalds 1062b81d3436SAlan Stern urb->actual_length = urb->error_count = 0; 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds i = 0; 10651da177e4SLinus Torvalds list_for_each_entry(td, &urbp->td_list, list) { 10661da177e4SLinus Torvalds int actlength; 10671da177e4SLinus Torvalds unsigned int ctrlstat = td_status(td); 10681da177e4SLinus Torvalds 10691da177e4SLinus Torvalds if (ctrlstat & TD_CTRL_ACTIVE) 10701da177e4SLinus Torvalds return -EINPROGRESS; 10711da177e4SLinus Torvalds 10721da177e4SLinus Torvalds actlength = uhci_actual_length(ctrlstat); 10731da177e4SLinus Torvalds urb->iso_frame_desc[i].actual_length = actlength; 10741da177e4SLinus Torvalds urb->actual_length += actlength; 10751da177e4SLinus Torvalds 10761da177e4SLinus Torvalds status = uhci_map_status(uhci_status_bits(ctrlstat), 10771da177e4SLinus Torvalds usb_pipeout(urb->pipe)); 10781da177e4SLinus Torvalds urb->iso_frame_desc[i].status = status; 10791da177e4SLinus Torvalds if (status) { 10801da177e4SLinus Torvalds urb->error_count++; 10811da177e4SLinus Torvalds ret = status; 10821da177e4SLinus Torvalds } 10831da177e4SLinus Torvalds 10841da177e4SLinus Torvalds i++; 10851da177e4SLinus Torvalds } 10861da177e4SLinus Torvalds 10871da177e4SLinus Torvalds return ret; 10881da177e4SLinus Torvalds } 10891da177e4SLinus Torvalds 10901da177e4SLinus Torvalds static int uhci_urb_enqueue(struct usb_hcd *hcd, 1091*dccf4a48SAlan Stern struct usb_host_endpoint *hep, 109255016f10SAl Viro struct urb *urb, gfp_t mem_flags) 10931da177e4SLinus Torvalds { 10941da177e4SLinus Torvalds int ret; 10951da177e4SLinus Torvalds struct uhci_hcd *uhci = hcd_to_uhci(hcd); 10961da177e4SLinus Torvalds unsigned long flags; 1097*dccf4a48SAlan Stern struct urb_priv *urbp; 1098*dccf4a48SAlan Stern struct uhci_qh *qh; 10991da177e4SLinus Torvalds int bustime; 11001da177e4SLinus Torvalds 11011da177e4SLinus Torvalds spin_lock_irqsave(&uhci->lock, flags); 11021da177e4SLinus Torvalds 11031da177e4SLinus Torvalds ret = urb->status; 11041da177e4SLinus Torvalds if (ret != -EINPROGRESS) /* URB already unlinked! */ 1105*dccf4a48SAlan Stern goto done; 11061da177e4SLinus Torvalds 11071da177e4SLinus Torvalds ret = -ENOMEM; 1108*dccf4a48SAlan Stern urbp = uhci_alloc_urb_priv(uhci, urb); 1109*dccf4a48SAlan Stern if (!urbp) 1110*dccf4a48SAlan Stern goto done; 1111*dccf4a48SAlan Stern 1112*dccf4a48SAlan Stern if (hep->hcpriv) 1113*dccf4a48SAlan Stern qh = (struct uhci_qh *) hep->hcpriv; 1114*dccf4a48SAlan Stern else { 1115*dccf4a48SAlan Stern qh = uhci_alloc_qh(uhci, urb->dev, hep); 1116*dccf4a48SAlan Stern if (!qh) 1117*dccf4a48SAlan Stern goto err_no_qh; 11181da177e4SLinus Torvalds } 1119*dccf4a48SAlan Stern urbp->qh = qh; 11201da177e4SLinus Torvalds 11211da177e4SLinus Torvalds switch (usb_pipetype(urb->pipe)) { 11221da177e4SLinus Torvalds case PIPE_CONTROL: 1123*dccf4a48SAlan Stern ret = uhci_submit_control(uhci, urb, qh); 1124*dccf4a48SAlan Stern break; 1125*dccf4a48SAlan Stern case PIPE_BULK: 1126*dccf4a48SAlan Stern ret = uhci_submit_bulk(uhci, urb, qh); 11271da177e4SLinus Torvalds break; 11281da177e4SLinus Torvalds case PIPE_INTERRUPT: 1129*dccf4a48SAlan Stern if (list_empty(&qh->queue)) { 11301da177e4SLinus Torvalds bustime = usb_check_bandwidth(urb->dev, urb); 11311da177e4SLinus Torvalds if (bustime < 0) 11321da177e4SLinus Torvalds ret = bustime; 11331da177e4SLinus Torvalds else { 1134*dccf4a48SAlan Stern ret = uhci_submit_interrupt(uhci, urb, qh); 1135*dccf4a48SAlan Stern if (ret == 0) 11361da177e4SLinus Torvalds usb_claim_bandwidth(urb->dev, urb, bustime, 0); 11371da177e4SLinus Torvalds } 11381da177e4SLinus Torvalds } else { /* inherit from parent */ 1139*dccf4a48SAlan Stern struct urb_priv *eurbp; 1140*dccf4a48SAlan Stern 1141*dccf4a48SAlan Stern eurbp = list_entry(qh->queue.prev, struct urb_priv, 1142*dccf4a48SAlan Stern node); 1143*dccf4a48SAlan Stern urb->bandwidth = eurbp->urb->bandwidth; 1144*dccf4a48SAlan Stern ret = uhci_submit_interrupt(uhci, urb, qh); 11451da177e4SLinus Torvalds } 11461da177e4SLinus Torvalds break; 11471da177e4SLinus Torvalds case PIPE_ISOCHRONOUS: 11481da177e4SLinus Torvalds bustime = usb_check_bandwidth(urb->dev, urb); 11491da177e4SLinus Torvalds if (bustime < 0) { 11501da177e4SLinus Torvalds ret = bustime; 11511da177e4SLinus Torvalds break; 11521da177e4SLinus Torvalds } 11531da177e4SLinus Torvalds 1154*dccf4a48SAlan Stern ret = uhci_submit_isochronous(uhci, urb, qh); 1155*dccf4a48SAlan Stern if (ret == 0) 11561da177e4SLinus Torvalds usb_claim_bandwidth(urb->dev, urb, bustime, 1); 11571da177e4SLinus Torvalds break; 11581da177e4SLinus Torvalds } 1159*dccf4a48SAlan Stern if (ret != 0) 1160*dccf4a48SAlan Stern goto err_submit_failed; 11611da177e4SLinus Torvalds 1162*dccf4a48SAlan Stern /* Add this URB to the QH */ 1163*dccf4a48SAlan Stern urbp->qh = qh; 1164*dccf4a48SAlan Stern list_add_tail(&urbp->node, &qh->queue); 1165*dccf4a48SAlan Stern list_add_tail(&urbp->urb_list, &uhci->urb_list); 11661da177e4SLinus Torvalds 1167*dccf4a48SAlan Stern /* If the new URB is the first and only one on this QH then either 1168*dccf4a48SAlan Stern * the QH is new and idle or else it's unlinked and waiting to 1169*dccf4a48SAlan Stern * become idle, so we can activate it right away. */ 1170*dccf4a48SAlan Stern if (qh->queue.next == &urbp->node) 1171*dccf4a48SAlan Stern uhci_activate_qh(uhci, qh); 11721da177e4SLinus Torvalds 1173*dccf4a48SAlan Stern /* If the QH is already active, we have a race with the hardware. 1174*dccf4a48SAlan Stern * This won't get fixed until dummy TDs are added. */ 1175*dccf4a48SAlan Stern else if (qh->state == QH_STATE_ACTIVE) { 1176*dccf4a48SAlan Stern 1177*dccf4a48SAlan Stern /* If the URB isn't first on its queue, adjust the link pointer 1178*dccf4a48SAlan Stern * of the last TD in the previous URB. */ 1179*dccf4a48SAlan Stern if (urbp->node.prev != &urbp->qh->queue) { 1180*dccf4a48SAlan Stern struct urb_priv *purbp = list_entry(urbp->node.prev, 1181*dccf4a48SAlan Stern struct urb_priv, node); 1182*dccf4a48SAlan Stern struct uhci_td *ptd = list_entry(purbp->td_list.prev, 1183*dccf4a48SAlan Stern struct uhci_td, list); 1184*dccf4a48SAlan Stern struct uhci_td *td = list_entry(urbp->td_list.next, 1185*dccf4a48SAlan Stern struct uhci_td, list); 1186*dccf4a48SAlan Stern 1187*dccf4a48SAlan Stern ptd->link = cpu_to_le32(td->dma_handle); 1188*dccf4a48SAlan Stern 1189*dccf4a48SAlan Stern } 1190*dccf4a48SAlan Stern if (qh_element(qh) == UHCI_PTR_TERM) { 1191*dccf4a48SAlan Stern struct uhci_td *td = list_entry(urbp->td_list.next, 1192*dccf4a48SAlan Stern struct uhci_td, list); 1193*dccf4a48SAlan Stern 1194*dccf4a48SAlan Stern qh->element = cpu_to_le32(td->dma_handle); 1195*dccf4a48SAlan Stern } 1196*dccf4a48SAlan Stern } 1197*dccf4a48SAlan Stern goto done; 1198*dccf4a48SAlan Stern 1199*dccf4a48SAlan Stern err_submit_failed: 1200*dccf4a48SAlan Stern if (qh->state == QH_STATE_IDLE) 1201*dccf4a48SAlan Stern uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ 1202*dccf4a48SAlan Stern 1203*dccf4a48SAlan Stern err_no_qh: 1204*dccf4a48SAlan Stern uhci_free_urb_priv(uhci, urbp); 1205*dccf4a48SAlan Stern 1206*dccf4a48SAlan Stern done: 12071da177e4SLinus Torvalds spin_unlock_irqrestore(&uhci->lock, flags); 12081da177e4SLinus Torvalds return ret; 12091da177e4SLinus Torvalds } 12101da177e4SLinus Torvalds 12111da177e4SLinus Torvalds /* 12121da177e4SLinus Torvalds * Return the result of a transfer 12131da177e4SLinus Torvalds */ 12141da177e4SLinus Torvalds static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb) 12151da177e4SLinus Torvalds { 1216*dccf4a48SAlan Stern int status; 1217*dccf4a48SAlan Stern int okay_to_giveback = 0; 1218*dccf4a48SAlan Stern struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 12191da177e4SLinus Torvalds 12201da177e4SLinus Torvalds switch (usb_pipetype(urb->pipe)) { 12211da177e4SLinus Torvalds case PIPE_CONTROL: 1222*dccf4a48SAlan Stern status = uhci_result_control(uhci, urb); 12231da177e4SLinus Torvalds break; 12241da177e4SLinus Torvalds case PIPE_ISOCHRONOUS: 1225*dccf4a48SAlan Stern status = uhci_result_isochronous(uhci, urb); 1226*dccf4a48SAlan Stern break; 1227*dccf4a48SAlan Stern default: /* PIPE_BULK or PIPE_INTERRUPT */ 1228*dccf4a48SAlan Stern status = uhci_result_common(uhci, urb); 12291da177e4SLinus Torvalds break; 12301da177e4SLinus Torvalds } 12311da177e4SLinus Torvalds 1232*dccf4a48SAlan Stern spin_lock(&urb->lock); 1233*dccf4a48SAlan Stern if (urb->status == -EINPROGRESS) { /* Not yet dequeued */ 1234*dccf4a48SAlan Stern if (status != -EINPROGRESS) { /* URB has completed */ 1235*dccf4a48SAlan Stern urb->status = status; 1236*dccf4a48SAlan Stern 1237*dccf4a48SAlan Stern /* If the URB got a real error (as opposed to 1238*dccf4a48SAlan Stern * simply being dequeued), we don't have to 1239*dccf4a48SAlan Stern * unlink the QH. Fix this later... */ 1240*dccf4a48SAlan Stern if (status < 0) 1241*dccf4a48SAlan Stern uhci_unlink_qh(uhci, urbp->qh); 1242*dccf4a48SAlan Stern else 1243*dccf4a48SAlan Stern okay_to_giveback = 1; 1244*dccf4a48SAlan Stern } 1245*dccf4a48SAlan Stern } else { /* Already dequeued */ 1246*dccf4a48SAlan Stern if (urbp->qh->state == QH_STATE_UNLINKING && 1247*dccf4a48SAlan Stern uhci->frame_number + uhci->is_stopped != 1248*dccf4a48SAlan Stern urbp->qh->unlink_frame) 1249*dccf4a48SAlan Stern okay_to_giveback = 1; 1250*dccf4a48SAlan Stern } 1251*dccf4a48SAlan Stern spin_unlock(&urb->lock); 1252*dccf4a48SAlan Stern if (!okay_to_giveback) 1253*dccf4a48SAlan Stern return; 12541da177e4SLinus Torvalds 12551da177e4SLinus Torvalds switch (usb_pipetype(urb->pipe)) { 12561da177e4SLinus Torvalds case PIPE_ISOCHRONOUS: 12571da177e4SLinus Torvalds /* Release bandwidth for Interrupt or Isoc. transfers */ 12581da177e4SLinus Torvalds if (urb->bandwidth) 12591da177e4SLinus Torvalds usb_release_bandwidth(urb->dev, urb, 1); 12601da177e4SLinus Torvalds break; 12611da177e4SLinus Torvalds case PIPE_INTERRUPT: 12621da177e4SLinus Torvalds /* Release bandwidth for Interrupt or Isoc. transfers */ 12631da177e4SLinus Torvalds /* Make sure we don't release if we have a queued URB */ 1264*dccf4a48SAlan Stern if (list_empty(&urbp->qh->queue) && urb->bandwidth) 12651da177e4SLinus Torvalds usb_release_bandwidth(urb->dev, urb, 0); 12661da177e4SLinus Torvalds else 12671da177e4SLinus Torvalds /* bandwidth was passed on to queued URB, */ 12681da177e4SLinus Torvalds /* so don't let usb_unlink_urb() release it */ 12691da177e4SLinus Torvalds urb->bandwidth = 0; 1270*dccf4a48SAlan Stern /* Falls through */ 1271*dccf4a48SAlan Stern case PIPE_BULK: 1272*dccf4a48SAlan Stern if (status < 0) 1273*dccf4a48SAlan Stern uhci_fixup_toggles(urb); 12741da177e4SLinus Torvalds break; 1275*dccf4a48SAlan Stern default: /* PIPE_CONTROL */ 1276*dccf4a48SAlan Stern break; 12771da177e4SLinus Torvalds } 12781da177e4SLinus Torvalds 1279*dccf4a48SAlan Stern /* Take the URB's TDs off the hardware schedule */ 1280*dccf4a48SAlan Stern uhci_remove_tds_from_schedule(uhci, urb, status); 12811da177e4SLinus Torvalds 1282*dccf4a48SAlan Stern /* Take the URB off the QH's queue and see if the QH is now unused */ 1283*dccf4a48SAlan Stern list_del_init(&urbp->node); 1284*dccf4a48SAlan Stern if (list_empty(&urbp->qh->queue)) 1285*dccf4a48SAlan Stern uhci_unlink_qh(uhci, urbp->qh); 12861da177e4SLinus Torvalds 12871da177e4SLinus Torvalds uhci_dec_fsbr(uhci, urb); /* Safe since it checks */ 12881da177e4SLinus Torvalds 1289*dccf4a48SAlan Stern /* Queue it for giving back */ 1290*dccf4a48SAlan Stern list_move_tail(&urbp->urb_list, &uhci->complete_list); 12911da177e4SLinus Torvalds } 12921da177e4SLinus Torvalds 1293*dccf4a48SAlan Stern /* 1294*dccf4a48SAlan Stern * Check out the QHs waiting to be fully unlinked 1295*dccf4a48SAlan Stern */ 1296*dccf4a48SAlan Stern static void uhci_scan_unlinking_qhs(struct uhci_hcd *uhci) 1297*dccf4a48SAlan Stern { 1298*dccf4a48SAlan Stern struct uhci_qh *qh, *tmp; 12991da177e4SLinus Torvalds 1300*dccf4a48SAlan Stern list_for_each_entry_safe(qh, tmp, &uhci->skel_unlink_qh->node, node) { 1301*dccf4a48SAlan Stern 1302*dccf4a48SAlan Stern /* If the queue is empty and the QH is fully unlinked then 1303*dccf4a48SAlan Stern * it can become IDLE. */ 1304*dccf4a48SAlan Stern if (list_empty(&qh->queue)) { 1305*dccf4a48SAlan Stern if (uhci->frame_number + uhci->is_stopped != 1306*dccf4a48SAlan Stern qh->unlink_frame) 1307*dccf4a48SAlan Stern uhci_make_qh_idle(uhci, qh); 1308*dccf4a48SAlan Stern 1309*dccf4a48SAlan Stern /* If none of the QH's URBs have been dequeued then the QH 1310*dccf4a48SAlan Stern * should be re-activated. */ 1311*dccf4a48SAlan Stern } else { 1312*dccf4a48SAlan Stern struct urb_priv *urbp; 1313*dccf4a48SAlan Stern int any_dequeued = 0; 1314*dccf4a48SAlan Stern 1315*dccf4a48SAlan Stern list_for_each_entry(urbp, &qh->queue, node) { 1316*dccf4a48SAlan Stern if (urbp->urb->status != -EINPROGRESS) { 1317*dccf4a48SAlan Stern any_dequeued = 1; 1318*dccf4a48SAlan Stern break; 1319*dccf4a48SAlan Stern } 1320*dccf4a48SAlan Stern } 1321*dccf4a48SAlan Stern if (!any_dequeued) 1322*dccf4a48SAlan Stern uhci_activate_qh(uhci, qh); 1323*dccf4a48SAlan Stern } 1324*dccf4a48SAlan Stern } 13251da177e4SLinus Torvalds } 13261da177e4SLinus Torvalds 13271da177e4SLinus Torvalds static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 13281da177e4SLinus Torvalds { 13291da177e4SLinus Torvalds struct uhci_hcd *uhci = hcd_to_uhci(hcd); 13301da177e4SLinus Torvalds unsigned long flags; 13311da177e4SLinus Torvalds struct urb_priv *urbp; 13321da177e4SLinus Torvalds 13331da177e4SLinus Torvalds spin_lock_irqsave(&uhci->lock, flags); 13341da177e4SLinus Torvalds urbp = urb->hcpriv; 13351da177e4SLinus Torvalds if (!urbp) /* URB was never linked! */ 13361da177e4SLinus Torvalds goto done; 13371da177e4SLinus Torvalds 1338*dccf4a48SAlan Stern /* Remove Isochronous TDs from the frame list ASAP */ 1339b81d3436SAlan Stern if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) 1340*dccf4a48SAlan Stern uhci_unlink_isochronous_tds(uhci, urb); 1341*dccf4a48SAlan Stern uhci_unlink_qh(uhci, urbp->qh); 13421da177e4SLinus Torvalds 13431da177e4SLinus Torvalds done: 13441da177e4SLinus Torvalds spin_unlock_irqrestore(&uhci->lock, flags); 13451da177e4SLinus Torvalds return 0; 13461da177e4SLinus Torvalds } 13471da177e4SLinus Torvalds 13481da177e4SLinus Torvalds static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb) 13491da177e4SLinus Torvalds { 13501da177e4SLinus Torvalds struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 13511da177e4SLinus Torvalds struct list_head *head; 13521da177e4SLinus Torvalds struct uhci_td *td; 13531da177e4SLinus Torvalds int count = 0; 13541da177e4SLinus Torvalds 13551da177e4SLinus Torvalds uhci_dec_fsbr(uhci, urb); 13561da177e4SLinus Torvalds 13571da177e4SLinus Torvalds urbp->fsbr_timeout = 1; 13581da177e4SLinus Torvalds 13591da177e4SLinus Torvalds /* 13601da177e4SLinus Torvalds * Ideally we would want to fix qh->element as well, but it's 13611da177e4SLinus Torvalds * read/write by the HC, so that can introduce a race. It's not 13621da177e4SLinus Torvalds * really worth the hassle 13631da177e4SLinus Torvalds */ 13641da177e4SLinus Torvalds 13651da177e4SLinus Torvalds head = &urbp->td_list; 13661da177e4SLinus Torvalds list_for_each_entry(td, head, list) { 13671da177e4SLinus Torvalds /* 13681da177e4SLinus Torvalds * Make sure we don't do the last one (since it'll have the 1369687f5f34SAlan Stern * TERM bit set) as well as we skip every so many TDs to 13701da177e4SLinus Torvalds * make sure it doesn't hog the bandwidth 13711da177e4SLinus Torvalds */ 13721da177e4SLinus Torvalds if (td->list.next != head && (count % DEPTH_INTERVAL) == 13731da177e4SLinus Torvalds (DEPTH_INTERVAL - 1)) 13741da177e4SLinus Torvalds td->link |= UHCI_PTR_DEPTH; 13751da177e4SLinus Torvalds 13761da177e4SLinus Torvalds count++; 13771da177e4SLinus Torvalds } 13781da177e4SLinus Torvalds 13791da177e4SLinus Torvalds return 0; 13801da177e4SLinus Torvalds } 13811da177e4SLinus Torvalds 13821da177e4SLinus Torvalds static void uhci_free_pending_tds(struct uhci_hcd *uhci) 13831da177e4SLinus Torvalds { 13841da177e4SLinus Torvalds struct uhci_td *td, *tmp; 13851da177e4SLinus Torvalds 13861da177e4SLinus Torvalds list_for_each_entry_safe(td, tmp, &uhci->td_remove_list, remove_list) { 13871da177e4SLinus Torvalds list_del_init(&td->remove_list); 13881da177e4SLinus Torvalds 13891da177e4SLinus Torvalds uhci_free_td(uhci, td); 13901da177e4SLinus Torvalds } 13911da177e4SLinus Torvalds } 13921da177e4SLinus Torvalds 13931da177e4SLinus Torvalds static void 13941da177e4SLinus Torvalds uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) 13951da177e4SLinus Torvalds __releases(uhci->lock) 13961da177e4SLinus Torvalds __acquires(uhci->lock) 13971da177e4SLinus Torvalds { 13981da177e4SLinus Torvalds struct uhci_hcd *uhci = hcd_to_uhci(hcd); 13991da177e4SLinus Torvalds 1400*dccf4a48SAlan Stern uhci_free_urb_priv(uhci, (struct urb_priv *) (urb->hcpriv)); 14011da177e4SLinus Torvalds 14021da177e4SLinus Torvalds spin_unlock(&uhci->lock); 14031da177e4SLinus Torvalds usb_hcd_giveback_urb(hcd, urb, regs); 14041da177e4SLinus Torvalds spin_lock(&uhci->lock); 14051da177e4SLinus Torvalds } 14061da177e4SLinus Torvalds 14071da177e4SLinus Torvalds static void uhci_finish_completion(struct uhci_hcd *uhci, struct pt_regs *regs) 14081da177e4SLinus Torvalds { 14091da177e4SLinus Torvalds struct urb_priv *urbp, *tmp; 14101da177e4SLinus Torvalds 14111da177e4SLinus Torvalds list_for_each_entry_safe(urbp, tmp, &uhci->complete_list, urb_list) { 14121da177e4SLinus Torvalds struct urb *urb = urbp->urb; 14131da177e4SLinus Torvalds 14141da177e4SLinus Torvalds list_del_init(&urbp->urb_list); 14151da177e4SLinus Torvalds uhci_finish_urb(uhci_to_hcd(uhci), urb, regs); 14161da177e4SLinus Torvalds } 14171da177e4SLinus Torvalds } 14181da177e4SLinus Torvalds 14191da177e4SLinus Torvalds /* Process events in the schedule, but only in one thread at a time */ 14201da177e4SLinus Torvalds static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) 14211da177e4SLinus Torvalds { 14221da177e4SLinus Torvalds struct urb_priv *urbp, *tmp; 14231da177e4SLinus Torvalds 14241da177e4SLinus Torvalds /* Don't allow re-entrant calls */ 14251da177e4SLinus Torvalds if (uhci->scan_in_progress) { 14261da177e4SLinus Torvalds uhci->need_rescan = 1; 14271da177e4SLinus Torvalds return; 14281da177e4SLinus Torvalds } 14291da177e4SLinus Torvalds uhci->scan_in_progress = 1; 14301da177e4SLinus Torvalds rescan: 14311da177e4SLinus Torvalds uhci->need_rescan = 0; 14321da177e4SLinus Torvalds 14336c1b445cSAlan Stern uhci_clear_next_interrupt(uhci); 14341da177e4SLinus Torvalds uhci_get_current_frame_number(uhci); 14351da177e4SLinus Torvalds 14361da177e4SLinus Torvalds if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) 14371da177e4SLinus Torvalds uhci_free_pending_tds(uhci); 14381da177e4SLinus Torvalds 14391da177e4SLinus Torvalds /* Walk the list of pending URBs to see which ones completed 14401da177e4SLinus Torvalds * (must be _safe because uhci_transfer_result() dequeues URBs) */ 14411da177e4SLinus Torvalds list_for_each_entry_safe(urbp, tmp, &uhci->urb_list, urb_list) { 14421da177e4SLinus Torvalds struct urb *urb = urbp->urb; 14431da177e4SLinus Torvalds 14441da177e4SLinus Torvalds /* Checks the status and does all of the magic necessary */ 14451da177e4SLinus Torvalds uhci_transfer_result(uhci, urb); 14461da177e4SLinus Torvalds } 14471da177e4SLinus Torvalds uhci_finish_completion(uhci, regs); 14481da177e4SLinus Torvalds 14491da177e4SLinus Torvalds /* If the controller is stopped, we can finish these off right now */ 1450*dccf4a48SAlan Stern if (uhci->is_stopped) 14511da177e4SLinus Torvalds uhci_free_pending_tds(uhci); 14521da177e4SLinus Torvalds 14531da177e4SLinus Torvalds if (uhci->need_rescan) 14541da177e4SLinus Torvalds goto rescan; 14551da177e4SLinus Torvalds uhci->scan_in_progress = 0; 14561da177e4SLinus Torvalds 1457*dccf4a48SAlan Stern /* Check out the QHs waiting for unlinking */ 1458*dccf4a48SAlan Stern uhci_scan_unlinking_qhs(uhci); 1459*dccf4a48SAlan Stern 1460*dccf4a48SAlan Stern if (list_empty(&uhci->td_remove_list) && 1461*dccf4a48SAlan Stern list_empty(&uhci->skel_unlink_qh->node)) 14621da177e4SLinus Torvalds uhci_clear_next_interrupt(uhci); 14631da177e4SLinus Torvalds else 14641da177e4SLinus Torvalds uhci_set_next_interrupt(uhci); 14651da177e4SLinus Torvalds } 1466f5946f82SAlan Stern 1467f5946f82SAlan Stern static void check_fsbr(struct uhci_hcd *uhci) 1468f5946f82SAlan Stern { 1469f5946f82SAlan Stern struct urb_priv *up; 1470f5946f82SAlan Stern 1471f5946f82SAlan Stern list_for_each_entry(up, &uhci->urb_list, urb_list) { 1472f5946f82SAlan Stern struct urb *u = up->urb; 1473f5946f82SAlan Stern 1474f5946f82SAlan Stern spin_lock(&u->lock); 1475f5946f82SAlan Stern 1476f5946f82SAlan Stern /* Check if the FSBR timed out */ 1477f5946f82SAlan Stern if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT)) 1478f5946f82SAlan Stern uhci_fsbr_timeout(uhci, u); 1479f5946f82SAlan Stern 1480f5946f82SAlan Stern spin_unlock(&u->lock); 1481f5946f82SAlan Stern } 1482f5946f82SAlan Stern 1483f5946f82SAlan Stern /* Really disable FSBR */ 1484f5946f82SAlan Stern if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { 1485f5946f82SAlan Stern uhci->fsbrtimeout = 0; 1486f5946f82SAlan Stern uhci->skel_term_qh->link = UHCI_PTR_TERM; 1487f5946f82SAlan Stern } 1488f5946f82SAlan Stern } 1489