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: ->For request length < maxPayloadSize - DATA0, ->For maxPayloadSize < length < 2*maxPayloadSize - DATA0,DATA1 ->For 2*maxPayloadSize < length < 3*maxPayloadSize - DATA2, DATA1, DATA0. 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@xxxxxxxxxxxxxx> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index aea9a5b..b81547d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -854,8 +854,13 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; if (speed == USB_SPEED_HIGH) { - struct usb_ep *ep = &dep->endpoint; - trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1); + unsigned int maxp = usb_endpoint_maxp( + dep->endpoint.desc); + unsigned int rem = length % maxp; + unsigned int mult = (length / maxp) & 0x3; + + trb->size |= DWC3_TRB_SIZE_PCM1( + rem ? mult : mult - 1); } } else { trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html