mirror of https://gitee.com/openkylin/linux.git
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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPRDFiAAoJEBMGWMLi1Gc5rfsP/1Edfcj6zeXG3FUdy2bpcVup N1M1POaa5tX3/IbOw7/8HUhyzwz8g2Wt96Z6NJu5X34LUtbYij8m/NSBxZ3dR23/ w34/j4UQ6GgB8oUuBBqHSki99ggFhYHqM+3yty/tCIUVyoc7MxwXeZQx0TDqMdso COnio83h4lW7ixeeWdS/jHD5BijQfQnFRztpfPz7AGLD8nEFYnnYtiHOng/PrVoE RTORO6+kZvYqpaJmVME1WPioPfXu9G9kbjO6fQSThDI1fcBZq50k3wrZS+KiEGQT y7uKsZLPNmITV/hrltI7Zs9E6miSO6Q5ITNHs+ffqvwu5Mw/cMrBriCq7DxP11tC k/eFMMzJpiKAMmc/Zg6EtP/8wJAuYnFIFJNjiX3iNPdN3QS4BK9vFIRkjZp3/xDm 9H4Asw20xQMt2OnXiSkip2/nRYlk1IEVHNeXekoF+6+9V6Nbkd+ufw/F1UXupkXG L95LeC/HpdtG4TMwNdJFRNEEd1+D+9fC95Vgo2N5phboiqDINJXRQlJ2Vc/2yPI/ zK4euMbbNjpQbvNIEWwJk8gQe1sdbI83b8Z+FvEhldvEvnkxgeIRHomHaXT+oi5Y atOTeHoaYPvEIBXic8dycAHIj5/8Ztgemz/CG58GUiJU+H5lueYtBD0hqyxrvkKH lp4QV0pzKED2jn/HFMre =sNJE -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
9a9a71b77c
|
@ -705,10 +705,26 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|||
if (type == HUB_INIT3)
|
||||
goto init3;
|
||||
|
||||
/* After a resume, port power should still be on.
|
||||
/* The superspeed hub except for root hub has to use Hub Depth
|
||||
* value as an offset into the route string to locate the bits
|
||||
* it uses to determine the downstream port number. So hub driver
|
||||
* should send a set hub depth request to superspeed hub after
|
||||
* the superspeed hub is set configuration in initialization or
|
||||
* reset procedure.
|
||||
*
|
||||
* After a resume, port power should still be on.
|
||||
* For any other type of activation, turn it on.
|
||||
*/
|
||||
if (type != HUB_RESUME) {
|
||||
if (hdev->parent && hub_is_superspeed(hdev)) {
|
||||
ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
|
||||
HUB_SET_DEPTH, USB_RT_HUB,
|
||||
hdev->level - 1, 0, NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (ret < 0)
|
||||
dev_err(hub->intfdev,
|
||||
"set hub depth failed\n");
|
||||
}
|
||||
|
||||
/* Speed up system boot by using a delayed_work for the
|
||||
* hub's initial power-up delays. This is pretty awkward
|
||||
|
@ -987,18 +1003,6 @@ static int hub_configure(struct usb_hub *hub,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
|
||||
ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
|
||||
HUB_SET_DEPTH, USB_RT_HUB,
|
||||
hdev->level - 1, 0, NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
if (ret < 0) {
|
||||
message = "can't set hub depth";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Request the entire hub descriptor.
|
||||
* hub->descriptor can handle USB_MAXCHILDREN ports,
|
||||
* but the hub can/will return fewer bytes here.
|
||||
|
|
|
@ -872,7 +872,17 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
|
|||
*/
|
||||
if (pdev->vendor == 0x184e) /* vendor Netlogic */
|
||||
return;
|
||||
if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
|
||||
return;
|
||||
|
||||
if (pci_enable_device(pdev) < 0) {
|
||||
dev_warn(&pdev->dev, "Can't enable PCI device, "
|
||||
"BIOS handoff failed.\n");
|
||||
return;
|
||||
}
|
||||
if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
|
||||
quirk_usb_handoff_uhci(pdev);
|
||||
else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
|
||||
|
@ -881,5 +891,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
|
|||
quirk_usb_disable_ehci(pdev);
|
||||
else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
|
||||
quirk_usb_handoff_xhci(pdev);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
|
||||
|
|
|
@ -1126,26 +1126,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
|
|||
}
|
||||
|
||||
/*
|
||||
* Convert bInterval expressed in frames (in 1-255 range) to exponent of
|
||||
* Convert bInterval expressed in microframes (in 1-255 range) to exponent of
|
||||
* microframes, rounded down to nearest power of 2.
|
||||
*/
|
||||
static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep, unsigned int desc_interval,
|
||||
unsigned int min_exponent, unsigned int max_exponent)
|
||||
{
|
||||
unsigned int interval;
|
||||
|
||||
interval = fls(8 * ep->desc.bInterval) - 1;
|
||||
interval = clamp_val(interval, 3, 10);
|
||||
if ((1 << interval) != 8 * ep->desc.bInterval)
|
||||
interval = fls(desc_interval) - 1;
|
||||
interval = clamp_val(interval, min_exponent, max_exponent);
|
||||
if ((1 << interval) != desc_interval)
|
||||
dev_warn(&udev->dev,
|
||||
"ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
|
||||
ep->desc.bEndpointAddress,
|
||||
1 << interval,
|
||||
8 * ep->desc.bInterval);
|
||||
desc_interval);
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
return xhci_microframes_to_exponent(udev, ep,
|
||||
ep->desc.bInterval, 0, 15);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
return xhci_microframes_to_exponent(udev, ep,
|
||||
ep->desc.bInterval * 8, 3, 10);
|
||||
}
|
||||
|
||||
/* Return the polling or NAK interval.
|
||||
*
|
||||
* 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,
|
|||
/* Max NAK rate */
|
||||
if (usb_endpoint_xfer_control(&ep->desc) ||
|
||||
usb_endpoint_xfer_bulk(&ep->desc)) {
|
||||
interval = ep->desc.bInterval;
|
||||
interval = xhci_parse_microframe_interval(udev, ep);
|
||||
break;
|
||||
}
|
||||
/* Fall through - SS and HS isoc/int have same decoding */
|
||||
|
|
Loading…
Reference in New Issue