aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/gadget.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 0d75158e43fe..79e7a3480d51 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
171 int status) 171 int status)
172{ 172{
173 struct dwc3 *dwc = dep->dwc; 173 struct dwc3 *dwc = dep->dwc;
174 unsigned int unmap_after_complete = false;
174 175
175 req->started = false; 176 req->started = false;
176 list_del(&req->list); 177 list_del(&req->list);
@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
180 if (req->request.status == -EINPROGRESS) 181 if (req->request.status == -EINPROGRESS)
181 req->request.status = status; 182 req->request.status = status;
182 183
183 if (dwc->ep0_bounced && dep->number <= 1) 184 /*
185 * NOTICE we don't want to unmap before calling ->complete() if we're
186 * dealing with a bounced ep0 request. If we unmap it here, we would end
187 * up overwritting the contents of req->buf and this could confuse the
188 * gadget driver.
189 */
190 if (dwc->ep0_bounced && dep->number <= 1) {
184 dwc->ep0_bounced = false; 191 dwc->ep0_bounced = false;
185 192 unmap_after_complete = true;
186 usb_gadget_unmap_request_by_dev(dwc->sysdev, 193 } else {
187 &req->request, req->direction); 194 usb_gadget_unmap_request_by_dev(dwc->sysdev,
195 &req->request, req->direction);
196 }
188 197
189 trace_dwc3_gadget_giveback(req); 198 trace_dwc3_gadget_giveback(req);
190 199
@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
192 usb_gadget_giveback_request(&dep->endpoint, &req->request); 201 usb_gadget_giveback_request(&dep->endpoint, &req->request);
193 spin_lock(&dwc->lock); 202 spin_lock(&dwc->lock);
194 203
204 if (unmap_after_complete)
205 usb_gadget_unmap_request_by_dev(dwc->sysdev,
206 &req->request, req->direction);
207
195 if (dep->number > 1) 208 if (dep->number > 1)
196 pm_runtime_put(dwc->dev); 209 pm_runtime_put(dwc->dev);
197} 210}