Commit a28dde61 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'for-usb-linus-2012-01-24' of...

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
parents 949db153 54a3ac0c
...@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev) ...@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)
EXPORT_SYMBOL_GPL(usb_enable_ltm); EXPORT_SYMBOL_GPL(usb_enable_ltm);
#ifdef CONFIG_USB_SUSPEND #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 * 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) ...@@ -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", dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
port1, status); port1, status);
/* paranoia: "should not happen" */ /* paranoia: "should not happen" */
if (udev->do_remote_wakeup) if (udev->do_remote_wakeup) {
(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), if (!hub_is_superspeed(hub->hdev)) {
USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, (void) usb_control_msg(udev,
USB_DEVICE_REMOTE_WAKEUP, 0, usb_sndctrlpipe(udev, 0),
NULL, 0, USB_REQ_CLEAR_FEATURE,
USB_CTRL_SET_TIMEOUT); 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 */ /* Try to enable USB2 hardware LPM again */
if (udev->usb2_hw_lpm_capable == 1) if (udev->usb2_hw_lpm_capable == 1)
...@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev) ...@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev)
* udev->reset_resume * udev->reset_resume
*/ */
} else if (udev->actconfig && !udev->reset_resume) { } else if (udev->actconfig && !udev->reset_resume) {
le16_to_cpus(&devstatus); if (!hub_is_superspeed(udev->parent)) {
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { le16_to_cpus(&devstatus);
status = usb_control_msg(udev, if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
usb_sndctrlpipe(udev, 0), status = usb_control_msg(udev,
USB_REQ_CLEAR_FEATURE, usb_sndctrlpipe(udev, 0),
USB_REQ_CLEAR_FEATURE,
USB_RECIP_DEVICE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0, USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0, NULL, 0,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
if (status) } else {
dev_dbg(&udev->dev, status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
"disable remote wakeup, status %d\n", &devstatus);
status); 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; status = 0;
} }
return status; return status;
......
...@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) ...@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
"defaulting to EHCI.\n"); "defaulting to EHCI.\n");
dev_warn(&xhci_pdev->dev, dev_warn(&xhci_pdev->dev,
"USB 3.0 devices will work at USB 2.0 speeds.\n"); "USB 3.0 devices will work at USB 2.0 speeds.\n");
usb_disable_xhci_ports(xhci_pdev);
return; return;
} }
......
...@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci, ...@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
faked_port_index + 1); faked_port_index + 1);
if (slot_id && xhci->devs[slot_id]) if (slot_id && xhci->devs[slot_id])
xhci_ring_device(xhci, 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 &= bus_state->port_remote_wakeup &=
~(1 << faked_port_index); ~(1 << faked_port_index);
xhci_test_and_clear_bit(xhci, port_array, xhci_test_and_clear_bit(xhci, port_array,
...@@ -2589,6 +2589,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, ...@@ -2589,6 +2589,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
(trb_comp_code != COMP_STALL && (trb_comp_code != COMP_STALL &&
trb_comp_code != COMP_BABBLE)) trb_comp_code != COMP_BABBLE))
xhci_urb_free_priv(xhci, urb_priv); xhci_urb_free_priv(xhci, urb_priv);
else
kfree(urb_priv);
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
if ((urb->actual_length != urb->transfer_buffer_length && 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, ...@@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
* running_total. * running_total.
*/ */
packets_transferred = (running_total + trb_buff_len) / 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) if ((total_packet_count - packets_transferred) > 31)
return 31 << 17; return 31 << 17;
...@@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -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_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len; td_remain_len = td_len;
total_packet_count = DIV_ROUND_UP(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. */ /* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0) if (total_packet_count == 0)
total_packet_count++; total_packet_count++;
...@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
td = urb_priv->td[i]; td = urb_priv->td[i];
for (j = 0; j < trbs_per_td; j++) { for (j = 0; j < trbs_per_td; j++) {
u32 remainder = 0; u32 remainder = 0;
field = TRB_TBC(burst_count) | TRB_TLBPC(residue); field = 0;
if (first_trb) { if (first_trb) {
field = TRB_TBC(burst_count) |
TRB_TLBPC(residue);
/* Queue the isoc TRB */ /* Queue the isoc TRB */
field |= TRB_TYPE(TRB_ISOC); field |= TRB_TYPE(TRB_ISOC);
/* Assume URB_ISO_ASAP is set */ /* Assume URB_ISO_ASAP is set */
......
...@@ -152,6 +152,12 @@ ...@@ -152,6 +152,12 @@
#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))
#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) #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 */ #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment