WORKAROUND: usb: gadget: composite: Set usb_req len with additional bytes 39/314839/5 accepted/tizen/unified/toolchain/20240812.132224 accepted/tizen/unified/x/20240723.043551 accepted/tizen/unified/x/asan/20240813.230510
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 22 Jul 2024 03:58:56 +0000 (12:58 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 22 Jul 2024 07:05:19 +0000 (16:05 +0900)
If the usb gadget of cdns3 drd device is used, set ep0 usb_req
length with additional 2 bytes for zlp with exactly multiple of
max packet length of the ep0 to resolve the cdns3 specific ep0
enumeration issue.

The cdns3 has a known issue that zlp is missed when its usb_req
size is exactly multiple of max packet length, 64 and it is not
handled.

In the visionfive2 board with cdns3 in its usb c port, board serial
number is exactly 31 characters and including null character,
utf-8 string length is 64, so the cdns3 zlp issue is occured
during usb sdb enumeration for iSerial usb string descriptor.

If it is fixed from cdns3 driver, this workaround can be reverted.

Change-Id: I751c334d03bcf8fe94aa9f4b0367070bfc47c539
Ref: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1289171/am6411-no-usb-gadget-zlp-for-cdns3_ep0_run_transfer
Suggested-by: Dongwoo Lee <dwoo08.lee@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
drivers/usb/gadget/composite.c

index 0ace45b..8916ab4 100644 (file)
@@ -2277,6 +2277,15 @@ check_value:
                req->length = value;
                req->context = cdev;
                req->zero = value < w_length;
+
+#if defined(CONFIG_USB_CDNS3_GADGET)
+               /* workaround for visionfive2 cdns3 dual role device */
+               if (req->zero) {
+                       if (value % cdev->gadget->ep0->maxpacket == 0)
+                               req->length += 2;
+               }
+#endif
+
                value = composite_ep0_queue(cdev, req, GFP_ATOMIC);
                if (value < 0) {
                        DBG(cdev, "ep_queue --> %d\n", value);