diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/base/core.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6bee6af8d8e1..b56a0ba31d4a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -56,7 +56,14 @@ static inline int device_is_not_partition(struct device *dev) | |||
56 | */ | 56 | */ |
57 | const char *dev_driver_string(const struct device *dev) | 57 | const char *dev_driver_string(const struct device *dev) |
58 | { | 58 | { |
59 | return dev->driver ? dev->driver->name : | 59 | struct device_driver *drv; |
60 | |||
61 | /* dev->driver can change to NULL underneath us because of unbinding, | ||
62 | * so be careful about accessing it. dev->bus and dev->class should | ||
63 | * never change once they are set, so they don't need special care. | ||
64 | */ | ||
65 | drv = ACCESS_ONCE(dev->driver); | ||
66 | return drv ? drv->name : | ||
60 | (dev->bus ? dev->bus->name : | 67 | (dev->bus ? dev->bus->name : |
61 | (dev->class ? dev->class->name : "")); | 68 | (dev->class ? dev->class->name : "")); |
62 | } | 69 | } |
@@ -93,7 +100,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
93 | return ret; | 100 | return ret; |
94 | } | 101 | } |
95 | 102 | ||
96 | static struct sysfs_ops dev_sysfs_ops = { | 103 | static const struct sysfs_ops dev_sysfs_ops = { |
97 | .show = dev_attr_show, | 104 | .show = dev_attr_show, |
98 | .store = dev_attr_store, | 105 | .store = dev_attr_store, |
99 | }; | 106 | }; |
@@ -245,7 +252,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
245 | return retval; | 252 | return retval; |
246 | } | 253 | } |
247 | 254 | ||
248 | static struct kset_uevent_ops device_uevent_ops = { | 255 | static const struct kset_uevent_ops device_uevent_ops = { |
249 | .filter = dev_uevent_filter, | 256 | .filter = dev_uevent_filter, |
250 | .name = dev_uevent_name, | 257 | .name = dev_uevent_name, |
251 | .uevent = dev_uevent, | 258 | .uevent = dev_uevent, |
@@ -299,15 +306,10 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
299 | { | 306 | { |
300 | enum kobject_action action; | 307 | enum kobject_action action; |
301 | 308 | ||
302 | if (kobject_action_type(buf, count, &action) == 0) { | 309 | if (kobject_action_type(buf, count, &action) == 0) |
303 | kobject_uevent(&dev->kobj, action); | 310 | kobject_uevent(&dev->kobj, action); |
304 | goto out; | 311 | else |
305 | } | 312 | dev_err(dev, "uevent: unknown action-string\n"); |
306 | |||
307 | dev_err(dev, "uevent: unsupported action-string; this will " | ||
308 | "be ignored in a future kernel version\n"); | ||
309 | kobject_uevent(&dev->kobj, KOBJ_ADD); | ||
310 | out: | ||
311 | return count; | 313 | return count; |
312 | } | 314 | } |
313 | 315 | ||
@@ -439,7 +441,8 @@ struct kset *devices_kset; | |||
439 | * @dev: device. | 441 | * @dev: device. |
440 | * @attr: device attribute descriptor. | 442 | * @attr: device attribute descriptor. |
441 | */ | 443 | */ |
442 | int device_create_file(struct device *dev, struct device_attribute *attr) | 444 | int device_create_file(struct device *dev, |
445 | const struct device_attribute *attr) | ||
443 | { | 446 | { |
444 | int error = 0; | 447 | int error = 0; |
445 | if (dev) | 448 | if (dev) |
@@ -452,7 +455,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr) | |||
452 | * @dev: device. | 455 | * @dev: device. |
453 | * @attr: device attribute descriptor. | 456 | * @attr: device attribute descriptor. |
454 | */ | 457 | */ |
455 | void device_remove_file(struct device *dev, struct device_attribute *attr) | 458 | void device_remove_file(struct device *dev, |
459 | const struct device_attribute *attr) | ||
456 | { | 460 | { |
457 | if (dev) | 461 | if (dev) |
458 | sysfs_remove_file(&dev->kobj, &attr->attr); | 462 | sysfs_remove_file(&dev->kobj, &attr->attr); |
@@ -463,7 +467,8 @@ void device_remove_file(struct device *dev, struct device_attribute *attr) | |||
463 | * @dev: device. | 467 | * @dev: device. |
464 | * @attr: device binary attribute descriptor. | 468 | * @attr: device binary attribute descriptor. |
465 | */ | 469 | */ |
466 | int device_create_bin_file(struct device *dev, struct bin_attribute *attr) | 470 | int device_create_bin_file(struct device *dev, |
471 | const struct bin_attribute *attr) | ||
467 | { | 472 | { |
468 | int error = -EINVAL; | 473 | int error = -EINVAL; |
469 | if (dev) | 474 | if (dev) |
@@ -477,7 +482,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file); | |||
477 | * @dev: device. | 482 | * @dev: device. |
478 | * @attr: device binary attribute descriptor. | 483 | * @attr: device binary attribute descriptor. |
479 | */ | 484 | */ |
480 | void device_remove_bin_file(struct device *dev, struct bin_attribute *attr) | 485 | void device_remove_bin_file(struct device *dev, |
486 | const struct bin_attribute *attr) | ||
481 | { | 487 | { |
482 | if (dev) | 488 | if (dev) |
483 | sysfs_remove_bin_file(&dev->kobj, attr); | 489 | sysfs_remove_bin_file(&dev->kobj, attr); |
@@ -596,6 +602,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
596 | int retval; | 602 | int retval; |
597 | 603 | ||
598 | if (dev->class) { | 604 | if (dev->class) { |
605 | static DEFINE_MUTEX(gdp_mutex); | ||
599 | struct kobject *kobj = NULL; | 606 | struct kobject *kobj = NULL; |
600 | struct kobject *parent_kobj; | 607 | struct kobject *parent_kobj; |
601 | struct kobject *k; | 608 | struct kobject *k; |
@@ -612,6 +619,8 @@ static struct kobject *get_device_parent(struct device *dev, | |||
612 | else | 619 | else |
613 | parent_kobj = &parent->kobj; | 620 | parent_kobj = &parent->kobj; |
614 | 621 | ||
622 | mutex_lock(&gdp_mutex); | ||
623 | |||
615 | /* find our class-directory at the parent and reference it */ | 624 | /* find our class-directory at the parent and reference it */ |
616 | spin_lock(&dev->class->p->class_dirs.list_lock); | 625 | spin_lock(&dev->class->p->class_dirs.list_lock); |
617 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | 626 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) |
@@ -620,20 +629,26 @@ static struct kobject *get_device_parent(struct device *dev, | |||
620 | break; | 629 | break; |
621 | } | 630 | } |
622 | spin_unlock(&dev->class->p->class_dirs.list_lock); | 631 | spin_unlock(&dev->class->p->class_dirs.list_lock); |
623 | if (kobj) | 632 | if (kobj) { |
633 | mutex_unlock(&gdp_mutex); | ||
624 | return kobj; | 634 | return kobj; |
635 | } | ||
625 | 636 | ||
626 | /* or create a new class-directory at the parent device */ | 637 | /* or create a new class-directory at the parent device */ |
627 | k = kobject_create(); | 638 | k = kobject_create(); |
628 | if (!k) | 639 | if (!k) { |
640 | mutex_unlock(&gdp_mutex); | ||
629 | return NULL; | 641 | return NULL; |
642 | } | ||
630 | k->kset = &dev->class->p->class_dirs; | 643 | k->kset = &dev->class->p->class_dirs; |
631 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | 644 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); |
632 | if (retval < 0) { | 645 | if (retval < 0) { |
646 | mutex_unlock(&gdp_mutex); | ||
633 | kobject_put(k); | 647 | kobject_put(k); |
634 | return NULL; | 648 | return NULL; |
635 | } | 649 | } |
636 | /* do not emit an uevent for this simple "glue" directory */ | 650 | /* do not emit an uevent for this simple "glue" directory */ |
651 | mutex_unlock(&gdp_mutex); | ||
637 | return k; | 652 | return k; |
638 | } | 653 | } |
639 | 654 | ||
@@ -898,8 +913,10 @@ int device_add(struct device *dev) | |||
898 | dev->init_name = NULL; | 913 | dev->init_name = NULL; |
899 | } | 914 | } |
900 | 915 | ||
901 | if (!dev_name(dev)) | 916 | if (!dev_name(dev)) { |
917 | error = -EINVAL; | ||
902 | goto name_error; | 918 | goto name_error; |
919 | } | ||
903 | 920 | ||
904 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 921 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
905 | 922 | ||
@@ -987,6 +1004,8 @@ done: | |||
987 | device_remove_class_symlinks(dev); | 1004 | device_remove_class_symlinks(dev); |
988 | SymlinkError: | 1005 | SymlinkError: |
989 | if (MAJOR(dev->devt)) | 1006 | if (MAJOR(dev->devt)) |
1007 | devtmpfs_delete_node(dev); | ||
1008 | if (MAJOR(dev->devt)) | ||
990 | device_remove_sys_dev_entry(dev); | 1009 | device_remove_sys_dev_entry(dev); |
991 | devtattrError: | 1010 | devtattrError: |
992 | if (MAJOR(dev->devt)) | 1011 | if (MAJOR(dev->devt)) |
@@ -1326,6 +1345,8 @@ static void root_device_release(struct device *dev) | |||
1326 | * 'module' symlink which points to the @owner directory | 1345 | * 'module' symlink which points to the @owner directory |
1327 | * in sysfs. | 1346 | * in sysfs. |
1328 | * | 1347 | * |
1348 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1349 | * | ||
1329 | * Note: You probably want to use root_device_register(). | 1350 | * Note: You probably want to use root_device_register(). |
1330 | */ | 1351 | */ |
1331 | struct device *__root_device_register(const char *name, struct module *owner) | 1352 | struct device *__root_device_register(const char *name, struct module *owner) |
@@ -1413,6 +1434,8 @@ static void device_create_release(struct device *dev) | |||
1413 | * Any further sysfs files that might be required can be created using this | 1434 | * Any further sysfs files that might be required can be created using this |
1414 | * pointer. | 1435 | * pointer. |
1415 | * | 1436 | * |
1437 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1438 | * | ||
1416 | * Note: the struct class passed to this function must have previously | 1439 | * Note: the struct class passed to this function must have previously |
1417 | * been created with a call to class_create(). | 1440 | * been created with a call to class_create(). |
1418 | */ | 1441 | */ |
@@ -1473,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs); | |||
1473 | * Any further sysfs files that might be required can be created using this | 1496 | * Any further sysfs files that might be required can be created using this |
1474 | * pointer. | 1497 | * pointer. |
1475 | * | 1498 | * |
1499 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1500 | * | ||
1476 | * Note: the struct class passed to this function must have previously | 1501 | * Note: the struct class passed to this function must have previously |
1477 | * been created with a call to class_create(). | 1502 | * been created with a call to class_create(). |
1478 | */ | 1503 | */ |
@@ -1559,22 +1584,16 @@ int device_rename(struct device *dev, char *new_name) | |||
1559 | if (old_class_name) { | 1584 | if (old_class_name) { |
1560 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | 1585 | new_class_name = make_class_name(dev->class->name, &dev->kobj); |
1561 | if (new_class_name) { | 1586 | if (new_class_name) { |
1562 | error = sysfs_create_link_nowarn(&dev->parent->kobj, | 1587 | error = sysfs_rename_link(&dev->parent->kobj, |
1563 | &dev->kobj, | 1588 | &dev->kobj, |
1564 | new_class_name); | 1589 | old_class_name, |
1565 | if (error) | 1590 | new_class_name); |
1566 | goto out; | ||
1567 | sysfs_remove_link(&dev->parent->kobj, old_class_name); | ||
1568 | } | 1591 | } |
1569 | } | 1592 | } |
1570 | #else | 1593 | #else |
1571 | if (dev->class) { | 1594 | if (dev->class) { |
1572 | error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj, | 1595 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, |
1573 | &dev->kobj, dev_name(dev)); | 1596 | &dev->kobj, old_device_name, new_name); |
1574 | if (error) | ||
1575 | goto out; | ||
1576 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, | ||
1577 | old_device_name); | ||
1578 | } | 1597 | } |
1579 | #endif | 1598 | #endif |
1580 | 1599 | ||
@@ -1728,8 +1747,5 @@ void device_shutdown(void) | |||
1728 | dev->driver->shutdown(dev); | 1747 | dev->driver->shutdown(dev); |
1729 | } | 1748 | } |
1730 | } | 1749 | } |
1731 | kobject_put(sysfs_dev_char_kobj); | ||
1732 | kobject_put(sysfs_dev_block_kobj); | ||
1733 | kobject_put(dev_kobj); | ||
1734 | async_synchronize_full(); | 1750 | async_synchronize_full(); |
1735 | } | 1751 | } |