USB: xhci: Don't wait for a disable slot cmd when HC dies.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Wed, 16 Sep 2009 23:42:39 +0000 (16:42 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 9 Oct 2009 20:52:06 +0000 (13:52 -0700)
When the host controller dies or is removed while a device is plugged in,
the USB core will attempt to deallocate the struct usb_device.  That will
call into xhci_free_dev().  This function used to attempt to submit a
disable slot command to the host controller and clean up the device
structures when that command returned.  Change xhci_free_dev() to skip the
command submission and just free the memory if the host controller died.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/xhci-hcd.c

index 592e742c5f35c17fd1aa7542725951129d0a727d..d61c49f90f4ae84aebe09d0e6037926d6dbde61b 100644 (file)
@@ -1428,11 +1428,20 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        unsigned long flags;
+       u32 state;
 
        if (udev->slot_id == 0)
                return;
 
        spin_lock_irqsave(&xhci->lock, flags);
+       /* Don't disable the slot if the host controller is dead. */
+       state = xhci_readl(xhci, &xhci->op_regs->status);
+       if (state == 0xffffffff) {
+               xhci_free_virt_device(xhci, udev->slot_id);
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }
+
        if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
                spin_unlock_irqrestore(&xhci->lock, flags);
                xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");