--- /dev/null
+From 40d829fb2ec636b6b4b0cc95e2546ab9aca04cc9 Mon Sep 17 00:00:00 2001
+From: Manu Gautam <mgautam@codeaurora.org>
+Date: Wed, 19 Jul 2017 17:07:10 +0530
+Subject: usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets
+
+From: Manu Gautam <mgautam@codeaurora.org>
+
+commit 40d829fb2ec636b6b4b0cc95e2546ab9aca04cc9 upstream.
+
+The PIDs for Isochronous data transfers are incorrect
+for high bandwidth IN endpoints when the request length
+is less than EP wMaxPacketSize.
+
+As per spec correct PIDs for ISOC data transfers are:
+
+1) For request length <= maxpacket
+ - DATA0,
+
+2) For maxpacket < length <= (2 * maxpacket)
+ - DATA1, DATA0
+
+3) For (2 * maxpacket) < length <= (3 * maxpacket)
+ - DATA2, DATA1, DATA0.
+
+But driver always sets PCM fields based on wMaxPacketSize
+due to which DATA2 happens even for small requests.
+
+Fix this by setting the PCM field of trb->size depending
+on request length rather than fixing it to the value
+depending on wMaxPacketSize.
+
+Ideally it shouldn't give any issues as dwc3 will send
+0-length packet for next IN token if host sends (even
+after receiving a short packet). Windows seems to ignore
+this but with MacOS frame loss observed when using f_uvc.
+
+Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+[b-liu@ti.com added following change for v4.9.]
+
+- unsigned int maxp = usb_endpoint_maxp(ep->desc);
++ unsigned int maxp;
++ maxp = usb_endpoint_maxp(ep->desc) & 0x07ff;
+
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -817,9 +817,42 @@ static void dwc3_prepare_one_trb(struct
+ if (!node) {
+ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+
++ /*
++ * USB Specification 2.0 Section 5.9.2 states that: "If
++ * there is only a single transaction in the microframe,
++ * only a DATA0 data packet PID is used. If there are
++ * two transactions per microframe, DATA1 is used for
++ * the first transaction data packet and DATA0 is used
++ * for the second transaction data packet. If there are
++ * three transactions per microframe, DATA2 is used for
++ * the first transaction data packet, DATA1 is used for
++ * the second, and DATA0 is used for the third."
++ *
++ * IOW, we should satisfy the following cases:
++ *
++ * 1) length <= maxpacket
++ * - DATA0
++ *
++ * 2) maxpacket < length <= (2 * maxpacket)
++ * - DATA1, DATA0
++ *
++ * 3) (2 * maxpacket) < length <= (3 * maxpacket)
++ * - DATA2, DATA1, DATA0
++ */
+ if (speed == USB_SPEED_HIGH) {
+ struct usb_ep *ep = &dep->endpoint;
+- trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1);
++ unsigned int mult = ep->mult - 1;
++ unsigned int maxp;
++
++ maxp = usb_endpoint_maxp(ep->desc) & 0x07ff;
++
++ if (length <= (2 * maxp))
++ mult--;
++
++ if (length <= maxp)
++ mult--;
++
++ trb->size |= DWC3_TRB_SIZE_PCM1(mult);
+ }
+ } else {
+ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;