On Fri, 16 Apr 2004, Simone Gotti wrote:

> Sorry, I've tried it but I've got the same behavior, I've looked at the output 
> of /proc/driver/uhci/0000:00:10.0 but it's quite similar. It's attached.
> Let me know if you need any other tests.

Ooh, yes, there's a serious mistake in there.  The file you included looks
pretty much the same as before, but there are important differences.  All
right, try this patch instead of the other one (actually this includes the 
other one).

Alan Stern



===== drivers/usb/host/uhci-hcd.c 1.101 vs edited =====
--- 1.101/drivers/usb/host/uhci-hcd.c   Fri Mar 26 10:19:10 2004
+++ edited/drivers/usb/host/uhci-hcd.c  Fri Apr 16 13:43:12 2004
@@ -382,6 +382,7 @@
 static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
        struct uhci_qh *pqh;
+       __u32 newlink;
 
        if (!qh)
                return;
@@ -390,8 +391,24 @@
         * Only go through the hoops if it's actually linked in
         */
        if (!list_empty(&qh->list)) {
-               pqh = list_entry(qh->list.prev, struct uhci_qh, list);
 
+               /* If our queue is nonempty, make the next URB the head */
+               if (!list_empty(&qh->urbp->queue_list)) {
+                       struct urb_priv *nurbp;
+
+                       nurbp = list_entry(qh->urbp->queue_list.next,
+                                       struct urb_priv, queue_list);
+                       nurbp->queued = 0;
+                       list_add(&nurbp->qh->list, &qh->list);
+                       newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
+               } else
+                       newlink = qh->link;
+
+               /* Fix up the previous QH's queue to link to either
+                * the new head of this queue or the start of the
+                * next endpoint's queue. */
+               pqh = list_entry(qh->list.prev, struct uhci_qh, list);
+               pqh->link = newlink;
                if (pqh->urbp) {
                        struct list_head *head, *tmp;
 
@@ -403,28 +420,19 @@
 
                                tmp = tmp->next;
 
-                               turbp->qh->link = qh->link;
+                               turbp->qh->link = newlink;
                        }
                }
-
-               pqh->link = qh->link;
                mb();
+
                /* Leave qh->link in case the HC is on the QH now, it will */
                /* continue the rest of the schedule */
                qh->element = UHCI_PTR_TERM;
 
-               /* If our queue is nonempty, make the next URB the head */
-               if (!list_empty(&qh->urbp->queue_list)) {
-                       struct urb_priv *nurbp;
-
-                       nurbp = list_entry(qh->urbp->queue_list.next,
-                                       struct urb_priv, queue_list);
-                       nurbp->queued = 0;
-                       list_add_tail(&nurbp->qh->list, &qh->list);
-               }
                list_del_init(&qh->list);
        }
 
+       list_del_init(&qh->urbp->queue_list);
        qh->urbp = NULL;
 
        /* Check to see if the remove list is empty. Set the IOC bit */
@@ -579,7 +587,7 @@
                        pltd->link = UHCI_PTR_TERM;
        }
 
-       list_del_init(&urbp->queue_list);
+       /* urbp->queue_list is handled in uhci_remove_qh() */
 }
 
 static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb)



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to