Branch data Line data Source code
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/slab.h>
11 : : #include <linux/string.h>
12 : : #include "base.h"
13 : :
14 : : static char *make_driver_name(struct device_driver *drv)
15 : : {
16 : : char *driver_name;
17 : :
18 : 0 : driver_name = kasprintf(GFP_KERNEL, "%s:%s", drv->bus->name, drv->name);
19 [ # # ][ # # ]: 0 : if (!driver_name)
20 : : return NULL;
21 : :
22 : : return driver_name;
23 : : }
24 : :
25 : 0 : static void module_create_drivers_dir(struct module_kobject *mk)
26 : : {
27 [ # # ][ # # ]: 0 : if (!mk || mk->drivers_dir)
28 : 0 : return;
29 : :
30 : 0 : mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
31 : : }
32 : :
33 : 0 : void module_add_driver(struct module *mod, struct device_driver *drv)
34 : : {
35 : : char *driver_name;
36 : : int no_warn;
37 : : struct module_kobject *mk = NULL;
38 : :
39 [ # # ]: 0 : if (!drv)
40 : : return;
41 : :
42 [ # # ]: 0 : if (mod)
43 : 0 : mk = &mod->mkobj;
44 [ # # ]: 0 : else if (drv->mod_name) {
45 : : struct kobject *mkobj;
46 : :
47 : : /* Lookup built-in module entry in /sys/modules */
48 : 0 : mkobj = kset_find_obj(module_kset, drv->mod_name);
49 [ # # ]: 0 : if (mkobj) {
50 : : mk = container_of(mkobj, struct module_kobject, kobj);
51 : : /* remember our module structure */
52 : 0 : drv->p->mkobj = mk;
53 : : /* kset_find_obj took a reference */
54 : 0 : kobject_put(mkobj);
55 : : }
56 : : }
57 : :
58 [ # # ]: 0 : if (!mk)
59 : : return;
60 : :
61 : : /* Don't check return codes; these calls are idempotent */
62 : 0 : no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
63 : : driver_name = make_driver_name(drv);
64 [ # # ]: 0 : if (driver_name) {
65 : 0 : module_create_drivers_dir(mk);
66 : 0 : no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
67 : : driver_name);
68 : 0 : kfree(driver_name);
69 : : }
70 : : }
71 : :
72 : 0 : void module_remove_driver(struct device_driver *drv)
73 : : {
74 : : struct module_kobject *mk = NULL;
75 : : char *driver_name;
76 : :
77 [ # # ]: 0 : if (!drv)
78 : 0 : return;
79 : :
80 : 0 : sysfs_remove_link(&drv->p->kobj, "module");
81 : :
82 [ # # ]: 0 : if (drv->owner)
83 : 0 : mk = &drv->owner->mkobj;
84 [ # # ]: 0 : else if (drv->p->mkobj)
85 : : mk = drv->p->mkobj;
86 [ # # ][ # # ]: 0 : if (mk && mk->drivers_dir) {
87 : : driver_name = make_driver_name(drv);
88 [ # # ]: 0 : if (driver_name) {
89 : 0 : sysfs_remove_link(mk->drivers_dir, driver_name);
90 : 0 : kfree(driver_name);
91 : : }
92 : : }
93 : : }
|