Commit 18a860b2 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[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
parent dc6b9d7f
......@@ -418,9 +418,14 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
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 */
......
......@@ -344,8 +344,11 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
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... */
......
......@@ -156,6 +156,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed)
wmb ();
*prev = ed;
*prev_p = cpu_to_le32p (&ed->dma);
wmb();
}
ohci->load [i] += ed->load;
}
......@@ -195,6 +196,7 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
}
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 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
}
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 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment