#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/dma-mapping.h>
+#include <linux/usb/quirks.h>
#include "xhci.h"
#include "xhci-trace.h"
if (ret || !urb->hcpriv)
goto done;
temp = readl(&xhci->op_regs->status);
- if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
+ if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED) ||
+ (xhci->xhc_state & XHCI_STATE_REMOVING)) {
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"HW died, freeing TD.");
urb_priv = urb->hcpriv;
xhci_urb_free_priv(urb_priv);
return ret;
}
- if ((xhci->xhc_state & XHCI_STATE_DYING) ||
- (xhci->xhc_state & XHCI_STATE_HALTED)) {
- xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "Ep 0x%x: URB %p to be canceled on "
- "non-responsive xHCI host.",
- urb->ep->desc.bEndpointAddress, urb);
- /* Let the stop endpoint command watchdog timer (which set this
- * state) finish cleaning up the endpoint TD lists. We must
- * have caught it in the middle of dropping a lock and giving
- * back an URB.
- */
- goto done;
- }
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
/* Don't disable the slot if the host controller is dead. */
state = readl(&xhci->op_regs->status);
if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
- (xhci->xhc_state & XHCI_STATE_HALTED)) {
+ (xhci->xhc_state & XHCI_STATE_HALTED) ||
+ (xhci->xhc_state & XHCI_STATE_REMOVING)) {
xhci_free_virt_device(xhci, udev->slot_id);
spin_unlock_irqrestore(&xhci->lock, flags);
kfree(command);
mutex_lock(&xhci->mutex);
- if (xhci->xhc_state) /* dying, removing or halted */
+ if (xhci->xhc_state) { /* dying, removing or halted */
+ ret = -ESHUTDOWN;
goto out;
+ }
if (!udev->slot_id) {
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
/* xHCI private pointer was set in xhci_pci_probe for the second
* registered roothub.
*/
+ if (xhci->quirks & XHCI_DIS_AUTOSUSPEND)
+ xhci->shared_hcd->self.root_hub->quirks |=
+ USB_QUIRK_AUTO_SUSPEND;
+
return 0;
}