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

Merge tag 'for-usb-linus-2012-06-13' of...

Merge tag 'for-usb-linus-2012-06-13' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus

xhci: Bug fixes for 3.5

Hi Greg,

Here's five bug fixes for 3.5.  They fix some memory leaks in the
bandwidth calculation code, fix a couple bugs in the USB3 Link PM
patchset, and make system suspend and resume work on platforms with the
AsMedia ASM1042 xHCI host controller.

Sarah Sharp
parents afff07e6 622eb783
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3379,7 +3379,7 @@ int usb_disable_lpm(struct usb_device *udev)
		return 0;

	udev->lpm_disable_count++;
	if ((udev->u1_params.timeout == 0 && udev->u1_params.timeout == 0))
	if ((udev->u1_params.timeout == 0 && udev->u2_params.timeout == 0))
		return 0;

	/* If LPM is enabled, attempt to disable it. */
+24 −50
Original line number Diff line number Diff line
@@ -793,10 +793,9 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
		struct xhci_virt_device *virt_dev,
		int slot_id)
{
	struct list_head *tt;
	struct list_head *tt_list_head;
	struct list_head *tt_next;
	struct xhci_tt_bw_info *tt_info;
	struct xhci_tt_bw_info *tt_info, *next;
	bool slot_found = false;

	/* If the device never made it past the Set Address stage,
	 * it may not have the real_port set correctly.
@@ -808,34 +807,16 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
	}

	tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts);
	if (list_empty(tt_list_head))
		return;

	list_for_each(tt, tt_list_head) {
		tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
		if (tt_info->slot_id == slot_id)
			break;
	}
	/* Cautionary measure in case the hub was disconnected before we
	 * stored the TT information.
	 */
	if (tt_info->slot_id != slot_id)
		return;

	tt_next = tt->next;
	tt_info = list_entry(tt, struct xhci_tt_bw_info,
			tt_list);
	list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
		/* Multi-TT hubs will have more than one entry */
	do {
		list_del(tt);
		if (tt_info->slot_id == slot_id) {
			slot_found = true;
			list_del(&tt_info->tt_list);
			kfree(tt_info);
		tt = tt_next;
		if (list_empty(tt_list_head))
		} else if (slot_found) {
			break;
		tt_next = tt->next;
		tt_info = list_entry(tt, struct xhci_tt_bw_info,
				tt_list);
	} while (tt_info->slot_id == slot_id);
		}
	}
}

int xhci_alloc_tt_info(struct xhci_hcd *xhci,
@@ -1791,17 +1772,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
	struct dev_info	*dev_info, *next;
	struct list_head *tt_list_head;
	struct list_head *tt;
	struct list_head *endpoints;
	struct list_head *ep, *q;
	struct xhci_tt_bw_info *tt_info;
	struct xhci_interval_bw_table *bwt;
	struct xhci_virt_ep *virt_ep;

	unsigned long	flags;
	int size;
	int i;
	int i, j, num_ports;

	/* Free the Event Ring Segment Table and the actual Event Ring */
	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
@@ -1860,21 +1833,22 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
	}
	spin_unlock_irqrestore(&xhci->lock, flags);

	bwt = &xhci->rh_bw->bw_table;
	for (i = 0; i < XHCI_MAX_INTERVAL; i++) {
		endpoints = &bwt->interval_bw[i].endpoints;
		list_for_each_safe(ep, q, endpoints) {
			virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list);
			list_del(&virt_ep->bw_endpoint_list);
			kfree(virt_ep);
	num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
	for (i = 0; i < num_ports; i++) {
		struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
		for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
			struct list_head *ep = &bwt->interval_bw[j].endpoints;
			while (!list_empty(ep))
				list_del_init(ep->next);
		}
	}

	tt_list_head = &xhci->rh_bw->tts;
	list_for_each_safe(tt, q, tt_list_head) {
		tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
		list_del(tt);
		kfree(tt_info);
	for (i = 0; i < num_ports; i++) {
		struct xhci_tt_bw_info *tt, *n;
		list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) {
			list_del(&tt->tt_list);
			kfree(tt);
		}
	}

	xhci->num_usb2_ports = 0;
+5 −5
Original line number Diff line number Diff line
@@ -795,8 +795,8 @@ int xhci_suspend(struct xhci_hcd *xhci)
	command = xhci_readl(xhci, &xhci->op_regs->command);
	command |= CMD_CSS;
	xhci_writel(xhci, command, &xhci->op_regs->command);
	if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) {
		xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n");
	if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) {
		xhci_warn(xhci, "WARN: xHC save state timeout\n");
		spin_unlock_irq(&xhci->lock);
		return -ETIMEDOUT;
	}
@@ -848,8 +848,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
		command |= CMD_CRS;
		xhci_writel(xhci, command, &xhci->op_regs->command);
		if (handshake(xhci, &xhci->op_regs->status,
			      STS_RESTORE, 0, 10*100)) {
			xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n");
			      STS_RESTORE, 0, 10 * 1000)) {
			xhci_warn(xhci, "WARN: xHC restore state timeout\n");
			spin_unlock_irq(&xhci->lock);
			return -ETIMEDOUT;
		}
@@ -3906,7 +3906,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev,
	default:
		dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n",
				__func__);
		return -EINVAL;
		return USB3_LPM_DISABLED;
	}

	if (sel <= max_sel_pel && pel <= max_sel_pel)