USB/xhci: Misc fixes for 3.8.
Hi Greg, Here's six patches for xHCI and the USB core. There's a couple of patches to fix xHCI 1.0 field formats, some memory leaks, dead ports, and USB 3.0 remote wakeup disabling. All of these are marked for stable. I know I owe you some re-works of failed stable patches from my last patchset round, but I don't think I'm going to get to them before I head off to Linux Conf Australia tomorrow. Sarah Sharp -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRAc31AAoJEBMGWMLi1Gc59wcP/3DkD5HYuRd9WWSh9gk2MQ9J Gq63E+GaPa1pumFqXkTWB7t8o2wU+G0IZNXVJhQsdYMsEzLMR/ObfzuCu0pZbyxa appsRnCkUKJe00m9itislJHcWe0eI8+2HqCFqO3IapHiv+B5x+wovvbVtyWcRyKY 3YsAumZlyaLbEAZhfTcIFkszqvdCupeg5O3XB2Jt1Fyk1k/JlgD4xmV6bbsOE8py /4uq6fc5wYjfBVatV2wh8/GToz9dOlgeuNTAFl29HrB2ibMUEHYlFpmBnAise8A0 OaMJxH0NtaCXx2AiyNRlSFRdLsi86GtWnOWQWNvdCG0xSyUzF/03MEJ58NaxBSx/ glq7G6EwqYSo7xSSgxqqph/RBA8cZAgsVg/Y3M+dBiuN3Px0xOuWF0+aMCuQcbpR l9vMNEFIubGniqqAiHuc/rwZ9wCwj7NF16C2nbyE9Abs89yC9m0J2W4dRx3JQ+ox pV1QkbmU9Go9IPrz+5kTdKrJ2fCL+X4LVTWQj3391LLzr3DEmMHk+uV1RPADeapK +RRFw0LGpM4qe5+T+/tO0LvV25aNqvnO9ir9ITJZnj5chSQaKcnDDJ9N0ZkYMPm2 gN89cYZhykbsZlKPpRfuy2+Mxd679AIAB94Yo2+Rmzg+tQNFVmqmplCbBQd3/MSC 2VCrHq2jBztN0BZE0XoN =rgLf -----END PGP SIGNATURE----- Merge tag 'for-usb-linus-2012-01-24' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus Sarah writes: USB/xhci: Misc fixes for 3.8. Hi Greg, Here's six patches for xHCI and the USB core. There's a couple of patches to fix xHCI 1.0 field formats, some memory leaks, dead ports, and USB 3.0 remote wakeup disabling. All of these are marked for stable. I know I owe you some re-works of failed stable patches from my last patchset round, but I don't think I'm going to get to them before I head off to Linux Conf Australia tomorrow. Sarah Sharp
This commit is contained in:
Коммит
a28dde6181
|
@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)
|
|||
EXPORT_SYMBOL_GPL(usb_enable_ltm);
|
||||
|
||||
#ifdef CONFIG_USB_SUSPEND
|
||||
/*
|
||||
* usb_disable_function_remotewakeup - disable usb3.0
|
||||
* device's function remote wakeup
|
||||
* @udev: target device
|
||||
*
|
||||
* Assume there's only one function on the USB 3.0
|
||||
* device and disable remote wake for the first
|
||||
* interface. FIXME if the interface association
|
||||
* descriptor shows there's more than one function.
|
||||
*/
|
||||
static int usb_disable_function_remotewakeup(struct usb_device *udev)
|
||||
{
|
||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
|
||||
USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* usb_port_suspend - suspend a usb device's upstream port
|
||||
|
@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
|
||||
port1, status);
|
||||
/* paranoia: "should not happen" */
|
||||
if (udev->do_remote_wakeup)
|
||||
(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
|
||||
if (udev->do_remote_wakeup) {
|
||||
if (!hub_is_superspeed(hub->hdev)) {
|
||||
(void) usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else
|
||||
(void) usb_disable_function_remotewakeup(udev);
|
||||
|
||||
}
|
||||
|
||||
/* Try to enable USB2 hardware LPM again */
|
||||
if (udev->usb2_hw_lpm_capable == 1)
|
||||
|
@ -3052,8 +3076,9 @@ static int finish_port_resume(struct usb_device *udev)
|
|||
* udev->reset_resume
|
||||
*/
|
||||
} else if (udev->actconfig && !udev->reset_resume) {
|
||||
if (!hub_is_superspeed(udev->parent)) {
|
||||
le16_to_cpus(&devstatus);
|
||||
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
|
||||
status = usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
|
@ -3061,11 +3086,20 @@ static int finish_port_resume(struct usb_device *udev)
|
|||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else {
|
||||
status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
|
||||
&devstatus);
|
||||
le16_to_cpus(&devstatus);
|
||||
if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP
|
||||
| USB_INTRF_STAT_FUNC_RW))
|
||||
status =
|
||||
usb_disable_function_remotewakeup(udev);
|
||||
}
|
||||
|
||||
if (status)
|
||||
dev_dbg(&udev->dev,
|
||||
"disable remote wakeup, status %d\n",
|
||||
status);
|
||||
}
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
|
|
|
@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
|
|||
"defaulting to EHCI.\n");
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"USB 3.0 devices will work at USB 2.0 speeds.\n");
|
||||
usb_disable_xhci_ports(xhci_pdev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
|
|||
faked_port_index + 1);
|
||||
if (slot_id && xhci->devs[slot_id])
|
||||
xhci_ring_device(xhci, slot_id);
|
||||
if (bus_state->port_remote_wakeup && (1 << faked_port_index)) {
|
||||
if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
|
||||
bus_state->port_remote_wakeup &=
|
||||
~(1 << faked_port_index);
|
||||
xhci_test_and_clear_bit(xhci, port_array,
|
||||
|
@ -2589,6 +2589,8 @@ cleanup:
|
|||
(trb_comp_code != COMP_STALL &&
|
||||
trb_comp_code != COMP_BABBLE))
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
else
|
||||
kfree(urb_priv);
|
||||
|
||||
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
|
||||
if ((urb->actual_length != urb->transfer_buffer_length &&
|
||||
|
@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
|
|||
* running_total.
|
||||
*/
|
||||
packets_transferred = (running_total + trb_buff_len) /
|
||||
usb_endpoint_maxp(&urb->ep->desc);
|
||||
GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
|
||||
if ((total_packet_count - packets_transferred) > 31)
|
||||
return 31 << 17;
|
||||
|
@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
td_len = urb->iso_frame_desc[i].length;
|
||||
td_remain_len = td_len;
|
||||
total_packet_count = DIV_ROUND_UP(td_len,
|
||||
usb_endpoint_maxp(&urb->ep->desc));
|
||||
GET_MAX_PACKET(
|
||||
usb_endpoint_maxp(&urb->ep->desc)));
|
||||
/* A zero-length transfer still involves at least one packet. */
|
||||
if (total_packet_count == 0)
|
||||
total_packet_count++;
|
||||
|
@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
td = urb_priv->td[i];
|
||||
for (j = 0; j < trbs_per_td; j++) {
|
||||
u32 remainder = 0;
|
||||
field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
|
||||
field = 0;
|
||||
|
||||
if (first_trb) {
|
||||
field = TRB_TBC(burst_count) |
|
||||
TRB_TLBPC(residue);
|
||||
/* Queue the isoc TRB */
|
||||
field |= TRB_TYPE(TRB_ISOC);
|
||||
/* Assume URB_ISO_ASAP is set */
|
||||
|
|
|
@ -152,6 +152,12 @@
|
|||
#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))
|
||||
#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1))
|
||||
|
||||
/*
|
||||
* Interface status, Figure 9-5 USB 3.0 spec
|
||||
*/
|
||||
#define USB_INTRF_STAT_FUNC_RW_CAP 1
|
||||
#define USB_INTRF_STAT_FUNC_RW 2
|
||||
|
||||
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
|
||||
|
||||
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче