diff options
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r-- | drivers/usb/core/message.c | 65 |
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", |