summaryrefslogtreecommitdiff
path: root/drivers/dahdi/dahdi-base.c
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-01-10 21:30:54 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-01-10 21:30:54 +0000
commit75e299f20fbba1ddfcb983d7be3da27eb0152e95 (patch)
treebba72b61bc543b5b72a52b76937b14aa6e89d0b5 /drivers/dahdi/dahdi-base.c
parentebd396872801f4998d413872716d743dee9cd9fe (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.c151
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");