Commit 68d07f64 authored by Sarah Sharp's avatar Sarah Sharp

USB: Don't fail USB3 probe on missing legacy PCI IRQ.

Intel has a PCI USB xhci host controller on a new platform. It doesn't
have a line IRQ definition in BIOS.  The Linux driver refuses to
initialize this controller, but Windows works well because it only depends
on MSI.

Actually, Linux also can work for MSI.  This patch avoids the line IRQ
checking for USB3 HCDs in usb core PCI probe.  It allows the xHCI driver
to try to enable MSI or MSI-X first.  It will fail the probe if MSI
enabling failed and there's no legacy PCI IRQ.

This patch should be backported to kernels as old as 2.6.32.
Signed-off-by: default avatarAlex Shi <alex.shi@intel.com>
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
parent b7bc5925
...@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV; return -ENODEV;
dev->current_state = PCI_D0; dev->current_state = PCI_D0;
if (!dev->irq) { /* The xHCI driver supports MSI and MSI-X,
* so don't fail if the BIOS doesn't provide a legacy IRQ.
*/
if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
dev_err(&dev->dev, dev_err(&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n", "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev)); pci_name(dev));
......
...@@ -2447,8 +2447,10 @@ int usb_add_hcd(struct usb_hcd *hcd, ...@@ -2447,8 +2447,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
&& device_can_wakeup(&hcd->self.root_hub->dev)) && device_can_wakeup(&hcd->self.root_hub->dev))
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
/* enable irqs just before we start the controller */ /* enable irqs just before we start the controller,
if (usb_hcd_is_primary_hcd(hcd)) { * if the BIOS provides legacy PCI irqs.
*/
if (usb_hcd_is_primary_hcd(hcd) && irqnum) {
retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
if (retval) if (retval)
goto err_request_irq; goto err_request_irq;
......
...@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) ...@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
/* hcd->irq is -1, we have MSI */ /* hcd->irq is -1, we have MSI */
return 0; return 0;
if (!pdev->irq) {
xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
return -EINVAL;
}
/* fall back to legacy interrupt*/ /* fall back to legacy interrupt*/
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd); hcd->irq_descr, hcd);
......
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