diff options
author | Kay Sievers <kay.sievers@novell.com> | 2006-10-07 21:54:55 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 19:37:14 +0100 |
commit | f9f852df2faf76a2667949ddb4947d4b8f99f02f (patch) | |
tree | 3dfdbae06ef17c83266cc18ed77fcd1c51328c15 /drivers/base | |
parent | Driver core: add uevent vars for devices of a class (diff) | |
download | linux-f9f852df2faf76a2667949ddb4947d4b8f99f02f.tar.xz linux-f9f852df2faf76a2667949ddb4947d4b8f99f02f.zip |
Driver core: add device_type to struct device
This allows us to add type specific attributes, uevent vars and
release funtions.
A subsystem can carry different types of devices like the "block"
subsys has disks and partitions. Both types create a different set
of attributes, but belong to the same subsystem.
This corresponds to the low level objects:
kobject -> device (object/device data)
kobj_type -> device_type (type of object/device we are embedded in)
kset -> class/bus (list of objects/devices of a subsystem)
Signed-off-by: Kay Sievers <kay.sievers@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/core.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 7a5336f7df89..34ac18778d8a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj) if (dev->release) dev->release(dev); + else if (dev->type && dev->type->release) + dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); else { @@ -206,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, if (dev->bus && dev->bus->uevent) { /* have the bus specific function add its stuff */ retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) { - pr_debug ("%s - uevent() returned %d\n", + if (retval) + pr_debug ("%s: bus uevent() returned %d\n", __FUNCTION__, retval); - } } if (dev->class && dev->class->dev_uevent) { /* have the class specific function add its stuff */ retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) { - pr_debug("%s - dev_uevent() returned %d\n", - __FUNCTION__, retval); - } + if (retval) + pr_debug("%s: class uevent() returned %d\n", + __FUNCTION__, retval); + } + + if (dev->type && dev->type->uevent) { + /* have the device type specific fuction add its stuff */ + retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size); + if (retval) + pr_debug("%s: dev_type uevent() returned %d\n", + __FUNCTION__, retval); } return retval; @@ -269,37 +277,50 @@ static void device_remove_groups(struct device *dev) static int device_add_attrs(struct device *dev) { struct class *class = dev->class; + struct device_type *type = dev->type; int error = 0; int i; - if (!class) - return 0; - - if (class->dev_attrs) { + if (class && class->dev_attrs) { for (i = 0; attr_name(class->dev_attrs[i]); i++) { error = device_create_file(dev, &class->dev_attrs[i]); if (error) break; } + if (error) + while (--i >= 0) + device_remove_file(dev, &class->dev_attrs[i]); } - if (error) - while (--i >= 0) - device_remove_file(dev, &class->dev_attrs[i]); + + if (type && type->attrs) { + for (i = 0; attr_name(type->attrs[i]); i++) { + error = device_create_file(dev, &type->attrs[i]); + if (error) + break; + } + if (error) + while (--i >= 0) + device_remove_file(dev, &type->attrs[i]); + } + return error; } static void device_remove_attrs(struct device *dev) { struct class *class = dev->class; + struct device_type *type = dev->type; int i; - if (!class) - return; - - if (class->dev_attrs) { + if (class && class->dev_attrs) { for (i = 0; attr_name(class->dev_attrs[i]); i++) device_remove_file(dev, &class->dev_attrs[i]); } + + if (type && type->attrs) { + for (i = 0; attr_name(type->attrs[i]); i++) + device_remove_file(dev, &type->attrs[i]); + } } |