diff options
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 21 | 
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ba444e7f9c4..c9e729a4bf6 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, @@ -1017,6 +1020,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;  	} @@ -1078,6 +1082,19 @@ 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)  			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",  |