Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361254
b: refs/heads/master
c: 6402c79
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Mar 5, 2013
1 parent 27d0380 commit 05b4166
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ea5301aa130a07e8d0f8bd7d7d3124f45e592208
refs/heads/master: 6402c796d3b4205d3d7296157956c5100a05d7d6
6 changes: 2 additions & 4 deletions trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* guard against (alleged) silicon errata */
if (cmd & CMD_IAAD)
ehci_dbg(ehci, "IAA with IAAD still set?\n");
if (ehci->async_iaa) {
if (ehci->async_iaa)
COUNT(ehci->stats.iaa);
end_unlink_async(ehci);
} else
ehci_dbg(ehci, "IAA with nothing unlinked?\n");
end_unlink_async(ehci);
}

/* remote wakeup [4.3.1] */
Expand Down
18 changes: 14 additions & 4 deletions trunk/drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
struct ehci_qh *prev;

/* Add to the end of the list of QHs waiting for the next IAAD */
qh->qh_state = QH_STATE_UNLINK;
qh->qh_state = QH_STATE_UNLINK_WAIT;
if (ehci->async_unlink)
ehci->async_unlink_last->unlink_next = qh;
else
Expand Down Expand Up @@ -1213,9 +1213,19 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)

/* Do only the first waiting QH (nVidia bug?) */
qh = ehci->async_unlink;
ehci->async_iaa = qh;
ehci->async_unlink = qh->unlink_next;
qh->unlink_next = NULL;

/*
* Intel (?) bug: The HC can write back the overlay region
* even after the IAA interrupt occurs. In self-defense,
* always go through two IAA cycles for each QH.
*/
if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
qh->qh_state = QH_STATE_UNLINK;
} else {
ehci->async_iaa = qh;
ehci->async_unlink = qh->unlink_next;
qh->unlink_next = NULL;
}

/* Make sure the unlinks are all visible to the hardware */
wmb();
Expand Down

0 comments on commit 05b4166

Please sign in to comment.