From 7cab70d1cb7298035429dd8953e521a31fc6770d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 12 Sep 2004 19:52:51 +0000 Subject: [PATCH] Improve error handling, especially in the DRI case. Do some FatalErrors instead of ErrorFs for things that are really bad, and put limits on some loops. Now, sometimes instead of hanging the entire system, we (mostly-) cleanly drop to console when the card has hung. --- hw/kdrive/ati/ati_dma.c | 12 ++++++++---- hw/kdrive/ati/ati_dma.h | 4 ++-- hw/kdrive/ati/ati_dri.c | 16 +++++++++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/hw/kdrive/ati/ati_dma.c b/hw/kdrive/ati/ati_dma.c index 2df8125e4..66aa48fad 100644 --- a/hw/kdrive/ati/ati_dma.c +++ b/hw/kdrive/ati/ati_dma.c @@ -41,7 +41,6 @@ extern CARD32 radeon_cp_microcode[][2]; extern CARD32 r200_cp_microcode[][2]; extern CARD32 r300_cp_microcode[][2]; -#if DEBUG_FIFO static void ATIDebugFifo(ATIScreenInfo *atis) { @@ -68,7 +67,6 @@ ATIDebugFifo(ATIScreenInfo *atis) MMIO_IN32(mmio, R128_REG_PC_NGUI_CTLSTAT)); } } -#endif static void ATIUploadMicrocode(ATIScreenInfo *atis) @@ -320,9 +318,15 @@ ATIWaitIdle(ATIScreenInfo *atis) int ret; int cmd = (atic->is_radeon ? DRM_RADEON_CP_IDLE : DRM_R128_CCE_IDLE); - do { + for (tries = 100; tries != 0; tries--) { ret = drmCommandNone(atic->drmFd, cmd); - } while (ret == -EBUSY); + if (ret != -EBUSY) + break; + } + if (tries == 0) { + ATIDebugFifo(atis); + FatalError("Timed out idling CCE (card hung)\n"); + } if (ret != 0) ErrorF("Failed to idle DMA, returned %d\n", ret); return; diff --git a/hw/kdrive/ati/ati_dma.h b/hw/kdrive/ati/ati_dma.h index ce30384c4..76c7733de 100644 --- a/hw/kdrive/ati/ati_dma.h +++ b/hw/kdrive/ati/ati_dma.h @@ -65,8 +65,8 @@ do { \ } while (0) #define END_DMA() do { \ if (__count != __total) \ - ErrorF("count != total (%d vs %d) at %s:%d\n", __count, \ - __total, __FILE__, __LINE__); \ + FatalError("count != total (%d vs %d) at %s:%d\n", \ + __count, __total, __FILE__, __LINE__); \ atis->indirectBuffer->used += __count * 4; \ } while (0) diff --git a/hw/kdrive/ati/ati_dri.c b/hw/kdrive/ati/ati_dri.c index d86802550..0c1881175 100644 --- a/hw/kdrive/ati/ati_dri.c +++ b/hw/kdrive/ati/ati_dri.c @@ -1048,7 +1048,7 @@ ATIDRIDMAStart(ScreenPtr pScreen) if (ret == 0) atis->dma_started = TRUE; else - ErrorF("%s: DMA start returned %d\n", __FUNCTION__, ret); + FatalError("%s: DMA start returned %d\n", __FUNCTION__, ret); } /* Attempts to idle the DMA engine and stops it. Note that the ioctl is the @@ -1105,7 +1105,7 @@ ATIDRIGetBuffer(ATIScreenInfo *atis) drmBufPtr buf = NULL; int indx = 0; int size = 0; - int ret; + int ret, tries; dma.context = atis->serverContext; dma.send_count = 0; @@ -1113,7 +1113,7 @@ ATIDRIGetBuffer(ATIScreenInfo *atis) dma.send_sizes = NULL; dma.flags = 0; dma.request_count = 1; - if (atis->atic->is_radeon) + if (atic->is_radeon) dma.request_size = RADEON_BUFFER_SIZE; else dma.request_size = R128_BUFFER_SIZE; @@ -1121,9 +1121,15 @@ ATIDRIGetBuffer(ATIScreenInfo *atis) dma.request_sizes = &size; dma.granted_count = 0; - do { + for (tries = 100; tries != 0; tries--) { ret = drmDMA(atic->drmFd, &dma); - } while (ret != 0); + if (ret != -EBUSY) + break; + } + if (tries == 0) + FatalError("Timeout fetching DMA buffer (card hung)\n"); + if (ret != 0) + FatalError("Error fetching DMA buffer: %d\n", ret); buf = &atis->buffers->list[indx]; buf->used = 0;