diff options
-rw-r--r-- | include/linux/device.h | 1 | ||||
-rw-r--r-- | include/linux/module.h | 2 | ||||
-rw-r--r-- | kernel/module.c | 33 | ||||
-rw-r--r-- | kernel/params.c | 12 |
4 files changed, 31 insertions, 17 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index f44247fe8135..da7221913114 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -126,6 +126,7 @@ struct device_driver { | |||
126 | struct klist_node knode_bus; | 126 | struct klist_node knode_bus; |
127 | 127 | ||
128 | struct module * owner; | 128 | struct module * owner; |
129 | const char * mod_name; /* used for built-in modules */ | ||
129 | 130 | ||
130 | int (*probe) (struct device * dev); | 131 | int (*probe) (struct device * dev); |
131 | int (*remove) (struct device * dev); | 132 | int (*remove) (struct device * dev); |
diff --git a/include/linux/module.h b/include/linux/module.h index 10f771a49997..90dc2542978c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -58,6 +58,7 @@ struct module_kobject | |||
58 | { | 58 | { |
59 | struct kobject kobj; | 59 | struct kobject kobj; |
60 | struct module *mod; | 60 | struct module *mod; |
61 | struct kobject *drivers_dir; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | /* These are either module local, or the kernel's dummy ones. */ | 64 | /* These are either module local, or the kernel's dummy ones. */ |
@@ -263,7 +264,6 @@ struct module | |||
263 | struct module_attribute *modinfo_attrs; | 264 | struct module_attribute *modinfo_attrs; |
264 | const char *version; | 265 | const char *version; |
265 | const char *srcversion; | 266 | const char *srcversion; |
266 | struct kobject *drivers_dir; | ||
267 | 267 | ||
268 | /* Exported symbols */ | 268 | /* Exported symbols */ |
269 | const struct kernel_symbol *syms; | 269 | const struct kernel_symbol *syms; |
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, | |||
1131 | if (err) | 1131 | if (err) |
1132 | goto out; | 1132 | goto out; |
1133 | 1133 | ||
1134 | mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); | 1134 | mod->mkobj.drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); |
1135 | if (!mod->drivers_dir) { | 1135 | if (!mod->mkobj.drivers_dir) { |
1136 | err = -ENOMEM; | 1136 | err = -ENOMEM; |
1137 | goto out_unreg; | 1137 | goto out_unreg; |
1138 | } | 1138 | } |
@@ -1151,7 +1151,7 @@ static int mod_sysfs_setup(struct module *mod, | |||
1151 | out_unreg_param: | 1151 | out_unreg_param: |
1152 | module_param_sysfs_remove(mod); | 1152 | module_param_sysfs_remove(mod); |
1153 | out_unreg_drivers: | 1153 | out_unreg_drivers: |
1154 | kobject_unregister(mod->drivers_dir); | 1154 | kobject_unregister(mod->mkobj.drivers_dir); |
1155 | out_unreg: | 1155 | out_unreg: |
1156 | kobject_del(&mod->mkobj.kobj); | 1156 | kobject_del(&mod->mkobj.kobj); |
1157 | kobject_put(&mod->mkobj.kobj); | 1157 | kobject_put(&mod->mkobj.kobj); |
@@ -1163,7 +1163,7 @@ static void mod_kobject_remove(struct module *mod) | |||
1163 | { | 1163 | { |
1164 | module_remove_modinfo_attrs(mod); | 1164 | module_remove_modinfo_attrs(mod); |
1165 | module_param_sysfs_remove(mod); | 1165 | module_param_sysfs_remove(mod); |
1166 | kobject_unregister(mod->drivers_dir); | 1166 | kobject_unregister(mod->mkobj.drivers_dir); |
1167 | 1167 | ||
1168 | kobject_unregister(&mod->mkobj.kobj); | 1168 | kobject_unregister(&mod->mkobj.kobj); |
1169 | } | 1169 | } |
@@ -2344,15 +2344,30 @@ void module_add_driver(struct module *mod, struct device_driver *drv) | |||
2344 | { | 2344 | { |
2345 | char *driver_name; | 2345 | char *driver_name; |
2346 | int no_warn; | 2346 | int no_warn; |
2347 | struct module_kobject *mk = NULL; | ||
2347 | 2348 | ||
2348 | if (!mod || !drv) | 2349 | if (!drv) |
2350 | return; | ||
2351 | |||
2352 | if (mod) | ||
2353 | mk = &mod->mkobj; | ||
2354 | else if (drv->mod_name) { | ||
2355 | struct kobject *mkobj; | ||
2356 | |||
2357 | /* Lookup built-in module entry in /sys/modules */ | ||
2358 | mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name); | ||
2359 | if (mkobj) | ||
2360 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
2361 | } | ||
2362 | |||
2363 | if (!mk) | ||
2349 | return; | 2364 | return; |
2350 | 2365 | ||
2351 | /* Don't check return codes; these calls are idempotent */ | 2366 | /* Don't check return codes; these calls are idempotent */ |
2352 | no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); | 2367 | no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); |
2353 | driver_name = make_driver_name(drv); | 2368 | driver_name = make_driver_name(drv); |
2354 | if (driver_name) { | 2369 | if (driver_name) { |
2355 | no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, | 2370 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, |
2356 | driver_name); | 2371 | driver_name); |
2357 | kfree(driver_name); | 2372 | kfree(driver_name); |
2358 | } | 2373 | } |
@@ -2367,10 +2382,10 @@ void module_remove_driver(struct device_driver *drv) | |||
2367 | return; | 2382 | return; |
2368 | 2383 | ||
2369 | sysfs_remove_link(&drv->kobj, "module"); | 2384 | sysfs_remove_link(&drv->kobj, "module"); |
2370 | if (drv->owner && drv->owner->drivers_dir) { | 2385 | if (drv->owner && drv->owner->mkobj.drivers_dir) { |
2371 | driver_name = make_driver_name(drv); | 2386 | driver_name = make_driver_name(drv); |
2372 | if (driver_name) { | 2387 | if (driver_name) { |
2373 | sysfs_remove_link(drv->owner->drivers_dir, | 2388 | sysfs_remove_link(drv->owner->mkobj.drivers_dir, |
2374 | driver_name); | 2389 | driver_name); |
2375 | kfree(driver_name); | 2390 | kfree(driver_name); |
2376 | } | 2391 | } |
diff --git a/kernel/params.c b/kernel/params.c index 718945da8f58..737b7c5e93aa 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -561,14 +561,12 @@ static void __init kernel_param_sysfs_setup(const char *name, | |||
561 | mk->mod = THIS_MODULE; | 561 | mk->mod = THIS_MODULE; |
562 | kobj_set_kset_s(mk, module_subsys); | 562 | kobj_set_kset_s(mk, module_subsys); |
563 | kobject_set_name(&mk->kobj, name); | 563 | kobject_set_name(&mk->kobj, name); |
564 | ret = kobject_register(&mk->kobj); | 564 | kobject_init(&mk->kobj); |
565 | ret = kobject_add(&mk->kobj); | ||
565 | BUG_ON(ret < 0); | 566 | BUG_ON(ret < 0); |
566 | 567 | param_sysfs_setup(mk, kparam, num_params, name_skip); | |
567 | /* no need to keep the kobject if no parameter is exported */ | 568 | mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers"); |
568 | if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) { | 569 | kobject_uevent(&mk->kobj, KOBJ_ADD); |
569 | kobject_unregister(&mk->kobj); | ||
570 | kfree(mk); | ||
571 | } | ||
572 | } | 570 | } |
573 | 571 | ||
574 | /* | 572 | /* |