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;