driver core: remove fields from struct bus_type
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 2 Nov 2007 02:41:16 +0000 (19:41 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Jan 2008 04:40:33 +0000 (20:40 -0800)
struct bus_type is static everywhere in the kernel.  This moves the
kobject in the structure out of it, and a bunch of other private only to
the driver core fields are now moved to a private structure.  This lets
us dynamically create the backing kobject properly and gives us the
chance to be able to document to users exactly how to use the struct
bus_type as there are no fields they can improperly access.

Thanks to Kay for the build fixes on this patch.

Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/base/base.h
drivers/base/bus.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/driver.c
drivers/base/platform.c
include/linux/device.h

index 7e309a49a7113e1bf8b1c88b61e3780fc30e7c96..ca6d273064f870a0671d5d01745b847bd8c2f6d6 100644 (file)
@@ -1,6 +1,34 @@
 
-/* initialisation functions */
+/**
+ * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.
+ *
+ * @subsys - the struct kset that defines this bus.  This is the main kobject
+ * @drivers_kset - the list of drivers associated with this bus
+ * @devices_kset - the list of devices associated with this bus
+ * @klist_devices - the klist to iterate over the @devices_kset
+ * @klist_drivers - the klist to iterate over the @drivers_kset
+ * @bus_notifier - the bus notifier list for anything that cares about things
+ * on this bus.
+ * @bus - pointer back to the struct bus_type that this structure is associated
+ * with.
+ *
+ * This structure is the one that is the actual kobject allowing struct
+ * bus_type to be statically allocated safely.  Nothing outside of the driver
+ * core should ever touch these fields.
+ */
+struct bus_type_private {
+       struct kset subsys;
+       struct kset *drivers_kset;
+       struct kset *devices_kset;
+       struct klist klist_devices;
+       struct klist klist_drivers;
+       struct blocking_notifier_head bus_notifier;
+       unsigned int drivers_autoprobe:1;
+       struct bus_type *bus;
+};
+
 
+/* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
 extern int classes_init(void);
index 9c9027b2c44eef9cbbf591c9113e490ed27b51c9..04d3850ff4b7f642125d267b13c6828846ad9a0c 100644 (file)
@@ -17,7 +17,7 @@
 #include "power/power.h"
 
 #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
-#define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj)
+#define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj)
 
 /*
  * sysfs bindings for drivers
@@ -32,13 +32,17 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
 
 static struct bus_type *bus_get(struct bus_type *bus)
 {
-       return bus ? container_of(kset_get(&bus->subsys),
-                               struct bus_type, subsys) : NULL;
+       if (bus) {
+               kset_get(&bus->p->subsys);
+               return bus;
+       }
+       return NULL;
 }
 
 static void bus_put(struct bus_type *bus)
 {
-       kset_put(&bus->subsys);
+       if (bus)
+               kset_put(&bus->p->subsys);
 }
 
 static ssize_t
@@ -104,11 +108,11 @@ static ssize_t
 bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
        struct bus_attribute * bus_attr = to_bus_attr(attr);
-       struct bus_type * bus = to_bus(kobj);
+       struct bus_type_private *bus_priv = to_bus(kobj);
        ssize_t ret = 0;
 
        if (bus_attr->show)
-               ret = bus_attr->show(bus, buf);
+               ret = bus_attr->show(bus_priv->bus, buf);
        return ret;
 }
 
@@ -117,11 +121,11 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr,
               const char * buf, size_t count)
 {
        struct bus_attribute * bus_attr = to_bus_attr(attr);
-       struct bus_type * bus = to_bus(kobj);
+       struct bus_type_private *bus_priv = to_bus(kobj);
        ssize_t ret = 0;
 
        if (bus_attr->store)
-               ret = bus_attr->store(bus, buf, count);
+               ret = bus_attr->store(bus_priv->bus, buf, count);
        return ret;
 }
 
@@ -134,7 +138,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
 {
        int error;
        if (bus_get(bus)) {
-               error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
+               error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);
                bus_put(bus);
        } else
                error = -EINVAL;
@@ -144,7 +148,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
 void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
 {
        if (bus_get(bus)) {
-               sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
+               sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
                bus_put(bus);
        }
 }
@@ -237,16 +241,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
 
 static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
 {
-       return sprintf(buf, "%d\n", bus->drivers_autoprobe);
+       return sprintf(buf, "%d\n", bus->p->drivers_autoprobe);
 }
 
 static ssize_t store_drivers_autoprobe(struct bus_type *bus,
                                       const char *buf, size_t count)
 {
        if (buf[0] == '0')
-               bus->drivers_autoprobe = 0;
+               bus->p->drivers_autoprobe = 0;
        else
-               bus->drivers_autoprobe = 1;
+               bus->p->drivers_autoprobe = 1;
        return count;
 }
 
@@ -300,7 +304,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
        if (!bus)
                return -EINVAL;
 
-       klist_iter_init_node(&bus->klist_devices, &i,
+       klist_iter_init_node(&bus->p->klist_devices, &i,
                             (start ? &start->knode_bus : NULL));
        while ((dev = next_device(&i)) && !error)
                error = fn(dev, data);
@@ -333,7 +337,7 @@ struct device * bus_find_device(struct bus_type *bus,
        if (!bus)
                return NULL;
 
-       klist_iter_init_node(&bus->klist_devices, &i,
+       klist_iter_init_node(&bus->p->klist_devices, &i,
                             (start ? &start->knode_bus : NULL));
        while ((dev = next_device(&i)))
                if (match(dev, data) && get_device(dev))
@@ -379,7 +383,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
        if (!bus)
                return -EINVAL;
 
-       klist_iter_init_node(&bus->klist_drivers, &i,
+       klist_iter_init_node(&bus->p->klist_drivers, &i,
                             start ? &start->knode_bus : NULL);
        while ((drv = next_driver(&i)) && !error)
                error = fn(drv, data);
@@ -420,7 +424,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev)
 static int make_deprecated_bus_links(struct device *dev)
 {
        return sysfs_create_link(&dev->kobj,
-                                &dev->bus->subsys.kobj, "bus");
+                                &dev->bus->p->subsys.kobj, "bus");
 }
 
 static void remove_deprecated_bus_links(struct device *dev)
@@ -449,12 +453,12 @@ int bus_add_device(struct device * dev)
                error = device_add_attrs(bus, dev);
                if (error)
                        goto out_put;
-               error = sysfs_create_link(&bus->devices_kset->kobj,
+               error = sysfs_create_link(&bus->p->devices_kset->kobj,
                                                &dev->kobj, dev->bus_id);
                if (error)
                        goto out_id;
                error = sysfs_create_link(&dev->kobj,
-                               &dev->bus->subsys.kobj, "subsystem");
+                               &dev->bus->p->subsys.kobj, "subsystem");
                if (error)
                        goto out_subsys;
                error = make_deprecated_bus_links(dev);
@@ -466,7 +470,7 @@ int bus_add_device(struct device * dev)
 out_deprecated:
        sysfs_remove_link(&dev->kobj, "subsystem");
 out_subsys:
-       sysfs_remove_link(&bus->devices_kset->kobj, dev->bus_id);
+       sysfs_remove_link(&bus->p->devices_kset->kobj, dev->bus_id);
 out_id:
        device_remove_attrs(bus, dev);
 out_put:
@@ -488,11 +492,11 @@ void bus_attach_device(struct device * dev)
 
        if (bus) {
                dev->is_registered = 1;
-               if (bus->drivers_autoprobe)
+               if (bus->p->drivers_autoprobe)
                        ret = device_attach(dev);
                WARN_ON(ret < 0);
                if (ret >= 0)
-                       klist_add_tail(&dev->knode_bus, &bus->klist_devices);
+                       klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
                else
                        dev->is_registered = 0;
        }
@@ -512,7 +516,7 @@ void bus_remove_device(struct device * dev)
        if (dev->bus) {
                sysfs_remove_link(&dev->kobj, "subsystem");
                remove_deprecated_bus_links(dev);
-               sysfs_remove_link(&dev->bus->devices_kset->kobj, dev->bus_id);
+               sysfs_remove_link(&dev->bus->p->devices_kset->kobj, dev->bus_id);
                device_remove_attrs(dev->bus, dev);
                if (dev->is_registered) {
                        dev->is_registered = 0;
@@ -638,18 +642,18 @@ int bus_add_driver(struct device_driver *drv)
        error = kobject_set_name(&drv->kobj, "%s", drv->name);
        if (error)
                goto out_put_bus;
-       drv->kobj.kset = bus->drivers_kset;
+       drv->kobj.kset = bus->p->drivers_kset;
        drv->kobj.ktype = &driver_ktype;
        error = kobject_register(&drv->kobj);
        if (error)
                goto out_put_bus;
 
-       if (drv->bus->drivers_autoprobe) {
+       if (drv->bus->p->drivers_autoprobe) {
                error = driver_attach(drv);
                if (error)
                        goto out_unregister;
        }
-       klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
+       klist_add_tail(&drv->knode_bus, &bus->p->klist_drivers);
        module_add_driver(drv->owner, drv);
 
        error = driver_create_file(drv, &driver_attr_uevent);
@@ -828,7 +832,7 @@ static ssize_t bus_uevent_store(struct bus_type *bus,
        enum kobject_action action;
 
        if (kobject_action_type(buf, count, &action) == 0)
-               kobject_uevent(&bus->subsys.kobj, action);
+               kobject_uevent(&bus->p->subsys.kobj, action);
        return count;
 }
 static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
@@ -844,17 +848,26 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
 int bus_register(struct bus_type * bus)
 {
        int retval;
+       struct bus_type_private *priv;
+
+       priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->bus = bus;
+       bus->p = priv;
 
-       BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
+       BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
 
-       retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);
+       retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
        if (retval)
                goto out;
 
-       bus->subsys.kobj.kset = bus_kset;
-       bus->subsys.kobj.ktype = &bus_ktype;
+       priv->subsys.kobj.kset = bus_kset;
+       priv->subsys.kobj.ktype = &bus_ktype;
+       priv->drivers_autoprobe = 1;
 
-       retval = kset_register(&bus->subsys);
+       retval = kset_register(&priv->subsys);
        if (retval)
                goto out;
 
@@ -862,24 +875,23 @@ int bus_register(struct bus_type * bus)
        if (retval)
                goto bus_uevent_fail;
 
-       bus->devices_kset = kset_create_and_add("devices", NULL,
-                                               &bus->subsys.kobj);
-       if (!bus->devices_kset) {
+       priv->devices_kset = kset_create_and_add("devices", NULL,
+                                                &priv->subsys.kobj);
+       if (!priv->devices_kset) {
                retval = -ENOMEM;
                goto bus_devices_fail;
        }
 
-       bus->drivers_kset = kset_create_and_add("drivers", NULL,
-                                               &bus->subsys.kobj);
-       if (!bus->drivers_kset) {
+       priv->drivers_kset = kset_create_and_add("drivers", NULL,
+                                                &priv->subsys.kobj);
+       if (!priv->drivers_kset) {
                retval = -ENOMEM;
                goto bus_drivers_fail;
        }
 
-       klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
-       klist_init(&bus->klist_drivers, NULL, NULL);
+       klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
+       klist_init(&priv->klist_drivers, NULL, NULL);
 
-       bus->drivers_autoprobe = 1;
        retval = add_probe_files(bus);
        if (retval)
                goto bus_probe_files_fail;
@@ -894,13 +906,14 @@ int bus_register(struct bus_type * bus)
 bus_attrs_fail:
        remove_probe_files(bus);
 bus_probe_files_fail:
-       kset_unregister(bus->drivers_kset);
+       kset_unregister(bus->p->drivers_kset);
 bus_drivers_fail:
-       kset_unregister(bus->devices_kset);
+       kset_unregister(bus->p->devices_kset);
 bus_devices_fail:
        bus_remove_file(bus, &bus_attr_uevent);
 bus_uevent_fail:
-       kset_unregister(&bus->subsys);
+       kset_unregister(&bus->p->subsys);
+       kfree(bus->p);
 out:
        return retval;
 }
@@ -917,33 +930,34 @@ void bus_unregister(struct bus_type * bus)
        pr_debug("bus %s: unregistering\n", bus->name);
        bus_remove_attrs(bus);
        remove_probe_files(bus);
-       kset_unregister(bus->drivers_kset);
-       kset_unregister(bus->devices_kset);
+       kset_unregister(bus->p->drivers_kset);
+       kset_unregister(bus->p->devices_kset);
        bus_remove_file(bus, &bus_attr_uevent);
-       kset_unregister(&bus->subsys);
+       kset_unregister(&bus->p->subsys);
+       kfree(bus->p);
 }
 
 int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
 {
-       return blocking_notifier_chain_register(&bus->bus_notifier, nb);
+       return blocking_notifier_chain_register(&bus->p->bus_notifier, nb);
 }
 EXPORT_SYMBOL_GPL(bus_register_notifier);
 
 int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
 {
-       return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
+       return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb);
 }
 EXPORT_SYMBOL_GPL(bus_unregister_notifier);
 
 struct kset *bus_get_kset(struct bus_type *bus)
 {
-       return &bus->subsys;
+       return &bus->p->subsys;
 }
 EXPORT_SYMBOL_GPL(bus_get_kset);
 
 struct klist *bus_get_device_klist(struct bus_type *bus)
 {
-       return &bus->klist_devices;
+       return &bus->p->klist_devices;
 }
 EXPORT_SYMBOL_GPL(bus_get_device_klist);
 
index beb35160067502a473d066a8c420ca9051ffc054..414a480e10a35d8f1eb144ab9f8bae7a97441b9b 100644 (file)
@@ -769,7 +769,7 @@ int device_add(struct device *dev)
 
        /* notify clients of device entry (new way) */
        if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_ADD_DEVICE, dev);
 
        error = device_create_file(dev, &uevent_attr);
@@ -820,7 +820,7 @@ int device_add(struct device *dev)
        dpm_sysfs_remove(dev);
  PMError:
        if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_DEL_DEVICE, dev);
        device_remove_attrs(dev);
  AttrsError:
@@ -999,7 +999,7 @@ void device_del(struct device * dev)
        if (platform_notify_remove)
                platform_notify_remove(dev);
        if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_DEL_DEVICE, dev);
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
index 7ac474db88c525f46a0846810ca5f384fa07b104..7bf0e674c975f75b6e4a43b4194f266af2118c82 100644 (file)
@@ -38,7 +38,7 @@ static void driver_bound(struct device *dev)
                 dev->bus_id, dev->driver->name);
 
        if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_BOUND_DRIVER, dev);
 
        klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
@@ -296,7 +296,7 @@ static void __device_release_driver(struct device * dev)
                klist_remove(&dev->knode_driver);
 
                if (dev->bus)
-                       blocking_notifier_call_chain(&dev->bus->bus_notifier,
+                       blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                                     BUS_NOTIFY_UNBIND_DRIVER,
                                                     dev);
 
index 1c9770dfb8018220e278114f129cd1f699915f07..f94be40646d2c3a5d16a2d438544299056b4c55d 100644 (file)
@@ -185,7 +185,7 @@ void driver_unregister(struct device_driver * drv)
  */
 struct device_driver *driver_find(const char *name, struct bus_type *bus)
 {
-       struct kobject *k = kset_find_obj(bus->drivers_kset, name);
+       struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
        if (k)
                return to_drv(k);
        return NULL;
index fb56092414821645342071f5c0da32ef2a486b4b..d56a05f94f67dcda9e606c259fe5a3c7feb9f21f 100644 (file)
@@ -497,12 +497,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
         * if the probe was successful, and make sure any forced probes of
         * new devices fail.
         */
-       spin_lock(&platform_bus_type.klist_drivers.k_lock);
+       spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
        drv->probe = NULL;
        if (code == 0 && list_empty(&drv->driver.klist_devices.k_list))
                retval = -ENODEV;
        drv->driver.probe = platform_drv_probe_fail;
-       spin_unlock(&platform_bus_type.klist_drivers.k_lock);
+       spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
 
        if (code != retval)
                platform_driver_unregister(drv);
index 62e695bd3c931b574a70853ad29eeebf1651bd04..3f24bf46d298f6f859f161ab27338d84c50f31a9 100644 (file)
@@ -35,6 +35,7 @@ struct device_driver;
 struct class;
 struct class_device;
 struct bus_type;
+struct bus_type_private;
 
 struct bus_attribute {
        struct attribute        attr;
@@ -51,15 +52,6 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
 
 struct bus_type {
        const char              * name;
-
-       struct kset             subsys;
-       struct kset             *drivers_kset;
-       struct kset             *devices_kset;
-       struct klist            klist_devices;
-       struct klist            klist_drivers;
-
-       struct blocking_notifier_head bus_notifier;
-
        struct bus_attribute    * bus_attrs;
        struct device_attribute * dev_attrs;
        struct driver_attribute * drv_attrs;
@@ -75,7 +67,7 @@ struct bus_type {
        int (*resume_early)(struct device * dev);
        int (*resume)(struct device * dev);
 
-       unsigned int drivers_autoprobe:1;
+       struct bus_type_private *p;
 };
 
 extern int __must_check bus_register(struct bus_type * bus);