On 01/10/2012 03:34 PM, Alex Shi wrote: > 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. > > Signed-off-by: Alex Shi <alex.shi@xxxxxxxxx> > --- > drivers/usb/core/hcd-pci.c | 3 ++- > drivers/usb/core/hcd.c | 7 +++++-- > drivers/usb/host/xhci-pci.c | 6 ++++++ > drivers/usb/host/xhci.c | 31 +++++++++++++++++-------------- > 4 files changed, 30 insertions(+), 17 deletions(-) > > diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c > index a004db3..d99df3b 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_FST) && !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 13222d3..6545454 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -2466,8 +2466,11 @@ 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 xhci primary > + * hcd doesn't need this, since it will do it in driver->start(); > + */ > + if (usb_hcd_is_primary_hcd(hcd) && > + !(hcd->driver->flags & HCD_MSI_FST)) { > 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 ef98b38..e12c00f 100644 > --- a/drivers/usb/host/xhci-pci.c > +++ b/drivers/usb/host/xhci-pci.c > @@ -136,6 +136,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_USB_XHCI) > + driver->flags |= HCD_MSI_FST; > + > /* 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 a1afb7c..4014467 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -331,27 +331,30 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) > struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); > int ret; > > - /* > - * Some Fresco Logic host controllers advertise MSI, but fail to > - * generate interrupts. Don't even try to enable MSI. > - */ > - if (xhci->quirks & XHCI_BROKEN_MSI) > - return 0; > - Why do you change the logic for XHCI_BROKEN_MSI? The original logic: request_irq() in usb_add_hcd(), and do nothing in xhci_try_enable_msi(). With your patch: request_irq() in usb_add_hcd(), free_irq() and request_irq() again in xhci_try_enable_msi(). What's the point here? Thanks, Andiry > /* unregister the legacy interrupt */ > if (hcd->irq) > free_irq(hcd->irq, hcd); > hcd->irq = -1; > > - ret = xhci_setup_msix(xhci); > - if (ret) > - /* fall back to msi*/ > - ret = xhci_setup_msi(xhci); > + /* > + * Some Fresco Logic host controllers advertise MSI, but fail to > + * generate interrupts. Don't even try to enable MSI. > + */ > + if (!(xhci->quirks & XHCI_BROKEN_MSI)) { > + ret = xhci_setup_msix(xhci); > + if (ret) > + /* fall back to msi*/ > + ret = xhci_setup_msi(xhci); > > - if (!ret) > - /* hcd->irq is -1, we have MSI */ > - return 0; > + if (!ret) > + /* hcd->irq is -1, we have MSI */ > + 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*/ > ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, > hcd->irq_descr, hcd); -- 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