xhci: don't dereference a xhci member after removing xhci
authorMathias Nyman <mathias.nyman@linux.intel.com>
Tue, 16 Aug 2016 07:18:06 +0000 (10:18 +0300)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 20 Nov 2016 01:01:33 +0000 (01:01 +0000)
commit f1f6d9a8b540df22b87a5bf6bc104edaade81f47 upstream.

Remove the hcd after checking for the xhci last quirks, not before.

This caused a hang on a Alpine Ridge xhci based maching which remove
the whole xhci controller when unplugging the last usb device

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/host/xhci-pci.c

index 50af559..cc6aa66 100644 (file)
@@ -252,12 +252,13 @@ static void xhci_pci_remove(struct pci_dev *dev)
                usb_remove_hcd(xhci->shared_hcd);
                usb_put_hcd(xhci->shared_hcd);
        }
                usb_remove_hcd(xhci->shared_hcd);
                usb_put_hcd(xhci->shared_hcd);
        }
-       usb_hcd_pci_remove(dev);
 
        /* Workaround for spurious wakeups at shutdown with HSW */
        if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
                pci_set_power_state(dev, PCI_D3hot);
 
 
        /* Workaround for spurious wakeups at shutdown with HSW */
        if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
                pci_set_power_state(dev, PCI_D3hot);
 
+       usb_hcd_pci_remove(dev);
+
        kfree(xhci);
 }
 
        kfree(xhci);
 }