summaryrefslogtreecommitdiff
path: root/zaptel.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-23 15:11:45 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-23 15:11:45 +0000
commit93820c7b1970ab51552deeb444964b900522d5b0 (patch)
tree19382abb5c960730b1b510636fa1289e68da9184 /zaptel.c
parent43f2f3ea520866189bedefedf3a96172c2c9681d (diff)
add infrastructure for zaptel transcoders
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1162 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'zaptel.c')
-rw-r--r--zaptel.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/zaptel.c b/zaptel.c
index 58f723b..8e22356 100644
--- a/zaptel.c
+++ b/zaptel.c
@@ -150,6 +150,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);
@@ -190,6 +191,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! */
@@ -283,6 +285,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
{
@@ -2389,10 +2392,24 @@ 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 (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;
+ }
if (unit == 253) {
if (maxspans) {
return zt_timing_open(inode, file);
@@ -2715,6 +2732,11 @@ static int zt_release(struct inode *inode, struct file *file)
if (unit == 253) {
return zt_timer_release(inode, file);
}
+ if (unit == 250) {
+ res = zt_transcode_fops->release(inode, file);
+ module_put(zt_transcode_fops->owner);
+ return res;
+ }
if (unit == 254) {
chan = file->private_data;
if (!chan)
@@ -4492,6 +4514,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 (unit == 250)
+ return zt_transcode_fops->ioctl(inode, file, cmd, data);
+
if (unit == 253) {
timer = file->private_data;
if (timer)
@@ -6369,6 +6395,14 @@ 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 (unit == 250)
+ return zt_transcode_fops->mmap(file, vm);
+ return -ENOSYS;
+}
+
static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_table)
{
int unit = UNIT(file);
@@ -6377,6 +6411,9 @@ static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_ta
if (!unit)
return -EINVAL;
+ if (unit == 250)
+ return zt_transcode_fops->poll(file, wait_table);
+
if (unit == 253)
return zt_timer_poll(file, wait_table);
@@ -6758,7 +6795,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,
@@ -6833,6 +6870,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");
@@ -6848,6 +6886,7 @@ static int __init zt_init(void) {
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);
+ transcode = devfs_register(zaptel_devfs_dir, "transcode", DEVFS_FL_DEFAULT, ZT_MAJOR, 250, mode, &zt_fops, NULL);
ctl = devfs_register(zaptel_devfs_dir, "ctl", DEVFS_FL_DEFAULT, ZT_MAJOR, 0, mode, &zt_fops, NULL);
}
#else
@@ -6884,6 +6923,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);
@@ -6891,6 +6931,7 @@ static void __exit zt_cleanup(void) {
devfs_unregister_chrdev(ZT_MAJOR, "zaptel");
#else
#ifdef CONFIG_ZAP_UDEV
+ class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 250)); /* transcode */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 253)); /* timer */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 254)); /* channel */
class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 255)); /* pseudo */