aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/ep0.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index a6fc5c316743..f1e0a5eb0544 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -185,10 +185,29 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
185 req->epnum = dep->number; 185 req->epnum = dep->number;
186 186
187 list_add_tail(&req->list, &dep->request_list); 187 list_add_tail(&req->list, &dep->request_list);
188 dwc3_map_buffer_to_dma(req); 188 if (req->request.length == 0) {
189 ret = dwc3_ep0_start_trans(dwc, dep->number,
190 dwc->ctrl_req_addr, 0);
191 } else if ((req->request.length % dep->endpoint.maxpacket)
192 && (dep->number == 0)) {
193 dwc->ep0_bounced = true;
194
195 WARN_ON(req->request.length > dep->endpoint.maxpacket);
196
197 /*
198 * REVISIT in case request length is bigger than EP0
199 * wMaxPacketSize, we will need two chained TRBs to handle
200 * the transfer.
201 */
202 ret = dwc3_ep0_start_trans(dwc, dep->number,
203 dwc->ep0_bounce_addr, dep->endpoint.maxpacket);
204 } else {
205 dwc3_map_buffer_to_dma(req);
206
207 ret = dwc3_ep0_start_trans(dwc, dep->number,
208 req->request.dma, req->request.length);
209 }
189 210
190 ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
191 req->request.length);
192 if (ret < 0) { 211 if (ret < 0) {
193 list_del(&req->list); 212 list_del(&req->list);
194 dwc3_unmap_buffer_from_dma(req); 213 dwc3_unmap_buffer_from_dma(req);
@@ -655,8 +674,16 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
655 674
656 dwc3_trb_to_nat(dwc->ep0_trb, &trb); 675 dwc3_trb_to_nat(dwc->ep0_trb, &trb);
657 676
658 transferred = ur->length - trb.length; 677 if (dwc->ep0_bounced) {
659 ur->actual += transferred; 678 struct dwc3_ep *ep0 = dwc->eps[0];
679
680 transferred = min(ur->length, dep->endpoint.maxpacket - trb.length);
681 memcpy(ur->buf, dwc->ep0_bounce, transferred);
682 dwc->ep0_bounced = false;
683 } else {
684 transferred = ur->length - trb.length;
685 ur->actual += transferred;
686 }
660 687
661 if ((epnum & 1) && ur->actual < ur->length) { 688 if ((epnum & 1) && ur->actual < ur->length) {
662 /* for some reason we did not get everything out */ 689 /* for some reason we did not get everything out */