[svn-commits] fjoe: freebsd/trunk r8311 - in /freebsd/trunk/drivers/dahdi: ./ voicebus/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Mar 9 13:42:18 CST 2010
Author: fjoe
Date: Tue Mar 9 13:42:14 2010
New Revision: 8311
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8311
Log:
Initial voicebus FreeBSD port.
Modified:
freebsd/trunk/drivers/dahdi/adt_lec.c
freebsd/trunk/drivers/dahdi/voicebus/GpakCust.c
freebsd/trunk/drivers/dahdi/voicebus/GpakCust.h
freebsd/trunk/drivers/dahdi/voicebus/voicebus.c
freebsd/trunk/drivers/dahdi/voicebus/voicebus.h
freebsd/trunk/drivers/dahdi/voicebus/voicebus_net.c
Modified: freebsd/trunk/drivers/dahdi/adt_lec.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/adt_lec.c?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/adt_lec.c (original)
+++ freebsd/trunk/drivers/dahdi/adt_lec.c Tue Mar 9 13:42:14 2010
@@ -25,7 +25,11 @@
#ifndef _ADT_LEC_C
#define _ADT_LEC_C
+#if defined(__FreeBSD__)
+#include <sys/ctype.h>
+#else /* !__FreeBSD__ */
#include <linux/ctype.h>
+#endif /* !__FreeBSD__ */
static inline void adt_lec_init_defaults(struct adt_lec_params *params, __u32 tap_length)
{
Modified: freebsd/trunk/drivers/dahdi/voicebus/GpakCust.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/voicebus/GpakCust.c?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/voicebus/GpakCust.c (original)
+++ freebsd/trunk/drivers/dahdi/voicebus/GpakCust.c Tue Mar 9 13:42:14 2010
@@ -30,6 +30,10 @@
* this program for more details.
*/
+#if defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/bus.h>
+#else /* !__FreeBSD__ */
#include <linux/version.h>
#include <linux/types.h>
#include <linux/delay.h>
@@ -39,6 +43,7 @@
#else
#include <asm/semaphore.h>
#endif
+#endif /* !__FreeBSD__ */
#include <dahdi/kernel.h>
#include <dahdi/user.h>
@@ -82,12 +87,17 @@
if (unlikely(!cmd))
return NULL;
memset(cmd, 0, sizeof(*cmd));
+#if defined(__FreeBSD__)
+ init_completion(&cmd->complete);
+#endif
} else {
cmd = list_entry(vpm->free_cmds.next, struct vpmadt032_cmd, node);
list_del_init(&cmd->node);
spin_unlock_irqrestore(&vpm->list_lock, flags);
}
+#if !defined(__FreeBSD__)
init_completion(&cmd->complete);
+#endif
return cmd;
}
@@ -390,7 +400,7 @@
* the hardware can take some time while messages are sent to the VPMADT032
* module and the driver waits for the responses.
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+#if !defined(__FreeBSD__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
static void vpmadt032_bh(void *data)
{
struct vpmadt032 *vpm = data;
@@ -535,7 +545,7 @@
INIT_LIST_HEAD(&vpm->free_cmds);
INIT_LIST_HEAD(&vpm->pending_cmds);
INIT_LIST_HEAD(&vpm->active_cmds);
- sema_init(&vpm->sem, 1);
+ _sema_init(&vpm->sem, 1);
vpm->curpage = 0x80;
vpm->dspid = -1;
@@ -660,7 +670,7 @@
goto failed_exit;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#if !defined(__FreeBSD__) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
INIT_WORK(&vpm->work, vpmadt032_bh, vpm);
#else
INIT_WORK(&vpm->work, vpmadt032_bh);
@@ -703,7 +713,7 @@
unsigned long flags;
struct vpmadt032_cmd *cmd;
struct change_order *order;
- LIST_HEAD(local_list);
+ _LIST_HEAD(local_list);
BUG_ON(!vpm);
BUG_ON(!vpm->wq);
@@ -720,6 +730,7 @@
while (!list_empty(&local_list)) {
cmd = list_entry(local_list.next, struct vpmadt032_cmd, node);
list_del(&cmd->node);
+ destroy_completion(&cmd->complete);
kfree(cmd);
}
@@ -737,6 +748,9 @@
write_lock(&ifacelock);
ifaces[vpm->dspid] = NULL;
write_unlock(&ifacelock);
+ _sema_destroy(&vpm->sem);
+ spin_lock_destroy(&vpm->change_list_lock);
+ spin_lock_destroy(&vpm->list_lock);
kfree(vpm);
}
EXPORT_SYMBOL(vpmadt032_free);
Modified: freebsd/trunk/drivers/dahdi/voicebus/GpakCust.h
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/voicebus/GpakCust.h?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/voicebus/GpakCust.h (original)
+++ freebsd/trunk/drivers/dahdi/voicebus/GpakCust.h Tue Mar 9 13:42:14 2010
@@ -36,9 +36,15 @@
#ifndef _GPAKCUST_H /* prevent multiple inclusion */
#define _GPAKCUST_H
+#if defined(__FreeBSD__)
+#include <dahdi/compat/types.h>
+#include <dahdi/compat/list.h>
+#include <dahdi/compat/bsd.h>
+#else /* !__FreeBSD__ */
#include <linux/device.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
+#endif /* !__FreeBSD__ */
#include "gpakenum.h"
#include "adt_lec.h"
Modified: freebsd/trunk/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/voicebus/voicebus.c (original)
+++ freebsd/trunk/drivers/dahdi/voicebus/voicebus.c Tue Mar 9 13:42:14 2010
@@ -27,6 +27,22 @@
* this program for more details.
*/
+#if defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/libkern.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <vm/uma.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <machine/resource.h>
+#else /* !__FreeBSD__ */
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/pci.h>
@@ -36,6 +52,7 @@
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/sched.h>
+#endif /* !__FreeBSD__ */
#include <dahdi/kernel.h>
#include "voicebus.h"
@@ -43,7 +60,7 @@
#include "vpmadtreg.h"
#include "GpakCust.h"
-#if VOICEBUS_DEFERRED == TIMER
+#if 0 && VOICEBUS_DEFERRED == TIMER
#if HZ < 1000
/* \todo Put an error message here. */
#endif
@@ -94,12 +111,152 @@
#define OWN_BIT (1 << 31)
+#if defined(__FreeBSD__)
+#define in_interrupt() 0
+#define barrier()
+
+#define DMA_FROM_DEVICE 0
+#define DMA_TO_DEVICE 1
+
+static void
+vb_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ uint32_t *paddr = arg;
+ *paddr = segs->ds_addr;
+}
+
+static int
+vb_dma_allocate(int size, bus_dma_tag_t *ptag, bus_dmamap_t *pmap, void **pvaddr, uint32_t *ppaddr)
+{
+ int res;
+
+ res = bus_dma_tag_create(NULL, 8, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ size, 1, size, BUS_DMA_ALLOCNOW, NULL, NULL, ptag);
+ if (res)
+ return res;
+
+ res = bus_dmamem_alloc(*ptag, pvaddr, BUS_DMA_NOWAIT | BUS_DMA_ZERO, pmap);
+ if (res) {
+ bus_dma_tag_destroy(*ptag);
+ *ptag = NULL;
+ return res;
+ }
+
+ res = bus_dmamap_load(*ptag, *pmap, *pvaddr, size, vb_dma_map_addr, ppaddr, 0);
+ if (res) {
+ bus_dmamem_free(*ptag, *pvaddr, *pmap);
+ *pvaddr = NULL;
+
+ bus_dmamap_destroy(*ptag, *pmap);
+ *pmap = NULL;
+
+ bus_dma_tag_destroy(*ptag);
+ *ptag = NULL;
+ return res;
+ }
+
+ return 0;
+}
+
+static void
+vb_dma_free(bus_dma_tag_t *ptag, bus_dmamap_t *pmap, void **pvaddr, uint32_t *ppaddr)
+{
+ if (*ppaddr != 0) {
+ bus_dmamap_unload(*ptag, *pmap);
+ *ppaddr = 0;
+ }
+ if (*pvaddr != NULL) {
+ bus_dmamem_free(*ptag, *pvaddr, *pmap);
+ *pvaddr = NULL;
+
+ bus_dmamap_destroy(*ptag, *pmap);
+ *pmap = NULL;
+ }
+ if (*ptag != NULL) {
+ bus_dma_tag_destroy(*ptag);
+ *ptag = NULL;
+ }
+}
+
+struct vbb *
+voicebus_alloc(struct voicebus *vb, int malloc_flags)
+{
+ struct vbb *vbb;
+ int res;
+ bus_dmamap_t dma_map;
+
+ res = bus_dmamem_alloc(vb->vbb_dma_tag, (void **) &vbb, BUS_DMA_NOWAIT | BUS_DMA_ZERO, &dma_map);
+ if (res)
+ return NULL;
+ vbb->dma_map = dma_map;
+
+ return vbb;
+}
+
+void
+voicebus_free(struct voicebus *vb, struct vbb *vbb)
+{
+ bus_dmamap_t dma_map = vbb->dma_map;
+
+ bus_dmamem_free(vb->vbb_dma_tag, vbb, dma_map);
+ bus_dmamap_destroy(vb->vbb_dma_tag, dma_map);
+}
+
+static __le32
+voicebus_map(struct voicebus *vb, struct vbb *vbb, int direction)
+{
+ int res;
+
+ res = bus_dmamap_load(vb->vbb_dma_tag, vbb->dma_map, vbb, sizeof(*vbb),
+ vb_dma_map_addr, &vbb->paddr, 0);
+ if (res) {
+ if (printk_ratelimit())
+ dev_err(&vb->pdev->dev, "Can't load DMA map\n");
+ return 0;
+ }
+ return vbb->paddr;
+}
+
+static void
+voicebus_unmap(struct voicebus *vb, struct vbb *vbb, int direction)
+{
+ bus_dmamap_unload(vb->vbb_dma_tag, vbb->dma_map);
+}
+#else /* !__FreeBSD__ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
kmem_cache_t *voicebus_vbb_cache;
#else
struct kmem_cache *voicebus_vbb_cache;
#endif
-EXPORT_SYMBOL(voicebus_vbb_cache);
+
+struct vbb *
+voicebus_alloc(struct voicebus *vb, int malloc_flags)
+{
+ return kmem_cache_alloc(voicebus_vbb_cache, GFP_KERNEL);
+}
+EXPORT_SYMBOL(voicebus_alloc);
+
+void
+voicebus_free(struct voicebus *vb, struct vbb *vbb)
+{
+ kmem_cache_free(voicebus_vbb_cache, vbb);
+}
+EXPORT_SYMBOL(voicebus_free);
+
+static __le32
+voicebus_map(struct voicebus *vb, struct vbb *vbb, int direction)
+{
+ vbb->paddr = dma_map_single(&vb->pdev->dev, vbb->data, sizeof(vbb->data), direction);
+ return vbb->paddr;
+}
+
+static void
+voicebus_unmap(struct voicebus *vb, struct vbb *vbb, int direction)
+{
+ dma_unmap_single(&vb->pdev->dev, vbb->paddr, VOICEBUS_SFRAME_SIZE, direction);
+}
+#endif /* !__FreeBSD__ */
/* In memory structure shared by the host and the adapter. */
struct voicebus_descriptor {
@@ -126,7 +283,7 @@
* matter if the deferred processing is running inside the interrupt handler,
* in a tasklet, or in a workqueue.
*/
-#if VOICEBUS_DEFERRED == WORKQUEUE
+#if 0 && VOICEBUS_DEFERRED == WORKQUEUE
/*
* When the deferred processing is running in a workqueue, voicebus will never
* be locked from the context of the interrupt handler, and therefore we do
@@ -158,8 +315,7 @@
}
static int
-vb_initialize_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl,
- u32 des1, unsigned int direction)
+vb_initialize_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl, u32 des1)
{
int i;
struct voicebus_descriptor *d;
@@ -174,11 +330,19 @@
* cache-line sizes that we support.
*
*/
+#if defined(__FreeBSD__)
+ if ((cache_line_size = pci_read_config(vb->pdev->dev, 0x0c, 1)) == 0) {
+ dev_err(&vb->pdev->dev, "Failed read of cache line "
+ "size from PCI configuration space.\n");
+ return EIO;
+ }
+#else /* !__FreeBSD__ */
if (pci_read_config_byte(vb->pdev, 0x0c, &cache_line_size)) {
dev_err(&vb->pdev->dev, "Failed read of cache line "
"size from PCI configuration space.\n");
return -EIO;
}
+#endif
if ((0x08 == cache_line_size) || (0x10 == cache_line_size) ||
(0x20 == cache_line_size)) {
@@ -187,10 +351,18 @@
dl->padding = 0;
}
+#if defined(__FreeBSD__)
+ i = vb_dma_allocate((sizeof(*d) + dl->padding) * DRING_SIZE,
+ &dl->dma_tag, &dl->dma_map, (void **) &dl->desc, &dl->desc_dma);
+ if (i) {
+ return i;
+ }
+#else /* !__FreeBSD__ */
dl->desc = pci_alloc_consistent(vb->pdev,
(sizeof(*d) + dl->padding) * DRING_SIZE, &dl->desc_dma);
if (!dl->desc)
return -ENOMEM;
+#endif /* !__FreeBSD__ */
memset(dl->desc, 0, (sizeof(*d) + dl->padding) * DRING_SIZE);
for (i = 0; i < DRING_SIZE; ++i) {
@@ -224,11 +396,19 @@
* cache-line sizes that we support.
*
*/
+#if defined(__FreeBSD__)
+ if ((cache_line_size = pci_read_config(vb->pdev->dev, 0x0c, 1)) == 0) {
+ dev_err(&vb->pdev->dev, "Failed read of cache line "
+ "size from PCI configuration space.\n");
+ return EIO;
+ }
+#else /* !__FreeBSD__ */
if (pci_read_config_byte(vb->pdev, 0x0c, &cache_line_size)) {
dev_err(&vb->pdev->dev, "Failed read of cache line "
"size from PCI configuration space.\n");
return -EIO;
}
+#endif /* !__FreeBSD__ */
if ((0x08 == cache_line_size) || (0x10 == cache_line_size) ||
(0x20 == cache_line_size)) {
@@ -237,11 +417,19 @@
dl->padding = 0;
}
+#if defined(__FreeBSD__)
+ i = vb_dma_allocate((sizeof(*d) + dl->padding) * DRING_SIZE,
+ &dl->dma_tag, &dl->dma_map, (void **) &dl->desc, &dl->desc_dma);
+ if (i) {
+ return i;
+ }
+#else /* !__FreeBSD__ */
dl->desc = pci_alloc_consistent(vb->pdev,
(sizeof(*d) + dl->padding) *
DRING_SIZE, &dl->desc_dma);
if (!dl->desc)
return -ENOMEM;
+#endif /* !__FreeBSD__ */
memset(dl->desc, 0, (sizeof(*d) + dl->padding) * DRING_SIZE);
@@ -260,7 +448,7 @@
vb_initialize_rx_descriptors(struct voicebus *vb)
{
return vb_initialize_descriptors(
- vb, &vb->rxd, VOICEBUS_SFRAME_SIZE, DMA_FROM_DEVICE);
+ vb, &vb->rxd, VOICEBUS_SFRAME_SIZE);
}
/*! \brief Use to set the minimum number of buffers queued to the hardware
@@ -312,8 +500,12 @@
__vb_getctl(struct voicebus *vb, u32 addr)
{
u32 ret;
+#if defined(__FreeBSD__)
+ ret = bus_space_read_4(rman_get_bustag(vb->mem_res), rman_get_bushandle(vb->mem_res), addr);
+#else
ret = readl(vb->iobase + addr);
rmb();
+#endif
return ret;
}
@@ -371,9 +563,8 @@
d = vb_descriptor(dl, i);
if (d->buffer1 && (d->buffer1 != vb->idle_vbb_dma_addr)) {
WARN_ON(!dl->pending[i]);
- dma_unmap_single(&vb->pdev->dev, d->buffer1,
- VOICEBUS_SFRAME_SIZE, DMA_TO_DEVICE);
- kmem_cache_free(voicebus_vbb_cache, dl->pending[i]);
+ voicebus_unmap(vb, dl->pending[i], DMA_TO_DEVICE);
+ voicebus_free(vb, dl->pending[i]);
}
if (!test_bit(VOICEBUS_NORMAL_MODE, &vb->flags)) {
d->buffer1 = 0;
@@ -404,11 +595,10 @@
for (i = 0; i < DRING_SIZE; ++i) {
d = vb_descriptor(dl, i);
if (d->buffer1) {
- dma_unmap_single(&vb->pdev->dev, d->buffer1,
- VOICEBUS_SFRAME_SIZE, DMA_FROM_DEVICE);
+ voicebus_unmap(vb, dl->pending[i], DMA_FROM_DEVICE);
d->buffer1 = 0;
BUG_ON(!dl->pending[i]);
- kmem_cache_free(voicebus_vbb_cache, dl->pending[i]);
+ voicebus_free(vb, dl->pending[i]);
dl->pending[i] = NULL;
}
d->des0 &= ~OWN_BIT;
@@ -436,10 +626,14 @@
return;
}
vb_cleanup_descriptors(vb, dl);
+#if defined(__FreeBSD__)
+ vb_dma_free(&dl->dma_tag, &dl->dma_map, (void **) &dl->desc, &dl->desc_dma);
+#else /* !__FreeBSD__ */
pci_free_consistent(
vb->pdev,
(sizeof(struct voicebus_descriptor)+dl->padding)*DRING_SIZE,
dl->desc, dl->desc_dma);
+#endif /* !__FreeBSD__ */
}
/*!
@@ -448,8 +642,13 @@
static inline void
__vb_setctl(struct voicebus *vb, u32 addr, u32 val)
{
+#if defined(__FreeBSD__)
+ bus_space_write_4(rman_get_bustag(vb->mem_res), rman_get_bushandle(vb->mem_res),
+ addr, cpu_to_le32(val));
+#else
wmb();
writel(val, vb->iobase + addr);
+#endif
}
/*!
@@ -512,12 +711,20 @@
vb_enable_io_access(struct voicebus *vb)
{
LOCKS_VOICEBUS
+#if !defined(__FreeBSD__)
u32 reg;
+#endif
BUG_ON(!vb->pdev);
VBLOCK(vb);
+#if defined(__FreeBSD__)
+ pci_enable_io(vb->pdev->dev, SYS_RES_IOPORT);
+ pci_enable_io(vb->pdev->dev, SYS_RES_MEMORY);
+ pci_enable_busmaster(vb->pdev->dev);
+#else /* !__FreeBSD__ */
pci_read_config_dword(vb->pdev, 0x0004, ®);
reg |= 0x00000007;
pci_write_config_dword(vb->pdev, 0x0004, reg);
+#endif /* !__FreeBSD__ */
VBUNLOCK(vb);
}
@@ -532,11 +739,19 @@
u8 cache_line_size;
BUG_ON(in_interrupt());
+#if defined(__FreeBSD__)
+ if ((cache_line_size = pci_read_config(vb->pdev->dev, 0x0c, 1)) == 0) {
+ dev_err(&vb->pdev->dev, "Failed read of cache line "
+ "size from PCI configuration space.\n");
+ return EIO;
+ }
+#else /* !__FreeBSD__ */
if (pci_read_config_byte(vb->pdev, 0x0c, &cache_line_size)) {
dev_err(&vb->pdev->dev, "Failed read of cache line "
"size from PCI configuration space.\n");
return -EIO;
}
+#endif /* !__FreeBSD__ */
switch (cache_line_size) {
case 0x08:
@@ -596,14 +811,13 @@
if (unlikely(d->buffer1)) {
/* Do not overwrite a buffer that is still in progress. */
WARN_ON(1);
- kmem_cache_free(voicebus_vbb_cache, vbb);
+ voicebus_free(vb, vbb);
return -EBUSY;
}
dl->pending[tail] = vbb;
dl->tail = (++tail) & DRING_MASK;
- d->buffer1 = dma_map_single(&vb->pdev->dev, vbb->data,
- sizeof(vbb->data), DMA_FROM_DEVICE);
+ d->buffer1 = voicebus_map(vb, vbb, DMA_FROM_DEVICE);
SET_OWNED(d); /* That's it until the hardware is done with it. */
atomic_inc(&dl->count);
return 0;
@@ -623,7 +837,7 @@
if (unlikely((d->buffer1 != vb->idle_vbb_dma_addr) && d->buffer1)) {
if (printk_ratelimit())
dev_warn(&vb->pdev->dev, "Dropping tx buffer buffer\n");
- kmem_cache_free(voicebus_vbb_cache, vbb);
+ voicebus_free(vb, vbb);
/* Schedule the underrun handler to run here, since we'll need
* to cleanup as best we can. */
schedule_work(&vb->underrun_work);
@@ -631,8 +845,7 @@
}
dl->pending[dl->tail] = vbb;
- d->buffer1 = dma_map_single(&vb->pdev->dev, vbb->data,
- sizeof(vbb->data), DMA_TO_DEVICE);
+ d->buffer1 = voicebus_map(vb, vbb, DMA_TO_DEVICE);
dl->tail = (++(dl->tail)) & DRING_MASK;
SET_OWNED(d); /* That's it until the hardware is done with it. */
atomic_inc(&dl->count);
@@ -656,7 +869,7 @@
{
int i;
struct vbb *vbb;
- LIST_HEAD(buffers);
+ _LIST_HEAD(buffers);
unsigned long flags;
might_sleep();
@@ -669,7 +882,7 @@
vb_setctl(vb, 0x0018, (u32)vb->rxd.desc_dma);
for (i = 0; i < DRING_SIZE; ++i) {
- vbb = kmem_cache_alloc(voicebus_vbb_cache, GFP_KERNEL);
+ vbb = voicebus_alloc(vb, GFP_KERNEL);
if (unlikely(NULL == vbb))
BUG_ON(1);
list_add_tail(&vbb->entry, &buffers);
@@ -684,7 +897,7 @@
if (test_bit(VOICEBUS_NORMAL_MODE, &vb->flags)) {
for (i = 0; i < vb->min_tx_buffer_count; ++i) {
- vbb = kmem_cache_alloc(voicebus_vbb_cache, GFP_KERNEL);
+ vbb = voicebus_alloc(vb, GFP_KERNEL);
if (unlikely(NULL == vbb))
BUG_ON(1);
else
@@ -804,10 +1017,8 @@
if (OWNED(d) || !d->buffer1 || (d->buffer1 == vb->idle_vbb_dma_addr))
return NULL;
- dma_unmap_single(&vb->pdev->dev, d->buffer1,
- sizeof(vbb->data), DMA_TO_DEVICE);
-
vbb = dl->pending[head];
+ voicebus_unmap(vb, vbb, DMA_TO_DEVICE);
if (test_bit(VOICEBUS_NORMAL_MODE, &vb->flags)) {
d->buffer1 = vb->idle_vbb_dma_addr;
dl->pending[head] = vb->idle_vbb;
@@ -835,9 +1046,8 @@
if ((0 == d->buffer1) || OWNED(d))
return NULL;
- dma_unmap_single(&vb->pdev->dev, d->buffer1,
- sizeof(vbb->data), DMA_FROM_DEVICE);
vbb = dl->pending[head];
+ voicebus_unmap(vb, vbb, DMA_FROM_DEVICE);
dl->head = (++head) & DRING_MASK;
d->buffer1 = 0;
atomic_dec(&dl->count);
@@ -1038,7 +1248,7 @@
voicebus_stop(vb);
/* Make sure the underrun_work isn't running or going to run. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
+#if !defined(__FreeBSD__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
flush_scheduled_work();
#else
cancel_work_sync(&vb->underrun_work);
@@ -1049,22 +1259,52 @@
tasklet_kill(&vb->tasklet);
#if !defined(CONFIG_VOICEBUS_TIMER)
+#if defined(__FreeBSD__)
+ if (vb->irq_handle != NULL) {
+ bus_teardown_intr(vb->pdev->dev, vb->irq_res, vb->irq_handle);
+ vb->irq_handle = NULL;
+ }
+ if (vb->irq_res != NULL) {
+ bus_release_resource(vb->pdev->dev, SYS_RES_IRQ, vb->irq_rid, vb->irq_res);
+ vb->irq_res = NULL;
+ }
+#else /* !__FreeBSD__ */
free_irq(vb->pdev->irq, vb);
+#endif /* !__FreeBSD__ */
#endif
/* Cleanup memory and software resources. */
+ destroy_completion(&vb->stopped_completion);
+ spin_lock_destroy(&vb->lock);
vb_free_descriptors(vb, &vb->txd);
vb_free_descriptors(vb, &vb->rxd);
if (vb->idle_vbb_dma_addr) {
+#if defined(__FreeBSD__)
+ vb_dma_free(&vb->idle_vbb_dma_tag, &vb->idle_vbb_dma_map,
+ (void **) &vb->idle_vbb, &vb->idle_vbb_dma_addr);
+#else /* !__FreeBSD__ */
dma_free_coherent(&vb->pdev->dev, VOICEBUS_SFRAME_SIZE,
vb->idle_vbb, vb->idle_vbb_dma_addr);
- }
-
+#endif
+ }
+
+#if defined(__FreeBSD__)
+ if (vb->vbb_dma_tag != NULL) {
+ bus_dma_tag_destroy(vb->vbb_dma_tag);
+ vb->vbb_dma_tag = NULL;
+ }
+
+ if (vb->mem_res != NULL) {
+ bus_release_resource(vb->pdev->dev, SYS_RES_MEMORY, vb->mem_rid, vb->mem_res);
+ vb->mem_res = NULL;
+ }
+#else /* !__FreeBSD__ */
release_mem_region(pci_resource_start(vb->pdev, 1),
pci_resource_len(vb->pdev, 1));
pci_iounmap(vb->pdev, vb->iobase);
pci_disable_device(vb->pdev);
+#endif /* !__FreeBSD__ */
}
EXPORT_SYMBOL(voicebus_release);
@@ -1077,7 +1317,7 @@
struct vbb *n;
#endif
int i;
- LIST_HEAD(local);
+ _LIST_HEAD(local);
if (0 == increase)
return;
@@ -1101,7 +1341,7 @@
/* Set the minimum latency in case we're restarted...we don't want to
* wait for the buffer to grow to this depth again in that case. */
for (i = 0; i < increase; ++i) {
- vbb = kmem_cache_alloc(voicebus_vbb_cache, GFP_ATOMIC);
+ vbb = voicebus_alloc(vb, GFP_ATOMIC);
WARN_ON(NULL == vbb);
if (likely(NULL != vbb))
list_add_tail(&vbb->entry, &local);
@@ -1127,7 +1367,7 @@
static void vb_tasklet_relaxed(unsigned long data)
{
struct voicebus *vb = (struct voicebus *)data;
- LIST_HEAD(buffers);
+ _LIST_HEAD(buffers);
struct vbb *vbb;
const int DEFAULT_COUNT = 5;
int count = DEFAULT_COUNT;
@@ -1179,7 +1419,7 @@
{
struct voicebus *vb = (struct voicebus *)data;
int softunderrun;
- LIST_HEAD(buffers);
+ _LIST_HEAD(buffers);
struct vbb *vbb;
struct voicebus_descriptor_list *const dl = &vb->txd;
struct voicebus_descriptor *d;
@@ -1320,7 +1560,7 @@
while (!list_empty(&buffers)) {
vbb = list_entry(buffers.next, struct vbb, entry);
list_del(&vbb->entry);
- kmem_cache_free(voicebus_vbb_cache, vbb);
+ voicebus_free(vb, vbb);
}
return;
}
@@ -1330,7 +1570,7 @@
* @work: The work_struct used to queue this function.
*
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+#if !defined(__FreeBSD__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
static void handle_hardunderrun(void *data)
{
struct voicebus *vb = data;
@@ -1368,12 +1608,7 @@
* ALSO NOTE: Only access the interrupt status register from this function
* since it doesn't employ any locking on the voicebus interface.
*/
-static irqreturn_t
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-vb_isr(int irq, void *dev_id, struct pt_regs *regs)
-#else
-vb_isr(int irq, void *dev_id)
-#endif
+DAHDI_IRQ_HANDLER(vb_isr)
{
struct voicebus *vb = dev_id;
u32 int_status;
@@ -1384,7 +1619,11 @@
int_status &= 0x7fff;
if (!int_status)
+#if defined(__FreeBSD__)
+ return FILTER_STRAY;
+#else
return IRQ_NONE;
+#endif
if (unlikely((int_status &
(TX_UNAVAILABLE_INTERRUPT|RX_UNAVAILABLE_INTERRUPT)) &&
@@ -1422,7 +1661,11 @@
__vb_setctl(vb, SR_CSR5, int_status);
}
+#if defined(__FreeBSD__)
+ return FILTER_HANDLED;
+#else
return IRQ_HANDLED;
+#endif
}
#if defined(CONFIG_VOICEBUS_TIMER)
@@ -1487,12 +1730,21 @@
vb->timer.data = (unsigned long)vb;
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+#if !defined(__FreeBSD__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
INIT_WORK(&vb->underrun_work, handle_hardunderrun, vb);
#else
INIT_WORK(&vb->underrun_work, handle_hardunderrun);
#endif
+#if defined(__FreeBSD__)
+ vb->mem_rid = PCIR_BAR(1);
+ vb->mem_res = bus_alloc_resource_any(vb->pdev->dev, SYS_RES_MEMORY, &vb->mem_rid, RF_ACTIVE);
+ if (vb->mem_res == NULL) {
+ device_printf(vb->pdev->dev, "Can't allocate memory resource\n");
+ retval = ENXIO;
+ goto cleanup;
+ }
+#else /* !__FreeBSD__ */
/* ----------------------------------------------------------------
Configure the hardware / kernel module interfaces.
---------------------------------------------------------------- */
@@ -1522,10 +1774,29 @@
retval = -EIO;
goto cleanup;
}
-
+#endif
+
+#if defined(__FreeBSD__)
+ retval = bus_dma_tag_create(NULL, 8, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ sizeof(struct vbb), 1, sizeof(struct vbb), BUS_DMA_ALLOCNOW, NULL, NULL, &vb->vbb_dma_tag);
+ if (retval) {
+ dev_err(&vb->pdev->dev, "Can't allocate DMA tag for voicebus frames\n");
+ goto cleanup;
+ }
+
+ retval = vb_dma_allocate(VOICEBUS_SFRAME_SIZE,
+ &vb->idle_vbb_dma_tag, &vb->idle_vbb_dma_map, (void **) &vb->idle_vbb, &vb->idle_vbb_dma_addr);
+ if (retval) {
+ dev_err(&vb->pdev->dev, "Can't allocate DMA memory\n");
+ goto cleanup;
+ }
+#else /* !__FreeBSD__ */
vb->idle_vbb = dma_alloc_coherent(&vb->pdev->dev, VOICEBUS_SFRAME_SIZE,
&vb->idle_vbb_dma_addr, GFP_KERNEL);
-
+#endif
+
+#if !defined(__FreeBSD__)
/* ----------------------------------------------------------------
Configure the hardware interface.
---------------------------------------------------------------- */
@@ -1537,6 +1808,8 @@
}
pci_set_master(vb->pdev);
+#endif /* !__FreeBSD__ */
+
vb_enable_io_access(vb);
if (vb_reset_interface(vb)) {
@@ -1554,12 +1827,30 @@
goto cleanup;
#if !defined(CONFIG_VOICEBUS_TIMER)
+#if defined(__FreeBSD__)
+ vb->irq_res = bus_alloc_resource_any(
+ vb->pdev->dev, SYS_RES_IRQ, &vb->irq_rid, RF_SHAREABLE | RF_ACTIVE);
+ if (vb->irq_res == NULL) {
+ dev_err(&vb->pdev->dev, "Can't allocate IRQ resource\n");
+ retval = ENXIO;
+ goto cleanup;
+ }
+
+ retval = bus_setup_intr(
+ vb->pdev->dev, vb->irq_res, INTR_TYPE_CLK | INTR_MPSAFE,
+ vb_isr, NULL, vb, &vb->irq_handle);
+ if (retval) {
+ dev_err(&vb->pdev->dev, "Can't setup interrupt handler (error %d)\n", retval);
+ goto cleanup;
+ }
+#else /* !__FreeBSD__ */
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");
goto cleanup;
}
+#endif /* !__FreeBSD__ */
#endif
#ifdef VOICEBUS_NET_DEBUG
@@ -1577,6 +1868,32 @@
if (vb->rxd.desc)
vb_free_descriptors(vb, &vb->rxd);
+#if defined(__FreeBSD__)
+#if !defined(CONFIG_VOICEBUS_TIMER)
+ if (vb->irq_handle != NULL) {
+ bus_teardown_intr(vb->pdev->dev, vb->irq_res, vb->irq_handle);
+ vb->irq_handle = NULL;
+ }
+
+ if (vb->irq_res != NULL) {
+ bus_release_resource(vb->pdev->dev, SYS_RES_IRQ, vb->irq_rid, vb->irq_res);
+ vb->irq_res = NULL;
+ }
+#endif
+
+ vb_dma_free(&vb->idle_vbb_dma_tag, &vb->idle_vbb_dma_map,
+ (void **) &vb->idle_vbb, &vb->idle_vbb_dma_addr);
+
+ if (vb->vbb_dma_tag != NULL) {
+ bus_dma_tag_destroy(vb->vbb_dma_tag);
+ vb->vbb_dma_tag = NULL;
+ }
+
+ if (vb->mem_res != NULL) {
+ bus_release_resource(vb->pdev->dev, SYS_RES_MEMORY, vb->mem_rid, vb->mem_res);
+ vb->mem_res = NULL;
+ }
+#else /* !__FreeBSD__ */
dma_free_coherent(&vb->pdev->dev, VOICEBUS_SFRAME_SIZE,
vb->idle_vbb, vb->idle_vbb_dma_addr);
@@ -1585,6 +1902,7 @@
if (vb->pdev)
pci_disable_device(vb->pdev);
+#endif /* !__FreeBSD__ */
if (0 == retval)
retval = -EIO;
@@ -1593,7 +1911,7 @@
EXPORT_SYMBOL(__voicebus_init);
static spinlock_t loader_list_lock;
-static LIST_HEAD(binary_loader_list);
+static _LIST_HEAD(binary_loader_list);
/**
* vpmadtreg_loadfirmware - Load the vpmadt032 firmware.
@@ -1690,6 +2008,7 @@
{
int res;
+#if !defined(__FreeBSD__)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
voicebus_vbb_cache = kmem_cache_create(THIS_MODULE->name,
sizeof(struct vbb), 0,
@@ -1719,6 +2038,7 @@
THIS_MODULE->name);
return -ENOMEM;
}
+#endif /* !__FreeBSD__ */
/* This registration with dahdi.ko will fail since the span is not
* defined, but it will make sure that this module is a dependency of
@@ -1734,13 +2054,39 @@
static void __exit voicebus_module_cleanup(void)
{
+#if !defined(__FreeBSD__)
kmem_cache_destroy(voicebus_vbb_cache);
+#endif
+ spin_lock_destroy(&loader_list_lock);
WARN_ON(!list_empty(&binary_loader_list));
}
+#if defined(__FreeBSD__)
+static int
+dahdi_voicebus_modevent(module_t mod __unused, int type, void *data __unused)
+{
+ int res;
+
+ switch (type) {
+ case MOD_LOAD:
+ res = voicebus_module_init();
+ return -res;
+ case MOD_UNLOAD:
+ voicebus_module_cleanup();
+ return 0;
+ default:
+ return EOPNOTSUPP;
+ }
+}
+
+MODULE_VERSION(dahdi_voicebus, 1);
+DEV_MODULE(dahdi_voicebus, dahdi_voicebus_modevent, NULL);
+MODULE_DEPEND(dahdi_voicebus, dahdi, 1, 1, 1);
+#else /* !__FreeBSD__ */
MODULE_DESCRIPTION("Voicebus Interface w/VPMADT032 support");
MODULE_AUTHOR("Digium Incorporated <support at digium.com>");
MODULE_LICENSE("GPL");
module_init(voicebus_module_init);
module_exit(voicebus_module_cleanup);
+#endif /* !__FreeBSD__ */
Modified: freebsd/trunk/drivers/dahdi/voicebus/voicebus.h
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/voicebus/voicebus.h?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/voicebus/voicebus.h (original)
+++ freebsd/trunk/drivers/dahdi/voicebus/voicebus.h Tue Mar 9 13:42:14 2010
@@ -29,7 +29,11 @@
#ifndef __VOICEBUS_H__
#define __VOICEBUS_H__
+#if defined(__FreeBSD__)
+#include <machine/bus.h>
+#else
#include <linux/interrupt.h>
+#endif /* __FreeBSD__ */
#ifdef VOICEBUS_NET_DEBUG
@@ -63,6 +67,10 @@
struct vbb {
u8 data[VOICEBUS_SFRAME_SIZE];
struct list_head entry;
+ __le32 paddr;
+#if defined(__FreeBSD__)
+ bus_dmamap_t dma_map;
+#endif
};
struct voicebus_operations {
@@ -79,7 +87,13 @@
unsigned int head;
unsigned int tail;
void *pending[DRING_SIZE];
+#if defined(__FreeBSD__)
+ bus_dma_tag_t dma_tag;
+ bus_dmamap_t dma_map;
+ uint32_t desc_dma;
+#else
dma_addr_t desc_dma;
+#endif
atomic_t count;
unsigned int padding;
};
@@ -99,13 +113,31 @@
*/
struct voicebus {
struct pci_dev *pdev;
+#if defined(__FreeBSD__)
+ struct pci_dev _dev;
+
+ struct resource * irq_res; /* resource for irq */
+ int irq_rid;
+ void * irq_handle;
+
+ struct resource * mem_res; /* resource for memory I/O */
+ int mem_rid;
+#else
+ void __iomem *iobase;
+#endif
spinlock_t lock;
struct voicebus_descriptor_list rxd;
struct voicebus_descriptor_list txd;
u8 *idle_vbb;
+#if defined(__FreeBSD__)
+ bus_dma_tag_t vbb_dma_tag;
+ bus_dma_tag_t idle_vbb_dma_tag;
+ bus_dmamap_t idle_vbb_dma_map;
+ uint32_t idle_vbb_dma_addr;
+#else
dma_addr_t idle_vbb_dma_addr;
+#endif
const int *debug;
- void __iomem *iobase;
struct tasklet_struct tasklet;
#if defined(CONFIG_VOICEBUS_TIMER)
@@ -132,11 +164,13 @@
#endif
};
+#if !defined(__FreeBSD__)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
extern kmem_cache_t *voicebus_vbb_cache;
#else
extern struct kmem_cache *voicebus_vbb_cache;
#endif
+#endif /* !__FreeBSD__ */
int __voicebus_init(struct voicebus *vb, const char *board_name,
int normal_mode);
@@ -146,6 +180,8 @@
int voicebus_transmit(struct voicebus *vb, struct vbb *vbb);
int voicebus_set_minlatency(struct voicebus *vb, unsigned int milliseconds);
int voicebus_current_latency(struct voicebus *vb);
+struct vbb *voicebus_alloc(struct voicebus *vb, int malloc_flags);
+void voicebus_free(struct voicebus *vb, struct vbb *);
static inline int voicebus_init(struct voicebus *vb, const char *board_name)
{
Modified: freebsd/trunk/drivers/dahdi/voicebus/voicebus_net.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/voicebus/voicebus_net.c?view=diff&rev=8311&r1=8310&r2=8311
==============================================================================
--- freebsd/trunk/drivers/dahdi/voicebus/voicebus_net.c (original)
+++ freebsd/trunk/drivers/dahdi/voicebus/voicebus_net.c Tue Mar 9 13:42:14 2010
@@ -24,9 +24,11 @@
* this program for more details.
*/
+#if !defined(__FreeBSD__)
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#endif /* !__FreeBSD__ */
#include <dahdi/kernel.h>
More information about the svn-commits
mailing list