Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+52 −18
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;
	}

+9 −4
Original line number Diff line number Diff line
@@ -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 */
+6 −0
Original line number Diff line number Diff line
@@ -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. */