diff options
author | Tzafrir Cohen <tzafrir.cohen@xorcom.com> | 2011-01-10 21:30:54 +0000 |
---|---|---|
committer | Tzafrir Cohen <tzafrir.cohen@xorcom.com> | 2011-01-10 21:30:54 +0000 |
commit | 75e299f20fbba1ddfcb983d7be3da27eb0152e95 (patch) | |
tree | bba72b61bc543b5b72a52b76937b14aa6e89d0b5 /drivers/dahdi/dahdi-base.c | |
parent | ebd396872801f4998d413872716d743dee9cd9fe (diff) |
separate device init functions
Separate out device initialization and removal functions:
dahdi_sysfs_init() and dahdi_sysfs_exit(). A safer way of
generating the main device files.
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9623 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi-base.c')
-rw-r--r-- | drivers/dahdi/dahdi-base.c | 151 |
1 files changed, 128 insertions, 23 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 0564fd8..48666d3 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -57,6 +57,7 @@ #include <asm/atomic.h> +#define DAHDI_PRINK_MACROS_USE_debug #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) #include <dahdi/version.h> @@ -9323,27 +9324,123 @@ static const struct dahdi_echocan_factory hwec_factory = { .echocan_create = hwec_echocan_create, }; -static int __init dahdi_init(void) +#define MAKE_DAHDI_DEV(num, name) \ + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name) +#define DEL_DAHDI_DEV(num) \ + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num)) + +/* Only used to flag that the device exists: */ +static struct { + unsigned int ctl:1; + unsigned int timer:1; + unsigned int channel:1; + unsigned int pseudo:1; +} dummy_dev; + +static void dahdi_sysfs_exit(void) +{ + if (dummy_dev.pseudo) { + dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n"); + DEL_DAHDI_DEV(DAHDI_PSEUDO); + dummy_dev.pseudo = 0; + } + if (dummy_dev.channel) { + dahdi_dbg(DEVICES, "Removing /dev/dahdi/channel:\n"); + DEL_DAHDI_DEV(DAHDI_CHANNEL); + dummy_dev.channel = 0; + } + if (dummy_dev.timer) { + dahdi_dbg(DEVICES, "Removing /dev/dahdi/timer:\n"); + DEL_DAHDI_DEV(DAHDI_TIMER); + dummy_dev.timer = 0; + } + if (dummy_dev.ctl) { + dahdi_dbg(DEVICES, "Removing /dev/dahdi/ctl:\n"); + DEL_DAHDI_DEV(DAHDI_CTL); + dummy_dev.ctl = 0; + } + if (dahdi_class) { + dahdi_dbg(DEVICES, "Destroying DAHDI class:\n"); + class_destroy(dahdi_class); + dahdi_class = NULL; + } + unregister_chrdev(DAHDI_MAJOR, "dahdi"); +} + +static int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops) { int res = 0; + void *dev; -#ifdef CONFIG_PROC_FS - root_proc_entry = proc_mkdir("dahdi", NULL); -#endif - - if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) { + res = register_chrdev(DAHDI_MAJOR, "dahdi", dahdi_fops); + if (res) { module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR); return res; } + module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", + DAHDI_MAJOR); + module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION); dahdi_class = class_create(THIS_MODULE, "dahdi"); - CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_TIMER), NULL, "dahdi!timer"); - CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_CHANNEL), NULL, "dahdi!channel"); - CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_PSEUDO), NULL, "dahdi!pseudo"); - CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_CTL), NULL, "dahdi!ctl"); + if (!dahdi_class) { + res = -EEXIST; + goto cleanup; + } + + dahdi_dbg(DEVICES, "Creating /dev/dahdi/timer:\n"); + dev = MAKE_DAHDI_DEV(DAHDI_TIMER, "dahdi!timer"); + if (IS_ERR(dev)) { + res = PTR_ERR(dev); + goto cleanup; + } + dummy_dev.timer = 1; + + dahdi_dbg(DEVICES, "Creating /dev/dahdi/channel:\n"); + dev = MAKE_DAHDI_DEV(DAHDI_CHANNEL, "dahdi!channel"); + if (IS_ERR(dev)) { + res = PTR_ERR(dev); + goto cleanup; + } + dummy_dev.channel = 1; + + dahdi_dbg(DEVICES, "Creating /dev/dahdi/pseudo:\n"); + dev = MAKE_DAHDI_DEV(DAHDI_PSEUDO, "dahdi!pseudo"); + if (IS_ERR(dev)) { + res = PTR_ERR(dev); + goto cleanup; + } + dummy_dev.pseudo = 1; + + dahdi_dbg(DEVICES, "Creating /dev/dahdi/ctl:\n"); + dev = MAKE_DAHDI_DEV(DAHDI_CTL, "dahdi!ctl"); + if (IS_ERR(dev)) { + res = PTR_ERR(dev); + goto cleanup; + } + dummy_dev.ctl = 1; + + return 0; + +cleanup: + dahdi_sysfs_exit(); + return res; +} + +static int __init dahdi_init(void) +{ + int res = 0; + +#ifdef CONFIG_PROC_FS + root_proc_entry = proc_mkdir("dahdi", NULL); + if (!root_proc_entry) { + dahdi_err("dahdi init: Failed creating /proc/dahdi\n"); + return -EEXIST; + } +#endif + res = dahdi_sysfs_init(&dahdi_fops); + if (res) + goto failed_driver_init; - module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", DAHDI_MAJOR); - module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION); dahdi_conv_init(); fasthdlc_precalc(); rotate_sums(); @@ -9352,11 +9449,23 @@ static int __init dahdi_init(void) #endif coretimer_init(); - if (dahdi_register_echocan_factory(&hwec_factory)) { + res = dahdi_register_echocan_factory(&hwec_factory); + if (res) { WARN_ON(1); - return -EFAULT; + res = -EFAULT; + goto failed_register_ec_factory; } + return 0; + +failed_register_ec_factory: + coretimer_cleanup(); + dahdi_sysfs_exit(); +failed_driver_init: + if (root_proc_entry) { + remove_proc_entry("dahdi", NULL); + root_proc_entry = NULL; + } return res; } @@ -9378,17 +9487,13 @@ static void __exit dahdi_cleanup(void) dahdi_unregister_echocan_factory(&hwec_factory); coretimer_cleanup(); - - CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_TIMER)); /* timer */ - CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_CHANNEL)); /* channel */ - CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_PSEUDO)); /* pseudo */ - CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, DAHDI_CTL)); /* ctl */ - class_destroy(dahdi_class); - - unregister_chrdev(DAHDI_MAJOR, "dahdi"); + dahdi_sysfs_exit(); #ifdef CONFIG_PROC_FS - remove_proc_entry(root_proc_entry->name, NULL); + if (root_proc_entry) { + remove_proc_entry("dahdi", NULL); + root_proc_entry = NULL; + } #endif module_printk(KERN_INFO, "Telephony Interface Unloaded\n"); |