aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/asl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/whci/asl.c')
-rw-r--r--drivers/usb/host/whci/asl.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index c632437c7649..14ccbcfc4315 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -305,6 +305,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
305 struct whc_urb *wurb = urb->hcpriv; 305 struct whc_urb *wurb = urb->hcpriv;
306 struct whc_qset *qset = wurb->qset; 306 struct whc_qset *qset = wurb->qset;
307 struct whc_std *std, *t; 307 struct whc_std *std, *t;
308 bool has_qtd = false;
308 int ret; 309 int ret;
309 unsigned long flags; 310 unsigned long flags;
310 311
@@ -315,17 +316,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
315 goto out; 316 goto out;
316 317
317 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 318 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
318 if (std->urb == urb) 319 if (std->urb == urb) {
320 if (std->qtd)
321 has_qtd = true;
319 qset_free_std(whc, std); 322 qset_free_std(whc, std);
320 else 323 } else
321 std->qtd = NULL; /* so this std is re-added when the qset is */ 324 std->qtd = NULL; /* so this std is re-added when the qset is */
322 } 325 }
323 326
324 asl_qset_remove(whc, qset); 327 if (has_qtd) {
325 wurb->status = status; 328 asl_qset_remove(whc, qset);
326 wurb->is_async = true; 329 wurb->status = status;
327 queue_work(whc->workqueue, &wurb->dequeue_work); 330 wurb->is_async = true;
328 331 queue_work(whc->workqueue, &wurb->dequeue_work);
332 } else
333 qset_remove_urb(whc, qset, urb, status);
329out: 334out:
330 spin_unlock_irqrestore(&whc->lock, flags); 335 spin_unlock_irqrestore(&whc->lock, flags);
331 336