From 4819fef5e7cb9a39e1fd59ecd85861b3ffebdcaa Mon Sep 17 00:00:00 2001 From: Matt Evans Date: Wed, 1 Jun 2011 13:01:07 +1000 Subject: xhci: Bigendian fix for xhci_check_bandwidth() Commit 834cb0fc4712a3b21c6b8c5cb55bd13607191311 "xhci: Fix memory leak bug when dropping endpoints" added a small endian bug. This patch fixes xhci_check_bandwidth() to read add/drop_flags LE. Signed-off-by: Matt Evans Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb/host/xhci.c') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d9660eb97eb..ecd20210161 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1849,8 +1849,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) /* Free any rings that were dropped, but not changed. */ for (i = 1; i < 31; ++i) { - if ((ctrl_ctx->drop_flags & (1 << (i + 1))) && - !(ctrl_ctx->add_flags & (1 << (i + 1)))) + if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && + !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); } xhci_zero_in_ctx(xhci, virt_dev); -- cgit v1.2.3-70-g09d2 From 001fd3826f4c736ce292315782d015f768399080 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 1 Jun 2011 23:27:50 +0200 Subject: xhci: Do not issue device reset when device is not setup xHCI controllers respond to a Reset Device command when the Slot is in the Enabled/Disabled state by returning an error. This is fine on other host controllers, but the Etron xHCI host controller returns a vendor-specific error code that the xHCI driver doesn't understand. The xHCI driver then gives up on device enumeration. Instead of issuing a command that will fail, just return. This fixes the issue with the xhci driver not working on ASRock P67 Pro/Extreme boards. This should be backported to stable kernels as far back as 2.6.34. Signed-off-by: Maarten Lankhorst Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/usb/host/xhci.c') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ecd20210161..66f3e41bba5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2467,6 +2467,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_command *reset_device_cmd; int timeleft; int last_freed_endpoint; + struct xhci_slot_ctx *slot_ctx; ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); if (ret <= 0) @@ -2499,6 +2500,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) return -EINVAL; } + /* If device is not setup, there is no point in resetting it */ + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == + SLOT_STATE_DISABLED) + return 0; + xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); /* Allocate the command structure that holds the struct completion. * Assume we're in process context, since the normal device reset -- cgit v1.2.3-70-g09d2 From f5182b4155b9d686c5540a6822486400e34ddd98 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 2 Jun 2011 11:33:02 -0700 Subject: xhci: Disable MSI for some Fresco Logic hosts. Some Fresco Logic hosts, including those found in the AUAU N533V laptop, advertise MSI, but fail to actually generate MSI interrupts. Add a new xHCI quirk to skip MSI enabling for the Fresco Logic host controllers. Fresco Logic confirms that all chips with PCI vendor ID 0x1b73 and device ID 0x1000, regardless of PCI revision ID, do not support MSI. This should be backported to stable kernels as far back as 2.6.36, which was the first kernel to support MSI on xHCI hosts. Signed-off-by: Sarah Sharp Reported-by: Sergey Galanov Cc: stable@kernel.org --- drivers/usb/host/xhci-pci.c | 14 ++++++++++++-- drivers/usb/host/xhci.c | 7 +++++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/usb/host/xhci.c') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c408e9f6a70..17541d09eab 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -106,12 +106,22 @@ static int xhci_pci_setup(struct usb_hcd *hcd) /* Look for vendor-specific quirks */ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && - pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && - pdev->revision == 0x0) { + pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { + if (pdev->revision == 0x0) { xhci->quirks |= XHCI_RESET_EP_QUIRK; xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" " endpoint cmd after reset endpoint\n"); + } + /* Fresco Logic confirms: all revisions of this chip do not + * support MSI, even though some of them claim to in their PCI + * capabilities. + */ + xhci->quirks |= XHCI_BROKEN_MSI; + xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u " + "has broken MSI implementation\n", + pdev->revision); } + if (pdev->vendor == PCI_VENDOR_ID_NEC) xhci->quirks |= XHCI_NEC_HOST; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 66f3e41bba5..06e7023258d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd) free_irq(hcd->irq, hcd); hcd->irq = -1; + /* 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) + goto legacy_irq; + ret = xhci_setup_msix(xhci); if (ret) /* fall back to msi*/ ret = xhci_setup_msi(xhci); if (ret) { +legacy_irq: /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index bbc1d9afb49..7d1ea3bf5e1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1307,6 +1307,7 @@ struct xhci_hcd { * commands. */ #define XHCI_EP_LIMIT_QUIRK (1 << 5) +#define XHCI_BROKEN_MSI (1 << 6) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- cgit v1.2.3-70-g09d2