This patch fixes configuring FIFO for one-directional endpoints which have
either RX or TX queue and therefore only one FIFO.

Without this patch if FIFO size was zero then idx was incorrectly
calculated (expr. ffs(0)-1 is not zero) and size overflowed in fifosz
register. This register uses has only 4 bits for FIFO size.

This patch is fixing it by setting zero size and zero address when
particular endpoint does not use FIFO.

This issue caused loose of packets on USB bus in both directions and
basically usbtty was unusable.

Signed-off-by: Pali Rohár <p...@kernel.org>
---
 drivers/usb/musb/musb_core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index cc6dc3839d..75ccd4819d 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -49,8 +49,8 @@ void musb_start(void)
 #else
 # define config_fifo(dir, idx, addr) \
        do { \
-               writeb(idx, &musbr->dir##fifosz); \
-               writew(fifoaddr >> 3, &musbr->dir##fifoadd); \
+               writeb((idx) & 0xF, &musbr->dir##fifosz); \
+               writew((idx) ? ((addr) >> 3) : 0, &musbr->dir##fifoadd); \
        } while (0)
 #endif
 
@@ -73,7 +73,7 @@ void musb_configure_ep(const struct musb_epinfo *epinfo, u8 
cnt)
        while (cnt--) {
                /* prepare fifosize to write to register */
                fifosize = epinfo->epsize >> 3;
-               idx = ffs(fifosize) - 1;
+               idx = fifosize ? (ffs(fifosize) - 1) : 0;
 
                writeb(epinfo->epnum, &musbr->index);
                if (epinfo->epdir) {
-- 
2.20.1

Reply via email to