]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/message.c
USB: make usbdevices export their device nodes instead of using a separate class
[linux-2.6-omap-h63xx.git] / drivers / usb / core / message.c
index 2f17468b5c1efe19fdfa8c7a52e3f9fc3a670865..da4ee07e0094c59d17e96166abe1ff346f23ea6b 100644 (file)
@@ -221,10 +221,15 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
 
        if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                        USB_ENDPOINT_XFER_INT) {
+               int interval;
+
+               if (usb_dev->speed == USB_SPEED_HIGH)
+                       interval = 1 << min(15, ep->desc.bInterval - 1);
+               else
+                       interval = ep->desc.bInterval;
                pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
                usb_fill_int_urb(urb, usb_dev, pipe, data, len,
-                               usb_api_blocking_completion, NULL,
-                               ep->desc.bInterval);
+                               usb_api_blocking_completion, NULL, interval);
        } else
                usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
                                usb_api_blocking_completion, NULL);
@@ -1300,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 =
@@ -1310,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
@@ -1344,7 +1410,7 @@ static void release_interface(struct device *dev)
  *
  * This call is synchronous. The calling context must be able to sleep,
  * must own the device lock, and must not hold the driver model's USB
- * bus rwsem; usb device driver probe() methods cannot use this routine.
+ * bus mutex; usb device driver probe() methods cannot use this routine.
  *
  * Returns zero on success, or else the status code returned by the
  * underlying call that failed.  On successful completion, each interface
@@ -1473,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",