# 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
|