aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/pci-quirks.c11
-rw-r--r--drivers/usb/host/xhci-hub.c2
-rw-r--r--drivers/usb/host/xhci-mem.c32
-rw-r--r--drivers/usb/host/xhci.c5
4 files changed, 41 insertions, 9 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index ac53a662a6a3..7732d69e49e0 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -872,7 +872,17 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
872 */ 872 */
873 if (pdev->vendor == 0x184e) /* vendor Netlogic */ 873 if (pdev->vendor == 0x184e) /* vendor Netlogic */
874 return; 874 return;
875 if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
876 pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
877 pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
878 pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
879 return;
875 880
881 if (pci_enable_device(pdev) < 0) {
882 dev_warn(&pdev->dev, "Can't enable PCI device, "
883 "BIOS handoff failed.\n");
884 return;
885 }
876 if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) 886 if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
877 quirk_usb_handoff_uhci(pdev); 887 quirk_usb_handoff_uhci(pdev);
878 else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) 888 else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
@@ -881,5 +891,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
881 quirk_usb_disable_ehci(pdev); 891 quirk_usb_disable_ehci(pdev);
882 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) 892 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
883 quirk_usb_handoff_xhci(pdev); 893 quirk_usb_handoff_xhci(pdev);
894 pci_disable_device(pdev);
884} 895}
885DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); 896DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 35e257f79c7b..557b6f32db86 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -93,7 +93,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
93 */ 93 */
94 memset(port_removable, 0, sizeof(port_removable)); 94 memset(port_removable, 0, sizeof(port_removable));
95 for (i = 0; i < ports; i++) { 95 for (i = 0; i < ports; i++) {
96 portsc = xhci_readl(xhci, xhci->usb3_ports[i]); 96 portsc = xhci_readl(xhci, xhci->usb2_ports[i]);
97 /* If a device is removable, PORTSC reports a 0, same as in the 97 /* If a device is removable, PORTSC reports a 0, same as in the
98 * hub descriptor DeviceRemovable bits. 98 * hub descriptor DeviceRemovable bits.
99 */ 99 */
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 36cbe2226a44..383fc857491c 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1126,26 +1126,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
1126} 1126}
1127 1127
1128/* 1128/*
1129 * Convert bInterval expressed in frames (in 1-255 range) to exponent of 1129 * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
1130 * microframes, rounded down to nearest power of 2. 1130 * microframes, rounded down to nearest power of 2.
1131 */ 1131 */
1132static unsigned int xhci_parse_frame_interval(struct usb_device *udev, 1132static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
1133 struct usb_host_endpoint *ep) 1133 struct usb_host_endpoint *ep, unsigned int desc_interval,
1134 unsigned int min_exponent, unsigned int max_exponent)
1134{ 1135{
1135 unsigned int interval; 1136 unsigned int interval;
1136 1137
1137 interval = fls(8 * ep->desc.bInterval) - 1; 1138 interval = fls(desc_interval) - 1;
1138 interval = clamp_val(interval, 3, 10); 1139 interval = clamp_val(interval, min_exponent, max_exponent);
1139 if ((1 << interval) != 8 * ep->desc.bInterval) 1140 if ((1 << interval) != desc_interval)
1140 dev_warn(&udev->dev, 1141 dev_warn(&udev->dev,
1141 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", 1142 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
1142 ep->desc.bEndpointAddress, 1143 ep->desc.bEndpointAddress,
1143 1 << interval, 1144 1 << interval,
1144 8 * ep->desc.bInterval); 1145 desc_interval);
1145 1146
1146 return interval; 1147 return interval;
1147} 1148}
1148 1149
1150static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
1151 struct usb_host_endpoint *ep)
1152{
1153 return xhci_microframes_to_exponent(udev, ep,
1154 ep->desc.bInterval, 0, 15);
1155}
1156
1157
1158static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
1159 struct usb_host_endpoint *ep)
1160{
1161 return xhci_microframes_to_exponent(udev, ep,
1162 ep->desc.bInterval * 8, 3, 10);
1163}
1164
1149/* Return the polling or NAK interval. 1165/* Return the polling or NAK interval.
1150 * 1166 *
1151 * The polling interval is expressed in "microframes". If xHCI's Interval field 1167 * The polling interval is expressed in "microframes". If xHCI's Interval field
@@ -1164,7 +1180,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
1164 /* Max NAK rate */ 1180 /* Max NAK rate */
1165 if (usb_endpoint_xfer_control(&ep->desc) || 1181 if (usb_endpoint_xfer_control(&ep->desc) ||
1166 usb_endpoint_xfer_bulk(&ep->desc)) { 1182 usb_endpoint_xfer_bulk(&ep->desc)) {
1167 interval = ep->desc.bInterval; 1183 interval = xhci_parse_microframe_interval(udev, ep);
1168 break; 1184 break;
1169 } 1185 }
1170 /* Fall through - SS and HS isoc/int have same decoding */ 1186 /* Fall through - SS and HS isoc/int have same decoding */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6bbe3c3a7111..c939f5fdef9e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
352 /* hcd->irq is -1, we have MSI */ 352 /* hcd->irq is -1, we have MSI */
353 return 0; 353 return 0;
354 354
355 if (!pdev->irq) {
356 xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
357 return -EINVAL;
358 }
359
355 /* fall back to legacy interrupt*/ 360 /* fall back to legacy interrupt*/
356 ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, 361 ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
357 hcd->irq_descr, hcd); 362 hcd->irq_descr, hcd);