diff options
| author | Patrick Mochel <mochel@osdl.org> | 2002-10-30 00:04:57 -0800 |
|---|---|---|
| committer | Patrick Mochel <mochel@osdl.org> | 2002-10-30 00:04:57 -0800 |
| commit | 289609f07f4e96ef139af61bd2ee3d8f1592ba17 (patch) | |
| tree | da0259aecedc3a3469f4c9e92051e8bc4ef5879e /drivers/base | |
| parent | 77057f5a28c94d8ed1779b829d9ef0ad0a95db44 (diff) | |
driver model: convert bus drivers to use kobjects and sysfs.
- create bus subsystem and register on start up.
- add struct subsystem to struct bus type to get it in the object hierarchy.
- add device and driver subsystems to struct bus type to give it hierarchy
like it previously had.
- convert bus show()/store() callbacks to know about struct kobject.
- convert bus file creation/removal to use struct kobject.
- create symlinks from to device directories, like they had in driverfs.
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/bus.c | 90 | ||||
| -rw-r--r-- | drivers/base/fs/bus.c | 78 |
2 files changed, 88 insertions, 80 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 8d0bbb5c9256..57fd83004240 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/errno.h> +#include <linux/init.h> #include "base.h" static LIST_HEAD(bus_driver_list); @@ -19,6 +20,69 @@ static LIST_HEAD(bus_driver_list); #define to_dev(node) container_of(node,struct device,bus_list) #define to_drv(node) container_of(node,struct device_driver,bus_list) +#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr) +#define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj) + +/* + * sysfs bindings for buses + */ + + +static ssize_t +bus_attr_show(struct kobject * kobj, struct attribute * attr, + char * buf, size_t count, loff_t off) +{ + struct bus_attribute * bus_attr = to_bus_attr(attr); + struct bus_type * bus = to_bus(kobj); + ssize_t ret = 0; + + if (bus_attr->show) + ret = bus_attr->show(bus,buf,count,off); + return ret; +} + +static ssize_t +bus_attr_store(struct kobject * kobj, struct attribute * attr, + const char * buf, size_t count, loff_t off) +{ + struct bus_attribute * bus_attr = to_bus_attr(attr); + struct bus_type * bus = to_bus(kobj); + ssize_t ret = 0; + + if (bus_attr->store) + ret = bus_attr->store(bus,buf,count,off); + return ret; +} + +static struct sysfs_ops bus_sysfs_ops = { + .show = bus_attr_show, + .store = bus_attr_store, +}; + +int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) +{ + int error; + if (get_bus(bus)) { + error = sysfs_create_file(&bus->subsys.kobj,&attr->attr); + put_bus(bus); + } else + error = -EINVAL; + return error; +} + +void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) +{ + if (get_bus(bus)) { + sysfs_remove_file(&bus->subsys.kobj,&attr->attr); + put_bus(bus); + } +} + +struct subsystem bus_subsys = { + .kobj = { .name = "bus" }, + .sysfs_ops = &bus_sysfs_ops, +}; + /** * bus_for_each_dev - walk list of devices and do something to each * @bus: bus in question @@ -206,7 +270,7 @@ int bus_add_device(struct device * dev) list_add_tail(&dev->bus_list,&dev->bus->devices); device_attach(dev); up_write(&dev->bus->rwsem); - device_bus_link(dev); + sysfs_create_link(&bus->devsubsys.kobj,&dev->kobj,dev->bus_id); } return 0; } @@ -221,9 +285,9 @@ int bus_add_device(struct device * dev) void bus_remove_device(struct device * dev) { if (dev->bus) { + sysfs_remove_link(&dev->bus->devsubsys.kobj,dev->bus_id); down_write(&dev->bus->rwsem); pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id); - device_remove_symlink(&dev->bus->device_dir,dev->bus_id); device_detach(dev); list_del_init(&dev->bus_list); up_write(&dev->bus->rwsem); @@ -286,6 +350,18 @@ int bus_register(struct bus_type * bus) atomic_set(&bus->refcount,2); bus->present = 1; + strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN); + bus->subsys.parent = &bus_subsys; + subsystem_register(&bus->subsys); + + snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices"); + bus->devsubsys.parent = &bus->subsys; + subsystem_register(&bus->devsubsys); + + snprintf(bus->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers"); + bus->drvsubsys.parent = &bus->subsys; + subsystem_register(&bus->drvsubsys); + spin_lock(&device_lock); list_add_tail(&bus->node,&bus_driver_list); spin_unlock(&device_lock); @@ -309,6 +385,13 @@ void bus_unregister(struct bus_type * bus) put_bus(bus); } +static int __init bus_subsys_init(void) +{ + return subsystem_register(&bus_subsys); +} + +core_initcall(bus_subsys_init); + EXPORT_SYMBOL(bus_for_each_dev); EXPORT_SYMBOL(bus_for_each_drv); EXPORT_SYMBOL(bus_add_device); @@ -317,3 +400,6 @@ EXPORT_SYMBOL(bus_register); EXPORT_SYMBOL(bus_unregister); EXPORT_SYMBOL(get_bus); EXPORT_SYMBOL(put_bus); + +EXPORT_SYMBOL(bus_create_file); +EXPORT_SYMBOL(bus_remove_file); diff --git a/drivers/base/fs/bus.c b/drivers/base/fs/bus.c index bd6b92442f81..7c95233d9249 100644 --- a/drivers/base/fs/bus.c +++ b/drivers/base/fs/bus.c @@ -6,86 +6,10 @@ static struct driver_dir_entry bus_dir; -#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr) - -#define to_bus(dir) container_of(dir,struct bus_type,dir) - - -/* driverfs ops for device attribute files */ - -static int -bus_attr_open(struct driver_dir_entry * dir) -{ - struct bus_type * bus = to_bus(dir); - get_bus(bus); - return 0; -} - -static int -bus_attr_close(struct driver_dir_entry * dir) -{ - struct bus_type * bus = to_bus(dir); - put_bus(bus); - return 0; -} - -static ssize_t -bus_attr_show(struct driver_dir_entry * dir, struct attribute * attr, - char * buf, size_t count, loff_t off) -{ - struct bus_attribute * bus_attr = to_bus_attr(attr); - struct bus_type * bus = to_bus(dir); - ssize_t ret = 0; - - if (bus_attr->show) - ret = bus_attr->show(bus,buf,count,off); - return ret; -} - -static ssize_t -bus_attr_store(struct driver_dir_entry * dir, struct attribute * attr, - const char * buf, size_t count, loff_t off) -{ - struct bus_attribute * bus_attr = to_bus_attr(attr); - struct bus_type * bus = to_bus(dir); - ssize_t ret = 0; - - if (bus_attr->store) - ret = bus_attr->store(bus,buf,count,off); - return ret; -} - -static struct driverfs_ops bus_attr_ops = { - .open = bus_attr_open, - .close = bus_attr_close, - .show = bus_attr_show, - .store = bus_attr_store, -}; - -int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) -{ - int error; - if (get_bus(bus)) { - error = driverfs_create_file(&attr->attr,&bus->dir); - put_bus(bus); - } else - error = -EINVAL; - return error; -} - -void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) -{ - if (get_bus(bus)) { - driverfs_remove_file(&bus->dir,attr->attr.name); - put_bus(bus); - } -} - int bus_make_dir(struct bus_type * bus) { int error; bus->dir.name = bus->name; - bus->dir.ops = &bus_attr_ops; error = device_create_dir(&bus->dir,&bus_dir); if (!error) { @@ -119,5 +43,3 @@ static int __init bus_init(void) core_initcall(bus_init); -EXPORT_SYMBOL(bus_create_file); -EXPORT_SYMBOL(bus_remove_file); |
