aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r--drivers/base/bus.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 04d3850ff4b7..aa0c986c323a 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright (c) 2002-3 Patrick Mochel 4 * Copyright (c) 2002-3 Patrick Mochel
5 * Copyright (c) 2002-3 Open Source Development Labs 5 * Copyright (c) 2002-3 Open Source Development Labs
6 * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
7 * Copyright (c) 2007 Novell Inc.
6 * 8 *
7 * This file is released under the GPLv2 9 * This file is released under the GPLv2
8 * 10 *
@@ -24,7 +26,6 @@
24 */ 26 */
25 27
26#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) 28#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
27#define to_driver(obj) container_of(obj, struct device_driver, kobj)
28 29
29 30
30static int __must_check bus_rescan_devices_helper(struct device *dev, 31static int __must_check bus_rescan_devices_helper(struct device *dev,
@@ -49,11 +50,11 @@ static ssize_t
49drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 50drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
50{ 51{
51 struct driver_attribute * drv_attr = to_drv_attr(attr); 52 struct driver_attribute * drv_attr = to_drv_attr(attr);
52 struct device_driver * drv = to_driver(kobj); 53 struct driver_private *drv_priv = to_driver(kobj);
53 ssize_t ret = -EIO; 54 ssize_t ret = -EIO;
54 55
55 if (drv_attr->show) 56 if (drv_attr->show)
56 ret = drv_attr->show(drv, buf); 57 ret = drv_attr->show(drv_priv->driver, buf);
57 return ret; 58 return ret;
58} 59}
59 60
@@ -62,11 +63,11 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
62 const char * buf, size_t count) 63 const char * buf, size_t count)
63{ 64{
64 struct driver_attribute * drv_attr = to_drv_attr(attr); 65 struct driver_attribute * drv_attr = to_drv_attr(attr);
65 struct device_driver * drv = to_driver(kobj); 66 struct driver_private *drv_priv = to_driver(kobj);
66 ssize_t ret = -EIO; 67 ssize_t ret = -EIO;
67 68
68 if (drv_attr->store) 69 if (drv_attr->store)
69 ret = drv_attr->store(drv, buf, count); 70 ret = drv_attr->store(drv_priv->driver, buf, count);
70 return ret; 71 return ret;
71} 72}
72 73
@@ -75,22 +76,12 @@ static struct sysfs_ops driver_sysfs_ops = {
75 .store = drv_attr_store, 76 .store = drv_attr_store,
76}; 77};
77 78
78 79static void driver_release(struct kobject *kobj)
79static void driver_release(struct kobject * kobj)
80{ 80{
81 /* 81 struct driver_private *drv_priv = to_driver(kobj);
82 * Yes this is an empty release function, it is this way because struct 82
83 * device is always a static object, not a dynamic one. Yes, this is 83 pr_debug("%s: freeing %s\n", __FUNCTION__, kobject_name(kobj));
84 * not nice and bad, but remember, drivers are code, reference counted 84 kfree(drv_priv);
85 * by the module count, not a device, which is really data. And yes,
86 * in the future I do want to have all drivers be created dynamically,
87 * and am working toward that goal, but it will take a bit longer...
88 *
89 * But do not let this example give _anyone_ the idea that they can
90 * create a release function without any code in it at all, to do that
91 * is almost always wrong. If you have any questions about this,
92 * please send an email to <greg@kroah.com>
93 */
94} 85}
95 86
96static struct kobj_type driver_ktype = { 87static struct kobj_type driver_ktype = {
@@ -350,7 +341,13 @@ struct device * bus_find_device(struct bus_type *bus,
350static struct device_driver * next_driver(struct klist_iter * i) 341static struct device_driver * next_driver(struct klist_iter * i)
351{ 342{
352 struct klist_node * n = klist_next(i); 343 struct klist_node * n = klist_next(i);
353 return n ? container_of(n, struct device_driver, knode_bus) : NULL; 344 struct driver_private *drv_priv;
345
346 if (n) {
347 drv_priv = container_of(n, struct driver_private, knode_bus);
348 return drv_priv->driver;
349 }
350 return NULL;
354} 351}
355 352
356/** 353/**
@@ -384,7 +381,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
384 return -EINVAL; 381 return -EINVAL;
385 382
386 klist_iter_init_node(&bus->p->klist_drivers, &i, 383 klist_iter_init_node(&bus->p->klist_drivers, &i,
387 start ? &start->knode_bus : NULL); 384 start ? &start->p->knode_bus : NULL);
388 while ((drv = next_driver(&i)) && !error) 385 while ((drv = next_driver(&i)) && !error)
389 error = fn(drv, data); 386 error = fn(drv, data);
390 klist_iter_exit(&i); 387 klist_iter_exit(&i);
@@ -620,7 +617,7 @@ static ssize_t driver_uevent_store(struct device_driver *drv,
620 enum kobject_action action; 617 enum kobject_action action;
621 618
622 if (kobject_action_type(buf, count, &action) == 0) 619 if (kobject_action_type(buf, count, &action) == 0)
623 kobject_uevent(&drv->kobj, action); 620 kobject_uevent(&drv->p->kobj, action);
624 return count; 621 return count;
625} 622}
626static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); 623static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
@@ -632,19 +629,29 @@ static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
632 */ 629 */
633int bus_add_driver(struct device_driver *drv) 630int bus_add_driver(struct device_driver *drv)
634{ 631{
635 struct bus_type * bus = bus_get(drv->bus); 632 struct bus_type *bus;
633 struct driver_private *priv;
636 int error = 0; 634 int error = 0;
637 635
636 bus = bus_get(drv->bus);
638 if (!bus) 637 if (!bus)
639 return -EINVAL; 638 return -EINVAL;
640 639
641 pr_debug("bus %s: add driver %s\n", bus->name, drv->name); 640 pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
642 error = kobject_set_name(&drv->kobj, "%s", drv->name); 641
642 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
643 if (!priv)
644 return -ENOMEM;
645
646 error = kobject_set_name(&priv->kobj, "%s", drv->name);
643 if (error) 647 if (error)
644 goto out_put_bus; 648 goto out_put_bus;
645 drv->kobj.kset = bus->p->drivers_kset; 649 priv->kobj.kset = bus->p->drivers_kset;
646 drv->kobj.ktype = &driver_ktype; 650 priv->kobj.ktype = &driver_ktype;
647 error = kobject_register(&drv->kobj); 651 klist_init(&priv->klist_devices, NULL, NULL);
652 priv->driver = drv;
653 drv->p = priv;
654 error = kobject_register(&priv->kobj);
648 if (error) 655 if (error)
649 goto out_put_bus; 656 goto out_put_bus;
650 657
@@ -653,7 +660,7 @@ int bus_add_driver(struct device_driver *drv)
653 if (error) 660 if (error)
654 goto out_unregister; 661 goto out_unregister;
655 } 662 }
656 klist_add_tail(&drv->knode_bus, &bus->p->klist_drivers); 663 klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
657 module_add_driver(drv->owner, drv); 664 module_add_driver(drv->owner, drv);
658 665
659 error = driver_create_file(drv, &driver_attr_uevent); 666 error = driver_create_file(drv, &driver_attr_uevent);
@@ -676,7 +683,7 @@ int bus_add_driver(struct device_driver *drv)
676 683
677 return error; 684 return error;
678out_unregister: 685out_unregister:
679 kobject_unregister(&drv->kobj); 686 kobject_unregister(&priv->kobj);
680out_put_bus: 687out_put_bus:
681 bus_put(bus); 688 bus_put(bus);
682 return error; 689 return error;
@@ -699,11 +706,11 @@ void bus_remove_driver(struct device_driver * drv)
699 remove_bind_files(drv); 706 remove_bind_files(drv);
700 driver_remove_attrs(drv->bus, drv); 707 driver_remove_attrs(drv->bus, drv);
701 driver_remove_file(drv, &driver_attr_uevent); 708 driver_remove_file(drv, &driver_attr_uevent);
702 klist_remove(&drv->knode_bus); 709 klist_remove(&drv->p->knode_bus);
703 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 710 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
704 driver_detach(drv); 711 driver_detach(drv);
705 module_remove_driver(drv); 712 module_remove_driver(drv);
706 kobject_unregister(&drv->kobj); 713 kobject_unregister(&drv->p->kobj);
707 bus_put(drv->bus); 714 bus_put(drv->bus);
708} 715}
709 716