diff options
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/pci-quirks.c | 11 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-hub.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-mem.c | 32 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 5 |
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 | } |
| 885 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | 896 | DECLARE_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 | */ |
| 1132 | static unsigned int xhci_parse_frame_interval(struct usb_device *udev, | 1132 | static 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 | ||
| 1150 | static 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 | |||
| 1158 | static 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); |
