From 663d846cf3867a6aab40b981b4755a1f62a64dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Sat, 12 Jun 2021 13:12:44 +0200 Subject: [PATCH] Sansa Connect: Disable endpoint double buffering Disabling double buffering results in expected CPPI TX behaviour. With the double buffering enabled, sending single ZLP resulted in two ZLPs being available. The two ZLPs is problematic because this causes Windows to reset USB device after failed SCSI command. The problematic sequence on Windows 10 was as follows: * Host sends SCSI Mode Sense(6) Informational Exceptions Control(0x1C) * Device sends ZLP * Device sends command failed response With endpoint double buffering enabled the ZLP was read twice by host. As host was expecting command response on the second read (and got ZLP instead), host attempts recovery by resetting USB device and retrying. Change-Id: I64e95998f429ffb7b14143d956b1f29d20218d14 --- .../arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c index 00c9c2b80d..5563a40814 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c @@ -393,12 +393,18 @@ static void tnetv_init_endpoints(void) epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn)); epStartAddr.val = tnetv_usb_reg_read(TNETV_USB_EPx_ADR(epn)); - epCfg.f.in_dbl_buf = 1; + /* Linux kernel enables dbl buf for both IN and OUT. + * For IN this is problematic when tnetv_cppi_send() is called + * to send single ZLP, it will actually send two ZLPs. + * Disable the dbl buf here as datasheet is not available and + * this results in working mass storage on Windows 10. + */ + epCfg.f.in_dbl_buf = 0; epCfg.f.in_toggle_rst = 1; epCfg.f.in_ack_int = 0; epCfg.f.in_stall = 0; epCfg.f.in_nak_int = 0; - epCfg.f.out_dbl_buf = 1; + epCfg.f.out_dbl_buf = 0; epCfg.f.out_toggle_rst = 1; epCfg.f.out_ack_int = 0; epCfg.f.out_stall = 0;