diff options
author | Kay Sievers <kay.sievers@novell.com> | 2006-10-07 15:54:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 13:37:14 -0500 |
commit | f9f852df2faf76a2667949ddb4947d4b8f99f02f (patch) | |
tree | 3dfdbae06ef17c83266cc18ed77fcd1c51328c15 /drivers/base | |
parent | 239378f16aa1ab5c502e42a06359d2de4f88ebb4 (diff) |
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) | |||
95 | 95 | ||
96 | if (dev->release) | 96 | if (dev->release) |
97 | dev->release(dev); | 97 | dev->release(dev); |
98 | else if (dev->type && dev->type->release) | ||
99 | dev->type->release(dev); | ||
98 | else if (dev->class && dev->class->dev_release) | 100 | else if (dev->class && dev->class->dev_release) |
99 | dev->class->dev_release(dev); | 101 | dev->class->dev_release(dev); |
100 | else { | 102 | else { |
@@ -206,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
206 | if (dev->bus && dev->bus->uevent) { | 208 | if (dev->bus && dev->bus->uevent) { |
207 | /* have the bus specific function add its stuff */ | 209 | /* have the bus specific function add its stuff */ |
208 | retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); | 210 | retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); |
209 | if (retval) { | 211 | if (retval) |
210 | pr_debug ("%s - uevent() returned %d\n", | 212 | pr_debug ("%s: bus uevent() returned %d\n", |
211 | __FUNCTION__, retval); | 213 | __FUNCTION__, retval); |
212 | } | ||
213 | } | 214 | } |
214 | 215 | ||
215 | if (dev->class && dev->class->dev_uevent) { | 216 | if (dev->class && dev->class->dev_uevent) { |
216 | /* have the class specific function add its stuff */ | 217 | /* have the class specific function add its stuff */ |
217 | retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); | 218 | retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); |
218 | if (retval) { | 219 | if (retval) |
219 | pr_debug("%s - dev_uevent() returned %d\n", | 220 | pr_debug("%s: class uevent() returned %d\n", |
220 | __FUNCTION__, retval); | 221 | __FUNCTION__, retval); |
221 | } | 222 | } |
223 | |||
224 | if (dev->type && dev->type->uevent) { | ||
225 | /* have the device type specific fuction add its stuff */ | ||
226 | retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size); | ||
227 | if (retval) | ||
228 | pr_debug("%s: dev_type uevent() returned %d\n", | ||
229 | __FUNCTION__, retval); | ||
222 | } | 230 | } |
223 | 231 | ||
224 | return retval; | 232 | return retval; |
@@ -269,37 +277,50 @@ static void device_remove_groups(struct device *dev) | |||
269 | static int device_add_attrs(struct device *dev) | 277 | static int device_add_attrs(struct device *dev) |
270 | { | 278 | { |
271 | struct class *class = dev->class; | 279 | struct class *class = dev->class; |
280 | struct device_type *type = dev->type; | ||
272 | int error = 0; | 281 | int error = 0; |
273 | int i; | 282 | int i; |
274 | 283 | ||
275 | if (!class) | 284 | if (class && class->dev_attrs) { |
276 | return 0; | ||
277 | |||
278 | if (class->dev_attrs) { | ||
279 | for (i = 0; attr_name(class->dev_attrs[i]); i++) { | 285 | for (i = 0; attr_name(class->dev_attrs[i]); i++) { |
280 | error = device_create_file(dev, &class->dev_attrs[i]); | 286 | error = device_create_file(dev, &class->dev_attrs[i]); |
281 | if (error) | 287 | if (error) |
282 | break; | 288 | break; |
283 | } | 289 | } |
290 | if (error) | ||
291 | while (--i >= 0) | ||
292 | device_remove_file(dev, &class->dev_attrs[i]); | ||
284 | } | 293 | } |
285 | if (error) | 294 | |
286 | while (--i >= 0) | 295 | if (type && type->attrs) { |
287 | device_remove_file(dev, &class->dev_attrs[i]); | 296 | for (i = 0; attr_name(type->attrs[i]); i++) { |
297 | error = device_create_file(dev, &type->attrs[i]); | ||
298 | if (error) | ||
299 | break; | ||
300 | } | ||
301 | if (error) | ||
302 | while (--i >= 0) | ||
303 | device_remove_file(dev, &type->attrs[i]); | ||
304 | } | ||
305 | |||
288 | return error; | 306 | return error; |
289 | } | 307 | } |
290 | 308 | ||
291 | static void device_remove_attrs(struct device *dev) | 309 | static void device_remove_attrs(struct device *dev) |
292 | { | 310 | { |
293 | struct class *class = dev->class; | 311 | struct class *class = dev->class; |
312 | struct device_type *type = dev->type; | ||
294 | int i; | 313 | int i; |
295 | 314 | ||
296 | if (!class) | 315 | if (class && class->dev_attrs) { |
297 | return; | ||
298 | |||
299 | if (class->dev_attrs) { | ||
300 | for (i = 0; attr_name(class->dev_attrs[i]); i++) | 316 | for (i = 0; attr_name(class->dev_attrs[i]); i++) |
301 | device_remove_file(dev, &class->dev_attrs[i]); | 317 | device_remove_file(dev, &class->dev_attrs[i]); |
302 | } | 318 | } |
319 | |||
320 | if (type && type->attrs) { | ||
321 | for (i = 0; attr_name(type->attrs[i]); i++) | ||
322 | device_remove_file(dev, &type->attrs[i]); | ||
323 | } | ||
303 | } | 324 | } |
304 | 325 | ||
305 | 326 | ||