From bb546db52a8fe3bc8cd221faa05055d80aa6989e Mon Sep 17 00:00:00 2001 From: Josh Dersch Date: Thu, 9 May 2019 07:26:55 +0200 Subject: [PATCH] Workaround for low-level DMA issue; give up waiting for DMA transfers if enough time passes. This works around an as-yet-unexplained PRU bug. --- 10.01_base/2_src/arm/unibusadapter.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/10.01_base/2_src/arm/unibusadapter.cpp b/10.01_base/2_src/arm/unibusadapter.cpp index 563f31b..641216d 100644 --- a/10.01_base/2_src/arm/unibusadapter.cpp +++ b/10.01_base/2_src/arm/unibusadapter.cpp @@ -652,10 +652,25 @@ void unibusadapter_c::dma_worker() // // Wait for the transfer to complete. // TODO: we're polling the mailbox; is there a more efficient way to do this? - timeout_c timeout; - while (request_DMA_active(nullptr)) + timeout_c timeout; + int retries = 0; + while (request_DMA_active(nullptr) && retries < 10000) { timeout.wait_us(50); + retries++; + } + + // + // TODO: this should not be necessary. There are rare occasions + // where it appears that the PRU dma transfer is interrupted + // but never clears the DMA active flag, so we hang in the loop above + // forever. + // Nothing to do in that case but give up. + // And log the issue. Should get to the root of this.. + // + if (retries == 10000) + { + INFO("dma timeout"); } if (dmaReq->GetUnibusControl() == UNIBUS_CONTROL_DATI)