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]