diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-18 20:50:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-18 20:50:16 -0400 |
commit | 65740356ccfa66703e7e0d47fbe372ba5193916b (patch) | |
tree | e1db48e0967a9499d20a343e27af50abb0b1c24b /drivers | |
parent | 6a13a857becef065cd138b67c162dc5c5dd88655 (diff) | |
parent | 4d664238207a82c4018757e2d87cf2a780462dcd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6:
driver core: kmalloc() failure check in driver_probe_device
Driver core: bus: remove indentation level
Driver core: Don't ignore error returns from probing
Driver core: Don't leak 'old_class_name' in drivers/base/core.c::device_rename()
driver core fixes: sysfs_create_group() retval in topology.c
driver core fixes: device_create_file() retval check in dmapool.c
driver core fixes: device_add() cleanup on error
driver core fixes: bus_add_device() cleanup on error
driver core fixes: bus_add_attrs() retval check
driver core fixes: sysfs_create_link() retval check in class.c
sysfs: update obsolete comment in sysfs_update_file
sysfs: remove duplicated dput in sysfs_update_file
HOWTO: bug report addition
Fix dev_printk() is now GPL-only
Driver core: plug device probe memory leak
Documentation: feature-removal-schedule typo
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/bus.c | 108 | ||||
-rw-r--r-- | drivers/base/class.c | 5 | ||||
-rw-r--r-- | drivers/base/core.c | 26 | ||||
-rw-r--r-- | drivers/base/dd.c | 4 | ||||
-rw-r--r-- | drivers/base/dmapool.c | 13 | ||||
-rw-r--r-- | drivers/base/topology.c | 3 |
6 files changed, 101 insertions, 58 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 12173d16bea7..7d8a7ce73fb3 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -372,19 +372,30 @@ int bus_add_device(struct device * dev) | |||
372 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 372 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); |
373 | error = device_add_attrs(bus, dev); | 373 | error = device_add_attrs(bus, dev); |
374 | if (error) | 374 | if (error) |
375 | goto out; | 375 | goto out_put; |
376 | error = sysfs_create_link(&bus->devices.kobj, | 376 | error = sysfs_create_link(&bus->devices.kobj, |
377 | &dev->kobj, dev->bus_id); | 377 | &dev->kobj, dev->bus_id); |
378 | if (error) | 378 | if (error) |
379 | goto out; | 379 | goto out_id; |
380 | error = sysfs_create_link(&dev->kobj, | 380 | error = sysfs_create_link(&dev->kobj, |
381 | &dev->bus->subsys.kset.kobj, "subsystem"); | 381 | &dev->bus->subsys.kset.kobj, "subsystem"); |
382 | if (error) | 382 | if (error) |
383 | goto out; | 383 | goto out_subsys; |
384 | error = sysfs_create_link(&dev->kobj, | 384 | error = sysfs_create_link(&dev->kobj, |
385 | &dev->bus->subsys.kset.kobj, "bus"); | 385 | &dev->bus->subsys.kset.kobj, "bus"); |
386 | if (error) | ||
387 | goto out_deprecated; | ||
386 | } | 388 | } |
387 | out: | 389 | return 0; |
390 | |||
391 | out_deprecated: | ||
392 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
393 | out_subsys: | ||
394 | sysfs_remove_link(&bus->devices.kobj, dev->bus_id); | ||
395 | out_id: | ||
396 | device_remove_attrs(bus, dev); | ||
397 | out_put: | ||
398 | put_bus(dev->bus); | ||
388 | return error; | 399 | return error; |
389 | } | 400 | } |
390 | 401 | ||
@@ -428,8 +439,10 @@ void bus_remove_device(struct device * dev) | |||
428 | sysfs_remove_link(&dev->kobj, "bus"); | 439 | sysfs_remove_link(&dev->kobj, "bus"); |
429 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 440 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); |
430 | device_remove_attrs(dev->bus, dev); | 441 | device_remove_attrs(dev->bus, dev); |
431 | dev->is_registered = 0; | 442 | if (dev->is_registered) { |
432 | klist_del(&dev->knode_bus); | 443 | dev->is_registered = 0; |
444 | klist_del(&dev->knode_bus); | ||
445 | } | ||
433 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 446 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); |
434 | device_release_driver(dev); | 447 | device_release_driver(dev); |
435 | put_bus(dev->bus); | 448 | put_bus(dev->bus); |
@@ -505,34 +518,36 @@ int bus_add_driver(struct device_driver *drv) | |||
505 | struct bus_type * bus = get_bus(drv->bus); | 518 | struct bus_type * bus = get_bus(drv->bus); |
506 | int error = 0; | 519 | int error = 0; |
507 | 520 | ||
508 | if (bus) { | 521 | if (!bus) |
509 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 522 | return 0; |
510 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 523 | |
511 | if (error) | 524 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); |
512 | goto out_put_bus; | 525 | error = kobject_set_name(&drv->kobj, "%s", drv->name); |
513 | drv->kobj.kset = &bus->drivers; | 526 | if (error) |
514 | if ((error = kobject_register(&drv->kobj))) | 527 | goto out_put_bus; |
515 | goto out_put_bus; | 528 | drv->kobj.kset = &bus->drivers; |
516 | 529 | if ((error = kobject_register(&drv->kobj))) | |
517 | error = driver_attach(drv); | 530 | goto out_put_bus; |
518 | if (error) | 531 | |
519 | goto out_unregister; | 532 | error = driver_attach(drv); |
520 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 533 | if (error) |
521 | module_add_driver(drv->owner, drv); | 534 | goto out_unregister; |
522 | 535 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | |
523 | error = driver_add_attrs(bus, drv); | 536 | module_add_driver(drv->owner, drv); |
524 | if (error) { | 537 | |
525 | /* How the hell do we get out of this pickle? Give up */ | 538 | error = driver_add_attrs(bus, drv); |
526 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | 539 | if (error) { |
527 | __FUNCTION__, drv->name); | 540 | /* How the hell do we get out of this pickle? Give up */ |
528 | } | 541 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", |
529 | error = add_bind_files(drv); | 542 | __FUNCTION__, drv->name); |
530 | if (error) { | ||
531 | /* Ditto */ | ||
532 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
533 | __FUNCTION__, drv->name); | ||
534 | } | ||
535 | } | 543 | } |
544 | error = add_bind_files(drv); | ||
545 | if (error) { | ||
546 | /* Ditto */ | ||
547 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
548 | __FUNCTION__, drv->name); | ||
549 | } | ||
550 | |||
536 | return error; | 551 | return error; |
537 | out_unregister: | 552 | out_unregister: |
538 | kobject_unregister(&drv->kobj); | 553 | kobject_unregister(&drv->kobj); |
@@ -552,16 +567,17 @@ out_put_bus: | |||
552 | 567 | ||
553 | void bus_remove_driver(struct device_driver * drv) | 568 | void bus_remove_driver(struct device_driver * drv) |
554 | { | 569 | { |
555 | if (drv->bus) { | 570 | if (!drv->bus) |
556 | remove_bind_files(drv); | 571 | return; |
557 | driver_remove_attrs(drv->bus, drv); | 572 | |
558 | klist_remove(&drv->knode_bus); | 573 | remove_bind_files(drv); |
559 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 574 | driver_remove_attrs(drv->bus, drv); |
560 | driver_detach(drv); | 575 | klist_remove(&drv->knode_bus); |
561 | module_remove_driver(drv); | 576 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); |
562 | kobject_unregister(&drv->kobj); | 577 | driver_detach(drv); |
563 | put_bus(drv->bus); | 578 | module_remove_driver(drv); |
564 | } | 579 | kobject_unregister(&drv->kobj); |
580 | put_bus(drv->bus); | ||
565 | } | 581 | } |
566 | 582 | ||
567 | 583 | ||
@@ -732,11 +748,15 @@ int bus_register(struct bus_type * bus) | |||
732 | 748 | ||
733 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 749 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); |
734 | klist_init(&bus->klist_drivers, NULL, NULL); | 750 | klist_init(&bus->klist_drivers, NULL, NULL); |
735 | bus_add_attrs(bus); | 751 | retval = bus_add_attrs(bus); |
752 | if (retval) | ||
753 | goto bus_attrs_fail; | ||
736 | 754 | ||
737 | pr_debug("bus type '%s' registered\n", bus->name); | 755 | pr_debug("bus type '%s' registered\n", bus->name); |
738 | return 0; | 756 | return 0; |
739 | 757 | ||
758 | bus_attrs_fail: | ||
759 | kset_unregister(&bus->drivers); | ||
740 | bus_drivers_fail: | 760 | bus_drivers_fail: |
741 | kset_unregister(&bus->devices); | 761 | kset_unregister(&bus->devices); |
742 | bus_devices_fail: | 762 | bus_devices_fail: |
diff --git a/drivers/base/class.c b/drivers/base/class.c index b32b77ff2dcd..0ff267a248db 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -562,7 +562,10 @@ int class_device_add(struct class_device *class_dev) | |||
562 | goto out2; | 562 | goto out2; |
563 | 563 | ||
564 | /* add the needed attributes to this device */ | 564 | /* add the needed attributes to this device */ |
565 | sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); | 565 | error = sysfs_create_link(&class_dev->kobj, |
566 | &parent_class->subsys.kset.kobj, "subsystem"); | ||
567 | if (error) | ||
568 | goto out3; | ||
566 | class_dev->uevent_attr.attr.name = "uevent"; | 569 | class_dev->uevent_attr.attr.name = "uevent"; |
567 | class_dev->uevent_attr.attr.mode = S_IWUSR; | 570 | class_dev->uevent_attr.attr.mode = S_IWUSR; |
568 | class_dev->uevent_attr.attr.owner = parent_class->owner; | 571 | class_dev->uevent_attr.attr.owner = parent_class->owner; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index b224bb43ff63..68ad11af22b4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -44,7 +44,7 @@ const char *dev_driver_string(struct device *dev) | |||
44 | return dev->driver ? dev->driver->name : | 44 | return dev->driver ? dev->driver->name : |
45 | (dev->bus ? dev->bus->name : ""); | 45 | (dev->bus ? dev->bus->name : ""); |
46 | } | 46 | } |
47 | EXPORT_SYMBOL_GPL(dev_driver_string); | 47 | EXPORT_SYMBOL(dev_driver_string); |
48 | 48 | ||
49 | #define to_dev(obj) container_of(obj, struct device, kobj) | 49 | #define to_dev(obj) container_of(obj, struct device, kobj) |
50 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 50 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
@@ -433,14 +433,16 @@ int device_add(struct device *dev) | |||
433 | if (dev->driver) | 433 | if (dev->driver) |
434 | dev->uevent_attr.attr.owner = dev->driver->owner; | 434 | dev->uevent_attr.attr.owner = dev->driver->owner; |
435 | dev->uevent_attr.store = store_uevent; | 435 | dev->uevent_attr.store = store_uevent; |
436 | device_create_file(dev, &dev->uevent_attr); | 436 | error = device_create_file(dev, &dev->uevent_attr); |
437 | if (error) | ||
438 | goto attrError; | ||
437 | 439 | ||
438 | if (MAJOR(dev->devt)) { | 440 | if (MAJOR(dev->devt)) { |
439 | struct device_attribute *attr; | 441 | struct device_attribute *attr; |
440 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 442 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); |
441 | if (!attr) { | 443 | if (!attr) { |
442 | error = -ENOMEM; | 444 | error = -ENOMEM; |
443 | goto PMError; | 445 | goto ueventattrError; |
444 | } | 446 | } |
445 | attr->attr.name = "dev"; | 447 | attr->attr.name = "dev"; |
446 | attr->attr.mode = S_IRUGO; | 448 | attr->attr.mode = S_IRUGO; |
@@ -450,7 +452,7 @@ int device_add(struct device *dev) | |||
450 | error = device_create_file(dev, attr); | 452 | error = device_create_file(dev, attr); |
451 | if (error) { | 453 | if (error) { |
452 | kfree(attr); | 454 | kfree(attr); |
453 | goto attrError; | 455 | goto ueventattrError; |
454 | } | 456 | } |
455 | 457 | ||
456 | dev->devt_attr = attr; | 458 | dev->devt_attr = attr; |
@@ -477,7 +479,8 @@ int device_add(struct device *dev) | |||
477 | if ((error = bus_add_device(dev))) | 479 | if ((error = bus_add_device(dev))) |
478 | goto BusError; | 480 | goto BusError; |
479 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 481 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
480 | bus_attach_device(dev); | 482 | if ((error = bus_attach_device(dev))) |
483 | goto AttachError; | ||
481 | if (parent) | 484 | if (parent) |
482 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 485 | klist_add_tail(&dev->knode_parent, &parent->klist_children); |
483 | 486 | ||
@@ -496,6 +499,8 @@ int device_add(struct device *dev) | |||
496 | kfree(class_name); | 499 | kfree(class_name); |
497 | put_device(dev); | 500 | put_device(dev); |
498 | return error; | 501 | return error; |
502 | AttachError: | ||
503 | bus_remove_device(dev); | ||
499 | BusError: | 504 | BusError: |
500 | device_pm_remove(dev); | 505 | device_pm_remove(dev); |
501 | PMError: | 506 | PMError: |
@@ -507,6 +512,8 @@ int device_add(struct device *dev) | |||
507 | device_remove_file(dev, dev->devt_attr); | 512 | device_remove_file(dev, dev->devt_attr); |
508 | kfree(dev->devt_attr); | 513 | kfree(dev->devt_attr); |
509 | } | 514 | } |
515 | ueventattrError: | ||
516 | device_remove_file(dev, &dev->uevent_attr); | ||
510 | attrError: | 517 | attrError: |
511 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 518 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
512 | kobject_del(&dev->kobj); | 519 | kobject_del(&dev->kobj); |
@@ -805,8 +812,10 @@ int device_rename(struct device *dev, char *new_name) | |||
805 | 812 | ||
806 | if (dev->class) { | 813 | if (dev->class) { |
807 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); | 814 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); |
808 | if (!old_symlink_name) | 815 | if (!old_symlink_name) { |
809 | return -ENOMEM; | 816 | error = -ENOMEM; |
817 | goto out_free_old_class; | ||
818 | } | ||
810 | strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); | 819 | strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); |
811 | } | 820 | } |
812 | 821 | ||
@@ -830,9 +839,10 @@ int device_rename(struct device *dev, char *new_name) | |||
830 | } | 839 | } |
831 | put_device(dev); | 840 | put_device(dev); |
832 | 841 | ||
833 | kfree(old_class_name); | ||
834 | kfree(new_class_name); | 842 | kfree(new_class_name); |
835 | kfree(old_symlink_name); | 843 | kfree(old_symlink_name); |
844 | out_free_old_class: | ||
845 | kfree(old_class_name); | ||
836 | 846 | ||
837 | return error; | 847 | return error; |
838 | } | 848 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index b5f43c3e44fa..db01b95a47a5 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -171,6 +171,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
171 | drv->bus->name, dev->bus_id, drv->name); | 171 | drv->bus->name, dev->bus_id, drv->name); |
172 | 172 | ||
173 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 173 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
174 | if (!data) | ||
175 | return -ENOMEM; | ||
174 | data->drv = drv; | 176 | data->drv = drv; |
175 | data->dev = dev; | 177 | data->dev = dev; |
176 | 178 | ||
@@ -178,7 +180,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
178 | probe_task = kthread_run(really_probe, data, | 180 | probe_task = kthread_run(really_probe, data, |
179 | "probe-%s", dev->bus_id); | 181 | "probe-%s", dev->bus_id); |
180 | if (IS_ERR(probe_task)) | 182 | if (IS_ERR(probe_task)) |
181 | ret = PTR_ERR(probe_task); | 183 | ret = really_probe(data); |
182 | } else | 184 | } else |
183 | ret = really_probe(data); | 185 | ret = really_probe(data); |
184 | 186 | ||
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index 33c5cce1560b..b2efbd4cf710 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c | |||
@@ -141,11 +141,20 @@ dma_pool_create (const char *name, struct device *dev, | |||
141 | init_waitqueue_head (&retval->waitq); | 141 | init_waitqueue_head (&retval->waitq); |
142 | 142 | ||
143 | if (dev) { | 143 | if (dev) { |
144 | int ret; | ||
145 | |||
144 | down (&pools_lock); | 146 | down (&pools_lock); |
145 | if (list_empty (&dev->dma_pools)) | 147 | if (list_empty (&dev->dma_pools)) |
146 | device_create_file (dev, &dev_attr_pools); | 148 | ret = device_create_file (dev, &dev_attr_pools); |
149 | else | ||
150 | ret = 0; | ||
147 | /* note: not currently insisting "name" be unique */ | 151 | /* note: not currently insisting "name" be unique */ |
148 | list_add (&retval->pools, &dev->dma_pools); | 152 | if (!ret) |
153 | list_add (&retval->pools, &dev->dma_pools); | ||
154 | else { | ||
155 | kfree(retval); | ||
156 | retval = NULL; | ||
157 | } | ||
149 | up (&pools_lock); | 158 | up (&pools_lock); |
150 | } else | 159 | } else |
151 | INIT_LIST_HEAD (&retval->pools); | 160 | INIT_LIST_HEAD (&retval->pools); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 3ef9d514b916..28dccb730af9 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -97,8 +97,7 @@ static struct attribute_group topology_attr_group = { | |||
97 | /* Add/Remove cpu_topology interface for CPU device */ | 97 | /* Add/Remove cpu_topology interface for CPU device */ |
98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | 98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) |
99 | { | 99 | { |
100 | sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | 100 | return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); |
101 | return 0; | ||
102 | } | 101 | } |
103 | 102 | ||
104 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | 103 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) |