summaryrefslogtreecommitdiff
path: root/drivers/dahdi/voicebus
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-01-08 20:48:02 +0000
committerShaun Ruffell <sruffell@digium.com>2010-01-08 20:48:02 +0000
commit4d3c52e9fa00c3f18744a08a15df24907129effb (patch)
treed11dd39820dea77726af5f860967e904c8cf7b5d /drivers/dahdi/voicebus
parent6fb9c465e19b1eba4aa300de3f1e4902c2fb82b6 (diff)
voicebus: Make 'struct voicebus' embeddable by the client driver strutures.
In addition to making 'struct voicebus' embeddable, also add an 'voicebus_operations' structure. This was done so that a) remove the "context" pointer from struct voicebus, and also to show that handle_recieve/transmit are to be managed together. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@7778 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/voicebus')
-rw-r--r--drivers/dahdi/voicebus/GpakCust.c7
-rw-r--r--drivers/dahdi/voicebus/voicebus.c216
-rw-r--r--drivers/dahdi/voicebus/voicebus.h97
-rw-r--r--drivers/dahdi/voicebus/vpmadtreg.h3
4 files changed, 95 insertions, 228 deletions
diff --git a/drivers/dahdi/voicebus/GpakCust.c b/drivers/dahdi/voicebus/GpakCust.c
index b9964cf..bcf8bc7 100644
--- a/drivers/dahdi/voicebus/GpakCust.c
+++ b/drivers/dahdi/voicebus/GpakCust.c
@@ -54,7 +54,7 @@ static rwlock_t ifacelock;
static struct vpmadt032 *ifaces[MAX_DSP_CORES];
#define vpm_info(vpm, format, arg...) \
- dev_info(&voicebus_get_pci_dev(vpm->vb)->dev , format , ## arg)
+ dev_info(&vpm->vb->pdev->dev , format , ## arg)
static inline struct vpmadt032 *find_iface(const unsigned short dspid)
{
@@ -609,13 +609,12 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
res = vpmadtreg_loadfirmware(vb);
if (res) {
- struct pci_dev *pdev = voicebus_get_pci_dev(vb);
- dev_printk(KERN_INFO, &pdev->dev, "Failed to load the firmware.\n");
+ dev_info(&vb->pdev->dev, "Failed to load the firmware.\n");
return res;
}
vpm->curpage = -1;
- dev_info(&voicebus_get_pci_dev(vb)->dev, "Booting VPMADT032\n");
+ dev_info(&vb->pdev->dev, "Booting VPMADT032\n");
set_bit(VPM150M_SWRESET, &vpm->control);
while (test_bit(VPM150M_SWRESET, &vpm->control))
msleep(1);
diff --git a/drivers/dahdi/voicebus/voicebus.c b/drivers/dahdi/voicebus/voicebus.c
index b77ccdb..b7d4cc7 100644
--- a/drivers/dahdi/voicebus/voicebus.c
+++ b/drivers/dahdi/voicebus/voicebus.c
@@ -41,34 +41,18 @@
#include "vpmadtreg.h"
#include "GpakCust.h"
-#define INTERRUPT 0 /* Run the deferred processing in the ISR. */
-#define TASKLET 1 /* Run in a tasklet. */
-#define TIMER 2 /* Run in a system timer. */
-#define WORKQUEUE 3 /* Run in a workqueue. */
-#ifndef VOICEBUS_DEFERRED
-#define VOICEBUS_DEFERRED INTERRUPT
-#endif
#if VOICEBUS_DEFERRED == WORKQUEUE
#define VOICEBUS_ALLOC_FLAGS GFP_KERNEL
#else
#define VOICEBUS_ALLOC_FLAGS GFP_ATOMIC
#endif
-/* Define CONFIG_VOICEBUS_SYSFS to create some attributes under the pci device.
- * This is disabled by default because it hasn't been tested on the full range
- * of supported kernels. */
-#undef CONFIG_VOICEBUS_SYSFS
-
#if VOICEBUS_DEFERRED == TIMER
#if HZ < 1000
/* \todo Put an error message here. */
#endif
#endif
-/*! The number of descriptors in both the tx and rx descriptor ring. */
-#define DRING_SIZE (1 << 7) /* Must be a power of 2 */
-#define DRING_MASK (DRING_SIZE-1)
-
/* Interrupt status' reported in SR_CSR5 */
#define TX_COMPLETE_INTERRUPT 0x00000001
#define TX_STOPPED_INTERRUPT 0x00000002
@@ -119,90 +103,9 @@ struct voicebus_descriptor {
volatile __le32 container; /* Unused */
} __attribute__((packed));
-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;
- /*! 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;
-};
-
-/**
- * struct voicebus -
- *
- * @tx_idle_vbb:
- * @tx_idle_vbb_dma_addr:
- * @max_latency: Do not allow the driver to automatically insert more than this
- * much latency to the tdm stream by default.
- * @count: The number of non-idle buffers that we should be expecting.
- */
-struct voicebus {
- /*! The system pci device for this VoiceBus interface. */
- struct pci_dev *pdev;
- /*! Protects access to card registers and this structure. You should
- * hold this lock before accessing most of the members of this data
- * structure or the card registers. */
- spinlock_t lock;
- /*! The size of the transmit and receive buffers for this card. */
- u32 framesize;
- /*! The number of u32s in the host system cache line. */
- u8 cache_line_size;
- /*! Pool to allocate memory for the tx and rx descriptor rings. */
- struct voicebus_descriptor_list rxd;
- struct voicebus_descriptor_list txd;
- void *idle_vbb;
- dma_addr_t idle_vbb_dma_addr;
- /*! Level of debugging information. 0=None, 5=Insane. */
- atomic_t debuglevel;
- /*! Cache of buffer objects. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
- kmem_cache_t *buffer_cache;
-#else
- struct kmem_cache *buffer_cache;
-#endif
- /*! Base address of the VoiceBus interface registers in I/O space. */
- u32 iobase;
- /*! The IRQ line for this VoiceBus interface. */
- unsigned int irq;
-#if VOICEBUS_DEFERRED == WORKQUEUE
- /*! Process buffers in the context of this workqueue. */
- struct workqueue_struct *workqueue;
- /*! Work item to process tx / rx buffers. */
- struct work_struct workitem;
-#elif VOICEBUS_DEFERRED == TASKLET
- /*! Process buffers in the context of a tasklet. */
- struct tasklet_struct tasklet;
-#elif VOICEBUS_DEFERRED == TIMER
- /*! Process buffers in a timer without generating interrupts. */
- struct timer_list timer;
-#endif
- /*! Callback function to board specific module to process frames. */
- void (*handle_receive)(void *vbb, void *context);
- void (*handle_transmit)(void *vbb, void *context);
- /*! Data to pass to the receive and transmit callback. */
- void *context;
- struct completion stopped_completion;
- /*! Flags */
- unsigned long flags;
- /*! Number of tx buffers to queue up before enabling interrupts. */
- unsigned int min_tx_buffer_count;
- unsigned int max_latency;
- void *vbb_stash[DRING_SIZE];
- unsigned int count;
-};
-
static inline void handle_transmit(struct voicebus *vb, void *vbb)
{
- vb->handle_transmit(vbb, vb->context);
+ vb->ops->handle_transmit(vb, vbb);
}
/*
@@ -398,41 +301,6 @@ voicebus_set_minlatency(struct voicebus *vb, unsigned int ms)
}
EXPORT_SYMBOL(voicebus_set_minlatency);
-void
-voicebus_get_handlers(struct voicebus *vb, void **handle_receive,
- void **handle_transmit, void **context)
-{
- LOCKS_VOICEBUS;
- BUG_ON(!handle_receive);
- BUG_ON(!handle_transmit);
- BUG_ON(!context);
- VBLOCK(vb);
- *handle_receive = vb->handle_receive;
- *handle_transmit = vb->handle_transmit;
- *context = vb->context;
- VBUNLOCK(vb);
- return;
-}
-EXPORT_SYMBOL(voicebus_get_handlers);
-
-void
-voicebus_set_handlers(struct voicebus *vb,
- void (*handle_receive)(void *buffer, void *context),
- void (*handle_transmit)(void *buffer, void *context),
- void *context)
-{
- LOCKS_VOICEBUS;
- BUG_ON(!handle_receive);
- BUG_ON(!handle_transmit);
- BUG_ON(!context);
- VBLOCK(vb);
- vb->handle_receive = handle_receive;
- vb->handle_transmit = handle_transmit;
- vb->context = context;
- VBUNLOCK(vb);
-}
-EXPORT_SYMBOL(voicebus_set_handlers);
-
/*! \brief Returns the number of buffers currently on the transmit queue. */
int
voicebus_current_latency(struct voicebus *vb)
@@ -682,20 +550,6 @@ voicebus_alloc(struct voicebus *vb)
return vbb;
}
-void
-voicebus_setdebuglevel(struct voicebus *vb, u32 level)
-{
- atomic_set(&vb->debuglevel, level);
-}
-EXPORT_SYMBOL(voicebus_setdebuglevel);
-
-int
-voicebus_getdebuglevel(struct voicebus *vb)
-{
- return atomic_read(&vb->debuglevel);
-}
-EXPORT_SYMBOL(voicebus_getdebuglevel);
-
/*! \brief Resets the voicebus hardware interface. */
static int
vb_reset_interface(struct voicebus *vb)
@@ -717,7 +571,7 @@ vb_reset_interface(struct voicebus *vb)
pci_access = DEFAULT_PCI_ACCESS | (0x3 << 14);
break;
default:
- if (atomic_read(&vb->debuglevel)) {
+ if (*vb->debug) {
dev_warn(&vb->pdev->dev, "Host system set a cache "
"size of %d which is not supported. "
"Disabling memory write line and memory "
@@ -1024,10 +878,6 @@ voicebus_start(struct voicebus *vb)
void *vbb;
int ret;
- WARN_ON(pci_get_drvdata(vb->pdev) != vb);
- if (pci_get_drvdata(vb->pdev) != vb)
- return -EFAULT;
-
if (!vb_is_stopped(vb))
return -EBUSY;
@@ -1235,7 +1085,6 @@ voicebus_release(struct voicebus *vb)
kmem_cache_destroy(vb->buffer_cache);
release_region(vb->iobase, 0xff);
pci_disable_device(vb->pdev);
- kfree(vb);
}
EXPORT_SYMBOL(voicebus_release);
@@ -1518,7 +1367,7 @@ static void vb_deferred(struct voicebus *vb)
* the caller, but this needs more work.... */
while ((vb->vbb_stash[0] = vb_get_completed_rxb(vb))) {
if (vb->count) {
- vb->handle_receive(vb->vbb_stash[0], vb->context);
+ vb->ops->handle_receive(vb, vb->vbb_stash[0]);
--vb->count;
}
vb_submit_rxb(vb, vb->vbb_stash[0]);
@@ -1662,45 +1511,26 @@ vb_tasklet(unsigned long data)
* \todo Complete this description.
*/
int
-voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
- void (*handle_receive)(void *vbb, void *context),
- void (*handle_transmit)(void *vbb, void *context),
- void *context,
- u32 debuglevel,
- struct voicebus **vbp
- )
+voicebus_init(struct voicebus *vb, const char *board_name)
{
int retval = 0;
- struct voicebus *vb;
- BUG_ON(NULL == pdev);
+ BUG_ON(NULL == vb);
BUG_ON(NULL == board_name);
- BUG_ON(0 == framesize);
- BUG_ON(NULL == handle_receive);
- BUG_ON(NULL == handle_transmit);
+ BUG_ON(NULL == vb->ops);
+ BUG_ON(NULL == vb->pdev);
+ BUG_ON(0 == vb->framesize);
+ BUG_ON(NULL == vb->debug);
/* ----------------------------------------------------------------
Initialize the pure software constructs.
---------------------------------------------------------------- */
- *vbp = NULL;
- vb = kmalloc(sizeof(*vb), GFP_KERNEL);
- if (NULL == vb) {
- dev_dbg(&vb->pdev->dev, "Failed to allocate memory for "
- "voicebus interface.\n");
- retval = -ENOMEM;
- goto cleanup;
- }
- memset(vb, 0, sizeof(*vb));
- vb->pdev = pdev;
- pci_set_drvdata(pdev, vb);
- voicebus_setdebuglevel(vb, debuglevel);
vb->max_latency = VOICEBUS_DEFAULT_MAXLATENCY;
spin_lock_init(&vb->lock);
init_completion(&vb->stopped_completion);
set_bit(STOP, &vb->flags);
clear_bit(IN_DEFERRED_PROCESSING, &vb->flags);
- vb->framesize = framesize;
vb->min_tx_buffer_count = VOICEBUS_DEFAULT_LATENCY;
#if VOICEBUS_DEFERRED == WORKQUEUE
@@ -1725,10 +1555,6 @@ voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
vb->timer.data = (unsigned long)vb;
#endif
- vb->handle_receive = handle_receive;
- vb->handle_transmit = handle_transmit;
- vb->context = context;
-
/* \todo This cache should be shared by all instances supported by
* this driver. */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
@@ -1777,7 +1603,7 @@ voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
goto cleanup;
}
- if (pci_enable_device(pdev)) {
+ if (pci_enable_device(vb->pdev)) {
dev_err(&vb->pdev->dev, "Failed call to pci_enable_device.\n");
retval = -EIO;
goto cleanup;
@@ -1785,12 +1611,12 @@ voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
/* \todo This driver should be modified to use the memory mapped I/O
as opposed to IO space for portability and performance. */
- if (0 == (pci_resource_flags(pdev, 0)&IORESOURCE_IO)) {
+ if (0 == (pci_resource_flags(vb->pdev, 0)&IORESOURCE_IO)) {
dev_err(&vb->pdev->dev, "BAR0 is not IO Memory.\n");
retval = -EIO;
goto cleanup;
}
- vb->iobase = pci_resource_start(pdev, 0);
+ vb->iobase = pci_resource_start(vb->pdev, 0);
if (NULL == request_region(vb->iobase, 0xff, board_name)) {
dev_err(&vb->pdev->dev, "IO Registers are in use by another "
"module.\n");
@@ -1812,17 +1638,17 @@ voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
/* ----------------------------------------------------------------
Configure the hardware interface.
---------------------------------------------------------------- */
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (pci_set_dma_mask(vb->pdev, DMA_BIT_MASK(32))) {
release_region(vb->iobase, 0xff);
dev_warn(&vb->pdev->dev, "No suitable DMA available.\n");
goto cleanup;
}
- pci_set_master(pdev);
+ pci_set_master(vb->pdev);
vb_enable_io_access(vb);
#if VOICEBUS_DEFERRED != TIMER
- retval = request_irq(pdev->irq, vb_isr, DAHDI_IRQ_SHARED,
+ retval = request_irq(vb->pdev->irq, vb_isr, DAHDI_IRQ_SHARED,
board_name, vb);
if (retval) {
dev_warn(&vb->pdev->dev, "Failed to request interrupt line.\n");
@@ -1830,17 +1656,12 @@ voicebus_init(struct pci_dev *pdev, u32 framesize, const char *board_name,
}
#endif
- *vbp = vb;
return retval;
cleanup:
- if (NULL == vb)
- return retval;
#if VOICEBUS_DEFERRED == WORKQUEUE
-
if (vb->workqueue)
destroy_workqueue(vb->workqueue);
-
#elif VOICEBUS_DEFERRED == TASKLET
tasklet_kill(&vb->tasklet);
#endif
@@ -1864,7 +1685,6 @@ cleanup:
if (vb->pdev)
pci_disable_device(vb->pdev);
- kfree(vb);
WARN_ON(0 == retval);
return retval;
}
@@ -1879,12 +1699,6 @@ voicebus_get_pci_dev(struct voicebus *vb)
}
EXPORT_SYMBOL(voicebus_get_pci_dev);
-void *voicebus_pci_dev_to_context(struct pci_dev *pdev)
-{
- return ((struct voicebus *)pci_get_drvdata(pdev))->context;
-}
-EXPORT_SYMBOL(voicebus_pci_dev_to_context);
-
static spinlock_t loader_list_lock;
static struct list_head binary_loader_list;
diff --git a/drivers/dahdi/voicebus/voicebus.h b/drivers/dahdi/voicebus/voicebus.h
index 16768df..9cbacee 100644
--- a/drivers/dahdi/voicebus/voicebus.h
+++ b/drivers/dahdi/voicebus/voicebus.h
@@ -29,29 +29,86 @@
#ifndef __VOICEBUS_H__
#define __VOICEBUS_H__
+#define VOICEBUS_DEFAULT_LATENCY 3
+#define VOICEBUS_DEFAULT_MAXLATENCY 25
+#define VOICEBUS_MAXLATENCY_BUMP 6
+
+/*! The number of descriptors in both the tx and rx descriptor ring. */
+#define DRING_SIZE (1 << 7) /* Must be a power of 2 */
+#define DRING_MASK (DRING_SIZE-1)
+
+/* Define CONFIG_VOICEBUS_SYSFS to create some attributes under the pci device.
+ * This is disabled by default because it hasn't been tested on the full range
+ * of supported kernels. */
+#undef CONFIG_VOICEBUS_SYSFS
+
+#define INTERRUPT 0 /* Run the deferred processing in the ISR. */
+#define TASKLET 1 /* Run in a tasklet. */
+#define TIMER 2 /* Run in a system timer. */
+#define WORKQUEUE 3 /* Run in a workqueue. */
+
+#ifndef VOICEBUS_DEFERRED
+#define VOICEBUS_DEFERRED INTERRUPT
+#endif
+
struct voicebus;
-#define VOICEBUS_DEFAULT_LATENCY 3
-#define VOICEBUS_DEFAULT_MAXLATENCY 25
-#define VOICEBUS_MAXLATENCY_BUMP 6
+struct voicebus_operations {
+ void (*handle_receive)(struct voicebus *vb, void *vbb);
+ void (*handle_transmit)(struct voicebus *vb, void *vbb);
+};
+
+/**
+ * struct voicebus_descriptor_list - A single descriptor list.
+ */
+struct voicebus_descriptor_list {
+ struct voicebus_descriptor *desc;
+ unsigned int head;
+ unsigned int tail;
+ void *pending[DRING_SIZE];
+ dma_addr_t desc_dma;
+ atomic_t count;
+ unsigned int padding;
+};
+
+/**
+ * struct voicebus - Represents physical interface to voicebus card.
+ *
+ */
+struct voicebus {
+ struct pci_dev *pdev;
+ spinlock_t lock;
+ u32 framesize;
+ u8 cache_line_size;
+ struct voicebus_descriptor_list rxd;
+ struct voicebus_descriptor_list txd;
+ void *idle_vbb;
+ dma_addr_t idle_vbb_dma_addr;
+ const int *debug;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+ kmem_cache_t *buffer_cache;
+#else
+ struct kmem_cache *buffer_cache;
+#endif
+ u32 iobase;
+#if VOICEBUS_DEFERRED == WORKQUEUE
+ struct workqueue_struct *workqueue;
+ struct work_struct workitem;
+#elif VOICEBUS_DEFERRED == TASKLET
+ struct tasklet_struct tasklet;
+#elif VOICEBUS_DEFERRED == TIMER
+ struct timer_list timer;
+#endif
+ const struct voicebus_operations *ops;
+ struct completion stopped_completion;
+ unsigned long flags;
+ unsigned int min_tx_buffer_count;
+ unsigned int max_latency;
+ void *vbb_stash[DRING_SIZE];
+ unsigned int count;
+};
-void voicebus_setdebuglevel(struct voicebus *vb, u32 level);
-int voicebus_getdebuglevel(struct voicebus *vb);
-struct pci_dev *voicebus_get_pci_dev(struct voicebus *vb);
-void *voicebus_pci_dev_to_context(struct pci_dev *pdev);
-int voicebus_init(struct pci_dev* pdev, u32 framesize,
- const char *board_name,
- void (*handle_receive)(void *buffer, void *context),
- void (*handle_transmit)(void *buffer, void *context),
- void *context,
- u32 debuglevel,
- struct voicebus **vb_p);
-void voicebus_get_handlers(struct voicebus *vb, void **handle_receive,
- void **handle_transmit, void **context);
-void voicebus_set_handlers(struct voicebus *vb,
- void (*handle_receive)(void *buffer, void *context),
- void (*handle_transmit)(void *buffer, void *context),
- void *context);
+int voicebus_init(struct voicebus *vb, const char *board_name);
void voicebus_release(struct voicebus *vb);
int voicebus_start(struct voicebus *vb);
int voicebus_stop(struct voicebus *vb);
diff --git a/drivers/dahdi/voicebus/vpmadtreg.h b/drivers/dahdi/voicebus/vpmadtreg.h
index f3a5b8c..e6453d6 100644
--- a/drivers/dahdi/voicebus/vpmadtreg.h
+++ b/drivers/dahdi/voicebus/vpmadtreg.h
@@ -21,9 +21,6 @@
#ifndef __VPMADTREG_H__
#define __VPMADTREG_H__
-struct vpmadt032;
-struct voicebus;
-
struct vpmadt_loader {
struct module *owner;
struct list_head node;