ChangeSet 1.1673.8.42, 2004/03/26 14:26:00-08:00, david-b@pacbell.net [PATCH] USB: ohci misc updates Mostly from Benjamin Herrenschmidt: - 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 drivers/usb/core/hcd.c | 11 ++++++++--- drivers/usb/host/ohci-hcd.c | 5 ++++- drivers/usb/host/ohci-q.c | 4 ++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Wed Apr 14 14:36:41 2004 +++ b/drivers/usb/core/hcd.c Wed Apr 14 14:36:41 2004 @@ -418,9 +418,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 */ diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Wed Apr 14 14:36:41 2004 +++ b/drivers/usb/host/ohci-hcd.c Wed Apr 14 14:36:41 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... */ diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Wed Apr 14 14:36:41 2004 +++ b/drivers/usb/host/ohci-q.c Wed Apr 14 14:36:41 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.