summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2004-09-12 19:52:51 +0000
committerEric Anholt <anholt@freebsd.org>2004-09-12 19:52:51 +0000
commit7cab70d1cb7298035429dd8953e521a31fc6770d (patch)
tree69f2d27d6ee47a11777f8bca7f0d141a15247d66
parent0cd662ea80579c317d706ebe04971bb29d0f9b4f (diff)
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.
-rw-r--r--hw/kdrive/ati/ati_dma.c12
-rw-r--r--hw/kdrive/ati/ati_dma.h4
-rw-r--r--hw/kdrive/ati/ati_dri.c16
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;