]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 13:39:23 +0000 (15:39 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 13:39:23 +0000 (15:39 +0200)
added patches:
usb-dwc3-gadget-correct-isoc-data-pids-for-short-packets.patch

queue-4.9/series
queue-4.9/usb-dwc3-gadget-correct-isoc-data-pids-for-short-packets.patch [new file with mode: 0644]

index f88cbebcd865e4e409a21cc7b14d4b6ddf1effb9..0afae36219a6713658311a13a4955b10002174b9 100644 (file)
@@ -48,3 +48,4 @@ regulator-core-resolve-supplies-before-disabling-unused-regulators.patch
 btmrvl-avoid-double-disable_irq-race.patch
 edac-mce_amd-print-ipid-and-syndrome-on-a-separate-line.patch
 cpufreq-cppc-add-acpi_processor-dependency.patch
+usb-dwc3-gadget-correct-isoc-data-pids-for-short-packets.patch
diff --git a/queue-4.9/usb-dwc3-gadget-correct-isoc-data-pids-for-short-packets.patch b/queue-4.9/usb-dwc3-gadget-correct-isoc-data-pids-for-short-packets.patch
new file mode 100644 (file)
index 0000000..392db94
--- /dev/null
@@ -0,0 +1,97 @@
+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;