aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r--drivers/usb/core/message.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c359ccb3299..da4ee07e009 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1305,7 +1305,7 @@ int usb_reset_configuration(struct usb_device *dev)
return 0;
}
-static void release_interface(struct device *dev)
+void usb_release_interface(struct device *dev)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_interface_cache *intfc =
@@ -1315,6 +1315,67 @@ static void release_interface(struct device *dev)
kfree(intf);
}
+#ifdef CONFIG_HOTPLUG
+static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ struct usb_device *usb_dev;
+ struct usb_interface *intf;
+ struct usb_host_interface *alt;
+ int i = 0;
+ int length = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ /* driver is often null here; dev_dbg() would oops */
+ pr_debug ("usb %s: uevent\n", dev->bus_id);
+
+ intf = to_usb_interface(dev);
+ usb_dev = interface_to_usbdev(intf);
+ alt = intf->cur_altsetting;
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "INTERFACE=%d/%d/%d",
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol))
+ return -ENOMEM;
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+ le16_to_cpu(usb_dev->descriptor.idVendor),
+ le16_to_cpu(usb_dev->descriptor.idProduct),
+ le16_to_cpu(usb_dev->descriptor.bcdDevice),
+ usb_dev->descriptor.bDeviceClass,
+ usb_dev->descriptor.bDeviceSubClass,
+ usb_dev->descriptor.bDeviceProtocol,
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol))
+ return -ENOMEM;
+
+ envp[i] = NULL;
+ return 0;
+}
+
+#else
+
+static int usb_if_uevent(struct device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_HOTPLUG */
+
+struct device_type usb_if_device_type = {
+ .name = "usb_interface",
+ .release = usb_release_interface,
+ .uevent = usb_if_uevent,
+};
+
/*
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
@@ -1478,8 +1539,8 @@ free_interfaces:
intf->dev.parent = &dev->dev;
intf->dev.driver = NULL;
intf->dev.bus = &usb_bus_type;
+ intf->dev.type = &usb_if_device_type;
intf->dev.dma_mask = dev->dev.dma_mask;
- intf->dev.release = release_interface;
device_initialize (&intf->dev);
mark_quiesced(intf);
sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",