summaryrefslogtreecommitdiff
path: root/zaptel.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-31 17:27:30 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-31 17:27:30 +0000
commit92e6d005b1107055cdd62f41fc06bda8e98b14b3 (patch)
tree530476168181ed67fa632f008cca8ac1040eef0a /zaptel.c
parentec54d1fb2b09fc3a4027a58317d190a403b148eb (diff)
merge support for the Digium TC400B hardware transcoder
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2057 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'zaptel.c')
-rw-r--r--zaptel.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/zaptel.c b/zaptel.c
index 9ff991c..0625e2e 100644
--- a/zaptel.c
+++ b/zaptel.c
@@ -79,6 +79,7 @@
#define FAST_HDLC_NEED_TABLES
#include "fasthdlc.h"
+#include <linux/types.h>
#ifdef STANDALONE_ZAPATA
#include "zaptel.h"
#else
@@ -118,6 +119,7 @@ static char *zt_txlevelnames[] = {
"-22.5db (CSU)"
} ;
+EXPORT_SYMBOL(zt_transcode_fops);
EXPORT_SYMBOL(zt_init_tone_state);
EXPORT_SYMBOL(zt_dtmf_tone);
EXPORT_SYMBOL(zt_register);
@@ -154,6 +156,7 @@ static devfs_handle_t channel;
static devfs_handle_t pseudo;
static devfs_handle_t ctl;
static devfs_handle_t timer;
+static devfs_handle_t transcode;
#endif
/* udev necessary data structures. Yeah! */
@@ -249,6 +252,7 @@ static sumtype *conf_sums_prev;
static struct zt_span *master;
static struct file_operations zt_fops;
+struct file_operations *zt_transcode_fops = NULL;
static struct
{
@@ -2316,10 +2320,26 @@ static void zt_free_pseudo(struct zt_chan *pseudo)
static int zt_open(struct inode *inode, struct file *file)
{
int unit = UNIT(file);
+ int ret = -ENXIO;
struct zt_chan *chan;
/* Minor 0: Special "control" descriptor */
if (!unit)
return zt_ctl_open(inode, file);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (unit == 250) {
+ if (!zt_transcode_fops)
+ request_module("zttranscode");
+ if (zt_transcode_fops && zt_transcode_fops->open) {
+ if (try_module_get(zt_transcode_fops->owner)) {
+ ret = zt_transcode_fops->open(inode, file);
+ if (ret)
+ module_put(zt_transcode_fops->owner);
+ }
+ return ret;
+ }
+ return -ENXIO;
+ }
+#endif
if (unit == 253) {
if (maxspans) {
return zt_timing_open(inode, file);
@@ -2644,6 +2664,13 @@ static int zt_release(struct inode *inode, struct file *file)
if (unit == 253) {
return zt_timer_release(inode, file);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (unit == 250) {
+ res = zt_transcode_fops->release(inode, file);
+ module_put(zt_transcode_fops->owner);
+ return res;
+ }
+#endif
if (unit == 254) {
chan = file->private_data;
if (!chan)
@@ -4395,6 +4422,10 @@ static int zt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
if (!unit)
return zt_ctl_ioctl(inode, file, cmd, data);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (unit == 250)
+ return zt_transcode_fops->ioctl(inode, file, cmd, data);
+#endif
if (unit == 253) {
timer = file->private_data;
if (timer)
@@ -6097,6 +6128,16 @@ zt_chan_poll(struct file *file, struct poll_table_struct *wait_table, int unit)
return(ret); /* return what we found */
}
+static int zt_mmap(struct file *file, struct vm_area_struct *vm)
+{
+ int unit = UNIT(file);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (unit == 250)
+ return zt_transcode_fops->mmap(file, vm);
+#endif
+ return -ENOSYS;
+}
+
static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_table)
{
int unit = UNIT(file);
@@ -6104,7 +6145,10 @@ static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_ta
if (!unit)
return -EINVAL;
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (unit == 250)
+ return zt_transcode_fops->poll(file, wait_table);
+#endif
if (unit == 253)
return zt_timer_poll(file, wait_table);
@@ -6480,7 +6524,7 @@ static struct file_operations zt_fops = {
read: zt_read,
write: zt_write,
poll: zt_poll,
- mmap: NULL,
+ mmap: zt_mmap,
flush: NULL,
fsync: NULL,
fasync: NULL,
@@ -6555,6 +6599,7 @@ static int __init zt_init(void) {
#ifdef CONFIG_ZAP_UDEV /* udev support functions */
zap_class = class_create(THIS_MODULE, "zaptel");
+ CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 250), NULL, "zaptranscode");
CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 253), NULL, "zaptimer");
CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 254), NULL, "zapchannel");
CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 255), NULL, "zappseudo");
@@ -6567,6 +6612,7 @@ static int __init zt_init(void) {
devfs_register_chrdev(ZT_MAJOR, "zaptel", &zt_fops);
zaptel_devfs_dir = devfs_mk_dir(NULL, "zap", NULL);
if (!zaptel_devfs_dir) return -EBUSY; /* This would be bad */
+ transcode = devfs_register(zaptel_devfs_dir, "transcode", DEVFS_FL_DEFAULT, ZT_MAJOR, 250, mode, &zt_fops, NULL);
timer = devfs_register(zaptel_devfs_dir, "timer", DEVFS_FL_DEFAULT, ZT_MAJOR, 253, mode, &zt_fops, NULL);
channel = devfs_register(zaptel_devfs_dir, "channel", DEVFS_FL_DEFAULT, ZT_MAJOR, 254, mode, &zt_fops, NULL);
pseudo = devfs_register(zaptel_devfs_dir, "pseudo", DEVFS_FL_DEFAULT, ZT_MAJOR, 255, mode, &zt_fops, NULL);
@@ -6606,6 +6652,7 @@ static void __exit zt_cleanup(void) {
kfree(tone_zones[x]);
#ifdef CONFIG_DEVFS_FS
devfs_unregister(timer);
+ devfs_unregister(transcode);
devfs_unregister(channel);
devfs_unregister(pseudo);
devfs_unregister(ctl);
@@ -6614,6 +6661,7 @@ static void __exit zt_cleanup(void) {
#else
#ifdef CONFIG_ZAP_UDEV
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 253)); /* timer */
+ class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 250)); /* transcode */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 254)); /* channel */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 255)); /* pseudo */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 0)); /* ctl */