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
This commit is contained in:
Tzafrir Cohen
2011-01-10 21:30:54 +00:00
parent d5520c533a
commit 244dd928e5

View File

@@ -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,
};
#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;
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");
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);
#endif
if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) {
module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
return res;
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;
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");
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");