From a2d1b74b397ce2671f71db32e9b6170950f7fc81 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 31 Jul 2009 10:40:22 -0400 Subject: [PATCH] --- yaml --- r: 156547 b: refs/heads/master c: 7a0f0d951273eee889c2441846842348ebc00a2a h: refs/heads/master i: 156545: c084328f0d656f59b3e4b7249f28aeef2f32bdb2 156543: d6d4f46ab2fe6c849dfbe14c6f14d51580810783 v: v3 --- [refs] | 2 +- trunk/drivers/usb/host/ehci-hcd.c | 3 ++- trunk/drivers/usb/host/ehci-q.c | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ffd6c738d8a7..4ade8d7e8652 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 01105a246345f011fde64d24a601090b646e9e4c +refs/heads/master: 7a0f0d951273eee889c2441846842348ebc00a2a diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 7d03549c3339..11c627ce6022 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -903,7 +903,8 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) /* already started */ break; case QH_STATE_IDLE: - WARN_ON(1); + /* QH might be waiting for a Clear-TT-Buffer */ + qh_completions(ehci, qh); break; } break; diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index 9a1384747f3b..b27380505576 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -940,6 +940,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) head->qh_next.qh = qh; head->hw_next = dma; + qh_get(qh); qh->xacterrs = QH_XACTERR_MAX; qh->qh_state = QH_STATE_LINKED; /* qtd completions reported later by interrupt */ @@ -1080,7 +1081,7 @@ submit_async ( * the HC and TT handle it when the TT has a buffer ready. */ if (likely (qh->qh_state == QH_STATE_IDLE)) - qh_link_async (ehci, qh_get (qh)); + qh_link_async(ehci, qh); done: spin_unlock_irqrestore (&ehci->lock, flags); if (unlikely (qh == NULL)) @@ -1115,8 +1116,6 @@ static void end_unlink_async (struct ehci_hcd *ehci) && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) qh_link_async (ehci, qh); else { - qh_put (qh); // refcount from async list - /* it's not free to turn the async schedule on/off; leave it * active but idle for a while once it empties. */ @@ -1124,6 +1123,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) && ehci->async->qh_next.qh == NULL) timer_action (ehci, TIMER_ASYNC_OFF); } + qh_put(qh); /* refcount from async list */ if (next) { ehci->reclaim = NULL;