summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2002-10-30 14:59:20 -0800
committerPatrick Mochel <mochel@osdl.org>2002-10-30 14:59:20 -0800
commit117e6adf20d8e75f96948c9a896d9bb4396eb87b (patch)
treec7c67e896360df331ef1fa4ab45a2d30411a7a9a /drivers
parentb1b782f7b7fced03a6dc51d3e52595fcfc9ac106 (diff)
parent8de57ed6e13a1625695c016bf455ec7ebff68031 (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.c134
-rw-r--r--drivers/base/core.c86
-rw-r--r--drivers/base/driver.c32
-rw-r--r--drivers/base/fs/bus.c78
-rw-r--r--drivers/base/fs/device.c105
-rw-r--r--drivers/base/fs/driver.c78
-rw-r--r--drivers/base/interface.c6
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,
};