lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1161244591.10524.45.camel@localhost.localdomain>
Date:	Thu, 19 Oct 2006 17:56:31 +1000
From:	Benjamin Herrenschmidt <benh@...nel.crashing.org>
To:	Greg KH <greg@...ah.com>
Cc:	Linux Kernel list <linux-kernel@...r.kernel.org>,
	Andrew Morton <akpm@...l.org>, Len Brown <len.brown@...el.com>,
	Deepak Saxena <dsaxena@...xity.net>
Subject: [PATCH] Add device addition/removal notifier

This patch adds a notifier exposed by the device core to be used by
platform code to be notified of the addition and removal of devices
in the system.

It's intended as a replacement for the current platform_notify callbacks
which I'll remove as soon as we have converted the couple of users to
the new notifier.

In addition, that patch moves the remove callback & notification to after
bus_remove_device() where it belongs. The new notifier is also called
with a remove event in cases device addition fails after the platform
was notified of the addition to avoid leaks since I intend to use that
call to allocate auxilliary data structures.

The notifier approach is more interesting that just a pair of global
function pointers. For example, on powerpc, some of the new code I'm
working on involved separate subsystems requesting that to keep track
of various auxilliary informations attached to devices. PCI wants to
maintain some auxilliary data structure and this is the only good
place to actually dispose of it when a device is removed, and I have
at least one other case where the platform code wants to update the
dma operations for some types of platform devices. In addition, in
the future, I might use that to add firmware links to some other
generic bus types like USB etc... 

Signed-off-by: Benjamin Herrenschmidt <benh@...nel.crashing.org>
---

Note that we might even want to add more messages to it in the future.
For example, I already have a case where I could use a notification
when a driver binds to a device, when 2 inter-dependant device/drivers
couples need to find each other.

So I'd like that in 2.6.20 if possible and there is no objection.
It should be fairly trivial to update the 2 or so users of the old
callbacks to use that new notifier and remove the old style callbacks
too, I'm waiting for feedback from them though.

Index: linux-cell/drivers/base/core.c
===================================================================
--- linux-cell.orig/drivers/base/core.c	2006-10-19 17:44:02.000000000 +1000
+++ linux-cell/drivers/base/core.c	2006-10-19 17:45:07.000000000 +1000
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/kdev_t.h>
+#include <linux/notifier.h>
 
 #include <asm/semaphore.h>
 
@@ -25,6 +26,7 @@
 
 int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
+static BLOCKING_NOTIFIER_HEAD(device_notifier);
 
 /*
  * sysfs bindings for devices.
@@ -427,6 +429,9 @@ int device_add(struct device *dev)
 	/* notify platform of device entry */
 	if (platform_notify)
 		platform_notify(dev);
+	/* notify clients of device entry (new way) */
+	blocking_notifier_call_chain(&device_notifier, DEVICE_NOTIFY_ADD_DEV,
+				     dev);
 
 	dev->uevent_attr.attr.name = "uevent";
 	dev->uevent_attr.attr.mode = S_IWUSR;
@@ -499,6 +504,8 @@ int device_add(struct device *dev)
  BusError:
 	device_pm_remove(dev);
  PMError:
+	blocking_notifier_call_chain(&device_notifier, DEVICE_NOTIFY_DEL_DEV,
+				     dev);
 	device_remove_groups(dev);
  GroupError:
  	device_remove_attrs(dev);
@@ -608,12 +615,14 @@ void device_del(struct device * dev)
 	device_remove_groups(dev);
 	device_remove_attrs(dev);
 
+	bus_remove_device(dev);
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
 	 */
 	if (platform_notify_remove)
 		platform_notify_remove(dev);
-	bus_remove_device(dev);
+	blocking_notifier_call_chain(&device_notifier, DEVICE_NOTIFY_DEL_DEV,
+				     dev);
 	device_pm_remove(dev);
 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
 	kobject_del(&dev->kobj);
@@ -836,3 +845,15 @@ int device_rename(struct device *dev, ch
 
 	return error;
 }
+
+int register_device_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&device_notifier, nb);
+}
+EXPORT_SYMBOL(register_device_notifier);
+
+int unregister_device_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&device_notifier, nb);
+}
+EXPORT_SYMBOL(unregister_device_notifier);
Index: linux-cell/include/linux/device.h
===================================================================
--- linux-cell.orig/include/linux/device.h	2006-10-19 17:43:58.000000000 +1000
+++ linux-cell/include/linux/device.h	2006-10-19 17:44:24.000000000 +1000
@@ -427,6 +427,22 @@ extern int (*platform_notify)(struct dev
 
 extern int (*platform_notify_remove)(struct device * dev);
 
+/**
+ * Device notifiers. Get notified of addition/removal of devices
+ * and possibly other events in the future. Replacement for the
+ * platform "fixup" functions. This is a low level hook provided
+ * for the platform to initialize private parts of struct device,
+ * like firmware related links. Add is called before the device is
+ * added to a bus (and thus the driver probed) and Remove is called
+ * afterward.
+ */
+struct notifier_block;
+
+extern int register_device_notifier(struct notifier_block *nb);
+extern int unregister_device_notifier(struct notifier_block *nb);
+
+#define DEVICE_NOTIFY_ADD_DEV	0x00000001	/* device added */
+#define DEVICE_NOTIFY_DEL_DEV	0x00000002	/* device removed */
 
 /**
  * get_device - atomically increment the reference count for the device.


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ