aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-08-15 01:43:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-26 00:08:39 -0400
commitf86db396ff455ed586751d21816a1ebd431264e5 (patch)
treedfbeb27206b673ed46482b18ee6d779786be7ed1
parent370226449ced358e52d198081120826ef52c166b (diff)
drivers/base: check errors
Add lots of return-value checking. <pcornelia.huck@de.ibm.com>: fix bus_rescan_devices()] Cc: "Randy.Dunlap" <rdunlap@xenotime.net> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/bus.c107
-rw-r--r--drivers/base/dd.c37
-rw-r--r--include/linux/device.h8
4 files changed, 104 insertions, 50 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h
index c3b8dc98b8a7..d26644a59537 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -16,7 +16,7 @@ extern int cpu_dev_init(void);
16extern int attribute_container_init(void); 16extern int attribute_container_init(void);
17 17
18extern int bus_add_device(struct device * dev); 18extern int bus_add_device(struct device * dev);
19extern void bus_attach_device(struct device * dev); 19extern int bus_attach_device(struct device * dev);
20extern void bus_remove_device(struct device * dev); 20extern void bus_remove_device(struct device * dev);
21extern struct bus_type *get_bus(struct bus_type * bus); 21extern struct bus_type *get_bus(struct bus_type * bus);
22extern void put_bus(struct bus_type * bus); 22extern void put_bus(struct bus_type * bus);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 4d22a1d10a1c..aa685a20b649 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -371,12 +371,20 @@ int bus_add_device(struct device * dev)
371 if (bus) { 371 if (bus) {
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 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 375 goto out;
376 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); 376 error = sysfs_create_link(&bus->devices.kobj,
377 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); 377 &dev->kobj, dev->bus_id);
378 } 378 if (error)
379 goto out;
380 error = sysfs_create_link(&dev->kobj,
381 &dev->bus->subsys.kset.kobj, "subsystem");
382 if (error)
383 goto out;
384 error = sysfs_create_link(&dev->kobj,
385 &dev->bus->subsys.kset.kobj, "bus");
379 } 386 }
387out:
380 return error; 388 return error;
381} 389}
382 390
@@ -386,14 +394,19 @@ int bus_add_device(struct device * dev)
386 * 394 *
387 * - Try to attach to driver. 395 * - Try to attach to driver.
388 */ 396 */
389void bus_attach_device(struct device * dev) 397int bus_attach_device(struct device * dev)
390{ 398{
391 struct bus_type * bus = dev->bus; 399 struct bus_type *bus = dev->bus;
400 int ret = 0;
392 401
393 if (bus) { 402 if (bus) {
394 device_attach(dev); 403 ret = device_attach(dev);
395 klist_add_tail(&dev->knode_bus, &bus->klist_devices); 404 if (ret >= 0) {
405 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
406 ret = 0;
407 }
396 } 408 }
409 return ret;
397} 410}
398 411
399/** 412/**
@@ -455,10 +468,17 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr
455 * Thanks to drivers making their tables __devinit, we can't allow manual 468 * Thanks to drivers making their tables __devinit, we can't allow manual
456 * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled. 469 * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
457 */ 470 */
458static void add_bind_files(struct device_driver *drv) 471static int __must_check add_bind_files(struct device_driver *drv)
459{ 472{
460 driver_create_file(drv, &driver_attr_unbind); 473 int ret;
461 driver_create_file(drv, &driver_attr_bind); 474
475 ret = driver_create_file(drv, &driver_attr_unbind);
476 if (ret == 0) {
477 ret = driver_create_file(drv, &driver_attr_bind);
478 if (ret)
479 driver_remove_file(drv, &driver_attr_unbind);
480 }
481 return ret;
462} 482}
463 483
464static void remove_bind_files(struct device_driver *drv) 484static void remove_bind_files(struct device_driver *drv)
@@ -476,7 +496,7 @@ static inline void remove_bind_files(struct device_driver *drv) {}
476 * @drv: driver. 496 * @drv: driver.
477 * 497 *
478 */ 498 */
479int bus_add_driver(struct device_driver * drv) 499int bus_add_driver(struct device_driver *drv)
480{ 500{
481 struct bus_type * bus = get_bus(drv->bus); 501 struct bus_type * bus = get_bus(drv->bus);
482 int error = 0; 502 int error = 0;
@@ -484,27 +504,39 @@ int bus_add_driver(struct device_driver * drv)
484 if (bus) { 504 if (bus) {
485 pr_debug("bus %s: add driver %s\n", bus->name, drv->name); 505 pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
486 error = kobject_set_name(&drv->kobj, "%s", drv->name); 506 error = kobject_set_name(&drv->kobj, "%s", drv->name);
487 if (error) { 507 if (error)
488 put_bus(bus); 508 goto out_put_bus;
489 return error;
490 }
491 drv->kobj.kset = &bus->drivers; 509 drv->kobj.kset = &bus->drivers;
492 if ((error = kobject_register(&drv->kobj))) { 510 if ((error = kobject_register(&drv->kobj)))
493 put_bus(bus); 511 goto out_put_bus;
494 return error;
495 }
496 512
497 driver_attach(drv); 513 error = driver_attach(drv);
514 if (error)
515 goto out_unregister;
498 klist_add_tail(&drv->knode_bus, &bus->klist_drivers); 516 klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
499 module_add_driver(drv->owner, drv); 517 module_add_driver(drv->owner, drv);
500 518
501 driver_add_attrs(bus, drv); 519 error = driver_add_attrs(bus, drv);
502 add_bind_files(drv); 520 if (error) {
521 /* How the hell do we get out of this pickle? Give up */
522 printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
523 __FUNCTION__, drv->name);
524 }
525 error = add_bind_files(drv);
526 if (error) {
527 /* Ditto */
528 printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
529 __FUNCTION__, drv->name);
530 }
503 } 531 }
504 return error; 532 return error;
533out_unregister:
534 kobject_unregister(&drv->kobj);
535out_put_bus:
536 put_bus(bus);
537 return error;
505} 538}
506 539
507
508/** 540/**
509 * bus_remove_driver - delete driver from bus's knowledge. 541 * bus_remove_driver - delete driver from bus's knowledge.
510 * @drv: driver. 542 * @drv: driver.
@@ -530,16 +562,21 @@ void bus_remove_driver(struct device_driver * drv)
530 562
531 563
532/* Helper for bus_rescan_devices's iter */ 564/* Helper for bus_rescan_devices's iter */
533static int bus_rescan_devices_helper(struct device *dev, void *data) 565static int __must_check bus_rescan_devices_helper(struct device *dev,
566 void *data)
534{ 567{
568 int ret = 0;
569
535 if (!dev->driver) { 570 if (!dev->driver) {
536 if (dev->parent) /* Needed for USB */ 571 if (dev->parent) /* Needed for USB */
537 down(&dev->parent->sem); 572 down(&dev->parent->sem);
538 device_attach(dev); 573 ret = device_attach(dev);
539 if (dev->parent) 574 if (dev->parent)
540 up(&dev->parent->sem); 575 up(&dev->parent->sem);
576 if (ret > 0)
577 ret = 0;
541 } 578 }
542 return 0; 579 return ret < 0 ? ret : 0;
543} 580}
544 581
545/** 582/**
@@ -550,9 +587,9 @@ static int bus_rescan_devices_helper(struct device *dev, void *data)
550 * attached and rescan it against existing drivers to see if it matches 587 * attached and rescan it against existing drivers to see if it matches
551 * any by calling device_attach() for the unbound devices. 588 * any by calling device_attach() for the unbound devices.
552 */ 589 */
553void bus_rescan_devices(struct bus_type * bus) 590int bus_rescan_devices(struct bus_type * bus)
554{ 591{
555 bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); 592 return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
556} 593}
557 594
558/** 595/**
@@ -564,7 +601,7 @@ void bus_rescan_devices(struct bus_type * bus)
564 * to use if probing criteria changed during a devices lifetime and 601 * to use if probing criteria changed during a devices lifetime and
565 * driver attachment should change accordingly. 602 * driver attachment should change accordingly.
566 */ 603 */
567void device_reprobe(struct device *dev) 604int device_reprobe(struct device *dev)
568{ 605{
569 if (dev->driver) { 606 if (dev->driver) {
570 if (dev->parent) /* Needed for USB */ 607 if (dev->parent) /* Needed for USB */
@@ -573,14 +610,14 @@ void device_reprobe(struct device *dev)
573 if (dev->parent) 610 if (dev->parent)
574 up(&dev->parent->sem); 611 up(&dev->parent->sem);
575 } 612 }
576 613 return bus_rescan_devices_helper(dev, NULL);
577 bus_rescan_devices_helper(dev, NULL);
578} 614}
579EXPORT_SYMBOL_GPL(device_reprobe); 615EXPORT_SYMBOL_GPL(device_reprobe);
580 616
581struct bus_type * get_bus(struct bus_type * bus) 617struct bus_type *get_bus(struct bus_type *bus)
582{ 618{
583 return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL; 619 return bus ? container_of(subsys_get(&bus->subsys),
620 struct bus_type, subsys) : NULL;
584} 621}
585 622
586void put_bus(struct bus_type * bus) 623void put_bus(struct bus_type * bus)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 889c71111239..9f6f11ca0ab6 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -38,17 +38,29 @@
38 * 38 *
39 * This function must be called with @dev->sem held. 39 * This function must be called with @dev->sem held.
40 */ 40 */
41void device_bind_driver(struct device * dev) 41int device_bind_driver(struct device *dev)
42{ 42{
43 if (klist_node_attached(&dev->knode_driver)) 43 int ret;
44 return; 44
45 if (klist_node_attached(&dev->knode_driver)) {
46 printk(KERN_WARNING "%s: device %s already bound\n",
47 __FUNCTION__, kobject_name(&dev->kobj));
48 return 0;
49 }
45 50
46 pr_debug("bound device '%s' to driver '%s'\n", 51 pr_debug("bound device '%s' to driver '%s'\n",
47 dev->bus_id, dev->driver->name); 52 dev->bus_id, dev->driver->name);
48 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); 53 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
49 sysfs_create_link(&dev->driver->kobj, &dev->kobj, 54 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
50 kobject_name(&dev->kobj)); 55 kobject_name(&dev->kobj));
51 sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); 56 if (ret == 0) {
57 ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj,
58 "driver");
59 if (ret)
60 sysfs_remove_link(&dev->driver->kobj,
61 kobject_name(&dev->kobj));
62 }
63 return ret;
52} 64}
53 65
54/** 66/**
@@ -91,7 +103,11 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
91 goto ProbeFailed; 103 goto ProbeFailed;
92 } 104 }
93 } 105 }
94 device_bind_driver(dev); 106 if (device_bind_driver(dev)) {
107 printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
108 __FUNCTION__, dev->bus_id);
109 /* How does undo a ->probe? We're screwed. */
110 }
95 ret = 1; 111 ret = 1;
96 pr_debug("%s: Bound Device %s to Driver %s\n", 112 pr_debug("%s: Bound Device %s to Driver %s\n",
97 drv->bus->name, dev->bus_id, drv->name); 113 drv->bus->name, dev->bus_id, drv->name);
@@ -139,8 +155,9 @@ int device_attach(struct device * dev)
139 155
140 down(&dev->sem); 156 down(&dev->sem);
141 if (dev->driver) { 157 if (dev->driver) {
142 device_bind_driver(dev); 158 ret = device_bind_driver(dev);
143 ret = 1; 159 if (ret == 0)
160 ret = 1;
144 } else 161 } else
145 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); 162 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
146 up(&dev->sem); 163 up(&dev->sem);
@@ -182,9 +199,9 @@ static int __driver_attach(struct device * dev, void * data)
182 * returns 0 and the @dev->driver is set, we've found a 199 * returns 0 and the @dev->driver is set, we've found a
183 * compatible pair. 200 * compatible pair.
184 */ 201 */
185void driver_attach(struct device_driver * drv) 202int driver_attach(struct device_driver * drv)
186{ 203{
187 bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); 204 return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
188} 205}
189 206
190/** 207/**
diff --git a/include/linux/device.h b/include/linux/device.h
index ad4db72f5733..b3da9a870cfc 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -62,7 +62,7 @@ struct bus_type {
62extern int __must_check bus_register(struct bus_type * bus); 62extern int __must_check bus_register(struct bus_type * bus);
63extern void bus_unregister(struct bus_type * bus); 63extern void bus_unregister(struct bus_type * bus);
64 64
65extern void bus_rescan_devices(struct bus_type * bus); 65extern int __must_check bus_rescan_devices(struct bus_type * bus);
66 66
67/* iterator helpers for buses */ 67/* iterator helpers for buses */
68 68
@@ -397,11 +397,11 @@ extern int device_rename(struct device *dev, char *new_name);
397 * Manual binding of a device to driver. See drivers/base/bus.c 397 * Manual binding of a device to driver. See drivers/base/bus.c
398 * for information on use. 398 * for information on use.
399 */ 399 */
400extern void device_bind_driver(struct device * dev); 400extern int __must_check device_bind_driver(struct device *dev);
401extern void device_release_driver(struct device * dev); 401extern void device_release_driver(struct device * dev);
402extern int __must_check device_attach(struct device * dev); 402extern int __must_check device_attach(struct device * dev);
403extern void driver_attach(struct device_driver * drv); 403extern int __must_check driver_attach(struct device_driver *drv);
404extern void device_reprobe(struct device *dev); 404extern int __must_check device_reprobe(struct device *dev);
405 405
406/* 406/*
407 * Easy functions for dynamically creating devices on the fly 407 * Easy functions for dynamically creating devices on the fly