diff options
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 19 | 
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 58fdfad96b4..c2813c2b005 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,  	if (req->request.status == -EINPROGRESS)  		req->request.status = status; -	usb_gadget_unmap_request(&dwc->gadget, &req->request, -			req->direction); +	if (dwc->ep0_bounced && dep->number == 0) +		dwc->ep0_bounced = false; +	else +		usb_gadget_unmap_request(&dwc->gadget, &req->request, +				req->direction);  	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",  			req, dep->name, req->request.actual, @@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,  	if (list_empty(&dep->request_list)) {  		dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",  			dep->name); +		dep->flags |= DWC3_EP_PENDING_REQUEST;  		return;  	} @@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)  	if (dep->flags & DWC3_EP_PENDING_REQUEST) {  		int	ret; +		/* +		 * If xfernotready is already elapsed and it is a case +		 * of isoc transfer, then issue END TRANSFER, so that +		 * you can receive xfernotready again and can have +		 * notion of current microframe. +		 */ +		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { +			dwc3_stop_active_transfer(dwc, dep->number); +			return 0; +		} +  		ret = __dwc3_gadget_kick_transfer(dep, 0, true);  		if (ret && ret != -EBUSY) {  			struct dwc3	*dwc = dep->dwc;  |