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 <sruffell@digium.com>
This commit is contained in:
parent
665bf9feb6
commit
50f2fd15b6
@ -64,7 +64,7 @@
|
|||||||
#define DESC_INT (1 << 1)
|
#define DESC_INT (1 << 1)
|
||||||
#define DESC_IO_ERROR (1 << 30)
|
#define DESC_IO_ERROR (1 << 30)
|
||||||
#define DESC_OWN (1 << 31)
|
#define DESC_OWN (1 << 31)
|
||||||
#define DESC_DEFAULT_STATUS 0xdeadbeef
|
#define DESC_DEFAULT_STATUS 0xdeadbe00
|
||||||
#define DMA_CHAN_SIZE 128
|
#define DMA_CHAN_SIZE 128
|
||||||
|
|
||||||
/* Echocan definitions */
|
/* Echocan definitions */
|
||||||
@ -352,11 +352,18 @@ static void _wcxb_reset_dring(struct wcxb *xb)
|
|||||||
BUG_ON(!hdesc);
|
BUG_ON(!hdesc);
|
||||||
/* Set end of ring bit in last descriptor to force hw to loop around */
|
/* Set end of ring bit in last descriptor to force hw to loop around */
|
||||||
hdesc->control |= cpu_to_be32(DESC_EOR);
|
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);
|
iowrite32be(xb->hw_dring_phys, xb->membase + TDM_DRING_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wcxb_handle_dma(struct wcxb *xb)
|
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_meta_desc *mdesc;
|
||||||
struct wcxb_hw_desc *tail = &(xb->hw_dring[xb->dma_tail]);
|
struct wcxb_hw_desc *tail = &(xb->hw_dring[xb->dma_tail]);
|
||||||
|
|
||||||
@ -380,6 +387,14 @@ static void wcxb_handle_dma(struct wcxb *xb)
|
|||||||
return;
|
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];
|
mdesc = &xb->meta_dring[xb->dma_tail];
|
||||||
frame = mdesc->rx_buf_virt;
|
frame = mdesc->rx_buf_virt;
|
||||||
|
|
||||||
@ -399,6 +414,13 @@ static void wcxb_handle_dma(struct wcxb *xb)
|
|||||||
xb->dma_head =
|
xb->dma_head =
|
||||||
(xb->dma_head == xb->latency-1) ? 0 : xb->dma_head + 1;
|
(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)
|
static irqreturn_t _wcxb_isr(int irq, void *dev_id)
|
||||||
|
@ -47,6 +47,11 @@ struct wcxb_operations {
|
|||||||
struct wcxb_meta_desc;
|
struct wcxb_meta_desc;
|
||||||
struct wcxb_hw_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 wcxb {
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
@ -71,6 +76,9 @@ struct wcxb {
|
|||||||
dma_addr_t hw_dring_phys;
|
dma_addr_t hw_dring_phys;
|
||||||
struct dma_pool *pool;
|
struct dma_pool *pool;
|
||||||
unsigned long framecount;
|
unsigned long framecount;
|
||||||
|
#ifdef DEBUG
|
||||||
|
u8 last_retry_count;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode);
|
extern int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode);
|
||||||
|
Loading…
Reference in New Issue
Block a user