Greg:

This patch (as681) moves some code for cleaning up after unlinked URBs out 
of the general completion pathway into the unlinking pathway.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

---

Index: usb-2.6/drivers/usb/host/uhci-q.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/uhci-q.c
+++ usb-2.6/drivers/usb/host/uhci-q.c
@@ -204,25 +204,49 @@ static void uhci_free_qh(struct uhci_hcd
 }
 
 /*
- * When the currently executing URB is dequeued, save its current toggle value
+ * When a queue is stopped and a dequeued URB is given back, adjust
+ * the previous TD link (if the URB isn't first on the queue) or
+ * save its toggle value (if it is first and is currently executing).
  */
-static void uhci_save_toggle(struct uhci_qh *qh, struct urb *urb)
+static void uhci_cleanup_queue(struct uhci_qh *qh,
+               struct urb *urb)
 {
-       struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+       struct urb_priv *urbp = urb->hcpriv;
        struct uhci_td *td;
 
+       /* Isochronous pipes don't use toggles and their TD link pointers
+        * get adjusted during uhci_urb_dequeue(). */
+       if (qh->type == USB_ENDPOINT_XFER_ISOC)
+               return;
+
+       /* If the URB isn't first on its queue, adjust the link pointer
+        * of the last TD in the previous URB.  The toggle doesn't need
+        * to be saved since this URB can't be executing yet. */
+       if (qh->queue.next != &urbp->node) {
+               struct urb_priv *purbp;
+               struct uhci_td *ptd;
+
+               purbp = list_entry(urbp->node.prev, struct urb_priv, node);
+               WARN_ON(list_empty(&purbp->td_list));
+               ptd = list_entry(purbp->td_list.prev, struct uhci_td,
+                               list);
+               td = list_entry(urbp->td_list.prev, struct uhci_td,
+                               list);
+               ptd->link = td->link;
+               return;
+       }
+
        /* If the QH element pointer is UHCI_PTR_TERM then then currently
         * executing URB has already been unlinked, so this one isn't it. */
-       if (qh_element(qh) == UHCI_PTR_TERM ||
-                               qh->queue.next != &urbp->node)
+       if (qh_element(qh) == UHCI_PTR_TERM)
                return;
        qh->element = UHCI_PTR_TERM;
 
-       /* Only bulk and interrupt pipes have to worry about toggles */
-       if (!(qh->type == USB_ENDPOINT_XFER_BULK ||
-                       qh->type == USB_ENDPOINT_XFER_INT))
+       /* Control pipes have to worry about toggles */
+       if (qh->type == USB_ENDPOINT_XFER_CONTROL)
                return;
 
+       /* Save the next toggle value */
        WARN_ON(list_empty(&urbp->td_list));
        td = list_entry(urbp->td_list.next, struct uhci_td, list);
        qh->needs_fixup = 1;
@@ -1121,21 +1145,6 @@ __acquires(uhci->lock)
        if (qh->type == USB_ENDPOINT_XFER_ISOC)
                uhci_unlink_isochronous_tds(uhci, urb);
 
-       /* If the URB isn't first on its queue, adjust the link pointer
-        * of the last TD in the previous URB. */
-       else if (qh->queue.next != &urbp->node) {
-               struct urb_priv *purbp;
-               struct uhci_td *ptd, *ltd;
-
-               purbp = list_entry(urbp->node.prev, struct urb_priv, node);
-               WARN_ON(list_empty(&purbp->td_list));
-               ptd = list_entry(purbp->td_list.prev, struct uhci_td,
-                               list);
-               ltd = list_entry(urbp->td_list.prev, struct uhci_td,
-                               list);
-               ptd->link = ltd->link;
-       }
-
        /* Take the URB off the QH's queue.  If the queue is now empty,
         * this is a perfect time for a toggle fixup. */
        list_del_init(&urbp->node);
@@ -1237,7 +1246,7 @@ restart:
        list_for_each_entry(urbp, &qh->queue, node) {
                urb = urbp->urb;
                if (urb->status != -EINPROGRESS) {
-                       uhci_save_toggle(qh, urb);
+                       uhci_cleanup_queue(qh, urb);
                        uhci_giveback_urb(uhci, qh, urb, regs);
                        goto restart;
                }



-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to