Skip to content

Commit

Permalink
Driver core: move the driver specific module code into the driver core
Browse files Browse the repository at this point in the history
The module driver specific code should belong in the driver core, not in
the kernel/ directory.  So move this code.  This is done in preparation
for some struct device_driver rework that should be confined to the
driver core code only.

This also lets us keep from exporting these functions, as no external
code should ever be calling it.

Thanks to Andrew Morton for the !CONFIG_MODULES fix.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Greg Kroah-Hartman committed Jan 25, 2008
1 parent cbe9c59 commit c63469a
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 102 deletions.
1 change: 1 addition & 0 deletions drivers/base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
obj-$(CONFIG_SMP) += topology.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o

ifeq ($(CONFIG_DEBUG_DRIVER),y)
Expand Down
9 changes: 9 additions & 0 deletions drivers/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,12 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
extern int devres_release_all(struct device *dev);

extern struct kset *devices_kset;

#ifdef CONFIG_MODULES
extern void module_add_driver(struct module *mod, struct device_driver *drv);
extern void module_remove_driver(struct device_driver *drv);
#else
static inline void module_add_driver(struct module *mod,
struct device_driver *drv) { }
static inline void module_remove_driver(struct device_driver *drv) { }
#endif
94 changes: 94 additions & 0 deletions drivers/base/module.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* module.c - module sysfs fun for drivers
*
* This file is released under the GPLv2
*
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#include "base.h"

static char *make_driver_name(struct device_driver *drv)
{
char *driver_name;

driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
GFP_KERNEL);
if (!driver_name)
return NULL;

sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
return driver_name;
}

static void module_create_drivers_dir(struct module_kobject *mk)
{
if (!mk || mk->drivers_dir)
return;

mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
}

void module_add_driver(struct module *mod, struct device_driver *drv)
{
char *driver_name;
int no_warn;
struct module_kobject *mk = NULL;

if (!drv)
return;

if (mod)
mk = &mod->mkobj;
else if (drv->mod_name) {
struct kobject *mkobj;

/* Lookup built-in module entry in /sys/modules */
mkobj = kset_find_obj(module_kset, drv->mod_name);
if (mkobj) {
mk = container_of(mkobj, struct module_kobject, kobj);
/* remember our module structure */
drv->mkobj = mk;
/* kset_find_obj took a reference */
kobject_put(mkobj);
}
}

if (!mk)
return;

/* Don't check return codes; these calls are idempotent */
no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
driver_name = make_driver_name(drv);
if (driver_name) {
module_create_drivers_dir(mk);
no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
driver_name);
kfree(driver_name);
}
}

void module_remove_driver(struct device_driver *drv)
{
struct module_kobject *mk = NULL;
char *driver_name;

if (!drv)
return;

sysfs_remove_link(&drv->kobj, "module");

if (drv->owner)
mk = &drv->owner->mkobj;
else if (drv->mkobj)
mk = drv->mkobj;
if (mk && mk->drivers_dir) {
driver_name = make_driver_name(drv);
if (driver_name) {
sysfs_remove_link(mk->drivers_dir, driver_name);
kfree(driver_name);
}
}
}
15 changes: 0 additions & 15 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,21 +609,6 @@ static inline void module_remove_modinfo_attrs(struct module *mod)

#endif /* CONFIG_SYSFS */

#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)

void module_add_driver(struct module *mod, struct device_driver *drv);
void module_remove_driver(struct device_driver *drv);

#else /* not both CONFIG_SYSFS && CONFIG_MODULES */

static inline void module_add_driver(struct module *mod, struct device_driver *drv)
{ }

static inline void module_remove_driver(struct device_driver *drv)
{ }

#endif

#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)

/* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */
Expand Down
87 changes: 0 additions & 87 deletions kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -2501,93 +2501,6 @@ void print_modules(void)
printk("\n");
}

#ifdef CONFIG_SYSFS
static char *make_driver_name(struct device_driver *drv)
{
char *driver_name;

driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
GFP_KERNEL);
if (!driver_name)
return NULL;

sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
return driver_name;
}

static void module_create_drivers_dir(struct module_kobject *mk)
{
if (!mk || mk->drivers_dir)
return;

mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
}

void module_add_driver(struct module *mod, struct device_driver *drv)
{
char *driver_name;
int no_warn;
struct module_kobject *mk = NULL;

if (!drv)
return;

if (mod)
mk = &mod->mkobj;
else if (drv->mod_name) {
struct kobject *mkobj;

/* Lookup built-in module entry in /sys/modules */
mkobj = kset_find_obj(module_kset, drv->mod_name);
if (mkobj) {
mk = container_of(mkobj, struct module_kobject, kobj);
/* remember our module structure */
drv->mkobj = mk;
/* kset_find_obj took a reference */
kobject_put(mkobj);
}
}

if (!mk)
return;

/* Don't check return codes; these calls are idempotent */
no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
driver_name = make_driver_name(drv);
if (driver_name) {
module_create_drivers_dir(mk);
no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
driver_name);
kfree(driver_name);
}
}
EXPORT_SYMBOL(module_add_driver);

void module_remove_driver(struct device_driver *drv)
{
struct module_kobject *mk = NULL;
char *driver_name;

if (!drv)
return;

sysfs_remove_link(&drv->kobj, "module");

if (drv->owner)
mk = &drv->owner->mkobj;
else if (drv->mkobj)
mk = drv->mkobj;
if (mk && mk->drivers_dir) {
driver_name = make_driver_name(drv);
if (driver_name) {
sysfs_remove_link(mk->drivers_dir, driver_name);
kfree(driver_name);
}
}
}
EXPORT_SYMBOL(module_remove_driver);
#endif

#ifdef CONFIG_MODVERSIONS
/* Generate the signature for struct module here, too, for modversions. */
void struct_module(struct module *mod) { return; }
Expand Down

0 comments on commit c63469a

Please sign in to comment.