aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-21 19:25:30 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-21 19:25:30 -0500
commit9a9a71b77c3fd511e5dda6236deb8a02d156b864 (patch)
tree304eb27f688f4420ce82b5689a1f1e74aab4ae0f
parentb9e44fe5ecda4158c22bc1ea4bffa378a4f83f65 (diff)
parent340a3504fd39dad753ba908fb6f894ee81fc3ae2 (diff)
Merge tag 'for-usb-linus-2012-02-21' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus
Hi Greg, Here's three bug fixes that should be queued for 3.3. The first fixes an issue we saw with an Intel Panther Point xHCI host, where a certain OSV's custom BIOS would disable the PCI device during boot. It changes the generic PCI quirks handler for all USB host controllers, but in a way both Jesse Barnes and Oliver Neukum have agreed is safe. The second patch is Elric Fu's first kernel patch! Congrats! It fixes a bug in the USB 3.0 hub reset handling. The last patch fixes a bug in the xHCI driver that feeds invalid input to the xHC host. Only the VIA host controller seems to have issues with it. Thanks to Felipe Contreras for testing this patch on his VIA host, and Andiry Xu for suggesting the fix. All three patches are marked for stable. Sarah Sharp
-rw-r--r--drivers/usb/core/hub.c30
-rw-r--r--drivers/usb/host/pci-quirks.c11
-rw-r--r--drivers/usb/host/xhci-mem.c32
3 files changed, 52 insertions, 21 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a0613d8f9be7..265c2f675d04 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -705,10 +705,26 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
705 if (type == HUB_INIT3) 705 if (type == HUB_INIT3)
706 goto init3; 706 goto init3;
707 707
708 /* After a resume, port power should still be on. 708 /* The superspeed hub except for root hub has to use Hub Depth
709 * value as an offset into the route string to locate the bits
710 * it uses to determine the downstream port number. So hub driver
711 * should send a set hub depth request to superspeed hub after
712 * the superspeed hub is set configuration in initialization or
713 * reset procedure.
714 *
715 * After a resume, port power should still be on.
709 * For any other type of activation, turn it on. 716 * For any other type of activation, turn it on.
710 */ 717 */
711 if (type != HUB_RESUME) { 718 if (type != HUB_RESUME) {
719 if (hdev->parent && hub_is_superspeed(hdev)) {
720 ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
721 HUB_SET_DEPTH, USB_RT_HUB,
722 hdev->level - 1, 0, NULL, 0,
723 USB_CTRL_SET_TIMEOUT);
724 if (ret < 0)
725 dev_err(hub->intfdev,
726 "set hub depth failed\n");
727 }
712 728
713 /* Speed up system boot by using a delayed_work for the 729 /* Speed up system boot by using a delayed_work for the
714 * hub's initial power-up delays. This is pretty awkward 730 * hub's initial power-up delays. This is pretty awkward
@@ -987,18 +1003,6 @@ static int hub_configure(struct usb_hub *hub,
987 goto fail; 1003 goto fail;
988 } 1004 }
989 1005
990 if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
991 ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
992 HUB_SET_DEPTH, USB_RT_HUB,
993 hdev->level - 1, 0, NULL, 0,
994 USB_CTRL_SET_TIMEOUT);
995
996 if (ret < 0) {
997 message = "can't set hub depth";
998 goto fail;
999 }
1000 }
1001
1002 /* Request the entire hub descriptor. 1006 /* Request the entire hub descriptor.
1003 * hub->descriptor can handle USB_MAXCHILDREN ports, 1007 * hub->descriptor can handle USB_MAXCHILDREN ports,
1004 * but the hub can/will return fewer bytes here. 1008 * but the hub can/will return fewer bytes here.
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-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 */