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:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user