diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 128 |
1 files changed, 18 insertions, 110 deletions
diff --git a/kernel/module.c b/kernel/module.c index c2e3e2e98801..dcb8a2cbf75e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -47,8 +47,6 @@ | |||
47 | #include <asm/cacheflush.h> | 47 | #include <asm/cacheflush.h> |
48 | #include <linux/license.h> | 48 | #include <linux/license.h> |
49 | 49 | ||
50 | extern int module_sysfs_initialized; | ||
51 | |||
52 | #if 0 | 50 | #if 0 |
53 | #define DEBUGP printk | 51 | #define DEBUGP printk |
54 | #else | 52 | #else |
@@ -1122,7 +1120,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, | |||
1122 | ++loaded; | 1120 | ++loaded; |
1123 | } | 1121 | } |
1124 | 1122 | ||
1125 | notes_attrs->dir = kobject_add_dir(&mod->mkobj.kobj, "notes"); | 1123 | notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj); |
1126 | if (!notes_attrs->dir) | 1124 | if (!notes_attrs->dir) |
1127 | goto out; | 1125 | goto out; |
1128 | 1126 | ||
@@ -1219,15 +1217,16 @@ int mod_sysfs_init(struct module *mod) | |||
1219 | err = -EINVAL; | 1217 | err = -EINVAL; |
1220 | goto out; | 1218 | goto out; |
1221 | } | 1219 | } |
1222 | memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); | ||
1223 | err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name); | ||
1224 | if (err) | ||
1225 | goto out; | ||
1226 | kobj_set_kset_s(&mod->mkobj, module_subsys); | ||
1227 | mod->mkobj.mod = mod; | 1220 | mod->mkobj.mod = mod; |
1228 | 1221 | ||
1229 | kobject_init(&mod->mkobj.kobj); | 1222 | memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); |
1223 | mod->mkobj.kobj.kset = module_kset; | ||
1224 | err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, | ||
1225 | "%s", mod->name); | ||
1226 | if (err) | ||
1227 | kobject_put(&mod->mkobj.kobj); | ||
1230 | 1228 | ||
1229 | /* delay uevent until full sysfs population */ | ||
1231 | out: | 1230 | out: |
1232 | return err; | 1231 | return err; |
1233 | } | 1232 | } |
@@ -1238,12 +1237,7 @@ int mod_sysfs_setup(struct module *mod, | |||
1238 | { | 1237 | { |
1239 | int err; | 1238 | int err; |
1240 | 1239 | ||
1241 | /* delay uevent until full sysfs population */ | 1240 | mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj); |
1242 | err = kobject_add(&mod->mkobj.kobj); | ||
1243 | if (err) | ||
1244 | goto out; | ||
1245 | |||
1246 | mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders"); | ||
1247 | if (!mod->holders_dir) { | 1241 | if (!mod->holders_dir) { |
1248 | err = -ENOMEM; | 1242 | err = -ENOMEM; |
1249 | goto out_unreg; | 1243 | goto out_unreg; |
@@ -1263,11 +1257,9 @@ int mod_sysfs_setup(struct module *mod, | |||
1263 | out_unreg_param: | 1257 | out_unreg_param: |
1264 | module_param_sysfs_remove(mod); | 1258 | module_param_sysfs_remove(mod); |
1265 | out_unreg_holders: | 1259 | out_unreg_holders: |
1266 | kobject_unregister(mod->holders_dir); | 1260 | kobject_put(mod->holders_dir); |
1267 | out_unreg: | 1261 | out_unreg: |
1268 | kobject_del(&mod->mkobj.kobj); | ||
1269 | kobject_put(&mod->mkobj.kobj); | 1262 | kobject_put(&mod->mkobj.kobj); |
1270 | out: | ||
1271 | return err; | 1263 | return err; |
1272 | } | 1264 | } |
1273 | #endif | 1265 | #endif |
@@ -1276,9 +1268,9 @@ static void mod_kobject_remove(struct module *mod) | |||
1276 | { | 1268 | { |
1277 | module_remove_modinfo_attrs(mod); | 1269 | module_remove_modinfo_attrs(mod); |
1278 | module_param_sysfs_remove(mod); | 1270 | module_param_sysfs_remove(mod); |
1279 | kobject_unregister(mod->mkobj.drivers_dir); | 1271 | kobject_put(mod->mkobj.drivers_dir); |
1280 | kobject_unregister(mod->holders_dir); | 1272 | kobject_put(mod->holders_dir); |
1281 | kobject_unregister(&mod->mkobj.kobj); | 1273 | kobject_put(&mod->mkobj.kobj); |
1282 | } | 1274 | } |
1283 | 1275 | ||
1284 | /* | 1276 | /* |
@@ -1884,10 +1876,10 @@ static struct module *load_module(void __user *umod, | |||
1884 | /* Now we've moved module, initialize linked lists, etc. */ | 1876 | /* Now we've moved module, initialize linked lists, etc. */ |
1885 | module_unload_init(mod); | 1877 | module_unload_init(mod); |
1886 | 1878 | ||
1887 | /* Initialize kobject, so we can reference it. */ | 1879 | /* add kobject, so we can reference it. */ |
1888 | err = mod_sysfs_init(mod); | 1880 | err = mod_sysfs_init(mod); |
1889 | if (err) | 1881 | if (err) |
1890 | goto cleanup; | 1882 | goto free_unload; |
1891 | 1883 | ||
1892 | /* Set up license info based on the info section */ | 1884 | /* Set up license info based on the info section */ |
1893 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); | 1885 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); |
@@ -2057,6 +2049,9 @@ static struct module *load_module(void __user *umod, | |||
2057 | arch_cleanup: | 2049 | arch_cleanup: |
2058 | module_arch_cleanup(mod); | 2050 | module_arch_cleanup(mod); |
2059 | cleanup: | 2051 | cleanup: |
2052 | kobject_del(&mod->mkobj.kobj); | ||
2053 | kobject_put(&mod->mkobj.kobj); | ||
2054 | free_unload: | ||
2060 | module_unload_free(mod); | 2055 | module_unload_free(mod); |
2061 | module_free(mod, mod->module_init); | 2056 | module_free(mod, mod->module_init); |
2062 | free_core: | 2057 | free_core: |
@@ -2502,93 +2497,6 @@ void print_modules(void) | |||
2502 | printk("\n"); | 2497 | printk("\n"); |
2503 | } | 2498 | } |
2504 | 2499 | ||
2505 | #ifdef CONFIG_SYSFS | ||
2506 | static char *make_driver_name(struct device_driver *drv) | ||
2507 | { | ||
2508 | char *driver_name; | ||
2509 | |||
2510 | driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | ||
2511 | GFP_KERNEL); | ||
2512 | if (!driver_name) | ||
2513 | return NULL; | ||
2514 | |||
2515 | sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | ||
2516 | return driver_name; | ||
2517 | } | ||
2518 | |||
2519 | static void module_create_drivers_dir(struct module_kobject *mk) | ||
2520 | { | ||
2521 | if (!mk || mk->drivers_dir) | ||
2522 | return; | ||
2523 | |||
2524 | mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers"); | ||
2525 | } | ||
2526 | |||
2527 | void module_add_driver(struct module *mod, struct device_driver *drv) | ||
2528 | { | ||
2529 | char *driver_name; | ||
2530 | int no_warn; | ||
2531 | struct module_kobject *mk = NULL; | ||
2532 | |||
2533 | if (!drv) | ||
2534 | return; | ||
2535 | |||
2536 | if (mod) | ||
2537 | mk = &mod->mkobj; | ||
2538 | else if (drv->mod_name) { | ||
2539 | struct kobject *mkobj; | ||
2540 | |||
2541 | /* Lookup built-in module entry in /sys/modules */ | ||
2542 | mkobj = kset_find_obj(&module_subsys, drv->mod_name); | ||
2543 | if (mkobj) { | ||
2544 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
2545 | /* remember our module structure */ | ||
2546 | drv->mkobj = mk; | ||
2547 | /* kset_find_obj took a reference */ | ||
2548 | kobject_put(mkobj); | ||
2549 | } | ||
2550 | } | ||
2551 | |||
2552 | if (!mk) | ||
2553 | return; | ||
2554 | |||
2555 | /* Don't check return codes; these calls are idempotent */ | ||
2556 | no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); | ||
2557 | driver_name = make_driver_name(drv); | ||
2558 | if (driver_name) { | ||
2559 | module_create_drivers_dir(mk); | ||
2560 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, | ||
2561 | driver_name); | ||
2562 | kfree(driver_name); | ||
2563 | } | ||
2564 | } | ||
2565 | EXPORT_SYMBOL(module_add_driver); | ||
2566 | |||
2567 | void module_remove_driver(struct device_driver *drv) | ||
2568 | { | ||
2569 | struct module_kobject *mk = NULL; | ||
2570 | char *driver_name; | ||
2571 | |||
2572 | if (!drv) | ||
2573 | return; | ||
2574 | |||
2575 | sysfs_remove_link(&drv->kobj, "module"); | ||
2576 | |||
2577 | if (drv->owner) | ||
2578 | mk = &drv->owner->mkobj; | ||
2579 | else if (drv->mkobj) | ||
2580 | mk = drv->mkobj; | ||
2581 | if (mk && mk->drivers_dir) { | ||
2582 | driver_name = make_driver_name(drv); | ||
2583 | if (driver_name) { | ||
2584 | sysfs_remove_link(mk->drivers_dir, driver_name); | ||
2585 | kfree(driver_name); | ||
2586 | } | ||
2587 | } | ||
2588 | } | ||
2589 | EXPORT_SYMBOL(module_remove_driver); | ||
2590 | #endif | ||
2591 | |||
2592 | #ifdef CONFIG_MODVERSIONS | 2500 | #ifdef CONFIG_MODVERSIONS |
2593 | /* Generate the signature for struct module here, too, for modversions. */ | 2501 | /* Generate the signature for struct module here, too, for modversions. */ |
2594 | void struct_module(struct module *mod) { return; } | 2502 | void struct_module(struct module *mod) { return; } |