[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] pcie io space multiplex: backport of bus event notification patch



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1243500971 -3600
# Node ID e9f508296fc7f42aa1d8c7aeaa9bfd97b914bf3a
# Parent  4ffa9ad54890a237ed6ddbf25386d27dc92fab8c
pcie io space multiplex: backport of bus event notification patch

back port of 116af378201ef793424cd10508ccf18b06d8a021 and
ec0676ee28528dc8dda13a93ee4b1f215a0c2f9d.

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

    Driver core: add notification of bus events

    Signed-off-by: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

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

    Driver core: move the bus notifier call points

    Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
    Cc: Kay Sievers <kay.sievers@xxxxxxxx>
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/base/bus.c     |   14 ++++++++++++++
 drivers/base/core.c    |   15 +++++++++++++++
 drivers/base/dd.c      |   10 ++++++++++
 include/linux/device.h |   25 +++++++++++++++++++++++++
 4 files changed, 64 insertions(+)

diff -r 4ffa9ad54890 -r e9f508296fc7 drivers/base/bus.c
--- a/drivers/base/bus.c        Thu May 28 09:53:22 2009 +0100
+++ b/drivers/base/bus.c        Thu May 28 09:56:11 2009 +0100
@@ -683,6 +683,8 @@ int bus_register(struct bus_type * bus)
 {
        int retval;
 
+       BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
+
        retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
        if (retval)
                goto out;
@@ -737,6 +739,18 @@ void bus_unregister(struct bus_type * bu
        subsystem_unregister(&bus->subsys);
 }
 
+int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&bus->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);
+}
+EXPORT_SYMBOL_GPL(bus_unregister_notifier);
+
 int __init buses_init(void)
 {
        return subsystem_register(&bus_subsys);
diff -r 4ffa9ad54890 -r e9f508296fc7 drivers/base/core.c
--- a/drivers/base/core.c       Thu May 28 09:53:22 2009 +0100
+++ b/drivers/base/core.c       Thu May 28 09:56:11 2009 +0100
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/kdev_t.h>
+#include <linux/notifier.h>
 
 #include <asm/semaphore.h>
 
@@ -350,6 +351,14 @@ int device_add(struct device *dev)
                goto PMError;
        if ((error = bus_add_device(dev)))
                goto BusError;
+
+       /* Notify clients of device addition.  This call must come
+        * after dpm_sysf_add() and before kobject_uevent().
+        */
+       if (dev->bus)
+               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+                                            BUS_NOTIFY_ADD_DEVICE, dev);
+
        kobject_uevent(&dev->kobj, KOBJ_ADD);
        bus_attach_device(dev);
        if (parent)
@@ -450,6 +459,12 @@ void device_del(struct device * dev)
        struct device * parent = dev->parent;
        char *class_name = NULL;
 
+       /* Notify clients of device removal.  This call must come
+        * before dpm_sysfs_remove().
+        */
+       if (dev->bus)
+               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+                                            BUS_NOTIFY_DEL_DEVICE, dev);
        if (parent)
                klist_del(&dev->knode_parent);
        if (dev->devt_attr)
diff -r 4ffa9ad54890 -r e9f508296fc7 drivers/base/dd.c
--- a/drivers/base/dd.c Thu May 28 09:53:22 2009 +0100
+++ b/drivers/base/dd.c Thu May 28 09:56:11 2009 +0100
@@ -45,6 +45,11 @@ void device_bind_driver(struct device * 
 
        pr_debug("bound device '%s' to driver '%s'\n",
                 dev->bus_id, dev->driver->name);
+
+       if (dev->bus)
+               blocking_notifier_call_chain(&dev->bus->bus_notifier,
+                                            BUS_NOTIFY_BOUND_DRIVER, dev);
+
        klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
        sysfs_create_link(&dev->driver->kobj, &dev->kobj,
                          kobject_name(&dev->kobj));
@@ -209,6 +214,11 @@ static void __device_release_driver(stru
                sysfs_remove_link(&dev->kobj, "driver");
                klist_remove(&dev->knode_driver);
 
+               if (dev->bus)
+                       blocking_notifier_call_chain(&dev->bus->bus_notifier,
+                                                    BUS_NOTIFY_UNBIND_DRIVER,
+                                                    dev);
+
                if (dev->bus && dev->bus->remove)
                        dev->bus->remove(dev);
                else if (drv->remove)
diff -r 4ffa9ad54890 -r e9f508296fc7 include/linux/device.h
--- a/include/linux/device.h    Thu May 28 09:53:22 2009 +0100
+++ b/include/linux/device.h    Thu May 28 09:56:11 2009 +0100
@@ -41,6 +41,8 @@ struct bus_type {
        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;
@@ -70,6 +72,29 @@ int bus_for_each_drv(struct bus_type * b
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 
                     void * data, int (*fn)(struct device_driver *, void *));
 
+
+/*
+ * Bus notifiers: Get notified of addition/removal of devices
+ * and binding/unbinding of drivers to devices.
+ * In the long run, it should be a replacement for the platform
+ * notify hooks.
+ */
+struct notifier_block;
+
+extern int bus_register_notifier(struct bus_type *bus,
+                                struct notifier_block *nb);
+extern int bus_unregister_notifier(struct bus_type *bus,
+                                  struct notifier_block *nb);
+
+/* All 4 notifers below get called with the target struct device *
+ * as an argument. Note that those functions are likely to be called
+ * with the device semaphore held in the core, so be careful.
+ */
+#define BUS_NOTIFY_ADD_DEVICE          0x00000001 /* device added */
+#define BUS_NOTIFY_DEL_DEVICE          0x00000002 /* device removed */
+#define BUS_NOTIFY_BOUND_DRIVER                0x00000003 /* driver bound to 
device */
+#define BUS_NOTIFY_UNBIND_DRIVER       0x00000004 /* driver about to be
+                                                     unbound */
 
 /* driverfs interface for exporting bus attributes */
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.