- prevent usbcore from asking the HCD root hub code to read registers on one more suspend path (some hardware gets upset in those cases);
- try handling a "device died" cleanup case better
- add some wmb() calls in spots that could matter on some hardware
Please merge.
- Dave
--- 1.80/drivers/usb/core/hcd.c Sun Mar 7 11:29:08 2004
+++ edited/drivers/usb/core/hcd.c Thu Mar 25 20:58:45 2004
@@ -416,9 +416,14 @@
default:
/* non-generic request */
- urb->status = hcd->driver->hub_control (hcd,
- typeReq, wValue, wIndex,
- ubuf, wLength);
+ if (HCD_IS_SUSPENDED (hcd->state))
+ urb->status = -EAGAIN;
+ else if (!HCD_IS_RUNNING (hcd->state))
+ urb->status = -ENODEV;
+ else
+ urb->status = hcd->driver->hub_control (hcd,
+ typeReq, wValue, wIndex,
+ ubuf, wLength);
break;
error:
/* "protocol stall" on error */
--- 1.56/drivers/usb/host/ohci-hcd.c Tue Mar 2 05:52:40 2004
+++ edited/drivers/usb/host/ohci-hcd.c Thu Mar 25 20:48:40 2004
@@ -344,8 +344,11 @@
if (!ed)
goto done;
- if (!HCD_IS_RUNNING (ohci->hcd.state))
+ if (!HCD_IS_RUNNING (ohci->hcd.state)) {
ed->state = ED_IDLE;
+ finish_unlinks (ohci, 0, 0);
+ }
+
switch (ed->state) {
case ED_UNLINK: /* wait for hw to finish? */
/* major IRQ delivery trouble loses INTR_SF too... */
--- 1.50/drivers/usb/host/ohci-q.c Wed Mar 10 08:17:32 2004
+++ edited/drivers/usb/host/ohci-q.c Thu Mar 25 20:46:59 2004
@@ -156,6 +156,7 @@
wmb ();
*prev = ed;
*prev_p = cpu_to_le32p (&ed->dma);
+ wmb();
}
ohci->load [i] += ed->load;
}
@@ -195,6 +196,7 @@
}
ed->ed_prev = ohci->ed_controltail;
if (!ohci->ed_controltail && !ohci->ed_rm_list) {
+ wmb();
ohci->hc_control |= OHCI_CTRL_CLE;
writel (0, &ohci->regs->ed_controlcurrent);
writel (ohci->hc_control, &ohci->regs->control);
@@ -212,6 +214,7 @@
}
ed->ed_prev = ohci->ed_bulktail;
if (!ohci->ed_bulktail && !ohci->ed_rm_list) {
+ wmb();
ohci->hc_control |= OHCI_CTRL_BLE;
writel (0, &ohci->regs->ed_bulkcurrent);
writel (ohci->hc_control, &ohci->regs->control);
@@ -868,6 +871,7 @@
td_dma = le32_to_cpup (&ohci->hcca->done_head);
ohci->hcca->done_head = 0;
+ wmb();
/* get TD from hc's singly linked list, and
* prepend to ours. ed->td_list changes later.
