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 ba444e7f9c44..c9e729a4bf65 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, | |||
263 | if (req->request.status == -EINPROGRESS) | 263 | if (req->request.status == -EINPROGRESS) |
264 | req->request.status = status; | 264 | req->request.status = status; |
265 | 265 | ||
266 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 266 | if (dwc->ep0_bounced && dep->number == 0) |
267 | req->direction); | 267 | dwc->ep0_bounced = false; |
268 | else | ||
269 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | ||
270 | req->direction); | ||
268 | 271 | ||
269 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 272 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
270 | req, dep->name, req->request.actual, | 273 | req, dep->name, req->request.actual, |
@@ -1017,6 +1020,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | |||
1017 | if (list_empty(&dep->request_list)) { | 1020 | if (list_empty(&dep->request_list)) { |
1018 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 1021 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", |
1019 | dep->name); | 1022 | dep->name); |
1023 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
1020 | return; | 1024 | return; |
1021 | } | 1025 | } |
1022 | 1026 | ||
@@ -1078,6 +1082,19 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1078 | * | 1082 | * |
1079 | */ | 1083 | */ |
1080 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1084 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1085 | int ret; | ||
1086 | |||
1087 | /* | ||
1088 | * If xfernotready is already elapsed and it is a case | ||
1089 | * of isoc transfer, then issue END TRANSFER, so that | ||
1090 | * you can receive xfernotready again and can have | ||
1091 | * notion of current microframe. | ||
1092 | */ | ||
1093 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1094 | dwc3_stop_active_transfer(dwc, dep->number); | ||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1081 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | 1098 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1082 | if (ret && ret != -EBUSY) | 1099 | if (ret && ret != -EBUSY) |
1083 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 1100 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |