aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2014-09-30 11:39:14 -0400
committerFelipe Balbi <balbi@ti.com>2014-10-23 10:55:35 -0400
commit36f84ffb45c75ff10442a9f8f2fd91dcf6c6f5dd (patch)
treeaadbdc58f32334172eb8b19f9b6c944618b7e74b /drivers/usb/dwc3
parent6856d30c6c0038dc0648009853533af3af6c5ba8 (diff)
usb: dwc3: ep0: fix Data Phase for transfer sizes aligned to wMaxPacketSize
According to Section 8.5.3.2 of the USB 2.0 specification, a USB device must terminate a Data Phase with either a short packet or a ZLP (if the previous transfer was a multiple of wMaxPacketSize). For reference, here's what the USB 2.0 specification, section 8.5.3.2 says: " 8.5.3.2 Variable-length Data Stage A control pipe may have a variable-length data phase in which the host requests more data than is contained in the specified data structure. When all of the data structure is returned to the host, the function should indicate that the Data stage is ended by returning a packet that is shorter than the MaxPacketSize for the pipe. If the data structure is an exact multiple of wMaxPacketSize for the pipe, the function will return a zero-length packet to indicate the end of the Data stage. " Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/ep0.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index a47cc1e97fae..711b23019d54 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -828,12 +828,19 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
828 828
829 dwc3_ep0_stall_and_restart(dwc); 829 dwc3_ep0_stall_and_restart(dwc);
830 } else { 830 } else {
831 /* 831 dwc3_gadget_giveback(ep0, r, 0);
832 * handle the case where we have to send a zero packet. This 832
833 * seems to be case when req.length > maxpacket. Could it be? 833 if (IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) &&
834 */ 834 ur->length && ur->zero) {
835 if (r) 835 int ret;
836 dwc3_gadget_giveback(ep0, r, 0); 836
837 dwc->ep0_next_event = DWC3_EP0_COMPLETE;
838
839 ret = dwc3_ep0_start_trans(dwc, epnum,
840 dwc->ctrl_req_addr, 0,
841 DWC3_TRBCTL_CONTROL_DATA);
842 WARN_ON(ret < 0);
843 }
837 } 844 }
838} 845}
839 846