diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-06-23 15:11:45 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-06-23 15:11:45 +0000 |
commit | 93820c7b1970ab51552deeb444964b900522d5b0 (patch) | |
tree | 19382abb5c960730b1b510636fa1289e68da9184 /zaptel.c | |
parent | 43f2f3ea520866189bedefedf3a96172c2c9681d (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.c | 43 |
1 files changed, 42 insertions, 1 deletions
@@ -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 */ |