usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets
authorManu Gautam <mgautam@codeaurora.org>
Wed, 19 Jul 2017 11:37:10 +0000 (17:07 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Oct 2017 15:21:39 +0000 (17:21 +0200)
commit480fd4fb29c596bf669a864ceda00dec7f0c2134
treee4453390d184def3b78278497342efad798bc869
parent9b9843154cd1d6916f49a1a95c9b49c7cee9c477
usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets

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