Re: 2.6.25-rc7: Ugh. ---> PATCH

Mark Lord
2008-04-02T15:47:47Z

Mark Lord wrote:
> This patch seems to fix it.
> Could you guys look this over some more,
> as I really am not familiar with the USB code.

Here it is again, with more lines of context, for easier review:

* * *

When comparing 2.6.24 against 2.6.25, this line of code
stood out as not looking entirely correct, given the new
uses of QH_STATE_UNLINK_WAIT in 2.6.25.

Applying this patch seems to fix the USB suspend/resume deaths
on my machine here. More testing is needed to be sure.

Signed-off-by: Mark Lord <mlord@pobox.com>
---

Regenerated with more context in diff, for easier review.

--- linux/drivers/usb/host/ehci-hcd.c.orig 2008-03-11 11:18:40.000000000 -0400
+++ linux/drivers/usb/host/ehci-hcd.c 2008-04-02 11:36:13.000000000 -0400
@@ -801,35 +801,35 @@
return intr_submit(ehci, urb, &qtd_list, mem_flags);

case PIPE_ISOCHRONOUS:
if (urb->dev->speed == USB_SPEED_HIGH)
return itd_submit (ehci, urb, mem_flags);
else
return sitd_submit (ehci, urb, mem_flags);
}
}

static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
/* failfast */
if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim)
end_unlink_async(ehci);

/* if it's not linked then there's nothing to do */
- if (qh->qh_state != QH_STATE_LINKED)
+ if (qh->qh_state != QH_STATE_LINKED && qh->qh_state != QH_STATE_UNLINK_WAIT)
;

/* defer till later if busy */
else if (ehci->reclaim) {
struct ehci_qh *last;

for (last = ehci->reclaim;
last->reclaim;
last = last->reclaim)
continue;
qh->qh_state = QH_STATE_UNLINK_WAIT;
last->reclaim = qh;

/* start IAA cycle */
} else
start_unlink_async (ehci, qh);
}