diff options
| -rw-r--r-- | drivers/usb/core/config.c | 3 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 7 | ||||
| -rw-r--r-- | drivers/usb/core/sysfs.c | 37 | ||||
| -rw-r--r-- | include/linux/usb.h | 3 |
4 files changed, 30 insertions, 20 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 42e9f8466272..837bad132449 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -420,6 +420,9 @@ void usb_destroy_configuration(struct usb_device *dev) for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { struct usb_host_config *cf = &dev->config[c]; + if (cf->string) + kfree(cf->string); + for (i = 0; i < cf->desc.bNumInterfaces; i++) { if (cf->intf_cache[i]) kref_put(&cf->intf_cache[i]->ref, diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f6b2c309e55d..b4624501cd58 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1413,6 +1413,13 @@ free_interfaces: } kfree(new_interfaces); + if ((cp->desc.iConfiguration) && + (cp->string == NULL)) { + cp->string = kmalloc(256, GFP_KERNEL); + if (cp->string) + usb_string(dev, cp->desc.iConfiguration, cp->string, 256); + } + /* Now that all the interfaces are set up, register them * to trigger binding of drivers to interfaces. probe() * routines may install different altsettings and may diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 3f5ae2de70e2..ec9b3bde8ae5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -46,27 +46,24 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") usb_actconfig_attr (bmAttributes, 1, "%2x\n") usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") -#define usb_actconfig_str(name, field) \ -static ssize_t show_##name(struct device *dev, char *buf) \ -{ \ - struct usb_device *udev; \ - struct usb_host_config *actconfig; \ - int len; \ - \ - udev = to_usb_device (dev); \ - actconfig = udev->actconfig; \ - if (!actconfig) \ - return 0; \ - len = usb_string(udev, actconfig->desc.field, buf, PAGE_SIZE); \ - if (len < 0) \ - return 0; \ - buf[len] = '\n'; \ - buf[len+1] = 0; \ - return len+1; \ -} \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); +static ssize_t show_configuration_string(struct device *dev, char *buf) +{ + struct usb_device *udev; + struct usb_host_config *actconfig; + int len; -usb_actconfig_str (configuration, iConfiguration) + udev = to_usb_device (dev); + actconfig = udev->actconfig; + if ((!actconfig) || (!actconfig->string)) + return 0; + len = sprintf(buf, actconfig->string, PAGE_SIZE); + if (len < 0) + return 0; + buf[len] = '\n'; + buf[len+1] = 0; + return len+1; +} +static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); /* configuration value is always present, and r/w */ usb_actconfig_show(bConfigurationValue, 1, "%u\n"); diff --git a/include/linux/usb.h b/include/linux/usb.h index f5ec1f5d8920..8d2687ae39ff 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -190,6 +190,8 @@ struct usb_interface_cache { /** * struct usb_host_config - representation of a device's configuration * @desc: the device's configuration descriptor. + * @string: pointer to the cached version of the iConfiguration string, if + * present for this configuration. * @interface: array of pointers to usb_interface structures, one for each * interface in the configuration. The number of interfaces is stored * in desc.bNumInterfaces. These pointers are valid only while the @@ -226,6 +228,7 @@ struct usb_interface_cache { struct usb_host_config { struct usb_config_descriptor desc; + char *string; /* the interfaces associated with this configuration, * stored in no particular order */ struct usb_interface *interface[USB_MAXINTERFACES]; |
