[dahdi-commits] sruffell: branch linux/sruffell/dahdi-linux-chainedvb r7305 - /linux/team/sru...
SVN commits to the DAHDI project
dahdi-commits at lists.digium.com
Thu Oct 1 15:43:05 CDT 2009
Author: sruffell
Date: Thu Oct 1 15:42:56 2009
New Revision: 7305
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7305
Log:
wip: Printing when the recovery is done, removing ring implementation.
Modified:
linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c
Modified: linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=7305&r1=7304&r2=7305
==============================================================================
--- linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c Thu Oct 1 15:42:56 2009
@@ -65,10 +65,6 @@
#endif
#endif
-/* Uncomment this to use the previous method of chained descriptors. */
-#define USE_CHAINED_DESCRIPTORS
-
-#if defined(USE_CHAINED_DESCRIPTORS)
/*
* DLIST_SIZE should be large enough to handle the worst case interrupt
@@ -76,13 +72,6 @@
*/
#define DLIST_SIZE 128
#define MAX_LATENCY DLIST_SIZE
-#else
-
-/*! The number of descriptors in both the tx and rx descriptor ring. */
-#define DRING_SIZE (1 << 5) /* Must be a power of 2 */
-#define DRING_MASK (DRING_SIZE-1)
-#define MAX_LATENCY DRING_SIZE
-#endif
/* Interrupt status' reported in SR_CSR5 */
@@ -135,7 +124,6 @@
__le32 volatile buffer2;
} __attribute__((packed));
-#if defined(USE_CHAINED_DESCRIPTORS)
/**
* struct voicebus_chained_descriptor -
* @desc: Kernel virtual address of the descriptor.
@@ -167,27 +155,6 @@
unsigned int padding;
atomic_t count;
};
-#else
-struct voicebus_descriptor_list {
- /* Pointer to an array of descriptors to give to hardware. */
- struct voicebus_descriptor *desc;
- /* Read completed buffers from the head. */
- unsigned int head;
- /* Write ready buffers to the tail. */
- unsigned int tail;
- /* Array to save the kernel virtual address of pending buffers. */
- void *pending[DRING_SIZE];
- /* PCI Bus address of the descriptor list. */
- dma_addr_t desc_dma;
- /*! either DMA_FROM_DEVICE or DMA_TO_DEVICE */
- unsigned int direction;
- /*! The number of buffers currently submitted to the hardware. */
- atomic_t count;
- /*! The number of bytes to pad each descriptor for cache alignment. */
- unsigned int padding;
-};
-
-#endif
/**
* struct voicebus -
@@ -214,7 +181,6 @@
struct voicebus_descriptor_list txd;
void *idle_vbb;
dma_addr_t idle_vbb_dma_addr;
- int underruncount;
/*! Level of debugging information. 0=None, 5=Insane. */
atomic_t debuglevel;
/*! Cache of buffer objects. */
@@ -252,7 +218,6 @@
#define IN_DEFERRED_PROCESSING 3
#define STOP 4
#define STOPPED 5
-#define TX_RECOVERING 6
unsigned long flags;
/* \todo see about removing this... */
@@ -320,8 +285,8 @@
#endif
#endif
-#ifdef DBG
-static inline int
+#ifdef DEBUG
+static inline void
assert_in_vb_deferred(struct voicebus *vb)
{
assert(test_bit(IN_DEFERRED_PROCESSING, &vb->flags));
@@ -344,18 +309,6 @@
#define stop_vb_deferred(_x_) do {; } while (0)
#endif
-#if !defined(USE_CHAINED_DESCRIPTORS)
-static inline struct voicebus_descriptor *
-vb_descriptor(struct voicebus_descriptor_list *dl, int index)
-{
- struct voicebus_descriptor *d;
- d = (struct voicebus_descriptor *)((u8*)dl->desc +
- ((sizeof(*d) + dl->padding) * index));
- return d;
-}
-#endif
-
-#if defined(USE_CHAINED_DESCRIPTORS)
static struct voicebus_chained_descriptor *
get_next_descriptor(struct voicebus_descriptor_list *dl,
struct voicebus_chained_descriptor *d)
@@ -379,7 +332,7 @@
#define OWNED(_d_) (((_d_)->des0)&OWN_BIT)
#define SET_OWNED(_d_) do { wmb(); (_d_)->des0 |= OWN_BIT; wmb(); } while (0)
-static void vb_cleanup_descriptors(struct voicebus *vb,
+static void vb_cleanup_tx_descriptors(struct voicebus *vb,
struct voicebus_descriptor_list *dl)
{
struct voicebus_chained_descriptor *d;
@@ -387,7 +340,6 @@
list_for_each_entry(d, list, node) {
if (d->desc->buffer1 && (d->desc->buffer1 != vb->idle_vbb_dma_addr)) {
- dev_dbg(&vb->pdev->dev, "buffer1: %p\n", (void*)vb->idle_vbb_dma_addr);
BUG_ON(!d->pending);
voicebus_free(vb, d->pending);
}
@@ -399,32 +351,36 @@
dl->tail = list_entry(list->next, typeof(*d), node);
atomic_set(&dl->count, 0);
}
-#else
-static void
-vb_cleanup_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl)
-{
- unsigned int i;
- struct voicebus_descriptor *d;
-
- assert(vb_is_stopped(vb));
-
- for (i = 0; i < DRING_SIZE; ++i) {
- d = vb_descriptor(dl, i);
- if (d->buffer1) {
- d->buffer1 = 0;
- assert(dl->pending[i]);
- voicebus_free(vb, dl->pending[i]);
- dl->pending[i] = NULL;
+static void vb_cleanup_rx_descriptors(struct voicebus *vb,
+ struct voicebus_descriptor_list *dl)
+{
+ struct voicebus_chained_descriptor *d;
+ struct list_head *const list = &dl->list;
+
+ list_for_each_entry(d, list, node) {
+ if (d->desc->buffer1) {
+ BUG_ON(!d->pending);
+ voicebus_free(vb, d->pending);
+ d->desc->buffer1 = 0;
+ d->pending = 0;
}
- d->des0 &= ~OWN_BIT;
- }
- dl->head = 0;
- dl->tail = 0;
+ }
+ dl->head = list_entry(list->next, typeof(*d), node);
+ dl->tail = list_entry(list->next, typeof(*d), node);
atomic_set(&dl->count, 0);
}
-#endif
-
-#if defined(USE_CHAINED_DESCRIPTORS)
+
+static void vb_cleanup_descriptors(struct voicebus *vb,
+ struct voicebus_descriptor_list *dl)
+{
+ if (dl == &vb->txd)
+ vb_cleanup_tx_descriptors(vb, dl);
+ else
+ vb_cleanup_rx_descriptors(vb, dl);
+
+}
+
+
static void
vb_free_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl)
{
@@ -441,22 +397,7 @@
kfree(d);
}
}
-#else
-static void
-vb_free_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl)
-{
- if (NULL == dl->desc)
- return;
-
- vb_cleanup_descriptors(vb, dl);
- pci_free_consistent(
- vb->pdev,
- (sizeof(struct voicebus_descriptor)+dl->padding)*DRING_SIZE,
- dl->desc, dl->desc_dma);
-}
-#endif
-
-#if defined(USE_CHAINED_DESCRIPTORS)
+
static int
vb_initialize_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl,
u32 des1, unsigned int direction)
@@ -500,47 +441,6 @@
vb_free_descriptors(vb, dl);
return -ENOMEM;
}
-#else
-static int
-vb_initialize_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl,
- u32 des1, unsigned int direction)
-{
- int i;
- struct voicebus_descriptor *d;
- const u32 END_OF_RING = 0x02000000;
-
- assert(dl);
-
- /*
- * Add some padding to each descriptor to ensure that they are aligned
- * on host system cache-line boundaries, but only for the cache-line
- * sizes that we support.
- *
- */
- if ((0x08 == vb->cache_line_size) ||
- (0x10 == vb->cache_line_size) ||
- (0x20 == vb->cache_line_size)) {
- dl->padding = (vb->cache_line_size*sizeof(u32)) - sizeof(struct voicebus_descriptor);
- } else {
- dl->padding = 0;
- }
-
- dl->desc = pci_alloc_consistent(vb->pdev,
- (sizeof(*d) + dl->padding) * DRING_SIZE, &dl->desc_dma);
- if (!dl->desc)
- return -ENOMEM;
-
- memset(dl->desc, 0, (sizeof(*d) + dl->padding) * DRING_SIZE);
- for (i = 0; i < DRING_SIZE; ++i) {
- d = vb_descriptor(dl, i);
- d->des1 = des1;
- }
- d->des1 |= cpu_to_le32(END_OF_RING);
- dl->direction = direction;
- atomic_set(&dl->count, 0);
- return 0;
-}
-#endif
static int
vb_initialize_tx_descriptors(struct voicebus *vb)
@@ -562,8 +462,10 @@
}
list_for_each_entry(d, &vb->txd.list, node) {
+ /*
dev_dbg(&vb->pdev->dev, "desc: %p (next: %08x)\n",
(void*)d->desc, d->desc->buffer2);
+ */
d->desc->buffer1 = vb->idle_vbb_dma_addr;
d->pending = vb->idle_vbb;
SET_OWNED(d->desc);
@@ -863,15 +765,9 @@
/* ...disable jabber and the receive watchdog. */
vb_setctl(vb, 0x0078, 0x00000013);
-# if defined(USE_CHAINED_DESCRIPTORS)
/* Tell the card where the descriptors are in host memory. */
vb_setctl(vb, 0x0020, (u32)vb->txd.head->dma_addr);
vb_setctl(vb, 0x0018, (u32)vb->rxd.head->dma_addr);
-# else
- /* Tell the card where the descriptors are in host memory. */
- vb_setctl(vb, 0x0020, (u32)vb->txd.desc_dma);
- vb_setctl(vb, 0x0018, (u32)vb->rxd.desc_dma);
-# endif
reg = vb_getctl(vb, 0x00fc);
vb_setctl(vb, 0x00fc, (reg & ~0x7) | 0x7);
@@ -893,135 +789,6 @@
return ((reg&0x7) == 0x4) ? 0 : -EIO;
}
-
-#ifdef DBG
-static void
-dump_descriptor(struct voicebus *vb, volatile struct voicebus_descriptor *d)
-{
- VB_PRINTK(vb, DEBUG, "Displaying descriptor at address %08x\n", (unsigned int)d);
- VB_PRINTK(vb, DEBUG, " des0: %08x\n", d->des0);
- VB_PRINTK(vb, DEBUG, " des1: %08x\n", d->des1);
- VB_PRINTK(vb, DEBUG, " buffer1: %08x\n", d->buffer1);
- VB_PRINTK(vb, DEBUG, " container: %08x\n", d->container);
-}
-
-static void
-show_buffer(struct voicebus *vb, void *vbb)
-{
- int x;
- unsigned char *c;
- c = vbb;
- printk(KERN_DEBUG "Packet %d\n", count);
- printk(KERN_DEBUG "");
- for (x = 1; x <= vb->framesize; ++x) {
- printk("%02x ", c[x]);
- if (x % 16 == 0)
- printk("\n");
- }
- printk(KERN_DEBUG "\n\n");
-}
-#endif
-
-#if defined(USE_CHAINED_DESCRIPTORS)
-
-static int vb_chained_submit(struct voicebus *vb,
- struct voicebus_descriptor_list *dl, void *vbb)
-{
- struct voicebus_chained_descriptor *d;
-
- d = dl->tail;
-
- /* Do not overwrite a buffer that is still in progress. */
- if (unlikely(d->desc->buffer1 != vb->idle_vbb_dma_addr)) {
- WARN_ON(1);
- voicebus_free(vb, vbb);
- }
-
- dl->tail = get_next_descriptor(dl, d);
- d->pending = vbb;
- d->desc->buffer1 = dma_map_single(&vb->pdev->dev, vbb,
- vb->framesize, dl->direction);
-
- /* That's it until the hardware is done with it. */
- SET_OWNED(d->desc);
- atomic_inc(&dl->count);
- return -EFAULT;
-}
-
-#if 0
-static void* vb_chained_retrieve(struct voicebus *vb,
- struct voicebus_descriptor_list *dl)
-{
- struct voicebus_chained_descriptor *d;
- void *vbb;
-
- assert_in_vb_deferred(vb);
- d = dl->head;
- if (d->desc->buffer1 && !OWNED(d->desc)) {
- dma_unmap_single(&vb->pdev->dev, d->desc->buffer1,
- vb->framesize, dl->direction);
- vbb = d->pending;
- dl->head = get_next_descriptor(dl, d);
- d->desc->buffer1 = 0;
- atomic_dec(&dl->count);
- return vbb;
- } else {
- return NULL;
- }
-}
-#endif
-
-#else
-
-static inline int
-vb_submit(struct voicebus *vb, struct voicebus_descriptor_list *dl, void *vbb)
-{
- volatile struct voicebus_descriptor *d;
- unsigned int tail = dl->tail;
- assert_in_vb_deferred(vb);
-
- d = vb_descriptor(dl, tail);
-
- if (unlikely(d->buffer1)) {
- /* Do not overwrite a buffer that is still in progress. */
- WARN_ON(1);
- voicebus_free(vb, vbb);
- return -EBUSY;
- }
-
- dl->pending[tail] = vbb;
- dl->tail = (++tail) & DRING_MASK;
- d->buffer1 = dma_map_single(
- &vb->pdev->dev, vbb, vb->framesize, dl->direction);
- SET_OWNED(d); /* That's it until the hardware is done with it. */
- atomic_inc(&dl->count);
- return 0;
-}
-
-static inline void*
-vb_retrieve(struct voicebus *vb, struct voicebus_descriptor_list *dl)
-{
- volatile struct voicebus_descriptor *d;
- void *vbb;
- unsigned int head = dl->head;
- assert_in_vb_deferred(vb);
- d = vb_descriptor(dl, head);
- if (d->buffer1 && !OWNED(d)) {
- dma_unmap_single(&vb->pdev->dev, d->buffer1,
- vb->framesize, dl->direction);
- vbb = dl->pending[head];
- dl->head = (++head) & DRING_MASK;
- d->buffer1 = 0;
- atomic_dec(&dl->count);
- return vbb;
- } else {
- return NULL;
- }
-}
-
-#endif
-
-#if defined(USE_CHAINED_DESCRIPTORS)
int voicebus_transmit(struct voicebus *vb, void *vbb)
{
@@ -1057,33 +824,30 @@
* \brief Give a frame to the hardware to use for receiving.
*
*/
-static inline int vb_submit_rxb(struct voicebus *vb, void *vbb)
-{
- return vb_chained_submit(vb, &vb->rxd, vbb);
-}
-
-#else
-/*!
- * \brief Give a frame to the hardware to transmit.
- *
- */
-int
-voicebus_transmit(struct voicebus *vb, void *vbb)
-{
- return vb_submit(vb, &vb->txd, vbb);
-}
-EXPORT_SYMBOL(voicebus_transmit);
-
-/*!
- * \brief Give a frame to the hardware to use for receiving.
- *
- */
-static inline int
-vb_submit_rxb(struct voicebus *vb, void *vbb)
-{
- return vb_submit(vb, &vb->rxd, vbb);
-}
-#endif
+static inline void vb_submit_rxb(struct voicebus *vb, void *vbb)
+{
+ struct voicebus_descriptor_list *const dl = &vb->rxd;
+ struct voicebus_chained_descriptor *d;
+
+ d = dl->tail;
+
+ /* Do not overwrite a buffer that is still in progress. */
+ if (unlikely(d->desc->buffer1)) {
+ WARN_ON(1);
+ voicebus_free(vb, vbb);
+ return;
+ }
+
+ dl->tail = get_next_descriptor(dl, d);
+ d->pending = vbb;
+ d->desc->buffer1 = dma_map_single(&vb->pdev->dev, vbb,
+ vb->framesize, dl->direction);
+
+ /* That's it until the hardware is done with it. */
+ SET_OWNED(d->desc);
+ atomic_inc(&dl->count);
+ return;
+}
/*!
* \brief Remove the next completed transmit buffer (txb) from the tx
@@ -1098,25 +862,68 @@
*
* \return Pointer to buffer, or NULL if not available.
*/
-#if defined(USE_CHAINED_DESCRIPTORS)
+static void* vb_get_completed_txb(struct voicebus *vb)
+{
+ struct voicebus_chained_descriptor *d;
+ struct voicebus_descriptor_list *const dl = &vb->txd;
+ void *vbb;
+
+ assert_in_vb_deferred(vb);
+ d = dl->head;
+
+ /*
+ if (printk_ratelimit()) {
+ dev_dbg(&vb->pdev->dev, "buffer1: %08x idle: %08x\n",
+ d->desc->buffer1, (u32)vb->idle_vbb_dma_addr);
+ }
+ */
+
+ if (d->desc->buffer1 == vb->idle_vbb_dma_addr)
+ return NULL;
+
+ dma_unmap_single(&vb->pdev->dev, d->desc->buffer1,
+ vb->framesize, dl->direction);
+ vbb = d->pending;
+
+ d->desc->buffer1 = vb->idle_vbb_dma_addr;
+ SET_OWNED(d->desc);
+
+ dl->head = get_next_descriptor(dl, d);
+ atomic_dec(&dl->count);
+
+ return vbb;
+}
/**
- * recover_transmit_descriptor_list() -
- * @vb:
- * @d:
- *
- * Called when the driver determined that the hardware has transmitted one of
- * the "idle" buffers.
- *
- */
-static void
-start_tx_descriptor_list_recovery(struct voicebus *vb,
- struct voicebus_chained_descriptor *d)
+ * vb_check_softunderrun() -
+ *
+ * Returns true if we're processing the idle buffers, which means that the host
+ * was not able to keep up with the hardware. This differs from a normal
+ * underrun in that the interface chip on the board still has descriptors to
+ * transmit (just in this case, they are the idle buffers).
+ */
+static bool vb_check_softunderrun(const struct voicebus *vb)
+{
+ return !OWNED(vb->txd.head->desc);
+}
+
+/**
+ * vb_recover_tx_descriptor_list() -
+ *
+ * Called if the head pointer points to one of the idle buffers. This means
+ * that the host computer has failed to keep far enough ahead of the voicebus
+ * card. This function acks the completed idle descriptors and gets everything
+ * setup for normal operation again.
+ *
+ */
+static void vb_recover_tx_descriptor_list(struct voicebus *vb)
{
struct voicebus_descriptor_list *const dl = &vb->txd;
struct voicebus_chained_descriptor *next;
int count = 1;
- next = get_next_descriptor(dl, d);
+
+ next = get_next_descriptor(dl, dl->head);
+
while (!OWNED(next->desc)) {
next->desc->buffer1 = vb->idle_vbb_dma_addr;
next->pending = vb->idle_vbb;
@@ -1125,8 +932,7 @@
++count;
}
- vb->underruncount = count;
-
+ dev_info(&vb->pdev->dev, "Behind by %d descriptors.\n", count);
count = 8;
while (--count) {
next = get_next_descriptor(dl, next);
@@ -1137,60 +943,6 @@
vb->txd.head = next;
WARN_ON(!OWNED(get_prev_descriptor(&vb->txd, next)->desc));
- set_bit(TX_RECOVERING, &vb->flags);
-
- dev_dbg(&vb->pdev->dev, "Setting tail to %p (head: %p)\n",
- next->desc, vb->txd.head->desc);
-}
-
-static void stop_tx_descriptor_list_recovery(struct voicebus *vb)
-{
- clear_bit(TX_RECOVERING, &vb->flags);
-}
-
-static int tx_descriptor_list_recovering(struct voicebus *vb)
-{
- return test_bit(TX_RECOVERING, &vb->flags);
-}
-
-static void* vb_get_completed_txb(struct voicebus *vb)
-{
- struct voicebus_chained_descriptor *d;
- struct voicebus_descriptor_list *const dl = &vb->txd;
- void *vbb;
-
- assert_in_vb_deferred(vb);
- d = dl->head;
- /*
- if (printk_ratelimit()) {
- dev_dbg(&vb->pdev->dev, "buffer1: %08x idle: %08x\n",
- d->desc->buffer1, (u32)vb->idle_vbb_dma_addr);
- }
- */
-
- if (d->desc->buffer1 == vb->idle_vbb_dma_addr) {
- if (unlikely(!OWNED(d->desc))) {
- if (!tx_descriptor_list_recovering(vb))
- start_tx_descriptor_list_recovery(vb, d);
- SET_OWNED(d->desc);
- }
- return NULL;
- }
-
- dma_unmap_single(&vb->pdev->dev, d->desc->buffer1,
- vb->framesize, dl->direction);
- vbb = d->pending;
-
- d->desc->buffer1 = vb->idle_vbb_dma_addr;
- SET_OWNED(d->desc);
-
- dl->head = get_next_descriptor(dl, d);
- atomic_dec(&dl->count);
-
- if (unlikely(tx_descriptor_list_recovering(vb)))
- stop_tx_descriptor_list_recovery(vb);
-
- return vbb;
}
static void* vb_get_completed_rxb(struct voicebus *vb)
@@ -1203,7 +955,7 @@
d = dl->head;
if (!d->desc->buffer1 || OWNED(d->desc))
return NULL;
-
+ BUG_ON(!d->pending);
dma_unmap_single(&vb->pdev->dev, d->desc->buffer1,
vb->framesize, dl->direction);
vbb = d->pending;
@@ -1213,21 +965,6 @@
return vbb;
}
-#else
-
-static inline void *
-vb_get_completed_txb(struct voicebus *vb)
-{
- return vb_retrieve(vb, &vb->txd);
-}
-
-static inline void *
-vb_get_completed_rxb(struct voicebus *vb)
-{
- return vb_retrieve(vb, &vb->rxd);
-}
-#endif
-
/*!
* \brief Free a buffer for reuse.
*
@@ -1320,11 +1057,7 @@
int i;
void *vbb;
int ret;
-#if defined(USE_CHAINED_DESCRIPTORS)
const int MAX_DESCRIPTORS = DLIST_SIZE;
-#else
- const int MAX_DESCRIPTORS = DRING_SIZE;
-#endif
assert(!in_interrupt());
@@ -1606,11 +1339,8 @@
vb->handle_transmit(vbb, vb->context);
}
- if (unlikely(vb->underruncount)) {
- dev_dbg(&vb->pdev->dev, "underrun: %d\n", vb->underruncount);
- __vb_increase_latency(vb, vb->underruncount);
- vb->underruncount = 0;
- }
+ if (unlikely(vb_check_softunderrun(vb)))
+ vb_recover_tx_descriptor_list(vb);
if (unlikely(underrun)) {
vb_rx_demand_poll(vb);
@@ -1624,6 +1354,7 @@
}
stop_vb_deferred(vb);
+ /* dev_dbg(&vb->pdev->dev, "Leaving %s\n", __func__); */
}
More information about the dahdi-commits
mailing list