From 4be86ee126a8a10a10f9b2181bf3f35a9d44cda8 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 30 May 2014 16:44:03 +0000 Subject: [PATCH] It appears the ISP/SAF1761 sometimes is busy when reading the status word of the PTD and simply returns a value of zero. Retry a few times before giving up. Sponsored by: DARPA, AFRL --- sys/dev/usb/controller/saf1761_otg.c | 40 +++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/sys/dev/usb/controller/saf1761_otg.c b/sys/dev/usb/controller/saf1761_otg.c index 012f9fd1017..d837593ece0 100644 --- a/sys/dev/usb/controller/saf1761_otg.c +++ b/sys/dev/usb/controller/saf1761_otg.c @@ -291,11 +291,23 @@ saf1761_host_channel_free(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t } static uint32_t -saf1761_peek_host_memory_le_4(struct saf1761_otg_softc *sc, uint32_t offset) +saf1761_peek_host_status_le_4(struct saf1761_otg_softc *sc, uint32_t offset) { - SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset); - SAF1761_90NS_DELAY(sc); /* read prefetch time is 90ns */ - return (SAF1761_READ_LE_4(sc, offset)); + uint32_t x = 0; + while (1) { + uint32_t retval; + + SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset); + SAF1761_90NS_DELAY(sc); /* read prefetch time is 90ns */ + retval = SAF1761_READ_LE_4(sc, offset); + if (retval != 0) + return (retval); + if (++x == 8) { + DPRINTF("STAUS is zero at offset 0x%x\n", offset); + break; + } + } + return (0); } static void @@ -415,9 +427,7 @@ saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td) if (td->channel < SOTG_HOST_CHANNEL_MAX) { pdt_addr = SOTG_PTD(td->channel); - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); - if (status == 0) - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); + status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3); DPRINTFN(5, "STATUS=0x%08x\n", status); @@ -487,9 +497,7 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t pdt_addr = SOTG_PTD(td->channel); - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); - if (status == 0) - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); + status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3); DPRINTFN(5, "STATUS=0x%08x\n", status); @@ -591,9 +599,7 @@ saf1761_host_bulk_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t pdt_addr = SOTG_PTD(td->channel); - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); - if (status == 0) - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); + status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3); DPRINTFN(5, "STATUS=0x%08x\n", status); @@ -681,9 +687,7 @@ saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t pdt_addr = SOTG_PTD(td->channel); - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); - if (status == 0) - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); + status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3); DPRINTFN(5, "STATUS=0x%08x\n", status); @@ -788,9 +792,7 @@ saf1761_host_intr_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t pdt_addr = SOTG_PTD(td->channel); - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); - if (status == 0) - status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3); + status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3); DPRINTFN(5, "STATUS=0x%08x\n", status);