From f30c53a873d0d227493197064b8886af2d57bbd6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Jan 2007 20:22:02 +0100 Subject: MODULES: add the module name for built in kernel drivers Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/module.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index d0f2260a0210..0f4489af3e29 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1131,8 +1131,8 @@ static int mod_sysfs_setup(struct module *mod, if (err) goto out; - mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); - if (!mod->drivers_dir) { + mod->mkobj.drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); + if (!mod->mkobj.drivers_dir) { err = -ENOMEM; goto out_unreg; } @@ -1151,7 +1151,7 @@ static int mod_sysfs_setup(struct module *mod, out_unreg_param: module_param_sysfs_remove(mod); out_unreg_drivers: - kobject_unregister(mod->drivers_dir); + kobject_unregister(mod->mkobj.drivers_dir); out_unreg: kobject_del(&mod->mkobj.kobj); kobject_put(&mod->mkobj.kobj); @@ -1163,7 +1163,7 @@ static void mod_kobject_remove(struct module *mod) { module_remove_modinfo_attrs(mod); module_param_sysfs_remove(mod); - kobject_unregister(mod->drivers_dir); + kobject_unregister(mod->mkobj.drivers_dir); kobject_unregister(&mod->mkobj.kobj); } @@ -2344,15 +2344,30 @@ void module_add_driver(struct module *mod, struct device_driver *drv) { char *driver_name; int no_warn; + struct module_kobject *mk = NULL; - if (!mod || !drv) + if (!drv) + return; + + if (mod) + mk = &mod->mkobj; + else if (drv->mod_name) { + struct kobject *mkobj; + + /* Lookup built-in module entry in /sys/modules */ + mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name); + if (mkobj) + mk = container_of(mkobj, struct module_kobject, kobj); + } + + if (!mk) return; /* 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(&drv->kobj, &mk->kobj, "module"); driver_name = make_driver_name(drv); if (driver_name) { - no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, + no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, driver_name); kfree(driver_name); } @@ -2367,10 +2382,10 @@ void module_remove_driver(struct device_driver *drv) return; sysfs_remove_link(&drv->kobj, "module"); - if (drv->owner && drv->owner->drivers_dir) { + if (drv->owner && drv->owner->mkobj.drivers_dir) { driver_name = make_driver_name(drv); if (driver_name) { - sysfs_remove_link(drv->owner->drivers_dir, + sysfs_remove_link(drv->owner->mkobj.drivers_dir, driver_name); kfree(driver_name); } -- cgit v1.2.2 From fe480a2675ed236af396597d9f05245c7bbd0149 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Jan 2007 11:50:02 -0800 Subject: Modules: only add drivers/ direcory if needed This changes the module core to only create the drivers/ directory if we are going to put something in it. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/module.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index 0f4489af3e29..9de4209f6a67 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1131,12 +1131,6 @@ static int mod_sysfs_setup(struct module *mod, if (err) goto out; - mod->mkobj.drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); - if (!mod->mkobj.drivers_dir) { - err = -ENOMEM; - goto out_unreg; - } - err = module_param_sysfs_setup(mod, kparam, num_params); if (err) goto out_unreg_drivers; @@ -1151,8 +1145,6 @@ static int mod_sysfs_setup(struct module *mod, out_unreg_param: module_param_sysfs_remove(mod); out_unreg_drivers: - kobject_unregister(mod->mkobj.drivers_dir); -out_unreg: kobject_del(&mod->mkobj.kobj); kobject_put(&mod->mkobj.kobj); out: @@ -1163,7 +1155,8 @@ static void mod_kobject_remove(struct module *mod) { module_remove_modinfo_attrs(mod); module_param_sysfs_remove(mod); - kobject_unregister(mod->mkobj.drivers_dir); + if (mod->mkobj.drivers_dir) + kobject_unregister(mod->mkobj.drivers_dir); kobject_unregister(&mod->mkobj.kobj); } @@ -2340,6 +2333,14 @@ static char *make_driver_name(struct device_driver *drv) return driver_name; } +static void module_create_drivers_dir(struct module_kobject *mk) +{ + if (!mk || mk->drivers_dir) + return; + + mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers"); +} + void module_add_driver(struct module *mod, struct device_driver *drv) { char *driver_name; @@ -2367,6 +2368,7 @@ void module_add_driver(struct module *mod, struct device_driver *drv) no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); driver_name = make_driver_name(drv); if (driver_name) { + module_create_drivers_dir(mk); no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, driver_name); kfree(driver_name); -- cgit v1.2.2 From 270a6c4cad809e92d7b81adde92d0b3d94eeb8ee Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Jan 2007 13:26:15 +0100 Subject: /sys/modules/*/holders /sys/module/usbcore/ |-- drivers | |-- usb:hub -> ../../../subsystem/usb/drivers/hub | |-- usb:usb -> ../../../subsystem/usb/drivers/usb | `-- usb:usbfs -> ../../../subsystem/usb/drivers/usbfs |-- holders | |-- ehci_hcd -> ../../../module/ehci_hcd | |-- uhci_hcd -> ../../../module/uhci_hcd | |-- usb_storage -> ../../../module/usb_storage | `-- usbhid -> ../../../module/usbhid |-- initstate Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/module.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index 9de4209f6a67..8a94e054230c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -537,6 +537,8 @@ static int already_uses(struct module *a, struct module *b) static int use_module(struct module *a, struct module *b) { struct module_use *use; + int no_warn; + if (b == NULL || already_uses(a, b)) return 1; if (!strong_try_module_get(b)) @@ -552,6 +554,7 @@ static int use_module(struct module *a, struct module *b) use->module_which_uses = a; list_add(&use->list, &b->modules_which_use_me); + no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); return 1; } @@ -569,6 +572,7 @@ static void module_unload_free(struct module *mod) module_put(i); list_del(&use->list); kfree(use); + sysfs_remove_link(i->holders_dir, mod->name); /* There can be at most one match. */ break; } @@ -1106,9 +1110,7 @@ static void module_remove_modinfo_attrs(struct module *mod) kfree(mod->modinfo_attrs); } -static int mod_sysfs_setup(struct module *mod, - struct kernel_param *kparam, - unsigned int num_params) +static int mod_sysfs_init(struct module *mod) { int err; @@ -1125,15 +1127,30 @@ static int mod_sysfs_setup(struct module *mod, kobj_set_kset_s(&mod->mkobj, module_subsys); mod->mkobj.mod = mod; - /* delay uevent until full sysfs population */ kobject_init(&mod->mkobj.kobj); + +out: + return err; +} + +static int mod_sysfs_setup(struct module *mod, + struct kernel_param *kparam, + unsigned int num_params) +{ + int err; + + /* delay uevent until full sysfs population */ err = kobject_add(&mod->mkobj.kobj); if (err) goto out; + mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders"); + if (!mod->holders_dir) + goto out_unreg; + err = module_param_sysfs_setup(mod, kparam, num_params); if (err) - goto out_unreg_drivers; + goto out_unreg_holders; err = module_add_modinfo_attrs(mod); if (err) @@ -1144,7 +1161,9 @@ static int mod_sysfs_setup(struct module *mod, out_unreg_param: module_param_sysfs_remove(mod); -out_unreg_drivers: +out_unreg_holders: + kobject_unregister(mod->holders_dir); +out_unreg: kobject_del(&mod->mkobj.kobj); kobject_put(&mod->mkobj.kobj); out: @@ -1157,6 +1176,8 @@ static void mod_kobject_remove(struct module *mod) module_param_sysfs_remove(mod); if (mod->mkobj.drivers_dir) kobject_unregister(mod->mkobj.drivers_dir); + if (mod->holders_dir) + kobject_unregister(mod->holders_dir); kobject_unregister(&mod->mkobj.kobj); } @@ -1761,6 +1782,10 @@ static struct module *load_module(void __user *umod, /* Now we've moved module, initialize linked lists, etc. */ module_unload_init(mod); + /* Initialize kobject, so we can reference it. */ + if (mod_sysfs_init(mod) != 0) + goto cleanup; + /* Set up license info based on the info section */ set_license(mod, get_modinfo(sechdrs, infoindex, "license")); -- cgit v1.2.2