diff options
| author | Alan Stern <stern@rowland.harvard.edu> | 2005-10-24 16:24:14 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:51 -0400 |
| commit | 4f62efe67f077db17dad03a1d4c9665000a3eb45 (patch) | |
| tree | 27f1837fd08ce3dccb94a88a5afef6eb1a5ed738 | |
| parent | 16f16d117c1eb99451e4c73c87546eef05c66790 (diff) | |
[PATCH] usbcore: Fix handling of sysfs strings and other attributes
This patch (as592) makes a few small improvements to the way device
strings are handled, and it fixes some bugs in a couple of other sysfs
attribute routines. (Look at show_configuration_string() to see what I
mean.)
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/core/config.c | 10 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 22 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 48 | ||||
| -rw-r--r-- | drivers/usb/core/sysfs.c | 36 | ||||
| -rw-r--r-- | drivers/usb/core/usb.h | 1 | ||||
| -rw-r--r-- | include/linux/usb.h | 10 |
6 files changed, 62 insertions, 65 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 63f374e62db2..993019500cc3 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
| @@ -112,8 +112,12 @@ void usb_release_interface_cache(struct kref *ref) | |||
| 112 | struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); | 112 | struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); |
| 113 | int j; | 113 | int j; |
| 114 | 114 | ||
| 115 | for (j = 0; j < intfc->num_altsetting; j++) | 115 | for (j = 0; j < intfc->num_altsetting; j++) { |
| 116 | kfree(intfc->altsetting[j].endpoint); | 116 | struct usb_host_interface *alt = &intfc->altsetting[j]; |
| 117 | |||
| 118 | kfree(alt->endpoint); | ||
| 119 | kfree(alt->string); | ||
| 120 | } | ||
| 117 | kfree(intfc); | 121 | kfree(intfc); |
| 118 | } | 122 | } |
| 119 | 123 | ||
| @@ -420,8 +424,6 @@ void usb_destroy_configuration(struct usb_device *dev) | |||
| 420 | struct usb_host_config *cf = &dev->config[c]; | 424 | struct usb_host_config *cf = &dev->config[c]; |
| 421 | 425 | ||
| 422 | kfree(cf->string); | 426 | kfree(cf->string); |
| 423 | cf->string = NULL; | ||
| 424 | |||
| 425 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { | 427 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { |
| 426 | if (cf->intf_cache[i]) | 428 | if (cf->intf_cache[i]) |
| 427 | kref_put(&cf->intf_cache[i]->ref, | 429 | kref_put(&cf->intf_cache[i]->ref, |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8ba5854e5387..1bacb374b007 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -1204,21 +1204,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
| 1204 | {} | 1204 | {} |
| 1205 | #endif | 1205 | #endif |
| 1206 | 1206 | ||
| 1207 | static void get_string(struct usb_device *udev, char **string, int index) | ||
| 1208 | { | ||
| 1209 | char *buf; | ||
| 1210 | |||
| 1211 | if (!index) | ||
| 1212 | return; | ||
| 1213 | buf = kmalloc(256, GFP_KERNEL); | ||
| 1214 | if (!buf) | ||
| 1215 | return; | ||
| 1216 | if (usb_string(udev, index, buf, 256) > 0) | ||
| 1217 | *string = buf; | ||
| 1218 | else | ||
| 1219 | kfree(buf); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | 1207 | ||
| 1223 | #ifdef CONFIG_USB_OTG | 1208 | #ifdef CONFIG_USB_OTG |
| 1224 | #include "otg_whitelist.h" | 1209 | #include "otg_whitelist.h" |
| @@ -1257,9 +1242,10 @@ int usb_new_device(struct usb_device *udev) | |||
| 1257 | } | 1242 | } |
| 1258 | 1243 | ||
| 1259 | /* read the standard strings and cache them if present */ | 1244 | /* read the standard strings and cache them if present */ |
| 1260 | get_string(udev, &udev->product, udev->descriptor.iProduct); | 1245 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); |
| 1261 | get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer); | 1246 | udev->manufacturer = usb_cache_string(udev, |
| 1262 | get_string(udev, &udev->serial, udev->descriptor.iSerialNumber); | 1247 | udev->descriptor.iManufacturer); |
| 1248 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
| 1263 | 1249 | ||
| 1264 | /* Tell the world! */ | 1250 | /* Tell the world! */ |
| 1265 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | 1251 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3519f317898e..644a3d4f12aa 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -787,6 +787,31 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
| 787 | return err; | 787 | return err; |
| 788 | } | 788 | } |
| 789 | 789 | ||
| 790 | /** | ||
| 791 | * usb_cache_string - read a string descriptor and cache it for later use | ||
| 792 | * @udev: the device whose string descriptor is being read | ||
| 793 | * @index: the descriptor index | ||
| 794 | * | ||
| 795 | * Returns a pointer to a kmalloc'ed buffer containing the descriptor string, | ||
| 796 | * or NULL if the index is 0 or the string could not be read. | ||
| 797 | */ | ||
| 798 | char *usb_cache_string(struct usb_device *udev, int index) | ||
| 799 | { | ||
| 800 | char *buf; | ||
| 801 | char *smallbuf = NULL; | ||
| 802 | int len; | ||
| 803 | |||
| 804 | if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) { | ||
| 805 | if ((len = usb_string(udev, index, buf, 256)) > 0) { | ||
| 806 | if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL) | ||
| 807 | return buf; | ||
| 808 | memcpy(smallbuf, buf, len); | ||
| 809 | } | ||
| 810 | kfree(buf); | ||
| 811 | } | ||
| 812 | return smallbuf; | ||
| 813 | } | ||
| 814 | |||
| 790 | /* | 815 | /* |
| 791 | * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) | 816 | * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) |
| 792 | * @dev: the device whose device descriptor is being updated | 817 | * @dev: the device whose device descriptor is being updated |
| @@ -1008,8 +1033,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
| 1008 | dev_dbg (&dev->dev, "unregistering interface %s\n", | 1033 | dev_dbg (&dev->dev, "unregistering interface %s\n", |
| 1009 | interface->dev.bus_id); | 1034 | interface->dev.bus_id); |
| 1010 | usb_remove_sysfs_intf_files(interface); | 1035 | usb_remove_sysfs_intf_files(interface); |
| 1011 | kfree(interface->cur_altsetting->string); | ||
| 1012 | interface->cur_altsetting->string = NULL; | ||
| 1013 | device_del (&interface->dev); | 1036 | device_del (&interface->dev); |
| 1014 | } | 1037 | } |
| 1015 | 1038 | ||
| @@ -1422,12 +1445,9 @@ free_interfaces: | |||
| 1422 | } | 1445 | } |
| 1423 | kfree(new_interfaces); | 1446 | kfree(new_interfaces); |
| 1424 | 1447 | ||
| 1425 | if ((cp->desc.iConfiguration) && | 1448 | if (cp->string == NULL) |
| 1426 | (cp->string == NULL)) { | 1449 | cp->string = usb_cache_string(dev, |
| 1427 | cp->string = kmalloc(256, GFP_KERNEL); | 1450 | cp->desc.iConfiguration); |
| 1428 | if (cp->string) | ||
| 1429 | usb_string(dev, cp->desc.iConfiguration, cp->string, 256); | ||
| 1430 | } | ||
| 1431 | 1451 | ||
| 1432 | /* Now that all the interfaces are set up, register them | 1452 | /* Now that all the interfaces are set up, register them |
| 1433 | * to trigger binding of drivers to interfaces. probe() | 1453 | * to trigger binding of drivers to interfaces. probe() |
| @@ -1437,13 +1457,12 @@ free_interfaces: | |||
| 1437 | */ | 1457 | */ |
| 1438 | for (i = 0; i < nintf; ++i) { | 1458 | for (i = 0; i < nintf; ++i) { |
| 1439 | struct usb_interface *intf = cp->interface[i]; | 1459 | struct usb_interface *intf = cp->interface[i]; |
| 1440 | struct usb_interface_descriptor *desc; | 1460 | struct usb_host_interface *alt = intf->cur_altsetting; |
| 1441 | 1461 | ||
| 1442 | desc = &intf->altsetting [0].desc; | ||
| 1443 | dev_dbg (&dev->dev, | 1462 | dev_dbg (&dev->dev, |
| 1444 | "adding %s (config #%d, interface %d)\n", | 1463 | "adding %s (config #%d, interface %d)\n", |
| 1445 | intf->dev.bus_id, configuration, | 1464 | intf->dev.bus_id, configuration, |
| 1446 | desc->bInterfaceNumber); | 1465 | alt->desc.bInterfaceNumber); |
| 1447 | ret = device_add (&intf->dev); | 1466 | ret = device_add (&intf->dev); |
| 1448 | if (ret != 0) { | 1467 | if (ret != 0) { |
| 1449 | dev_err(&dev->dev, | 1468 | dev_err(&dev->dev, |
| @@ -1452,13 +1471,6 @@ free_interfaces: | |||
| 1452 | ret); | 1471 | ret); |
| 1453 | continue; | 1472 | continue; |
| 1454 | } | 1473 | } |
| 1455 | if ((intf->cur_altsetting->desc.iInterface) && | ||
| 1456 | (intf->cur_altsetting->string == NULL)) { | ||
| 1457 | intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL); | ||
| 1458 | if (intf->cur_altsetting->string) | ||
| 1459 | usb_string(dev, intf->cur_altsetting->desc.iInterface, | ||
| 1460 | intf->cur_altsetting->string, 256); | ||
| 1461 | } | ||
| 1462 | usb_create_sysfs_intf_files (intf); | 1474 | usb_create_sysfs_intf_files (intf); |
| 1463 | } | 1475 | } |
| 1464 | } | 1476 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cca77cf0c48..edd83e014452 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -249,18 +249,12 @@ static ssize_t show_configuration_string(struct device *dev, | |||
| 249 | { | 249 | { |
| 250 | struct usb_device *udev; | 250 | struct usb_device *udev; |
| 251 | struct usb_host_config *actconfig; | 251 | struct usb_host_config *actconfig; |
