diff options
| author | Patrick Mochel <mochel@osdl.org> | 2002-10-30 14:59:20 -0800 |
|---|---|---|
| committer | Patrick Mochel <mochel@osdl.org> | 2002-10-30 14:59:20 -0800 |
| commit | 117e6adf20d8e75f96948c9a896d9bb4396eb87b (patch) | |
| tree | c7c67e896360df331ef1fa4ab45a2d30411a7a9a /drivers | |
| parent | b1b782f7b7fced03a6dc51d3e52595fcfc9ac106 (diff) | |
| parent | 8de57ed6e13a1625695c016bf455ec7ebff68031 (diff) | |
Merge bk://ldm@bkbits.net/linux-2.5-kobject
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/base/bus.c | 134 | ||||
| -rw-r--r-- | drivers/base/core.c | 86 | ||||
| -rw-r--r-- | drivers/base/driver.c | 32 | ||||
| -rw-r--r-- | drivers/base/fs/bus.c | 78 | ||||
| -rw-r--r-- | drivers/base/fs/device.c | 105 | ||||
| -rw-r--r-- | drivers/base/fs/driver.c | 78 | ||||
| -rw-r--r-- | drivers/base/interface.c | 6 |
7 files changed, 251 insertions, 268 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 8d0bbb5c9256..8428b8f1acd3 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,109 @@ 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 drivers + */ + +#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr) +#define to_driver(obj) container_of(obj, struct device_driver, kobj) + + +static ssize_t +drv_attr_show(struct kobject * kobj, struct attribute * attr, + char * buf, size_t count, loff_t off) +{ + struct driver_attribute * drv_attr = to_drv_attr(attr); + struct device_driver * drv = to_driver(kobj); + ssize_t ret = 0; + + if (drv_attr->show) + ret = drv_attr->show(drv,buf,count,off); + return ret; +} + +static ssize_t +drv_attr_store(struct kobject * kobj, struct attribute * attr, + const char * buf, size_t count, loff_t off) +{ + struct driver_attribute * drv_attr = to_drv_attr(attr); + struct device_driver * drv = to_driver(kobj); + ssize_t ret = 0; + + if (drv_attr->store) + ret = drv_attr->store(drv,buf,count,off); + return ret; +} + +static struct sysfs_ops driver_sysfs_ops = { + .show = drv_attr_show, + .store = drv_attr_store, +}; + + +/* + * sysfs bindings for drivers + */ + + +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 @@ -92,6 +196,7 @@ static void attach(struct device * dev) pr_debug("bound device '%s' to driver '%s'\n", dev->bus_id,dev->driver->name); list_add_tail(&dev->driver_list,&dev->driver->devices); + sysfs_create_link(&dev->driver->kobj,&dev->kobj,dev->kobj.name); } static int bus_match(struct device * dev, struct device_driver * drv) @@ -162,6 +267,7 @@ static int driver_attach(struct device_driver * drv) static void detach(struct device * dev, struct device_driver * drv) { if (drv) { + sysfs_remove_link(&drv->kobj,dev->kobj.name); list_del_init(&dev->driver_list); devclass_remove_device(dev); if (drv->remove) @@ -206,7 +312,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 +327,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); @@ -240,7 +346,6 @@ int bus_add_driver(struct device_driver * drv) list_add_tail(&drv->bus_list,&bus->drivers); driver_attach(drv); up_write(&bus->rwsem); - driver_make_dir(drv); } return 0; } @@ -286,6 +391,19 @@ 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; + bus->drvsubsys.sysfs_ops = &driver_sysfs_ops; + subsystem_register(&bus->drvsubsys); + spin_lock(&device_lock); list_add_tail(&bus->node,&bus_driver_list); spin_unlock(&device_lock); @@ -309,6 +427,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 +442,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/core.c b/drivers/base/core.c index 23ce66f60063..9bbe8bc96c62 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -23,7 +23,76 @@ DECLARE_MUTEX(device_sem); spinlock_t device_lock = SPIN_LOCK_UNLOCKED; -#define to_dev(node) container_of(node,struct device,driver_list) +struct subsystem device_subsys; + +#define to_dev(obj) container_of(obj,struct device,kobj) + + +/* + * sysfs bindings for devices. + */ + +#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr) + +extern struct attribute * dev_default_attrs[]; + +static ssize_t +dev_attr_show(struct kobject * kobj, struct attribute * attr, + char * buf, size_t count, loff_t off) +{ + struct device_attribute * dev_attr = to_dev_attr(attr); + struct device * dev = to_dev(kobj); + ssize_t ret = 0; + + if (dev_attr->show) + ret = dev_attr->show(dev,buf,count,off); + return ret; +} + +static ssize_t +dev_attr_store(struct kobject * kobj, struct attribute * attr, + const char * buf, size_t count, loff_t off) +{ + struct device_attribute * dev_attr = to_dev_attr(attr); + struct device * dev = to_dev(kobj); + ssize_t ret = 0; + + if (dev_attr->store) + ret = dev_attr->store(dev,buf,count,off); + return ret; +} + +static struct sysfs_ops dev_sysfs_ops = { + .show = dev_attr_show, + .store = dev_attr_store, +}; + +struct subsystem device_subsys = { + .kobj = { + .name = "devices", + }, + .sysfs_ops = &dev_sysfs_ops, + .default_attrs = dev_default_attrs, +}; + + +int device_create_file(struct device * dev, struct device_attribute * attr) +{ + int error = 0; + if (get_device(dev)) { + error = sysfs_create_file(&dev->kobj,&attr->attr); + put_device(dev); + } + return error; +} + +void device_remove_file(struct device * dev, struct device_attribute * attr) +{ + if (get_device(dev)) { + sysfs_remove_file(&dev->kobj,&attr->attr); + put_device(dev); + } +} int device_add(struct device *dev) { @@ -44,6 +113,12 @@ int device_add(struct device *dev) pr_debug("DEV: registering device: ID = '%s', name = %s\n", dev->bus_id, dev->name); + strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN); + if (dev->parent) + dev->kobj.parent = &dev->parent->kobj; + dev->kobj.subsys = &device_subsys; + kobject_register(&dev->kobj); + if ((error = device_make_dir(dev))) goto register_done; @@ -69,6 +144,7 @@ int device_add(struct device *dev) void device_initialize(struct device *dev) { + kobject_init(&dev->kobj); INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->children); INIT_LIST_HEAD(&dev->g_list); @@ -184,9 +260,17 @@ void device_unregister(struct device * dev) pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n", dev->bus_id,dev->name); + kobject_unregister(&dev->kobj); put_device(dev); } +static int __init device_subsys_init(void) +{ + return subsystem_register(&device_subsys); +} + +core_initcall(device_subsys_init); + EXPORT_SYMBOL(device_register); EXPORT_SYMBOL(device_unregister); EXPORT_SYMBOL(get_device); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 4bf4a005b918..f940cc4c5165 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -12,6 +12,29 @@ #define to_dev(node) container_of(node,struct device,driver_list) +/* + * helpers for creating driver attributes in sysfs + */ + +int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) +{ + int error; + if (get_driver(drv)) { + error = sysfs_create_file(&drv->kobj,&attr->attr); + put_driver(drv); + } else + error = -EINVAL; + return error; +} + +void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) +{ + if (get_driver(drv)) { + sysfs_remove_file(&drv->kobj,&attr->attr); + put_driver(drv); + } +} + int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback)(struct device *, void * )) { @@ -65,7 +88,6 @@ void put_driver(struct device_driver * drv) return; spin_unlock(&device_lock); BUG_ON(drv->present); - bus_remove_driver(drv); if (drv->release) drv->release(drv); put_bus(bus); @@ -84,6 +106,11 @@ int driver_register(struct device_driver * drv) pr_debug("driver %s:%s: registering\n",drv->bus->name,drv->name); + kobject_init(&drv->kobj); + strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN); + drv->kobj.subsys = &drv->bus->drvsubsys; + kobject_register(&drv->kobj); + get_bus(drv->bus); atomic_set(&drv->refcount,2); rwlock_init(&drv->lock); @@ -108,3 +135,6 @@ EXPORT_SYMBOL(driver_register); EXPORT_SYMBOL(driver_unregister); EXPORT_SYMBOL(get_driver); EXPORT_SYMBOL(put_driver); + +EXPORT_SYMBOL(driver_create_file); +EXPORT_SYMBOL(driver_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); diff --git a/drivers/base/fs/device.c b/drivers/base/fs/device.c index 06984c469a18..ddb2b5c33eb3 100644 --- a/drivers/base/fs/device.c +++ b/drivers/base/fs/device.c @@ -21,97 +21,6 @@ static struct driver_dir_entry device_root_dir = { .mode = (S_IRWXU | S_IRUGO | S_IXUGO), }; -extern struct device_attribute * device_default_files[]; - -#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr) - -#define to_device(d) container_of(d, struct device, dir) - - -/* driverfs ops for device attribute files */ - -static int -dev_attr_open(struct driver_dir_entry * dir) -{ - struct device * dev = to_device(dir); - get_device(dev); - return 0; -} - -static int -dev_attr_close(struct driver_dir_entry * dir) -{ - struct device * dev = to_device(dir); - put_device(dev); - return 0; -} - -static ssize_t -dev_attr_show(struct driver_dir_entry * dir, struct attribute * attr, - char * buf, size_t count, loff_t off) -{ - struct device_attribute * dev_attr = to_dev_attr(attr); - struct device * dev = to_device(dir); - ssize_t ret = 0; - - if (dev_attr->show) - ret = dev_attr->show(dev,buf,count,off); - return ret; -} - -static ssize_t -dev_attr_store(struct driver_dir_entry * dir, struct attribute * attr, - const char * buf, size_t count, loff_t off) -{ - struct device_attribute * dev_attr = to_dev_attr(attr); - struct device * dev = to_device(dir); - ssize_t ret = 0; - - if (dev_attr->store) - ret = dev_attr->store(dev,buf,count,off); - return ret; -} - -static struct driverfs_ops dev_attr_ops = { - .open = dev_attr_open, - .close = dev_attr_close, - .show = dev_attr_show, - .store = dev_attr_store, -}; - -/** - * device_create_file - create a driverfs file for a device - * @dev: device requesting file - * @entry: entry describing file - * - * Allocate space for file entry, copy descriptor, and create. - */ -int device_create_file(struct device * dev, struct device_attribute * entry) -{ - int error = -EINVAL; - - if (get_device(dev)) { - error = driverfs_create_file(&entry->attr,&dev->dir); - put_device(dev); - } - return error; -} - -/** - * device_remove_file - remove a device's file by name - * @dev: device requesting removal - * @name: name of the file - * - */ -void device_remove_file(struct device * dev, struct device_attribute * attr) -{ - if (dev) { - get_device(dev); - driverfs_remove_file(&dev->dir,attr->attr.name); - put_device(dev); - } -} - /** * device_remove_dir - remove a device's directory * @dev: device in question @@ -213,24 +122,12 @@ int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * p int device_make_dir(struct device * dev) { struct driver_dir_entry * parent; - struct device_attribute * entry; int error; - int i; parent = dev->parent ? &dev->parent->dir : &device_root_dir; dev->dir.name = dev->bus_id; - dev->dir.ops = &dev_attr_ops; - - if ((error = device_create_dir(&dev->dir,parent))) - return error; - for (i = 0; (entry = *(device_default_files + i)); i++) { - if ((error = device_create_file(dev,entry))) { - device_remove_dir(dev); - break; - } - } - return error; + return device_create_dir(&dev->dir,parent); } static int device_driverfs_init(void) diff --git a/drivers/base/fs/driver.c b/drivers/base/fs/driver.c index c70834d738fc..c259470c7bb6 100644 --- a/drivers/base/fs/driver.c +++ b/drivers/base/fs/driver.c @@ -4,80 +4,6 @@ #include <linux/err.h> #include "fs.h" -#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr) - -#define to_drv(d) container_of(d, struct device_driver, dir) - - -/* driverfs ops for device attribute files */ - -static int -drv_attr_open(struct driver_dir_entry * dir) -{ - struct device_driver * drv = to_drv(dir); - get_driver(drv); - return 0; -} - -static int -drv_attr_close(struct driver_dir_entry * dir) -{ - struct device_driver * drv = to_drv(dir); - put_driver(drv); - return 0; -} - -static ssize_t -drv_attr_show(struct driver_dir_entry * dir, struct attribute * attr, - char * buf, size_t count, loff_t off) -{ - struct driver_attribute * drv_attr = to_drv_attr(attr); - struct device_driver * drv = to_drv(dir); - ssize_t ret = 0; - - if (drv_attr->show) - ret = drv_attr->show(drv,buf,count,off); - return ret; -} - -static ssize_t -drv_attr_store(struct driver_dir_entry * dir, struct attribute * attr, - const char * buf, size_t count, loff_t off) -{ - struct driver_attribute * drv_attr = to_drv_attr(attr); - struct device_driver * drv = to_drv(dir); - ssize_t ret = 0; - - if (drv_attr->store) - ret = drv_attr->store(drv,buf,count,off); - return ret; -} - -static struct driverfs_ops drv_attr_ops = { - .open = drv_attr_open, - .close = drv_attr_close, - .show = drv_attr_show, - .store = drv_attr_store, -}; - -int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) -{ - int error; - if (get_driver(drv)) { - error = driverfs_create_file(&attr->attr,&drv->dir); - put_driver(drv); - } else - error = -EINVAL; - return error; -} - -void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) -{ - if (get_driver(drv)) { - driverfs_remove_file(&drv->dir,attr->attr.name); - put_driver(drv); - } -} /** * driver_make_dir - create a driverfs directory for a driver @@ -86,8 +12,6 @@ void driver_remove_file(struct device_driver * drv, struct driver_attribute * at int driver_make_dir(struct device_driver * drv) { drv->dir.name = drv->name; - drv->dir.ops = &drv_attr_ops; - return device_create_dir(&drv->dir,&drv->bus->driver_dir); } @@ -96,5 +20,3 @@ void driver_remove_dir(struct device_driver * drv) driverfs_remove_dir(&drv->dir); } -EXPORT_SYMBOL(driver_create_file); -EXPORT_SYMBOL(driver_remove_file); diff --git a/drivers/base/interface.c b/drivers/base/interface.c index 8a5c6e6bc226..a6e0c73d043f 100644 --- a/drivers/base/interface.c +++ b/drivers/base/interface.c @@ -88,8 +88,8 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o static DEVICE_ATTR(power,S_IWUSR | S_IRUGO, device_read_power,device_write_power); -struct device_attribute * device_default_files[] = { - &dev_attr_name, - &dev_attr_power, +struct attribute * dev_default_attrs[] = { + &dev_attr_name.attr, + &dev_attr_power.attr, NULL, }; |
