aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-10-24 16:24:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 19:47:51 -0400
commit4f62efe67f077db17dad03a1d4c9665000a3eb45 (patch)
tree27f1837fd08ce3dccb94a88a5afef6eb1a5ed738
parent16f16d117c1eb99451e4c73c87546eef05c66790 (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.c10
-rw-r--r--drivers/usb/core/hub.c22
-rw-r--r--drivers/usb/core/message.c48
-rw-r--r--drivers/usb/core/sysfs.c36
-rw-r--r--drivers/usb/core/usb.h1
-rw-r--r--include/linux/usb.h10
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
1207static 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 */
798char *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;