From: Alex Shi <alex.shi@xxxxxxxxx> We have a PCI USB xhci host controller on a new platform. It have no line IRQ definition in BIOS. So the Linux driver refuses to initial this controller. But Windows works well for it depending on MSI. Actually, Linux also can work for MSI. This patch skips the first line IRQ checking for our HCD in usb-core pci probe, then try to enable MSI firstly. That make this HCD works well under Linux. Thanks for Sarah's suggestion and review for this patch. This patch should be applied to kernels as old as 2.6.36, that have the commit 43b86af83da7db8b2c6d85ca970203950e5bad88 "USB: xHCI: Supporting MSI/MSI-X". This particular patch applies to kernels 3.1 and older, since 3.2 refactored the MSI initialization code. Signed-off-by: Alex Shi <alex.shi@xxxxxxxxx> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- Hi Alex, I had to modify your patch a bit to get it to apply to pre-3.2 stable kernels. Can you please verify that the following patch works against 3.1 on your system with no legacy PCI interrupt? Alternatively, you can just test the 3.1-stable branch in my git repo. Thanks, Sarah Sharp drivers/usb/core/hcd-pci.c | 3 ++- drivers/usb/core/hcd.c | 8 ++++++-- drivers/usb/host/xhci-pci.c | 6 ++++++ drivers/usb/host/xhci.c | 5 +++++ include/linux/usb/hcd.h | 1 + 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index ce22f4a..087b559 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -187,7 +187,8 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; dev->current_state = PCI_D0; - if (!dev->irq) { + /* skip irq check if hcd wants MSI firstly. */ + if (!(driver->flags & HCD_MSI_FIRST) && !dev->irq) { dev_err(&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ea47c13..e757b84 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2450,8 +2450,12 @@ int usb_add_hcd(struct usb_hcd *hcd, && device_can_wakeup(&hcd->self.root_hub->dev)) dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); - /* enable irqs just before we start the controller */ - if (usb_hcd_is_primary_hcd(hcd)) { + /* enable irqs just before we start the controller. But Intel USB3 + * hcd can't do this here on some platform, they will do it in + * following driver->start(); + */ + if (usb_hcd_is_primary_hcd(hcd) && + !(hcd->driver->flags & HCD_MSI_FIRST)) { retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); if (retval) goto err_request_irq; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 50e7156..318180c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -198,6 +198,12 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) struct usb_hcd *hcd; driver = (struct hc_driver *)id->driver_data; + + /* stop line IRQ checking in xhci_hcd_pci_probe. */ + if (dev->vendor == PCI_VENDOR_ID_INTEL && + dev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) + driver->flags |= HCD_MSI_FIRST; + /* Register the USB 2.0 roothub. * FIXME: USB core must know to register the USB 2.0 roothub first. * This is sort of silly, because we could just set the HCD driver flags diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 5fc595f..788f66a3 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -444,6 +444,11 @@ int xhci_run(struct usb_hcd *hcd) if (ret) { legacy_irq: + if (!pdev->irq) { + xhci_err(xhci, "No msi-x/msi found and " + "no IRQ in BIOS\n"); + return -EINVAL; + } /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c0ecc5a..def2a4b 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -212,6 +212,7 @@ struct hc_driver { #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ #define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ +#define HCD_MSI_FIRST 0x0008 /* Try to get MSI first, PCI only */ #define HCD_USB11 0x0010 /* USB 1.1 */ #define HCD_USB2 0x0020 /* USB 2.0 */ #define HCD_USB3 0x0040 /* USB 3.0 */ -- 1.7.9 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html