aboutsummaryrefslogtreecommitdiffstats
path: root/f1.patch
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2007-11-01 16:33:12 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2007-11-01 16:33:12 -0700
commit36846825b70f7f025d29bb997bcb6d93fa5a5837 (patch)
treef45779907ae6b60f10146d34a463c085f54240e9 /f1.patch
parenta0a8a272d2c293b38489cf28c743671fdefcfad2 (diff)
downloadpatches-36846825b70f7f025d29bb997bcb6d93fa5a5837.tar.gz
added working bus_type cleanup patch
Diffstat (limited to 'f1.patch')
-rw-r--r--f1.patch434
1 files changed, 434 insertions, 0 deletions
diff --git a/f1.patch b/f1.patch
new file mode 100644
index 00000000000000..9ec82dbd94bf70
--- /dev/null
+++ b/f1.patch
@@ -0,0 +1,434 @@
+#From foo@baz Tue Apr 9 12:12:43 2002
+#Date: Thu, 01 Nov 2007 13:31:26 -0700
+#To: Greg KH <greg@kroah.com>
+#From: Greg Kroah-Hartman <gregkh@suse.de>
+#Subject: driver core: remove fields from struct bus_type
+
+DOES NOT BUILD AND IS NOT FULLY TESTED!!!
+
+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.
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/base/base.h | 30 ++++++++++++-
+ drivers/base/bus.c | 110 ++++++++++++++++++++++++++++---------------------
+ drivers/base/core.c | 6 +-
+ include/linux/device.h | 12 -----
+ 4 files changed, 97 insertions(+), 61 deletions(-)
+
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -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);
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -18,7 +18,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
+@@ -33,13 +33,17 @@ static int __must_check bus_rescan_devic
+
+ 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
+@@ -105,11 +109,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;
+ }
+
+@@ -118,11 +122,11 @@ bus_attr_store(struct kobject * kobj, st
+ 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;
+ }
+
+@@ -135,7 +139,7 @@ int bus_create_file(struct bus_type * bu
+ {
+ 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;
+@@ -145,7 +149,7 @@ int bus_create_file(struct bus_type * bu
+ 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);
+ }
+ }
+@@ -238,16 +242,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL,
+
+ 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;
+ }
+
+@@ -301,7 +305,7 @@ int bus_for_each_dev(struct bus_type * b
+ 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);
+@@ -334,7 +338,7 @@ struct device * bus_find_device(struct b
+ 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))
+@@ -380,7 +384,7 @@ int bus_for_each_drv(struct bus_type * b
+ 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);
+@@ -450,12 +454,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);
+@@ -467,7 +471,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:
+@@ -493,7 +497,7 @@ void bus_attach_device(struct device * d
+ 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;
+ }
+@@ -513,7 +517,7 @@ void bus_remove_device(struct device * d
+ 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;
+@@ -639,7 +643,7 @@ int bus_add_driver(struct device_driver
+ 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)
+@@ -650,7 +654,7 @@ int bus_add_driver(struct device_driver
+ 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);
+@@ -829,7 +833,7 @@ static ssize_t bus_uevent_store(struct b
+ 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);
+@@ -845,17 +849,25 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, b
+ 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;
+
+- retval = subsystem_register(&bus->subsys);
++ retval = subsystem_register(&priv->subsys);
+ if (retval)
+ goto out;
+
+@@ -863,22 +875,24 @@ int bus_register(struct bus_type * bus)
+ if (retval)
+ goto bus_uevent_fail;
+
+- bus->devices_kset = kset_create_and_register("devices", NULL,
+- &bus->subsys.kobj, NULL);
+- if (IS_ERR(bus->devices_kset)) {
+- retval = PTR_ERR(bus->devices_kset);
++ priv->devices_kset = kset_create_and_register("devices", NULL,
++ &priv->subsys.kobj,
++ NULL);
++ if (IS_ERR(priv->devices_kset)) {
++ retval = PTR_ERR(priv->devices_kset);
+ goto bus_devices_fail;
+ }
+
+- bus->drivers_kset = kset_create_and_register("drivers", NULL,
+- &bus->subsys.kobj, NULL);
+- if (IS_ERR(bus->drivers_kset)) {
+- retval = PTR_ERR(bus->drivers_kset);
++ priv->drivers_kset = kset_create_and_register("drivers", NULL,
++ &priv->subsys.kobj,
++ NULL);
++ if (IS_ERR(priv->drivers_kset)) {
++ retval = PTR_ERR(priv->drivers_kset);
+ 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);
+@@ -895,13 +909,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:
+- subsystem_unregister(&bus->subsys);
++ subsystem_unregister(&bus->p->subsys);
++ kfree(bus->p);
+ out:
+ return retval;
+ }
+@@ -918,21 +933,22 @@ void bus_unregister(struct bus_type * bu
+ 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);
+- subsystem_unregister(&bus->subsys);
++ subsystem_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);
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -762,7 +762,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);
+@@ -811,7 +811,7 @@ int device_add(struct device *dev)
+ device_pm_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:
+@@ -990,7 +990,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);
+ device_pm_remove(dev);
+ kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -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_t
+
+ 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);