This patch should fix the FSBR problems people have noticed.

I think the problem was a misunderstanding of the workarounds Intel
suggested for the PIIX UHCI controller bugs.

I also fixed a problem where FSBR was being turned off too quickly.

I wasn't able to reproduce Matthew Dharm's bug report with usb-storage
causing the HC to give a "Host Controller Halted" error. However, my
test machines at work are all Intel UHCI controllers. I'll test again
with a VIA machine ASAP.

This patch also implements timeout's for URB's. Since no drivers support
URB timeout's, I haven't tested this yet.

The patch is against 2.3.99-pre4-3.

JE

--- linux-2.3.99-pre4-3.orig/drivers/usb/uhci.c Thu Mar 23 14:59:08 2000
+++ linux-2.3.99-pre4-3/drivers/usb/uhci.c      Tue Apr  4 19:10:27 2000
@@ -448,7 +448,7 @@
        if (!urbp->fsbr) {
                urbp->fsbr = 1;
                if (!uhci->fsbr++)
-                       uhci->skel_term_td.link = 
virt_to_bus(&uhci->skel_hs_control_qh) | UHCI_PTR_QH;
+                       uhci->skel_term_qh.link = 
+virt_to_bus(&uhci->skel_hs_control_qh) | UHCI_PTR_QH;
        }
 
        spin_unlock_irqrestore(&uhci->framelist_lock, flags);
@@ -467,7 +467,7 @@
        if (urbp->fsbr) {
                urbp->fsbr = 0;
                if (!--uhci->fsbr)
-                       uhci->skel_term_td.link = UHCI_PTR_TERM;
+                       uhci->skel_term_qh.link = UHCI_PTR_TERM;
        }
 
        spin_unlock_irqrestore(&uhci->framelist_lock, flags);
@@ -712,6 +712,10 @@
 
        urbp->short_control_packet = 1;
 
+       /* Create a new QH to avoid pointer overwriting problems */
+       uhci_remove_qh(uhci, urbp->qh);
+
+       urbp->qh = uhci_alloc_qh(urb->dev);
        /* Delete all of the TD's except for the status TD at the end */
        td = urbp->list.begin;
        while (td && td->list.next) {
@@ -726,10 +730,6 @@
                td = nexttd;
        }
 
-       /* Create a new QH to avoid pointer overwriting problems */
-       uhci_remove_qh(uhci, urbp->qh);
-
-       urbp->qh = uhci_alloc_qh(urb->dev);
        if (!urbp->qh)
                return -ENOMEM;
 
@@ -1403,7 +1403,7 @@
 
 static void rh_int_timer_do(unsigned long ptr)
 {
-       urb_t *urb = (urb_t *)ptr, *u;
+       struct urb *urb = (struct urb *)ptr;
        struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
        struct list_head *tmp, *head = &uhci->urb_list;
        struct urb_priv *urbp;
@@ -1422,15 +1422,22 @@
        nested_lock(&uhci->urblist_lock, flags);
        tmp = head->next;
        while (tmp != head) {
-               u = list_entry(tmp, urb_t, urb_list);
+               struct urb *u = list_entry(tmp, urb_t, urb_list);
+
+               tmp = tmp->next;
 
                urbp = (struct urb_priv *)u->hcpriv;
                if (urbp) {
-                       if (urbp->fsbr && time_after(jiffies, urbp->inserttime + 
IDLE_TIMEOUT))
+                       /* Check if the FSBR timed out */
+                       if (urbp->fsbr && time_after(urbp->inserttime + IDLE_TIMEOUT, 
+jiffies))
                                uhci_dec_fsbr(uhci, u);
-               }
 
-               tmp = tmp->next;
+                       /* Check if the URB timed out */
+                       if (u->timeout && time_after(u->timeout, jiffies)) {
+                               u->transfer_flags |= USB_ASYNC_UNLINK;
+                               uhci_unlink_urb(u);
+                       }
+               }
        }
        nested_unlock(&uhci->urblist_lock, flags);
 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to