aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core/usb.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-12-05 14:10:34 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-07 10:00:08 -0800
commit3b23dd6f8a718e5339de4f7d86ce76a078b5f771 (patch)
tree500a0402d7d8ba9afefc316124c1a6b4b4d575b2 /drivers/usb/core/usb.c
parentb9cef6c31913c34fb1065b1d01e04c3b92c59016 (diff)
USB: utilize the bus notifiers
This patch (as1185) makes usbcore take advantage of the bus notifications sent out by the driver core. Now we can create all our device and interface attribute files before the device or interface uevent is broadcast. A side effect is that we no longer create the endpoint "pseudo" devices at the same time as a device or interface is registered -- it seems like a bad idea to try registering an endpoint before the registration of its parent is complete. So the routines for creating and removing endpoint devices have been split out and renamed, and they are called explicitly when needed. A new bitflag is used for keeping track of whether or not the interface's endpoint devices have been created, since (just as with the interface attributes) they vary with the altsetting and hence can be changed at random times. 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>
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r--drivers/usb/core/usb.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 4c98f3975af..c0821564a3f 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -971,6 +971,37 @@ int usb_disabled(void)
EXPORT_SYMBOL_GPL(usb_disabled);
/*
+ * Notifications of device and interface registration
+ */
+static int usb_bus_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (dev->type == &usb_device_type)
+ (void) usb_create_sysfs_dev_files(to_usb_device(dev));
+ else if (dev->type == &usb_if_device_type)
+ (void) usb_create_sysfs_intf_files(
+ to_usb_interface(dev));
+ break;
+
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (dev->type == &usb_device_type)
+ usb_remove_sysfs_dev_files(to_usb_device(dev));
+ else if (dev->type == &usb_if_device_type)
+ usb_remove_sysfs_intf_files(to_usb_interface(dev));
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block usb_bus_nb = {
+ .notifier_call = usb_bus_notify,
+};
+
+/*
* Init
*/
static int __init usb_init(void)
@@ -987,6 +1018,9 @@ static int __init usb_init(void)
retval = bus_register(&usb_bus_type);
if (retval)
goto bus_register_failed;
+ retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb);
+ if (retval)
+ goto bus_notifier_failed;
retval = usb_host_init();
if (retval)
goto host_init_failed;
@@ -1021,6 +1055,8 @@ driver_register_failed:
major_init_failed:
usb_host_cleanup();
host_init_failed:
+ bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
+bus_notifier_failed:
bus_unregister(&usb_bus_type);
bus_register_failed:
ksuspend_usb_cleanup();
@@ -1044,6 +1080,7 @@ static void __exit usb_exit(void)
usb_devio_cleanup();
usb_hub_cleanup();
usb_host_cleanup();
+ bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
bus_unregister(&usb_bus_type);
ksuspend_usb_cleanup();
}