ia64/linux-2.6.18-xen.hg

changeset 881:e9f508296fc7

pcie io space multiplex: backport of bus event notification patch

back port of 116af378201ef793424cd10508ccf18b06d8a021 and
ec0676ee28528dc8dda13a93ee4b1f215a0c2f9d.

commit 116af378201ef793424cd10508ccf18b06d8a021
Author: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Wed Oct 25 13:44:59 2006 +1000

Driver core: add notification of bus events

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>


commit ec0676ee28528dc8dda13a93ee4b1f215a0c2f9d
Author: Alan Stern <stern@rowland.harvard.edu>
Date: Fri Dec 5 14:10:31 2008 -0500

Driver core: move the bus notifier call points

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 09:56:11 2009 +0100 (2009-05-28)
parents 4ffa9ad54890
children 8dec4aa9b8b9
files drivers/base/bus.c drivers/base/core.c drivers/base/dd.c include/linux/device.h
line diff
     1.1 --- a/drivers/base/bus.c	Thu May 28 09:53:22 2009 +0100
     1.2 +++ b/drivers/base/bus.c	Thu May 28 09:56:11 2009 +0100
     1.3 @@ -683,6 +683,8 @@ int bus_register(struct bus_type * bus)
     1.4  {
     1.5  	int retval;
     1.6  
     1.7 +	BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
     1.8 +
     1.9  	retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
    1.10  	if (retval)
    1.11  		goto out;
    1.12 @@ -737,6 +739,18 @@ void bus_unregister(struct bus_type * bu
    1.13  	subsystem_unregister(&bus->subsys);
    1.14  }
    1.15  
    1.16 +int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
    1.17 +{
    1.18 +	return blocking_notifier_chain_register(&bus->bus_notifier, nb);
    1.19 +}
    1.20 +EXPORT_SYMBOL_GPL(bus_register_notifier);
    1.21 +
    1.22 +int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
    1.23 +{
    1.24 +	return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
    1.25 +}
    1.26 +EXPORT_SYMBOL_GPL(bus_unregister_notifier);
    1.27 +
    1.28  int __init buses_init(void)
    1.29  {
    1.30  	return subsystem_register(&bus_subsys);
     2.1 --- a/drivers/base/core.c	Thu May 28 09:53:22 2009 +0100
     2.2 +++ b/drivers/base/core.c	Thu May 28 09:56:11 2009 +0100
     2.3 @@ -15,6 +15,7 @@
     2.4  #include <linux/slab.h>
     2.5  #include <linux/string.h>
     2.6  #include <linux/kdev_t.h>
     2.7 +#include <linux/notifier.h>
     2.8  
     2.9  #include <asm/semaphore.h>
    2.10  
    2.11 @@ -350,6 +351,14 @@ int device_add(struct device *dev)
    2.12  		goto PMError;
    2.13  	if ((error = bus_add_device(dev)))
    2.14  		goto BusError;
    2.15 +
    2.16 +	/* Notify clients of device addition.  This call must come
    2.17 +	 * after dpm_sysf_add() and before kobject_uevent().
    2.18 +	 */
    2.19 +	if (dev->bus)
    2.20 +		blocking_notifier_call_chain(&dev->bus->bus_notifier,
    2.21 +					     BUS_NOTIFY_ADD_DEVICE, dev);
    2.22 +
    2.23  	kobject_uevent(&dev->kobj, KOBJ_ADD);
    2.24  	bus_attach_device(dev);
    2.25  	if (parent)
    2.26 @@ -450,6 +459,12 @@ void device_del(struct device * dev)
    2.27  	struct device * parent = dev->parent;
    2.28  	char *class_name = NULL;
    2.29  
    2.30 +	/* Notify clients of device removal.  This call must come
    2.31 +	 * before dpm_sysfs_remove().
    2.32 +	 */
    2.33 +	if (dev->bus)
    2.34 +		blocking_notifier_call_chain(&dev->bus->bus_notifier,
    2.35 +					     BUS_NOTIFY_DEL_DEVICE, dev);
    2.36  	if (parent)
    2.37  		klist_del(&dev->knode_parent);
    2.38  	if (dev->devt_attr)
     3.1 --- a/drivers/base/dd.c	Thu May 28 09:53:22 2009 +0100
     3.2 +++ b/drivers/base/dd.c	Thu May 28 09:56:11 2009 +0100
     3.3 @@ -45,6 +45,11 @@ void device_bind_driver(struct device * 
     3.4  
     3.5  	pr_debug("bound device '%s' to driver '%s'\n",
     3.6  		 dev->bus_id, dev->driver->name);
     3.7 +
     3.8 +	if (dev->bus)
     3.9 +		blocking_notifier_call_chain(&dev->bus->bus_notifier,
    3.10 +					     BUS_NOTIFY_BOUND_DRIVER, dev);
    3.11 +
    3.12  	klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
    3.13  	sysfs_create_link(&dev->driver->kobj, &dev->kobj,
    3.14  			  kobject_name(&dev->kobj));
    3.15 @@ -209,6 +214,11 @@ static void __device_release_driver(stru
    3.16  		sysfs_remove_link(&dev->kobj, "driver");
    3.17  		klist_remove(&dev->knode_driver);
    3.18  
    3.19 +		if (dev->bus)
    3.20 +			blocking_notifier_call_chain(&dev->bus->bus_notifier,
    3.21 +						     BUS_NOTIFY_UNBIND_DRIVER,
    3.22 +						     dev);
    3.23 +
    3.24  		if (dev->bus && dev->bus->remove)
    3.25  			dev->bus->remove(dev);
    3.26  		else if (drv->remove)
     4.1 --- a/include/linux/device.h	Thu May 28 09:53:22 2009 +0100
     4.2 +++ b/include/linux/device.h	Thu May 28 09:56:11 2009 +0100
     4.3 @@ -41,6 +41,8 @@ struct bus_type {
     4.4  	struct klist		klist_devices;
     4.5  	struct klist		klist_drivers;
     4.6  
     4.7 +	struct blocking_notifier_head bus_notifier;
     4.8 +
     4.9  	struct bus_attribute	* bus_attrs;
    4.10  	struct device_attribute	* dev_attrs;
    4.11  	struct driver_attribute	* drv_attrs;
    4.12 @@ -71,6 +73,29 @@ int bus_for_each_drv(struct bus_type * b
    4.13  		     void * data, int (*fn)(struct device_driver *, void *));
    4.14  
    4.15  
    4.16 +/*
    4.17 + * Bus notifiers: Get notified of addition/removal of devices
    4.18 + * and binding/unbinding of drivers to devices.
    4.19 + * In the long run, it should be a replacement for the platform
    4.20 + * notify hooks.
    4.21 + */
    4.22 +struct notifier_block;
    4.23 +
    4.24 +extern int bus_register_notifier(struct bus_type *bus,
    4.25 +				 struct notifier_block *nb);
    4.26 +extern int bus_unregister_notifier(struct bus_type *bus,
    4.27 +				   struct notifier_block *nb);
    4.28 +
    4.29 +/* All 4 notifers below get called with the target struct device *
    4.30 + * as an argument. Note that those functions are likely to be called
    4.31 + * with the device semaphore held in the core, so be careful.
    4.32 + */
    4.33 +#define BUS_NOTIFY_ADD_DEVICE		0x00000001 /* device added */
    4.34 +#define BUS_NOTIFY_DEL_DEVICE		0x00000002 /* device removed */
    4.35 +#define BUS_NOTIFY_BOUND_DRIVER		0x00000003 /* driver bound to device */
    4.36 +#define BUS_NOTIFY_UNBIND_DRIVER	0x00000004 /* driver about to be
    4.37 +						      unbound */
    4.38 +
    4.39  /* driverfs interface for exporting bus attributes */
    4.40  
    4.41  struct bus_attribute {