From 50f2fd15b6d23298eb0cafcc28da000814bebe55 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Thu, 13 Mar 2014 01:37:51 -0500 Subject: [PATCH] wcxb: Add diagnostic message if DMA retries are increasing when DEBUG is defined. There are some platforms where the DMA operation to the host does not complete within the required 50us. When this happens some versions of the firmware will issue a retry and increment the retry field in the descriptor status word. Now if this driver is configured in DEBUG mode, the presence of these retries will be printed to the kernel log as a potential troubleshooting aide. Internal-Issue-ID: DAHDI-1087 Signed-off-by: Shaun Ruffell --- drivers/dahdi/wcxb.c | 24 +++++++++++++++++++++++- drivers/dahdi/wcxb.h | 8 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/dahdi/wcxb.c b/drivers/dahdi/wcxb.c index 6e770fb..c456282 100644 --- a/drivers/dahdi/wcxb.c +++ b/drivers/dahdi/wcxb.c @@ -64,7 +64,7 @@ #define DESC_INT (1 << 1) #define DESC_IO_ERROR (1 << 30) #define DESC_OWN (1 << 31) -#define DESC_DEFAULT_STATUS 0xdeadbeef +#define DESC_DEFAULT_STATUS 0xdeadbe00 #define DMA_CHAN_SIZE 128 /* Echocan definitions */ @@ -352,11 +352,18 @@ static void _wcxb_reset_dring(struct wcxb *xb) BUG_ON(!hdesc); /* Set end of ring bit in last descriptor to force hw to loop around */ hdesc->control |= cpu_to_be32(DESC_EOR); +#ifdef DEBUG + xb->last_retry_count = 0; +#endif iowrite32be(xb->hw_dring_phys, xb->membase + TDM_DRING_ADDR); } static void wcxb_handle_dma(struct wcxb *xb) { +#ifdef DEBUG + bool did_retry_dma = false; + u8 retry; +#endif struct wcxb_meta_desc *mdesc; struct wcxb_hw_desc *tail = &(xb->hw_dring[xb->dma_tail]); @@ -380,6 +387,14 @@ static void wcxb_handle_dma(struct wcxb *xb) return; } +#ifdef DEBUG + retry = be32_to_cpu(tail->status) & 0xff; + if (xb->last_retry_count != retry) { + xb->last_retry_count = retry; + did_retry_dma = true; + } +#endif + mdesc = &xb->meta_dring[xb->dma_tail]; frame = mdesc->rx_buf_virt; @@ -399,6 +414,13 @@ static void wcxb_handle_dma(struct wcxb *xb) xb->dma_head = (xb->dma_head == xb->latency-1) ? 0 : xb->dma_head + 1; } + +#ifdef DEBUG + if (did_retry_dma) { + dev_info(&xb->pdev->dev, + "DMA retries detected: %d\n", xb->last_retry_count); + } +#endif } static irqreturn_t _wcxb_isr(int irq, void *dev_id) diff --git a/drivers/dahdi/wcxb.h b/drivers/dahdi/wcxb.h index c7d54d5..3a0f8d3 100644 --- a/drivers/dahdi/wcxb.h +++ b/drivers/dahdi/wcxb.h @@ -47,6 +47,11 @@ struct wcxb_operations { struct wcxb_meta_desc; struct wcxb_hw_desc; +/** + * struct wcxb - Interface to wcxb firmware. + * @last_retry_count: Running count of times firmware had to retry host DMA + * transaction. Debugging aide. + */ struct wcxb { struct pci_dev *pdev; spinlock_t lock; @@ -71,6 +76,9 @@ struct wcxb { dma_addr_t hw_dring_phys; struct dma_pool *pool; unsigned long framecount; +#ifdef DEBUG + u8 last_retry_count; +#endif }; extern int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode);