Driver core: udev triggered device-<>driver binding

We get two per-bus sysfs files:
  ls-l /sys/subsystem/usb
  drwxr-xr-x 2 root root    0 2007-02-16 16:42 devices
  drwxr-xr-x 7 root root    0 2007-02-16 14:55 drivers
  -rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
  --w------- 1 root root 4096 2007-02-16 16:42 drivers_probe

The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.

The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.

Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
  echo 0 > /sys/subsystem/usb/drivers_autoprobe
  echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
  ...

and initiate the probing with udev rules like:
  ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
  ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
  ...

Custom driver binding can happen in earlier rules by something like:
  ACTION=="add", SUBSYSTEM=="usb", \
  ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
  ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"

This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.

With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...

To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/include/linux/device.h b/include/linux/device.h
index de0e73e..9d54fe1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -34,9 +34,24 @@
 struct device_driver;
 struct class;
 struct class_device;
+struct bus_type;
+
+struct bus_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct bus_type *, char * buf);
+	ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
+};
+
+#define BUS_ATTR(_name,_mode,_show,_store)	\
+struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+extern int __must_check bus_create_file(struct bus_type *,
+					struct bus_attribute *);
+extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
 
 struct bus_type {
 	const char		* name;
+	struct module		* owner;
 
 	struct subsystem	subsys;
 	struct kset		drivers;
@@ -49,6 +64,8 @@
 	struct bus_attribute	* bus_attrs;
 	struct device_attribute	* dev_attrs;
 	struct driver_attribute	* drv_attrs;
+	struct bus_attribute drivers_autoprobe_attr;
+	struct bus_attribute drivers_probe_attr;
 
 	int		(*match)(struct device * dev, struct device_driver * drv);
 	int		(*uevent)(struct device *dev, char **envp,
@@ -61,6 +78,8 @@
 	int (*suspend_late)(struct device * dev, pm_message_t state);
 	int (*resume_early)(struct device * dev);
 	int (*resume)(struct device * dev);
+
+	unsigned int drivers_autoprobe:1;
 };
 
 extern int __must_check bus_register(struct bus_type * bus);
@@ -102,21 +121,6 @@
 #define BUS_NOTIFY_UNBIND_DRIVER	0x00000004 /* driver about to be
 						      unbound */
 
-/* sysfs interface for exporting bus attributes */
-
-struct bus_attribute {
-	struct attribute	attr;
-	ssize_t (*show)(struct bus_type *, char * buf);
-	ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
-};
-
-#define BUS_ATTR(_name,_mode,_show,_store)	\
-struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
-
-extern int __must_check bus_create_file(struct bus_type *,
-					struct bus_attribute *);
-extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
-
 struct device_driver {
 	const char		* name;
 	struct bus_type		* bus;