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 a9e05bac664..0db3fb2dc03 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)  		if (status & QTD_STS_HALTED) {  			/* Ug, an error. */  			process_halted_qtd(whc, qset, td); +			/* A halted qTD always triggers an update +			   because the qset was either removed or +			   reactivated. */ +			update |= WHC_UPDATE_UPDATED;  			goto done;  		} @@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)  	struct whc_urb *wurb = urb->hcpriv;  	struct whc_qset *qset = wurb->qset;  	struct whc_std *std, *t; +	bool has_qtd = false;  	int ret;  	unsigned long flags; @@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)  		goto out;  	list_for_each_entry_safe(std, t, &qset->stds, list_node) { -		if (std->urb == urb) +		if (std->urb == urb) { +			if (std->qtd) +				has_qtd = true;  			qset_free_std(whc, std); -		else +		} else  			std->qtd = NULL; /* so this std is re-added when the qset is */  	} -	pzl_qset_remove(whc, qset); -	wurb->status = status; -	wurb->is_async = false; -	queue_work(whc->workqueue, &wurb->dequeue_work); - +	if (has_qtd) { +		pzl_qset_remove(whc, qset); +		update_pzl_hw_view(whc); +		wurb->status = status; +		wurb->is_async = false; +		queue_work(whc->workqueue, &wurb->dequeue_work); +	} else +		qset_remove_urb(whc, qset, urb, status);  out:  	spin_unlock_irqrestore(&whc->lock, flags);  |