diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2006-12-20 10:39:33 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-01-05 12:33:38 -0800 |
commit | 7f422e2e84307bdd9b51c19a602e1601d160aebc (patch) | |
tree | f4e8ab9aeb5e9ee57eb7e05718b0c46dac9dd015 /kernel/module.c | |
parent | 05a8057bb38bc803682f3e0af305c258b4566285 (diff) |
[PATCH] Driver core: Fix prefix driver links in /sys/module by bus-name
Modules may have drivers with the same name on different buses.
This patch fixes this problem.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/kernel/module.c b/kernel/module.c index dbce132b354..d0f2260a021 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1148,10 +1148,10 @@ static int mod_sysfs_setup(struct module *mod, kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); return 0; -out_unreg_drivers: - kobject_unregister(mod->drivers_dir); out_unreg_param: module_param_sysfs_remove(mod); +out_unreg_drivers: + kobject_unregister(mod->drivers_dir); out_unreg: kobject_del(&mod->mkobj.kobj); kobject_put(&mod->mkobj.kobj); @@ -2327,8 +2327,22 @@ void print_modules(void) printk("\n"); } +static char *make_driver_name(struct device_driver *drv) +{ + char *driver_name; + + driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, + GFP_KERNEL); + if (!driver_name) + return NULL; + + sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); + return driver_name; +} + void module_add_driver(struct module *mod, struct device_driver *drv) { + char *driver_name; int no_warn; if (!mod || !drv) @@ -2336,17 +2350,31 @@ void module_add_driver(struct module *mod, struct device_driver *drv) /* Don't check return codes; these calls are idempotent */ no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); - no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, drv->name); + driver_name = make_driver_name(drv); + if (driver_name) { + no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, + driver_name); + kfree(driver_name); + } } EXPORT_SYMBOL(module_add_driver); void module_remove_driver(struct device_driver *drv) { + char *driver_name; + if (!drv) return; + sysfs_remove_link(&drv->kobj, "module"); - if (drv->owner && drv->owner->drivers_dir) - sysfs_remove_link(drv->owner->drivers_dir, drv->name); + if (drv->owner && drv->owner->drivers_dir) { + driver_name = make_driver_name(drv); + if (driver_name) { + sysfs_remove_link(drv->owner->drivers_dir, + driver_name); + kfree(driver_name); + } + } } EXPORT_SYMBOL(module_remove_driver); |