[svn-commits] fjoe: freebsd/trunk r7432 - in /freebsd/trunk: drivers/dahdi/ drivers/dahdi/w...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Oct 28 16:34:19 CDT 2009
Author: fjoe
Date: Wed Oct 28 16:34:15 2009
New Revision: 7432
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7432
Log:
Initial FreeBSD port (WIP):
- FreeBSD build glue (located under freebsd/)
- main dahdi driver
- dahdi_dummy driver
- echo cancellation drivers (jpah, kb1, mg2, sec, sec2)
- wcb4xxp driver
- wct4xxp driver with VPM450 and firmware(9) support
Added:
freebsd/trunk/freebsd/
freebsd/trunk/freebsd/Makefile (with props)
freebsd/trunk/freebsd/Makefile.inc (with props)
freebsd/trunk/freebsd/dahdi/
freebsd/trunk/freebsd/dahdi/Makefile (with props)
freebsd/trunk/freebsd/dahdi_dummy/
freebsd/trunk/freebsd/dahdi_dummy/Makefile (with props)
freebsd/trunk/freebsd/dahdi_dummy/dahdi_dummy.c (with props)
freebsd/trunk/freebsd/dahdi_echocan_jpah/
freebsd/trunk/freebsd/dahdi_echocan_jpah/Makefile (with props)
freebsd/trunk/freebsd/dahdi_echocan_kb1/
freebsd/trunk/freebsd/dahdi_echocan_kb1/Makefile (with props)
freebsd/trunk/freebsd/dahdi_echocan_mg2/
freebsd/trunk/freebsd/dahdi_echocan_mg2/Makefile (with props)
freebsd/trunk/freebsd/dahdi_echocan_sec/
freebsd/trunk/freebsd/dahdi_echocan_sec/Makefile (with props)
freebsd/trunk/freebsd/dahdi_echocan_sec2/
freebsd/trunk/freebsd/dahdi_echocan_sec2/Makefile (with props)
freebsd/trunk/freebsd/dahdi_fw_oct6114_064/
freebsd/trunk/freebsd/dahdi_fw_oct6114_064/Makefile (with props)
freebsd/trunk/freebsd/dahdi_fw_oct6114_128/
freebsd/trunk/freebsd/dahdi_fw_oct6114_128/Makefile (with props)
freebsd/trunk/freebsd/wcb4xxp/
freebsd/trunk/freebsd/wcb4xxp/Makefile (with props)
freebsd/trunk/freebsd/wct4xxp/
freebsd/trunk/freebsd/wct4xxp/Makefile (with props)
freebsd/trunk/include/dahdi/compat/
freebsd/trunk/include/dahdi/compat/bsd.h (with props)
freebsd/trunk/include/dahdi/compat/list.h (with props)
freebsd/trunk/include/dahdi/compat/types.h (with props)
Modified:
freebsd/trunk/drivers/dahdi/dahdi-base.c
freebsd/trunk/drivers/dahdi/dahdi_echocan_jpah.c
freebsd/trunk/drivers/dahdi/dahdi_echocan_kb1.c
freebsd/trunk/drivers/dahdi/dahdi_echocan_mg2.c
freebsd/trunk/drivers/dahdi/dahdi_echocan_sec.c
freebsd/trunk/drivers/dahdi/dahdi_echocan_sec2.c
freebsd/trunk/drivers/dahdi/ecdis.h
freebsd/trunk/drivers/dahdi/wcb4xxp/base.c
freebsd/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h
freebsd/trunk/drivers/dahdi/wct4xxp/base.c
freebsd/trunk/drivers/dahdi/wct4xxp/vpm450m.c
freebsd/trunk/drivers/dahdi/wct4xxp/vpm450m.h
freebsd/trunk/drivers/dahdi/wct4xxp/wct4xxp.h
freebsd/trunk/include/dahdi/dahdi_config.h
freebsd/trunk/include/dahdi/kernel.h
freebsd/trunk/include/dahdi/user.h
freebsd/trunk/include/dahdi/wctdm_user.h
Modified: freebsd/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=7432&r1=7431&r2=7432
==============================================================================
--- freebsd/trunk/drivers/dahdi/dahdi-base.c (original)
+++ freebsd/trunk/drivers/dahdi/dahdi-base.c Wed Oct 28 16:34:15 2009
@@ -34,7 +34,34 @@
* this program for more details.
*/
-
+#if defined(__FreeBSD__)
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/ctype.h>
+#include <sys/kernel.h>
+#include <sys/fcntl.h>
+#include <sys/ioccom.h>
+#include <sys/libkern.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/poll.h>
+#include <net/ppp_defs.h>
+#include <sys/selinfo.h>
+#include <sys/syscallsubr.h>
+
+#include <machine/stdarg.h>
+
+#include "version.h"
+
+#define module_printk(level, fmt, args...) printf(fmt, ## args)
+
+#define FOP_READ_ARGS_DECL struct file *file, struct uio *uio, size_t count
+#define FOP_READ_ARGS file, uio, count
+#define FOP_WRITE_ARGS_DECL struct file *file, struct uio *uio, size_t count
+#define FOP_WRITE_ARGS file, uio, count
+
+#else /* !__FreeBSD__ */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -52,11 +79,19 @@
#include <asm/atomic.h>
+#include <dahdi/version.h>
+
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
+#define FOP_READ_ARGS_DECL struct file *file, char __user *usrbuf, size_t count, loff_t *ppos
+#define FOP_READ_ARGS file, usrbuf, count, ppos
+#define FOP_WRITE_ARGS_DECL struct file *file, const char __user *usrbuf, size_t count, loff_t *ppos
+#define FOP_WRITE_ARGS file, usrbuf, count, ppos
+
+#endif /* !__FreeBSD__ */
+
/* #define BUF_MUNGE */
-#include <dahdi/version.h>
/* Grab fasthdlc with tables */
#define FAST_HDLC_NEED_TABLES
#include <dahdi/kernel.h>
@@ -91,9 +126,6 @@
#define hdlc_to_ztchan(h) (((struct dahdi_hdlc *)(h))->chan)
#define dev_to_ztchan(h) (((struct dahdi_hdlc *)(dev_to_hdlc(h)->priv))->chan)
#define ztchan_to_dev(h) ((h)->hdlcnetdev->netdev)
-
-/* macro-oni for determining a unit (channel) number */
-#define UNIT(file) MINOR(file->f_dentry->d_inode->i_rdev)
/* names of tx level settings */
static char *dahdi_txlevelnames[] = {
@@ -106,6 +138,377 @@
"-15db (CSU)",
"-22.5db (CSU)"
} ;
+
+#if defined(__FreeBSD__)
+#if 0
+static void rlprintf(int pps, const char *fmt, ...)
+{
+ va_list ap;
+ static struct timeval last_printf;
+ static int count;
+
+ if (ppsratecheck(&last_printf, &count, pps)) {
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ }
+}
+
+#define DPRINTF(fmt, args...) rlprintf(10, "%s: " fmt, __FUNCTION__, ##args)
+#endif
+
+MALLOC_DEFINE(M_DAHDI, "dahdi", "DAHDI interface data structures");
+
+/*
+ * FCS lookup table as calculated by genfcstab.
+ */
+static u_short fcstab[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+static int
+request_module(const char *fmt, ...)
+{
+ va_list ap;
+ char modname[128];
+ int fileid;
+
+ va_start(ap, fmt);
+ vsnprintf(modname, sizeof(modname), fmt, ap);
+ va_end(ap);
+
+ return kern_kldload(curthread, modname, &fileid);
+}
+
+/*
+ * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
+ * are written at dst (at most n+1 bytes being appended). Return dst.
+ */
+static char *
+strncat(char * __restrict dst, const char * __restrict src, size_t n)
+{
+ if (n != 0) {
+ char *d = dst;
+ const char *s = src;
+
+ while (*d != 0)
+ d++;
+ do {
+ if ((*d = *s++) == 0)
+ break;
+ d++;
+ } while (--n != 0);
+ *d = 0;
+ }
+ return (dst);
+}
+
+static struct cdev *dev_ctl = NULL;
+
+static struct cdevsw dahdi_devsw;
+
+struct inode;
+
+struct file {
+ struct cdev *dev;
+ int f_flags;
+};
+
+struct vm_area_struct {
+ vm_offset_t offset;
+ vm_paddr_t *paddr;
+ int nprot;
+};
+
+struct poll_table_struct {
+ struct selinfo *selinfo;
+};
+
+#define UNIT(file) dev2unit(file->dev)
+
+struct dahdi_fp {
+ int fflags; /**< file flags */
+ void *private_data; /**< private data */
+};
+
+static void
+dahdi_fp_free(void *fp)
+{
+ free(fp, M_DAHDI);
+}
+
+static int
+dahdi_get_fp(struct cdev *dev, struct dahdi_fp **pfp)
+{
+ int error = devfs_get_cdevpriv((void **) pfp);
+ if (error == ENOENT) {
+ *pfp = malloc(sizeof(struct dahdi_fp), M_DAHDI, M_NOWAIT | M_ZERO);
+ if (*pfp == NULL)
+ return -ENOMEM;
+
+ error = devfs_set_cdevpriv(*pfp, dahdi_fp_free);
+ if (error) {
+ dahdi_fp_free(*pfp);
+ return -ENXIO;
+ }
+ } else if (error) {
+ return (error);
+ }
+
+ return 0;
+}
+
+static int
+dahdi_get_flags(struct cdev *dev)
+{
+ int error;
+ struct dahdi_fp *fp;
+
+ error = devfs_get_cdevpriv((void **) &fp);
+ if (error || fp == NULL)
+ return 0;
+
+ return fp->fflags;
+}
+
+static void
+dahdi_set_flags(struct file *file, int fflags)
+{
+ int error;
+ struct dahdi_fp *fp;
+
+ error = dahdi_get_fp(file->dev, &fp);
+ if (error)
+ return;
+
+ fp->fflags = fflags;
+}
+
+static void *
+dahdi_get_private_data(struct file *file)
+{
+ int error;
+ struct dahdi_fp *fp;
+
+ error = devfs_get_cdevpriv((void **) &fp);
+ if (error || fp == NULL)
+ return NULL;
+
+ return fp->private_data;
+}
+
+static void
+dahdi_set_private_data(struct file *file, void *private_data)
+{
+ int error;
+ struct dahdi_fp *fp;
+
+ error = dahdi_get_fp(file->dev, &fp);
+ if (error)
+ return;
+
+ fp->private_data = private_data;
+}
+
+static void
+handle_selwakeup(void *context, int pending)
+{
+ struct selinfo *selinfo = context;
+ selwakeup(selinfo);
+}
+
+static void
+dahdi_poll_init(struct pollinfo *sel)
+{
+ TASK_INIT(&sel->task, 0, handle_selwakeup, &sel->selinfo);
+}
+
+static void
+dahdi_poll_wait(struct file *file, struct pollinfo *sel, struct poll_table_struct *wait_table)
+{
+ wait_table->selinfo = &sel->selinfo;
+}
+
+static void
+dahdi_poll_wakeup(struct pollinfo *sel)
+{
+ taskqueue_enqueue_fast(taskqueue_fast, &sel->task);
+}
+
+static void
+dahdi_poll_drain(struct pollinfo *sel)
+{
+ taskqueue_drain(taskqueue_fast, &sel->task);
+}
+
+/* sleep in user space until woken up. Equivilant of tsleep() in BSD */
+static int
+schluffen(wait_queue_head_t *q)
+{
+ int rc = tsleep(q, PZERO | PCATCH, "schluffen", 10);
+ switch (rc) {
+ case EINTR:
+ case ERESTART:
+ return rc;
+ }
+ return 0;
+}
+
+static int
+dahdi_fop_read(FOP_READ_ARGS_DECL, int off, void *buf, int iocount)
+{
+ return uiomove(buf, iocount, uio);
+}
+
+static int
+dahdi_fop_write(FOP_WRITE_ARGS_DECL, int off, void *buf, int iocount)
+{
+ return uiomove(buf, iocount, uio);
+}
+
+static int
+dahdi_copy_from_user(void *to, const void *from, int n)
+{
+ return copyin(from, to, n);
+}
+
+#define try_module_get(m) (1)
+#define module_put(m) ((void) (&m))
+
+#else /* !__FreeBSD__ */
+/* macro-oni for determining a unit (channel) number */
+#define UNIT(file) MINOR(file->f_dentry->d_inode->i_rdev)
+
+static int
+dahdi_get_flags(struct file *file)
+{
+ if (!file)
+ return 0;
+
+ return file->f_flags;
+}
+
+static void *
+dahdi_get_private_data(struct file *file)
+{
+ return file->private_data;
+}
+
+static void
+dahdi_set_private_data(struct file *file, void *private_data)
+{
+ file->private_data = private_data;
+}
+
+static void
+dahdi_poll_init(struct pollinfo *sel)
+{
+ init_wait_queue_head(&sel->wait_queue);
+}
+
+static void
+dahdi_poll_wait(struct file *file, struct pollinfo *sel, struct poll_table_struct *wait_table)
+{
+ poll_wait(file, &sel->wait_queue, wait_table);
+}
+
+static void
+dahdi_poll_wakeup(struct pollinfo *sel)
+{
+ wake_up_interruptible(&sel->wait_queue);
+}
+
+#define dahdi_poll_drain(sel)
+
+/* sleep in user space until woken up. Equivilant of tsleep() in BSD */
+static int
+schluffen(wait_queue_head_t *q)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(q, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ if (!signal_pending(current))
+ schedule();
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(q, &wait);
+
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ return 0;
+}
+
+static int
+dahdi_fop_read(FOP_READ_ARGS_DECL, int off, void *buf, int iocount)
+{
+ return copy_to_user(usrbuf + off, buf, iocount);
+}
+
+static int
+dahdi_fop_write(FOP_WRITE_ARGS_DECL, int off, void *buf, int iocount)
+{
+ return copy_from_user(buf, usrbuf + off, iocount);
+}
+
+static int
+dahdi_copy_from_user(void *to, const void __user *from, int n)
+{
+ return copy_from_user(to, from, n);
+}
+
+int
+dahdi_register_chardev(struct dahdi_chardev *dev)
+{
+ char udevname[strlen(dev->name) + sizeof("dahdi!")];
+
+ strcpy(udevname, "dahdi!");
+ strcat(udevname, dev->name);
+ CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
+ return 0;
+}
+
+int
+dahdi_unregister_chardev(struct dahdi_chardev *dev)
+{
+ CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
+ return 0;
+}
+
+struct file_operations *dahdi_transcode_fops = NULL;
EXPORT_SYMBOL(dahdi_transcode_fops);
EXPORT_SYMBOL(dahdi_init_tone_state);
@@ -187,6 +590,7 @@
#define class_create class_simple_create
#define class_destroy class_simple_destroy
#endif
+#endif /* !__FreeBSD__ */
static int deftaps = 64;
@@ -228,8 +632,6 @@
static sumtype *conf_sums_prev;
static struct dahdi_span *master;
-static struct file_operations dahdi_fops;
-struct file_operations *dahdi_transcode_fops = NULL;
static struct {
int src; /* source conf number */
@@ -365,10 +767,10 @@
int ping; /* Whether we've been ping'd */
int tripped; /* Whether we're tripped */
struct list_head list;
- wait_queue_head_t sel;
+ struct pollinfo sel;
};
-static LIST_HEAD(zaptimers);
+static _LIST_HEAD(zaptimers);
#ifdef DEFINE_SPINLOCK
static DEFINE_SPINLOCK(zaptimerlock);
@@ -417,10 +819,6 @@
static u_char defgain[256];
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
-#define __RW_LOCK_UNLOCKED() RW_LOCK_UNLOCKED
-#endif
-
#ifdef DEFINE_RWLOCK
static DEFINE_RWLOCK(zone_lock);
static DEFINE_RWLOCK(chan_lock);
@@ -436,10 +834,14 @@
#ifdef DEFINE_RWLOCK
static DEFINE_RWLOCK(ecfactory_list_lock);
#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
+#define __RW_LOCK_UNLOCKED() RW_LOCK_UNLOCKED
+#endif
+
static rwlock_t ecfactory_list_lock = __RW_LOCK_UNLOCKED();
#endif
-static LIST_HEAD(ecfactory_list);
+static _LIST_HEAD(ecfactory_list);
struct ecfactory {
const struct dahdi_echocan_factory *ec;
@@ -888,7 +1290,7 @@
wake_up_interruptible(&chan->readbufq);
wake_up_interruptible(&chan->writebufq);
- wake_up_interruptible(&chan->sel);
+ dahdi_poll_wakeup(&chan->sel);
return;
}
@@ -904,26 +1306,6 @@
spin_lock_irqsave(&chan->lock, flags);
__qevent(chan, event);
spin_unlock_irqrestore(&chan->lock, flags);
-}
-
-/* sleep in user space until woken up. Equivilant of tsleep() in BSD */
-static int schluffen(wait_queue_head_t *q)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(q, &wait);
- current->state = TASK_INTERRUPTIBLE;
-
- if (!signal_pending(current))
- schedule();
-
- current->state = TASK_RUNNING;
- remove_wait_queue(q, &wait);
-
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- return 0;
}
static inline void calc_fcs(struct dahdi_chan *ss, int inwritebuf)
@@ -1252,7 +1634,7 @@
chan->pulsecount = 0;
chan->pulsetimer = 0;
chan->ringdebtimer = 0;
- init_waitqueue_head(&chan->sel);
+ dahdi_poll_init(&chan->sel);
init_waitqueue_head(&chan->readbufq);
init_waitqueue_head(&chan->writebufq);
init_waitqueue_head(&chan->eventbufq);
@@ -1968,10 +2350,12 @@
}
}
chan->channo = -1;
+ spin_lock_destroy(&chan->lock);
+ dahdi_poll_drain(&chan->sel);
write_unlock_irqrestore(&chan_lock, flags);
}
-static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf, size_t count, int unit)
+static ssize_t dahdi_chan_read(FOP_READ_ARGS_DECL, int unit)
{
struct dahdi_chan *chan = chans[unit];
int amnt;
@@ -2040,7 +2424,7 @@
pass = 128;
for (x = 0; x < pass; x++)
lindata[x] = DAHDI_XLAW(chan->readbuf[res][x + pos], chan);
- if (copy_to_user(usrbuf + (pos << 1), lindata, pass << 1))
+ if (dahdi_fop_read(FOP_READ_ARGS, pos << 1, lindata, pass << 1))
return -EFAULT;
left -= pass;
pos += pass;
@@ -2050,7 +2434,7 @@
if (amnt > chan->readn[res])
amnt = chan->readn[res];
if (amnt) {
- if (copy_to_user(usrbuf, chan->readbuf[res], amnt))
+ if (dahdi_fop_read(FOP_READ_ARGS, 0, chan->readbuf[res], amnt))
return -EFAULT;
}
}
@@ -2097,7 +2481,7 @@
return range1 + range2;
}
-static ssize_t dahdi_chan_write(struct file *file, const char __user *usrbuf, size_t count, int unit)
+static ssize_t dahdi_chan_write(FOP_WRITE_ARGS_DECL, int unit)
{
unsigned long flags;
struct dahdi_chan *chan = chans[unit];
@@ -2178,7 +2562,7 @@
pass = left;
if (pass > 128)
pass = 128;
- if (copy_from_user(lindata, usrbuf + (pos << 1), pass << 1)) {
+ if (dahdi_fop_write(FOP_WRITE_ARGS, pos << 1, lindata, pass << 1)) {
return -EFAULT;
}
left -= pass;
@@ -2188,7 +2572,7 @@
}
chan->writen[res] = amnt >> 1;
} else {
- if (copy_from_user(chan->writebuf[res], usrbuf, amnt)) {
+ if (dahdi_fop_write(FOP_WRITE_ARGS, 0, chan->writebuf[res], amnt)) {
return -EFAULT;
}
chan->writen[res] = amnt;
@@ -2545,7 +2929,7 @@
chan->itimerset = chan->itimer = chan->otimer = 0;
chan->ringdebtimer = 0;
- init_waitqueue_head(&chan->sel);
+ dahdi_poll_init(&chan->sel);
init_waitqueue_head(&chan->readbufq);
init_waitqueue_head(&chan->writebufq);
init_waitqueue_head(&chan->eventbufq);
@@ -2624,9 +3008,9 @@
if (!(t = kzalloc(sizeof(*t), GFP_KERNEL)))
return -ENOMEM;
- init_waitqueue_head(&t->sel);
+ dahdi_poll_init(&t->sel);
INIT_LIST_HEAD(&t->list);
- file->private_data = t;
+ dahdi_set_private_data(file, t);
spin_lock_irqsave(&zaptimerlock, flags);
list_add(&t->list, &zaptimers);
@@ -2640,7 +3024,7 @@
struct dahdi_timer *t, *cur, *next;
unsigned long flags;
- if (!(t = file->private_data))
+ if (!(t = dahdi_get_private_data(file)))
return 0;
spin_lock_irqsave(&zaptimerlock, flags);
@@ -2659,6 +3043,7 @@
return 0;
}
+ dahdi_poll_drain(&t->sel);
kfree(cur);
return 0;
@@ -2695,7 +3080,7 @@
res = chan->span->open(chan);
}
if (!res) {
- chan->file = file;
+ chan->file = file->dev;
spin_unlock_irqrestore(&chan->lock, flags);
} else {
spin_unlock_irqrestore(&chan->lock, flags);
@@ -2789,6 +3174,7 @@
if (!unit)
return dahdi_ctl_open(inode, file);
if (unit == 250) {
+#if !defined(__FreeBSD__)
if (!dahdi_transcode_fops) {
if (request_module("dahdi_transcode")) {
return -ENXIO;
@@ -2808,6 +3194,7 @@
* file_operations table. */
WARN_ON(1);
}
+#endif /* !__FreeBSD__ */
return -ENXIO;
}
if (unit == 253) {
@@ -2822,7 +3209,7 @@
if (unit == 255) {
chan = dahdi_alloc_pseudo();
if (chan) {
- file->private_data = chan;
+ dahdi_set_private_data(file, chan);
return dahdi_specchan_open(inode, file, chan->channo);
} else {
return -ENXIO;
@@ -2843,7 +3230,7 @@
}
#endif
-static ssize_t dahdi_read(struct file *file, char __user *usrbuf, size_t count, loff_t *ppos)
+static ssize_t dahdi_read(FOP_READ_ARGS_DECL)
{
int unit = UNIT(file);
struct dahdi_chan *chan;
@@ -2857,27 +3244,27 @@
return -EINVAL;
if (unit == 254) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan)
return -EINVAL;
- return dahdi_chan_read(file, usrbuf, count, chan->channo);
+ return dahdi_chan_read(FOP_READ_ARGS, chan->channo);
}
if (unit == 255) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan) {
module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
return -EINVAL;
}
- return dahdi_chan_read(file, usrbuf, count, chan->channo);
+ return dahdi_chan_read(FOP_READ_ARGS, chan->channo);
}
if (count < 0)
return -EINVAL;
- return dahdi_chan_read(file, usrbuf, count, unit);
-}
-
-static ssize_t dahdi_write(struct file *file, const char __user *usrbuf, size_t count, loff_t *ppos)
+ return dahdi_chan_read(FOP_READ_ARGS, unit);
+}
+
+static int dahdi_write(FOP_WRITE_ARGS_DECL)
{
int unit = UNIT(file);
struct dahdi_chan *chan;
@@ -2889,20 +3276,20 @@
if (unit == 253)
return -EINVAL;
if (unit == 254) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan)
return -EINVAL;
- return dahdi_chan_write(file, usrbuf, count, chan->channo);
+ return dahdi_chan_write(FOP_WRITE_ARGS, chan->channo);
}
if (unit == 255) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan) {
module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
return -EINVAL;
}
- return dahdi_chan_write(file, usrbuf, count, chan->channo);
- }
- return dahdi_chan_write(file, usrbuf, count, unit);
+ return dahdi_chan_write(FOP_WRITE_ARGS, chan->channo);
+ }
+ return dahdi_chan_write(FOP_WRITE_ARGS, unit);
}
@@ -2955,8 +3342,7 @@
if (!work)
return -ENOMEM;
- if (copy_from_user(&work->th, (struct dahdi_tone_def_header *)data,
- sizeof(work->th))) {
+ if (dahdi_copy_from_user(&work->th, (struct dahdi_tone_def_header *)data, sizeof(work->th))) {
kfree(work);
return -EFAULT;
}
@@ -2982,7 +3368,7 @@
return -ENOMEM;
}
- ptr += sizeof(*z);
+ ptr = (char *) ptr + sizeof(*z);
space -= sizeof(*z);
dahdi_copy_string(z->name, work->th.name, sizeof(z->name));
@@ -3008,8 +3394,7 @@
return -EINVAL;
}
- res = copy_from_user(&work->td, (struct dahdi_tone_def *)data,
- sizeof(work->td));
+ res = dahdi_copy_from_user(&work->td, (struct dahdi_tone_def *)data, sizeof(work->td));
if (res) {
kfree(slab);
kfree(work);
@@ -3024,7 +3409,7 @@
t = work->samples[x] = ptr;
space -= sizeof(*t);
- ptr += sizeof(*t);
+ ptr = (char *) ptr + sizeof(*t);
/* Remember which sample is work->next */
work->next[x] = work->td.next;
@@ -3371,14 +3756,14 @@
return -EFAULT;
}
if (unit == 254) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan)
return dahdi_chan_release(inode, file);
else
return dahdi_specchan_release(inode, file, chan->channo);
}
if (unit == 255) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (chan) {
res = dahdi_specchan_release(inode, file, chan->channo);
dahdi_free_pseudo(chan);
@@ -3519,7 +3904,7 @@
case DAHDI_TIMERPING:
spin_lock_irqsave(&zaptimerlock, flags);
timer->ping = 1;
- wake_up_interruptible(&timer->sel);
+ dahdi_poll_wakeup(&timer->sel);
spin_unlock_irqrestore(&zaptimerlock, flags);
break;
case DAHDI_TIMERPONG:
@@ -4289,6 +4674,10 @@
return -EFAULT;
return dahdi_set_default_zone(j);
case DAHDI_LOADZONE:
+#if defined(__FreeBSD__)
+ if (copy_from_user(&data, (void *) data, sizeof(data)))
+ return -EFAULT;
+#endif
return ioctl_load_zone(data);
case DAHDI_FREEZONE:
get_user(j, (int *) data);
@@ -4594,7 +4983,7 @@
chan->readidx[j] = 0;
}
wake_up_interruptible(&chan->readbufq); /* wake_up_interruptible waiting on read */
- wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */
+ dahdi_poll_wakeup(&chan->sel); /* wake up waiting on select */
}
if (i & DAHDI_FLUSH_WRITE) /* if for write (output) */
{
@@ -4607,7 +4996,7 @@
chan->writeidx[j] = 0;
}
wake_up_interruptible(&chan->writebufq); /* wake_up_interruptible waiting on write */
- wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */
+ dahdi_poll_wakeup(&chan->sel); /* wake up waiting on select */
/* if IO MUX wait on write empty, well, this
certainly *did* empty the write */
if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY)
@@ -5068,8 +5457,9 @@
return -ENOMEM;
/* enable mode, need the params */
-
- if (copy_from_user(params, (struct dahdi_echocanparam *) data, sizeof(params[0]) * ecp->param_count)) {
+ if (ecp->param_count != 0 &&
+ dahdi_copy_from_user(params, (struct dahdi_echocanparam *) data,
+ sizeof(params[0]) * ecp->param_count)) {
ret = -EFAULT;
goto exit_with_free;
}
@@ -5217,6 +5607,25 @@
return -ENOSYS;
switch(cmd) {
+#if defined(__FreeBSD__)
+ case F_SETFL: {
+ int fflags = dahdi_get_flags(file->dev);
+
+ get_user(j, data);
+ printf("F_SETFL: 0x%x\n", j);
+
+ /*
+ * XXX: On the moment we're interested only in O_NONBLOCK
+ * Need any other flags?
+ */
+ if ((j & O_NONBLOCK) != 0) {
+ dahdi_set_flags(file, fflags | O_NONBLOCK);
+ } else {
+ dahdi_set_flags(file, fflags & ~O_NONBLOCK);
+ }
+ break;
+ }
+#endif
case DAHDI_SETSIGFREEZE:
get_user(j, (int *)data);
spin_lock_irqsave(&chan->lock, flags);
@@ -5393,6 +5802,10 @@
{
struct dahdi_echocanparams ecp;
+#if defined(__FreeBSD__)
+ if (copy_from_user(&data, (void *) data, sizeof(data)))
+ return -EFAULT;
+#endif
if (!(chan->flags & DAHDI_FLAG_AUDIO))
return -EINVAL;
if (copy_from_user(&ecp, (struct dahdi_echocanparams *) data, sizeof(ecp)))
@@ -5585,7 +5998,7 @@
static int dahdi_prechan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
{
- struct dahdi_chan *chan = file->private_data;
+ struct dahdi_chan *chan = dahdi_get_private_data(file);
int channo;
int res;
@@ -5603,7 +6016,7 @@
if (!res) {
/* Setup the pointer for future stuff */
chan = chans[channo];
- file->private_data = chan;
+ dahdi_set_private_data(file, chan);
/* Return success */
return 0;
}
@@ -5631,21 +6044,21 @@
}
if (unit == 253) {
- timer = file->private_data;
+ timer = dahdi_get_private_data(file);
if (timer)
return dahdi_timer_ioctl(inode, file, cmd, data, timer);
else
return -EINVAL;
}
if (unit == 254) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (chan)
return dahdi_chan_ioctl(inode, file, cmd, data, chan->channo);
else
return dahdi_prechan_ioctl(inode, file, cmd, data, unit);
}
if (unit == 255) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan) {
module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
return -EINVAL;
@@ -5731,11 +6144,19 @@
for (x = 0; x < span->channels; x++) {
if (span->chans[x]->channo < 250) {
+#if defined(__FreeBSD__)
+ span->chans[x]->file = make_dev(
+ &dahdi_devsw, span->chans[x]->channo,
+ UID_ROOT, GID_WHEEL, 0644,
+ "dahdi/%d", span->chans[x]->channo);
+ dev_depends(dev_ctl, span->chans[x]->file);
+#else
char chan_name[32];
snprintf(chan_name, sizeof(chan_name), "dahdi!%d",
span->chans[x]->channo);
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR,
span->chans[x]->channo), NULL, chan_name);
+#endif
}
}
@@ -5794,8 +6215,16 @@
#endif /* CONFIG_PROC_FS */
for (x = 0; x < span->channels; x++) {
- if (span->chans[x]->channo < 250)
+ if (span->chans[x]->channo < 250) {
+#if defined(__FreeBSD__)
+ if (span->chans[x]->file != NULL) {
+ destroy_dev(span->chans[x]->file);
+ span->chans[x]->file = NULL;
+ }
+#else
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo));
+#endif
+ }
}
spans[span->spanno] = NULL;
@@ -5821,6 +6250,7 @@
(new_master)? new_master->name: "no master");
master = new_master;
+ spin_lock_destroy(&span->lock);
return 0;
}
@@ -6305,7 +6735,7 @@
out in the later versions, and is put back now. */
if (!(ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) {
wake_up_interruptible(&ms->writebufq);
- wake_up_interruptible(&ms->sel);
+ dahdi_poll_wakeup(&ms->sel);
if (ms->iomask & DAHDI_IOMUX_WRITE)
wake_up_interruptible(&ms->eventbufq);
}
@@ -6470,7 +6900,7 @@
case DAHDI_TXSTATE_WINK:
/* Wink complete, go on hook and stabalize */
dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0);
- if (chan->file && (chan->file->f_flags & O_NONBLOCK))
+ if (dahdi_get_flags(chan->file) & O_NONBLOCK)
__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
wake_up_interruptible(&chan->txstateq);
break;
@@ -6482,7 +6912,7 @@
case DAHDI_TXSTATE_FLASH:
dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0);
- if (chan->file && (chan->file->f_flags & O_NONBLOCK))
+ if (dahdi_get_flags(chan->file) & O_NONBLOCK)
__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
wake_up_interruptible(&chan->txstateq);
break;
@@ -6497,14 +6927,14 @@
case DAHDI_TXSTATE_AFTERSTART:
dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0);
- if (chan->file && (chan->file->f_flags & O_NONBLOCK))
+ if (dahdi_get_flags(chan->file) & O_NONBLOCK)
__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
wake_up_interruptible(&chan->txstateq);
break;
case DAHDI_TXSTATE_KEWL:
dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_AFTERKEWL, DAHDI_AFTERKEWLTIME);
- if (chan->file && (chan->file->f_flags & O_NONBLOCK))
+ if (dahdi_get_flags(chan->file) & O_NONBLOCK)
__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
wake_up_interruptible(&chan->txstateq);
break;
@@ -6809,7 +7239,7 @@
{
union dahdi_echocan_events events = chan->ec_state->events;
- if (events.CED_tx_detected) {
+ if (events.bit.CED_tx_detected) {
dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CED_DETECTED);
if (chan->ec_state) {
if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
@@ -6819,7 +7249,7 @@
}
}
- if (events.CED_rx_detected) {
+ if (events.bit.CED_rx_detected) {
dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CED_DETECTED);
if (chan->ec_state) {
if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
@@ -6829,18 +7259,18 @@
}
}
- if (events.CNG_tx_detected)
+ if (events.bit.CNG_tx_detected)
dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CNG_DETECTED);
- if (events.CNG_rx_detected)
+ if (events.bit.CNG_rx_detected)
dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CNG_DETECTED);
- if (events.NLP_auto_disabled) {
+ if (events.bit.NLP_auto_disabled) {
dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED);
chan->ec_state->status.mode = ECHO_MODE_FAX;
}
- if (events.NLP_auto_enabled) {
+ if (events.bit.NLP_auto_enabled) {
dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED);
chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
}
@@ -7438,7 +7868,7 @@
/* if there are processes waiting in poll() on this channel,
wake them up */
if (!ms->rxdisable) {
- wake_up_interruptible(&ms->sel);
+ dahdi_poll_wakeup(&ms->sel);
}
}
/* In the very orignal driver, it was quite well known to me (Jim) that there
@@ -7636,7 +8066,7 @@
if (!ss->rxdisable) {
wake_up_interruptible(&ss->readbufq);
- wake_up_interruptible(&ss->sel);
+ dahdi_poll_wakeup(&ss->sel);
if (ss->iomask & DAHDI_IOMUX_READ)
wake_up_interruptible(&ss->eventbufq);
}
@@ -7688,7 +8118,7 @@
if (!(ss->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) {
wake_up_interruptible(&ss->writebufq);
- wake_up_interruptible(&ss->sel);
+ dahdi_poll_wakeup(&ss->sel);
if ((ss->iomask & DAHDI_IOMUX_WRITE) && (res >= 0))
wake_up_interruptible(&ss->eventbufq);
}
@@ -7716,7 +8146,7 @@
if (cur->pos <= 0) {
cur->tripped++;
cur->pos = cur->ms;
- wake_up_interruptible(&cur->sel);
+ dahdi_poll_wakeup(&cur->sel);
}
}
}
@@ -7726,11 +8156,11 @@
static unsigned int dahdi_timer_poll(struct file *file, struct poll_table_struct *wait_table)
{
- struct dahdi_timer *timer = file->private_data;
+ struct dahdi_timer *timer = dahdi_get_private_data(file);
unsigned long flags;
int ret = 0;
if (timer) {
- poll_wait(file, &timer->sel, wait_table);
+ dahdi_poll_wait(file, &timer->sel, wait_table);
spin_lock_irqsave(&zaptimerlock, flags);
if (timer->tripped || timer->ping)
ret |= POLLPRI;
@@ -7751,7 +8181,7 @@
/* do the poll wait */
if (chan) {
- poll_wait(file, &chan->sel, wait_table);
+ dahdi_poll_wait(file, &chan->sel, wait_table);
ret = 0; /* start with nothing to return */
spin_lock_irqsave(&chan->lock, flags);
/* if at least 1 write buffer avail */
@@ -7774,9 +8204,11 @@
static int dahdi_mmap(struct file *file, struct vm_area_struct *vm)
{
+#if !defined(__FreeBSD__)
int unit = UNIT(file);
if (unit == 250)
return dahdi_transcode_fops->mmap(file, vm);
+#endif
return -ENOSYS;
}
@@ -7789,19 +8221,23 @@
return -EINVAL;
if (unit == 250)
+#if defined(__FreeBSD__)
+ return -ENXIO;
+#else
return dahdi_transcode_fops->poll(file, wait_table);
+#endif
if (unit == 253)
return dahdi_timer_poll(file, wait_table);
if (unit == 254) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan)
return -EINVAL;
return dahdi_chan_poll(file, wait_table,chan->channo);
}
if (unit == 255) {
- chan = file->private_data;
+ chan = dahdi_get_private_data(file);
if (!chan) {
module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
return -EINVAL;
@@ -8292,6 +8728,157 @@
return 0;
}
+#if defined(__FreeBSD__)
+static void
+init_file(struct file *file, struct cdev *dev, int ioflag)
+{
+ file->dev = dev;
+ file->f_flags = ioflag;
+}
+
+static int
+dahdi_device_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+ int res;
+ struct file file;
+
+ init_file(&file, dev, 0);
+ res = dahdi_open(NULL, &file);
+ if (res < 0)
+ return -res;
+
+ dahdi_set_flags(&file, oflags);
+ return res;
+}
+
+static int
+dahdi_device_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+{
+ int res;
+ struct file file;
+
+ init_file(&file, dev, 0);
+ res = dahdi_release(NULL, &file);
+ if (res < 0)
+ return -res;
+
+ if (res == 0)
+ devfs_clear_cdevpriv();
+ return res;
+}
+
+static int
+dahdi_device_read(struct cdev *dev, struct uio *uio, int ioflag)
+{
+ ssize_t res;
+ struct file file;
+
+ init_file(&file, dev, ioflag);
+ res = dahdi_read(&file, uio, uio->uio_resid);
+ if (res < 0)
+ return -res;
+ return 0;
+}
+
+static int
+dahdi_device_write(struct cdev *dev, struct uio *uio, int ioflag)
+{
+ ssize_t res;
+ struct file file;
+
+ init_file(&file, dev, ioflag);
+ res = dahdi_write(&file, uio, uio->uio_resid);
+ if (res < 0)
+ return -res;
+ return 0;
+}
+
+static int
+dahdi_device_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
+{
+ int res;
+ struct file file;
+
+ init_file(&file, dev, fflag);
+ res = dahdi_ioctl(NULL, &file, cmd, (unsigned long) data);
+ if (res < 0)
+ return -res;
+ return res;
+}
+
+static int
+dahdi_device_poll(struct cdev *dev, int events, struct thread *td)
+{
+ int res;
+ struct file file;
+ struct poll_table_struct wait_table;
+
+ init_file(&file, dev, 0);
+ wait_table.selinfo = NULL;
+ res = dahdi_poll(&file, &wait_table);
+ if (res < 0)
+ return 0;
+
+ res &= events;
+ if (res == 0 && wait_table.selinfo != NULL)
+ selrecord(td, wait_table.selinfo);
+ return res;
+}
+
+static int
+dahdi_device_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
+{
+ int res;
+ struct file file;
+ struct vm_area_struct vm;
+
+ init_file(&file, dev, 0);
+ vm.offset = offset;
+ vm.paddr = paddr;
+ vm.nprot = nprot;
+ res = dahdi_mmap(&file, &vm);
+ if (res < 0)
+ return -res;
+ return res;
+}
+
+static struct cdevsw dahdi_devsw = {
+ .d_version = D_VERSION,
+ .d_open = dahdi_device_open,
+ .d_close = dahdi_device_close,
+ .d_read = dahdi_device_read,
+ .d_write = dahdi_device_write,
+ .d_ioctl = dahdi_device_ioctl,
+ .d_poll = dahdi_device_poll,
+ .d_mmap = dahdi_device_mmap,
+ .d_name = "dahdi",
+#if __FreeBSD_version >= 800039
+ .d_flags = D_PSEUDO | D_TRACKCLOSE | D_NEEDMINOR
+#else
+ .d_flags = D_PSEUDO | D_TRACKCLOSE
+#endif
+};
+
+int
+dahdi_register_chardev(struct dahdi_chardev *dev)
+{
+ dev->dev = make_dev(&dahdi_devsw, dev->minor,
+ UID_ROOT, GID_WHEEL, 0644,
+ "dahdi/%s", dev->name);
+ return 0;
+}
+
+int
+dahdi_unregister_chardev(struct dahdi_chardev *dev)
+{
+ if (dev->dev) {
+ destroy_dev(dev->dev);
+ dev->dev = NULL;
+ }
+ return 0;
+}
+
+#else /* !__FreeBSD__ */
MODULE_AUTHOR("Mark Spencer <markster at digium.com>");
MODULE_DESCRIPTION("DAHDI Telephony Interface");
MODULE_LICENSE("GPL v2");
@@ -8314,6 +8901,7 @@
.fsync = NULL,
.fasync = NULL,
};
+#endif /* !__FreeBSD__ */
#ifdef CONFIG_DAHDI_WATCHDOG
static struct timer_list watchdogtimer;
@@ -8375,24 +8963,6 @@
#endif
-int dahdi_register_chardev(struct dahdi_chardev *dev)
-{
- char udevname[strlen(dev->name) + sizeof("dahdi!")];
-
- strcpy(udevname, "dahdi!");
- strcat(udevname, dev->name);
- CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
-
- return 0;
-}
-
-int dahdi_unregister_chardev(struct dahdi_chardev *dev)
-{
- CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
-
- return 0;
-}
-
static int __init dahdi_init(void)
{
int res = 0;
@@ -8401,6 +8971,18 @@
proc_entries[0] = proc_mkdir("dahdi", NULL);
#endif
+#if defined(__FreeBSD__)
+ dev_ctl = make_dev(&dahdi_devsw, 0, UID_ROOT, GID_WHEEL, 0644, "dahdi/ctl");
+ {
+ struct cdev *dev;
+ dev = make_dev(&dahdi_devsw, 253, UID_ROOT, GID_WHEEL, 0644, "dahdi/timer");
+ dev_depends(dev_ctl, dev);
+ dev = make_dev(&dahdi_devsw, 254, UID_ROOT, GID_WHEEL, 0644, "dahdi/channel");
+ dev_depends(dev_ctl, dev);
+ dev = make_dev(&dahdi_devsw, 255, UID_ROOT, GID_WHEEL, 0644, "dahdi/pseudo");
+ dev_depends(dev_ctl, dev);
+ }
+#else /* !__FreeBSD__ */
if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) {
module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
return res;
@@ -8411,6 +8993,7 @@
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 254), NULL, "dahdi!channel");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 255), NULL, "dahdi!pseudo");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 0), NULL, "dahdi!ctl");
+#endif
module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", DAHDI_MAJOR);
module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION);
@@ -8430,6 +9013,12 @@
coretimer_cleanup();
+#if defined(__FreeBSD__)
+ if (dev_ctl != NULL) {
+ destroy_dev(dev_ctl);
+ dev_ctl = NULL;
+ }
+#else
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 253)); /* timer */
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 254)); /* channel */
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 255)); /* pseudo */
@@ -8437,6 +9026,7 @@
class_destroy(dahdi_class);
unregister_chrdev(DAHDI_MAJOR, "dahdi");
+#endif
#ifdef CONFIG_PROC_FS
remove_proc_entry("dahdi", NULL);
@@ -8453,5 +9043,28 @@
#endif
}
+#if defined(__FreeBSD__)
+static int
+dahdi_modevent(module_t mod, int cmd, void *arg)
+{
+ switch (cmd) {
+ case MOD_LOAD:
+ return dahdi_init();
+
+ case MOD_UNLOAD:
+ dahdi_cleanup();
+ return 0;
+
+ default:
+ /* we only understand load/unload*/
+ return -EINVAL;
+ }
+}
+
[... 4388 lines stripped ...]
More information about the svn-commits
mailing list