]> git.neil.brown.name Git - history.git/commitdiff
driverfs: Add ability to create and remove files for bus drivers
authorPatrick Mochel <mochel@osdl.org>
Fri, 2 Aug 2002 05:18:12 +0000 (22:18 -0700)
committerPatrick Mochel <mochel@osdl.org>
Fri, 2 Aug 2002 05:18:12 +0000 (22:18 -0700)
These behave identically to device attribute files, but with different types.

We get struct bus_attribute, and a macro, BUS_ATTR for declaring attributes. It takes the same parameters
as DEVICE_ATTR, though the callbacks for bus attributes take a struct bus_type as the first parameter.

drivers/base/fs/bus.c
include/linux/device.h

index 8ccc250ef55c01e04a26cbf53509f672d541432d..07ed6c82a4cbefaac0ad1b5df07d9b895c6ba84d 100644 (file)
@@ -1,17 +1,91 @@
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/stat.h>
 #include "fs.h"
 
-static struct driver_dir_entry bus_dir = {
-       name:   "bus",
-       mode:   (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
+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) {
@@ -32,6 +106,11 @@ void bus_remove_dir(struct bus_type * bus)
        driverfs_remove_dir(&bus->dir);
 }
 
+static struct driver_dir_entry bus_dir = {
+       name:   "bus",
+       mode:   (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
+};
+
 static int __init bus_init(void)
 {
        /* make 'bus' driverfs directory */
@@ -40,3 +119,5 @@ static int __init bus_init(void)
 
 core_initcall(bus_init);
 
+EXPORT_SYMBOL(bus_create_file);
+EXPORT_SYMBOL(bus_remove_file);
index 5dfa05c2dd3a5bbd4034a1a37863649d2ded1990..9707eca4331f5049d299ac342db986312132911a 100644 (file)
@@ -85,6 +85,24 @@ extern int bus_for_each_drv(struct bus_type * bus, void * data,
                            int (*callback)(struct device_driver * drv, void * data));
 
 
+/* driverfs interface for exporting bus attributes */
+
+struct bus_attribute {
+       struct attribute        attr;
+       ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
+       ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
+};
+
+#define BUS_ATTR(_name,_str,_mode,_show,_store)        \
+struct bus_attribute bus_attr_##_name = {              \
+       .attr = {.name  = _str, .mode   = _mode },      \
+       .show   = _show,                                \
+       .store  = _store,                               \
+};
+
+extern int bus_create_file(struct bus_type *, struct bus_attribute *);
+extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+
 struct device_driver {
        char                    * name;
        struct bus_type         * bus;