diff options
-rw-r--r-- | drivers/base/Makefile | 1 | ||||
-rw-r--r-- | drivers/base/base.h | 9 | ||||
-rw-r--r-- | drivers/base/module.c | 94 | ||||
-rw-r--r-- | include/linux/module.h | 15 | ||||
-rw-r--r-- | kernel/module.c | 87 |
5 files changed, 104 insertions, 102 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b39ea3f59c9b..ff2696823f8d 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o | |||
11 | obj-$(CONFIG_NUMA) += node.o | 11 | obj-$(CONFIG_NUMA) += node.o |
12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o | 12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o |
13 | obj-$(CONFIG_SMP) += topology.o | 13 | obj-$(CONFIG_SMP) += topology.o |
14 | obj-$(CONFIG_MODULES) += module.o | ||
14 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o | 15 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o |
15 | 16 | ||
16 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 17 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
diff --git a/drivers/base/base.h b/drivers/base/base.h index ca6d273064f8..05472360f6a2 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -73,3 +73,12 @@ extern char *make_class_name(const char *name, struct kobject *kobj); | |||
73 | extern int devres_release_all(struct device *dev); | 73 | extern int devres_release_all(struct device *dev); |
74 | 74 | ||
75 | extern struct kset *devices_kset; | 75 | extern struct kset *devices_kset; |
76 | |||
77 | #ifdef CONFIG_MODULES | ||
78 | extern void module_add_driver(struct module *mod, struct device_driver *drv); | ||
79 | extern void module_remove_driver(struct device_driver *drv); | ||
80 | #else | ||
81 | static inline void module_add_driver(struct module *mod, | ||
82 | struct device_driver *drv) { } | ||
83 | static inline void module_remove_driver(struct device_driver *drv) { } | ||
84 | #endif | ||
diff --git a/drivers/base/module.c b/drivers/base/module.c new file mode 100644 index 000000000000..cad07be5de1a --- /dev/null +++ b/drivers/base/module.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * module.c - module sysfs fun for drivers | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/device.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include "base.h" | ||
12 | |||
13 | static char *make_driver_name(struct device_driver *drv) | ||
14 | { | ||
15 | char *driver_name; | ||
16 | |||
17 | driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | ||
18 | GFP_KERNEL); | ||
19 | if (!driver_name) | ||
20 | return NULL; | ||
21 | |||
22 | sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | ||
23 | return driver_name; | ||
24 | } | ||
25 | |||
26 | static void module_create_drivers_dir(struct module_kobject *mk) | ||
27 | { | ||
28 | if (!mk || mk->drivers_dir) | ||
29 | return; | ||
30 | |||
31 | mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj); | ||
32 | } | ||
33 | |||
34 | void module_add_driver(struct module *mod, struct device_driver *drv) | ||
35 | { | ||
36 | char *driver_name; | ||
37 | int no_warn; | ||
38 | struct module_kobject *mk = NULL; | ||
39 | |||
40 | if (!drv) | ||
41 | return; | ||
42 | |||
43 | if (mod) | ||
44 | mk = &mod->mkobj; | ||
45 | else if (drv->mod_name) { | ||
46 | struct kobject *mkobj; | ||
47 | |||
48 | /* Lookup built-in module entry in /sys/modules */ | ||
49 | mkobj = kset_find_obj(module_kset, drv->mod_name); | ||
50 | if (mkobj) { | ||
51 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
52 | /* remember our module structure */ | ||
53 | drv->mkobj = mk; | ||
54 | /* kset_find_obj took a reference */ | ||
55 | kobject_put(mkobj); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (!mk) | ||
60 | return; | ||
61 | |||
62 | /* Don't check return codes; these calls are idempotent */ | ||
63 | no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); | ||
64 | driver_name = make_driver_name(drv); | ||
65 | if (driver_name) { | ||
66 | module_create_drivers_dir(mk); | ||
67 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, | ||
68 | driver_name); | ||
69 | kfree(driver_name); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void module_remove_driver(struct device_driver *drv) | ||
74 | { | ||
75 | struct module_kobject *mk = NULL; | ||
76 | char *driver_name; | ||
77 | |||
78 | if (!drv) | ||
79 | return; | ||
80 | |||
81 | sysfs_remove_link(&drv->kobj, "module"); | ||
82 | |||
83 | if (drv->owner) | ||
84 | mk = &drv->owner->mkobj; | ||
85 | else if (drv->mkobj) | ||
86 | mk = drv->mkobj; | ||
87 | if (mk && mk->drivers_dir) { | ||
88 | driver_name = make_driver_name(drv); | ||
89 | if (driver_name) { | ||
90 | sysfs_remove_link(mk->drivers_dir, driver_name); | ||
91 | kfree(driver_name); | ||
92 | } | ||
93 | } | ||
94 | } | ||
diff --git a/include/linux/module.h b/include/linux/module.h index fbe930b9b69c..c97bdb7eb957 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -609,21 +609,6 @@ static inline void module_remove_modinfo_attrs(struct module *mod) | |||
609 | 609 | ||
610 | #endif /* CONFIG_SYSFS */ | 610 | #endif /* CONFIG_SYSFS */ |
611 | 611 | ||
612 | #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) | ||
613 | |||
614 | void module_add_driver(struct module *mod, struct device_driver *drv); | ||
615 | void module_remove_driver(struct device_driver *drv); | ||
616 | |||
617 | #else /* not both CONFIG_SYSFS && CONFIG_MODULES */ | ||
618 | |||
619 | static inline void module_add_driver(struct module *mod, struct device_driver *drv) | ||
620 | { } | ||
621 | |||
622 | static inline void module_remove_driver(struct device_driver *drv) | ||
623 | { } | ||
624 | |||
625 | #endif | ||
626 | |||
627 | #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) | 612 | #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) |
628 | 613 | ||
629 | /* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */ | 614 | /* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */ |
diff --git a/kernel/module.c b/kernel/module.c index d03fcd9d652c..dc4d3f5ce820 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2501,93 +2501,6 @@ void print_modules(void) | |||
2501 | printk("\n"); | 2501 | printk("\n"); |
2502 | } | 2502 | } |
2503 | 2503 | ||
2504 | #ifdef CONFIG_SYSFS | ||
2505 | static char *make_driver_name(struct device_driver *drv) | ||
2506 | { | ||
2507 | char *driver_name; | ||
2508 | |||
2509 | driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | ||
2510 | GFP_KERNEL); | ||
2511 | if (!driver_name) | ||
2512 | return NULL; | ||
2513 | |||
2514 | sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | ||
2515 | return driver_name; | ||
2516 | } | ||
2517 | |||
2518 | static void module_create_drivers_dir(struct module_kobject *mk) | ||
2519 | { | ||
2520 | if (!mk || mk->drivers_dir) | ||
2521 | return; | ||
2522 | |||
2523 | mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj); | ||
2524 | } | ||
2525 | |||
2526 | void module_add_driver(struct module *mod, struct device_driver *drv) | ||
2527 | { | ||
2528 | char *driver_name; | ||
2529 | int no_warn; | ||
2530 | struct module_kobject *mk = NULL; | ||
2531 | |||
2532 | if (!drv) | ||
2533 | return; | ||
2534 | |||
2535 | if (mod) | ||
2536 | mk = &mod->mkobj; | ||
2537 | else if (drv->mod_name) { | ||
2538 | struct kobject *mkobj; | ||
2539 | |||
2540 | /* Lookup built-in module entry in /sys/modules */ | ||
2541 | mkobj = kset_find_obj(module_kset, drv->mod_name); | ||
2542 | if (mkobj) { | ||
2543 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
2544 | /* remember our module structure */ | ||
2545 | drv->mkobj = mk; | ||
2546 | /* kset_find_obj took a reference */ | ||
2547 | kobject_put(mkobj); | ||
2548 | } | ||
2549 | } | ||
2550 | |||
2551 | if (!mk) | ||
2552 | return; | ||
2553 | |||
2554 | /* Don't check return codes; these calls are idempotent */ | ||
2555 | no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); | ||
2556 | driver_name = make_driver_name(drv); | ||
2557 | if (driver_name) { | ||
2558 | module_create_drivers_dir(mk); | ||
2559 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, | ||
2560 | driver_name); | ||
2561 | kfree(driver_name); | ||
2562 | } | ||
2563 | } | ||
2564 | EXPORT_SYMBOL(module_add_driver); | ||
2565 | |||
2566 | void module_remove_driver(struct device_driver *drv) | ||
2567 | { | ||
2568 | struct module_kobject *mk = NULL; | ||
2569 | char *driver_name; | ||
2570 | |||
2571 | if (!drv) | ||
2572 | return; | ||
2573 | |||
2574 | sysfs_remove_link(&drv->kobj, "module"); | ||
2575 | |||
2576 | if (drv->owner) | ||
2577 | mk = &drv->owner->mkobj; | ||
2578 | else if (drv->mkobj) | ||
2579 | mk = drv->mkobj; | ||
2580 | if (mk && mk->drivers_dir) { | ||
2581 | driver_name = make_driver_name(drv); | ||
2582 | if (driver_name) { | ||
2583 | sysfs_remove_link(mk->drivers_dir, driver_name); | ||
2584 | kfree(driver_name); | ||
2585 | } | ||
2586 | } | ||
2587 | } | ||
2588 | EXPORT_SYMBOL(module_remove_driver); | ||
2589 | #endif | ||
2590 | |||
2591 | #ifdef CONFIG_MODVERSIONS | 2504 | #ifdef CONFIG_MODVERSIONS |
2592 | /* Generate the signature for struct module here, too, for modversions. */ | 2505 | /* Generate the signature for struct module here, too, for modversions. */ |
2593 | void struct_module(struct module *mod) { return; } | 2506 | void struct_module(struct module *mod) { return; } |