summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-05-30 16:44:03 +0000
committerhselasky <hselasky@FreeBSD.org>2014-05-30 16:44:03 +0000
commit7acb98f193b8909173c34da13654c33e9dd6b625 (patch)
tree40a7045475eea7af97f8d6cddfedc339ec5a2554
parent725f0ee0bde88f4a9722f7b0f85cb4218ee26b68 (diff)
downloadFreeBSD-src-7acb98f193b8909173c34da13654c33e9dd6b625.zip
FreeBSD-src-7acb98f193b8909173c34da13654c33e9dd6b625.tar.gz
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
-rw-r--r--sys/dev/usb/controller/saf1761_otg.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/sys/dev/usb/controller/saf1761_otg.c b/sys/dev/usb/controller/saf1761_otg.c
index 012f9fd..d837593 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);
OpenPOWER on IntegriCloud