diff options
Diffstat (limited to 'drivers/usb/host/whci/pzl.c')
| -rw-r--r-- | drivers/usb/host/whci/pzl.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index a9e05bac6646..0db3fb2dc03a 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
| @@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset) | |||
| 121 | if (status & QTD_STS_HALTED) { | 121 | if (status & QTD_STS_HALTED) { |
| 122 | /* Ug, an error. */ | 122 | /* Ug, an error. */ |
| 123 | process_halted_qtd(whc, qset, td); | 123 | process_halted_qtd(whc, qset, td); |
| 124 | /* A halted qTD always triggers an update | ||
| 125 | because the qset was either removed or | ||
| 126 | reactivated. */ | ||
| 127 | update |= WHC_UPDATE_UPDATED; | ||
| 124 | goto done; | 128 | goto done; |
| 125 | } | 129 | } |
| 126 | 130 | ||
| @@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status) | |||
| 333 | struct whc_urb *wurb = urb->hcpriv; | 337 | struct whc_urb *wurb = urb->hcpriv; |
| 334 | struct whc_qset *qset = wurb->qset; | 338 | struct whc_qset *qset = wurb->qset; |
| 335 | struct whc_std *std, *t; | 339 | struct whc_std *std, *t; |
| 340 | bool has_qtd = false; | ||
| 336 | int ret; | 341 | int ret; |
| 337 | unsigned long flags; | 342 | unsigned long flags; |
| 338 | 343 | ||
| @@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status) | |||
| 343 | goto out; | 348 | goto out; |
| 344 | 349 | ||
| 345 | list_for_each_entry_safe(std, t, &qset->stds, list_node) { | 350 | list_for_each_entry_safe(std, t, &qset->stds, list_node) { |
| 346 | if (std->urb == urb) | 351 | if (std->urb == urb) { |
| 352 | if (std->qtd) | ||
| 353 | has_qtd = true; | ||
| 347 | qset_free_std(whc, std); | 354 | qset_free_std(whc, std); |
| 348 | else | 355 | } else |
| 349 | std->qtd = NULL; /* so this std is re-added when the qset is */ | 356 | std->qtd = NULL; /* so this std is re-added when the qset is */ |
| 350 | } | 357 | } |
| 351 | 358 | ||
| 352 | pzl_qset_remove(whc, qset); | 359 | if (has_qtd) { |
| 353 | wurb->status = status; | 360 | pzl_qset_remove(whc, qset); |
| 354 | wurb->is_async = false; | 361 | update_pzl_hw_view(whc); |
| 355 | queue_work(whc->workqueue, &wurb->dequeue_work); | 362 | wurb->status = status; |
| 356 | 363 | wurb->is_async = false; | |
| 364 | queue_work(whc->workqueue, &wurb->dequeue_work); | ||
| 365 | } else | ||
| 366 | qset_remove_urb(whc, qset, urb, status); | ||
| 357 | out: | 367 | out: |
| 358 | spin_unlock_irqrestore(&whc->lock, flags); | 368 | spin_unlock_irqrestore(&whc->lock, flags); |
| 359 | 369 | ||
