0001
0002
0003
0004
0005 #include <linux/device.h>
0006 #include <linux/module.h>
0007 #include <linux/errno.h>
0008 #include <linux/slab.h>
0009 #include <linux/string.h>
0010 #include "base.h"
0011
0012 static char *make_driver_name(struct device_driver *drv)
0013 {
0014 char *driver_name;
0015
0016 driver_name = kasprintf(GFP_KERNEL, "%s:%s", drv->bus->name, drv->name);
0017 if (!driver_name)
0018 return NULL;
0019
0020 return driver_name;
0021 }
0022
0023 static void module_create_drivers_dir(struct module_kobject *mk)
0024 {
0025 static DEFINE_MUTEX(drivers_dir_mutex);
0026
0027 mutex_lock(&drivers_dir_mutex);
0028 if (mk && !mk->drivers_dir)
0029 mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
0030 mutex_unlock(&drivers_dir_mutex);
0031 }
0032
0033 void module_add_driver(struct module *mod, struct device_driver *drv)
0034 {
0035 char *driver_name;
0036 int no_warn;
0037 struct module_kobject *mk = NULL;
0038
0039 if (!drv)
0040 return;
0041
0042 if (mod)
0043 mk = &mod->mkobj;
0044 else if (drv->mod_name) {
0045 struct kobject *mkobj;
0046
0047
0048 mkobj = kset_find_obj(module_kset, drv->mod_name);
0049 if (mkobj) {
0050 mk = container_of(mkobj, struct module_kobject, kobj);
0051
0052 drv->p->mkobj = mk;
0053
0054 kobject_put(mkobj);
0055 }
0056 }
0057
0058 if (!mk)
0059 return;
0060
0061
0062 no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
0063 driver_name = make_driver_name(drv);
0064 if (driver_name) {
0065 module_create_drivers_dir(mk);
0066 no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
0067 driver_name);
0068 kfree(driver_name);
0069 }
0070 }
0071
0072 void module_remove_driver(struct device_driver *drv)
0073 {
0074 struct module_kobject *mk = NULL;
0075 char *driver_name;
0076
0077 if (!drv)
0078 return;
0079
0080 sysfs_remove_link(&drv->p->kobj, "module");
0081
0082 if (drv->owner)
0083 mk = &drv->owner->mkobj;
0084 else if (drv->p->mkobj)
0085 mk = drv->p->mkobj;
0086 if (mk && mk->drivers_dir) {
0087 driver_name = make_driver_name(drv);
0088 if (driver_name) {
0089 sysfs_remove_link(mk->drivers_dir, driver_name);
0090 kfree(driver_name);
0091 }
0092 }
0093 }