aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-04-29 22:38:01 -0400
committerPaul Mackerras <paulus@samba.org>2007-04-29 22:38:01 -0400
commit49e1900d4cc2e7bcecb681fe60f0990bec2dcce8 (patch)
tree253801ebf57e0a23856a2c7be129c2c178f62fdf /drivers/base/core.c
parent34f6d749c0a328817d5e36274e53121c1db734dc (diff)
parentb9099ff63c75216d6ca10bce5a1abcd9293c27e6 (diff)
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c293
1 files changed, 207 insertions, 86 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d7fcf823a42a..8aa090da1cd7 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -43,7 +43,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
43const char *dev_driver_string(struct device *dev) 43const char *dev_driver_string(struct device *dev)
44{ 44{
45 return dev->driver ? dev->driver->name : 45 return dev->driver ? dev->driver->name :
46 (dev->bus ? dev->bus->name : ""); 46 (dev->bus ? dev->bus->name :
47 (dev->class ? dev->class->name : ""));
47} 48}
48EXPORT_SYMBOL(dev_driver_string); 49EXPORT_SYMBOL(dev_driver_string);
49 50
@@ -119,6 +120,8 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
119 120
120 if (ktype == &ktype_device) { 121 if (ktype == &ktype_device) {
121 struct device *dev = to_dev(kobj); 122 struct device *dev = to_dev(kobj);
123 if (dev->uevent_suppress)
124 return 0;
122 if (dev->bus) 125 if (dev->bus)
123 return 1; 126 return 1;
124 if (dev->class) 127 if (dev->class)
@@ -156,6 +159,11 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
156 "MINOR=%u", MINOR(dev->devt)); 159 "MINOR=%u", MINOR(dev->devt));
157 } 160 }
158 161
162 if (dev->type && dev->type->name)
163 add_uevent_var(envp, num_envp, &i,
164 buffer, buffer_size, &length,
165 "DEVTYPE=%s", dev->type->name);
166
159 if (dev->driver) 167 if (dev->driver)
160 add_uevent_var(envp, num_envp, &i, 168 add_uevent_var(envp, num_envp, &i,
161 buffer, buffer_size, &length, 169 buffer, buffer_size, &length,
@@ -238,71 +246,152 @@ static struct kset_uevent_ops device_uevent_ops = {
238 .uevent = dev_uevent, 246 .uevent = dev_uevent,
239}; 247};
240 248
249static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
250 char *buf)
251{
252 struct kobject *top_kobj;
253 struct kset *kset;
254 char *envp[32];
255 char data[PAGE_SIZE];
256 char *pos;
257 int i;
258 size_t count = 0;
259 int retval;
260
261 /* search the kset, the device belongs to */
262 top_kobj = &dev->kobj;
263 if (!top_kobj->kset && top_kobj->parent) {
264 do {
265 top_kobj = top_kobj->parent;
266 } while (!top_kobj->kset && top_kobj->parent);
267 }
268 if (!top_kobj->kset)
269 goto out;
270 kset = top_kobj->kset;
271 if (!kset->uevent_ops || !kset->uevent_ops->uevent)
272 goto out;
273
274 /* respect filter */
275 if (kset->uevent_ops && kset->uevent_ops->filter)
276 if (!kset->uevent_ops->filter(kset, &dev->kobj))
277 goto out;
278
279 /* let the kset specific function add its keys */
280 pos = data;
281 retval = kset->uevent_ops->uevent(kset, &dev->kobj,
282 envp, ARRAY_SIZE(envp),
283 pos, PAGE_SIZE);
284 if (retval)
285 goto out;
286
287 /* copy keys to file */
288 for (i = 0; envp[i]; i++) {
289 pos = &buf[count];
290 count += sprintf(pos, "%s\n", envp[i]);
291 }
292out:
293 return count;
294}
295
241static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, 296static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
242 const char *buf, size_t count) 297 const char *buf, size_t count)
243{ 298{
299 if (memcmp(buf, "add", 3) != 0)
300 dev_err(dev, "uevent: unsupported action-string; this will "
301 "be ignored in a future kernel version");
244 kobject_uevent(&dev->kobj, KOBJ_ADD); 302 kobject_uevent(&dev->kobj, KOBJ_ADD);
245 return count; 303 return count;
246} 304}
247 305
248static int device_add_groups(struct device *dev) 306static int device_add_attributes(struct device *dev,
307 struct device_attribute *attrs)
308{
309 int error = 0;
310 int i;
311
312 if (attrs) {
313 for (i = 0; attr_name(attrs[i]); i++) {
314 error = device_create_file(dev, &attrs[i]);
315 if (error)
316 break;
317 }
318 if (error)
319 while (--i >= 0)
320 device_remove_file(dev, &attrs[i]);
321 }
322 return error;
323}
324
325static void device_remove_attributes(struct device *dev,
326 struct device_attribute *attrs)
249{ 327{
250 int i; 328 int i;
329
330 if (attrs)
331 for (i = 0; attr_name(attrs[i]); i++)
332 device_remove_file(dev, &attrs[i]);
333}
334
335static int device_add_groups(struct device *dev,
336 struct attribute_group **groups)
337{
251 int error = 0; 338 int error = 0;
339 int i;
252 340
253 if (dev->groups) { 341 if (groups) {
254 for (i = 0; dev->groups[i]; i++) { 342 for (i = 0; groups[i]; i++) {
255 error = sysfs_create_group(&dev->kobj, dev->groups[i]); 343 error = sysfs_create_group(&dev->kobj, groups[i]);
256 if (error) { 344 if (error) {
257 while (--i >= 0) 345 while (--i >= 0)
258 sysfs_remove_group(&dev->kobj, dev->groups[i]); 346 sysfs_remove_group(&dev->kobj, groups[i]);
259 goto out; 347 break;
260 } 348 }
261 } 349 }
262 } 350 }
263out:
264 return error; 351 return error;
265} 352}
266 353
267static void device_remove_groups(struct device *dev) 354static void device_remove_groups(struct device *dev,
355 struct attribute_group **groups)
268{ 356{
269 int i; 357 int i;
270 if (dev->groups) { 358
271 for (i = 0; dev->groups[i]; i++) { 359 if (groups)
272 sysfs_remove_group(&dev->kobj, dev->groups[i]); 360 for (i = 0; groups[i]; i++)
273 } 361 sysfs_remove_group(&dev->kobj, groups[i]);
274 }
275} 362}
276 363
277static int device_add_attrs(struct device *dev) 364static int device_add_attrs(struct device *dev)
278{ 365{
279 struct class *class = dev->class; 366 struct class *class = dev->class;
280 struct device_type *type = dev->type; 367 struct device_type *type = dev->type;
281 int error = 0; 368 int error;
282 int i;
283 369
284 if (class && class->dev_attrs) { 370 if (class) {
285 for (i = 0; attr_name(class->dev_attrs[i]); i++) { 371 error = device_add_attributes(dev, class->dev_attrs);
286 error = device_create_file(dev, &class->dev_attrs[i]);
287 if (error)
288 break;
289 }
290 if (error) 372 if (error)
291 while (--i >= 0) 373 return error;
292 device_remove_file(dev, &class->dev_attrs[i]);
293 } 374 }
294 375
295 if (type && type->attrs) { 376 if (type) {
296 for (i = 0; attr_name(type->attrs[i]); i++) { 377 error = device_add_groups(dev, type->groups);
297 error = device_create_file(dev, &type->attrs[i]);
298 if (error)
299 break;
300 }
301 if (error) 378 if (error)
302 while (--i >= 0) 379 goto err_remove_class_attrs;
303 device_remove_file(dev, &type->attrs[i]);
304 } 380 }
305 381
382 error = device_add_groups(dev, dev->groups);
383 if (error)
384 goto err_remove_type_groups;
385
386 return 0;
387
388 err_remove_type_groups:
389 if (type)
390 device_remove_groups(dev, type->groups);
391 err_remove_class_attrs:
392 if (class)
393 device_remove_attributes(dev, class->dev_attrs);
394
306 return error; 395 return error;
307} 396}
308 397
@@ -310,17 +399,14 @@ static void device_remove_attrs(struct device *dev)
310{ 399{
311 struct class *class = dev->class; 400 struct class *class = dev->class;
312 struct device_type *type = dev->type; 401 struct device_type *type = dev->type;
313 int i;
314 402
315 if (class && class->dev_attrs) { 403 device_remove_groups(dev, dev->groups);
316 for (i = 0; attr_name(class->dev_attrs[i]); i++)
317 device_remove_file(dev, &class->dev_attrs[i]);
318 }
319 404
320 if (type && type->attrs) { 405 if (type)
321 for (i = 0; attr_name(type->attrs[i]); i++) 406 device_remove_groups(dev, type->groups);
322 device_remove_file(dev, &type->attrs[i]); 407
323 } 408 if (class)
409 device_remove_attributes(dev, class->dev_attrs);
324} 410}
325 411
326 412
@@ -394,9 +480,10 @@ void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
394EXPORT_SYMBOL_GPL(device_remove_bin_file); 480EXPORT_SYMBOL_GPL(device_remove_bin_file);
395 481
396/** 482/**
397 * device_schedule_callback - helper to schedule a callback for a device 483 * device_schedule_callback_owner - helper to schedule a callback for a device
398 * @dev: device. 484 * @dev: device.
399 * @func: callback function to invoke later. 485 * @func: callback function to invoke later.
486 * @owner: module owning the callback routine
400 * 487 *
401 * Attribute methods must not unregister themselves or their parent device 488 * Attribute methods must not unregister themselves or their parent device
402 * (which would amount to the same thing). Attempts to do so will deadlock, 489 * (which would amount to the same thing). Attempts to do so will deadlock,
@@ -407,20 +494,23 @@ EXPORT_SYMBOL_GPL(device_remove_bin_file);
407 * argument in the workqueue's process context. @dev will be pinned until 494 * argument in the workqueue's process context. @dev will be pinned until
408 * @func returns. 495 * @func returns.
409 * 496 *
497 * This routine is usually called via the inline device_schedule_callback(),
498 * which automatically sets @owner to THIS_MODULE.
499 *
410 * Returns 0 if the request was submitted, -ENOMEM if storage could not 500 * Returns 0 if the request was submitted, -ENOMEM if storage could not
411 * be allocated. 501 * be allocated, -ENODEV if a reference to @owner isn't available.
412 * 502 *
413 * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an 503 * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
414 * underlying sysfs routine (since it is intended for use by attribute 504 * underlying sysfs routine (since it is intended for use by attribute
415 * methods), and if sysfs isn't available you'll get nothing but -ENOSYS. 505 * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
416 */ 506 */
417int device_schedule_callback(struct device *dev, 507int device_schedule_callback_owner(struct device *dev,
418 void (*func)(struct device *)) 508 void (*func)(struct device *), struct module *owner)
419{ 509{
420 return sysfs_schedule_callback(&dev->kobj, 510 return sysfs_schedule_callback(&dev->kobj,
421 (void (*)(void *)) func, dev); 511 (void (*)(void *)) func, dev, owner);
422} 512}
423EXPORT_SYMBOL_GPL(device_schedule_callback); 513EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
424 514
425static void klist_children_get(struct klist_node *n) 515static void klist_children_get(struct klist_node *n)
426{ 516{
@@ -477,34 +567,58 @@ static struct kobject * get_device_parent(struct device *dev,
477 return NULL; 567 return NULL;
478} 568}
479#else 569#else
480static struct kobject * virtual_device_parent(struct device *dev) 570static struct kobject *virtual_device_parent(struct device *dev)
481{ 571{
482 if (!dev->class) 572 static struct kobject *virtual_dir = NULL;
483 return ERR_PTR(-ENODEV);
484 573
485 if (!dev->class->virtual_dir) { 574 if (!virtual_dir)
486 static struct kobject *virtual_dir = NULL; 575 virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual");
487 576
488 if (!virtual_dir) 577 return virtual_dir;
489 virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual");
490 dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
491 }
492
493 return dev->class->virtual_dir;
494} 578}
495 579
496static struct kobject * get_device_parent(struct device *dev, 580static struct kobject * get_device_parent(struct device *dev,
497 struct device *parent) 581 struct device *parent)
498{ 582{
499 /* if this is a class device, and has no parent, create one */ 583 if (dev->class) {
500 if ((dev->class) && (parent == NULL)) { 584 struct kobject *kobj = NULL;
501 return virtual_device_parent(dev); 585 struct kobject *parent_kobj;
502 } else if (parent) 586 struct kobject *k;
587
588 /*
589 * If we have no parent, we live in "virtual".
590 * Class-devices with a bus-device as parent, live
591 * in a class-directory to prevent namespace collisions.
592 */
593 if (parent == NULL)
594 parent_kobj = virtual_device_parent(dev);
595 else if (parent->class)
596 return &parent->kobj;
597 else
598 parent_kobj = &parent->kobj;
599
600 /* find our class-directory at the parent and reference it */
601 spin_lock(&dev->class->class_dirs.list_lock);
602 list_for_each_entry(k, &dev->class->class_dirs.list, entry)
603 if (k->parent == parent_kobj) {
604 kobj = kobject_get(k);
605 break;
606 }
607 spin_unlock(&dev->class->class_dirs.list_lock);
608 if (kobj)
609 return kobj;
610
611 /* or create a new class-directory at the parent device */
612 return kobject_kset_add_dir(&dev->class->class_dirs,
613 parent_kobj, dev->class->name);
614 }
615
616 if (parent)
503 return &parent->kobj; 617 return &parent->kobj;
504 return NULL; 618 return NULL;
505} 619}
506
507#endif 620#endif
621
508static int setup_parent(struct device *dev, struct device *parent) 622static int setup_parent(struct device *dev, struct device *parent)
509{ 623{
510 struct kobject *kobj; 624 struct kobject *kobj;
@@ -541,7 +655,6 @@ int device_add(struct device *dev)
541 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); 655 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
542 656
543 parent = get_device(dev->parent); 657 parent = get_device(dev->parent);
544
545 error = setup_parent(dev, parent); 658 error = setup_parent(dev, parent);
546 if (error) 659 if (error)
547 goto Error; 660 goto Error;
@@ -562,10 +675,11 @@ int device_add(struct device *dev)
562 BUS_NOTIFY_ADD_DEVICE, dev); 675 BUS_NOTIFY_ADD_DEVICE, dev);
563 676
564 dev->uevent_attr.attr.name = "uevent"; 677 dev->uevent_attr.attr.name = "uevent";
565 dev->uevent_attr.attr.mode = S_IWUSR; 678 dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR;
566 if (dev->driver) 679 if (dev->driver)
567 dev->uevent_attr.attr.owner = dev->driver->owner; 680 dev->uevent_attr.attr.owner = dev->driver->owner;
568 dev->uevent_attr.store = store_uevent; 681 dev->uevent_attr.store = store_uevent;
682 dev->uevent_attr.show = show_uevent;
569 error = device_create_file(dev, &dev->uevent_attr); 683 error = device_create_file(dev, &dev->uevent_attr);
570 if (error) 684 if (error)
571 goto attrError; 685 goto attrError;
@@ -614,16 +728,12 @@ int device_add(struct device *dev)
614 728
615 if ((error = device_add_attrs(dev))) 729 if ((error = device_add_attrs(dev)))
616 goto AttrsError; 730 goto AttrsError;
617 if ((error = device_add_groups(dev)))
618 goto GroupError;
619 if ((error = device_pm_add(dev))) 731 if ((error = device_pm_add(dev)))
620 goto PMError; 732 goto PMError;
621 if ((error = bus_add_device(dev))) 733 if ((error = bus_add_device(dev)))
622 goto BusError; 734 goto BusError;
623 if (!dev->uevent_suppress) 735 kobject_uevent(&dev->kobj, KOBJ_ADD);
624 kobject_uevent(&dev->kobj, KOBJ_ADD); 736 bus_attach_device(dev);
625 if ((error = bus_attach_device(dev)))
626 goto AttachError;
627 if (parent) 737 if (parent)
628 klist_add_tail(&dev->knode_parent, &parent->klist_children); 738 klist_add_tail(&dev->knode_parent, &parent->klist_children);
629 739
@@ -639,19 +749,15 @@ int device_add(struct device *dev)
639 up(&dev->class->sem); 749 up(&dev->class->sem);
640 } 750 }
641 Done: 751 Done:
642 kfree(class_name); 752 kfree(class_name);
643 put_device(dev); 753 put_device(dev);
644 return error; 754 return error;
645 AttachError:
646 bus_remove_device(dev);
647 BusError: 755 BusError:
648 device_pm_remove(dev); 756 device_pm_remove(dev);
649 PMError: 757 PMError:
650 if (dev->bus) 758 if (dev->bus)
651 blocking_notifier_call_chain(&dev->bus->bus_notifier, 759 blocking_notifier_call_chain(&dev->bus->bus_notifier,
652 BUS_NOTIFY_DEL_DEVICE, dev); 760 BUS_NOTIFY_DEL_DEVICE, dev);
653 device_remove_groups(dev);
654 GroupError:
655 device_remove_attrs(dev); 761 device_remove_attrs(dev);
656 AttrsError: 762 AttrsError:
657 if (dev->devt_attr) { 763 if (dev->devt_attr) {
@@ -677,15 +783,6 @@ int device_add(struct device *dev)
677#endif 783#endif
678 sysfs_remove_link(&dev->kobj, "device"); 784 sysfs_remove_link(&dev->kobj, "device");
679 } 785 }
680
681 down(&dev->class->sem);
682 /* notify any interfaces that the device is now gone */
683 list_for_each_entry(class_intf, &dev->class->interfaces, node)
684 if (class_intf->remove_dev)
685 class_intf->remove_dev(dev, class_intf);
686 /* remove the device from the class list */
687 list_del_init(&dev->node);
688 up(&dev->class->sem);
689 } 786 }
690 ueventattrError: 787 ueventattrError:
691 device_remove_file(dev, &dev->uevent_attr); 788 device_remove_file(dev, &dev->uevent_attr);
@@ -796,9 +893,33 @@ void device_del(struct device * dev)
796 /* remove the device from the class list */ 893 /* remove the device from the class list */
797 list_del_init(&dev->node); 894 list_del_init(&dev->node);
798 up(&dev->class->sem); 895 up(&dev->class->sem);
896
897 /* If we live in a parent class-directory, unreference it */
898 if (dev->kobj.parent->kset == &dev->class->class_dirs) {
899 struct device *d;
900 int other = 0;
901
902 /*
903 * if we are the last child of our class, delete
904 * our class-directory at this parent
905 */
906 down(&dev->class->sem);
907 list_for_each_entry(d, &dev->class->devices, node) {
908 if (d == dev)
909 continue;
910 if (d->kobj.parent == dev->kobj.parent) {
911 other = 1;
912 break;
913 }
914 }
915 if (!other)
916 kobject_del(dev->kobj.parent);
917
918 kobject_put(dev->kobj.parent);
919 up(&dev->class->sem);
920 }
799 } 921 }
800 device_remove_file(dev, &dev->uevent_attr); 922 device_remove_file(dev, &dev->uevent_attr);
801 device_remove_groups(dev);
802 device_remove_attrs(dev); 923 device_remove_attrs(dev);
803 bus_remove_device(dev); 924 bus_remove_device(dev);
804 925