aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/composite.c96
1 files changed, 64 insertions, 32 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index eaa9a599df63..717de39627c7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/utsname.h>
27 28
28#include <linux/usb/composite.h> 29#include <linux/usb/composite.h>
29 30
@@ -69,6 +70,8 @@ static char *iSerialNumber;
69module_param(iSerialNumber, charp, 0); 70module_param(iSerialNumber, charp, 0);
70MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); 71MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
71 72
73static char composite_manufacturer[50];
74
72/*-------------------------------------------------------------------------*/ 75/*-------------------------------------------------------------------------*/
73 76
74/** 77/**
@@ -599,6 +602,7 @@ static int get_string(struct usb_composite_dev *cdev,
599 struct usb_configuration *c; 602 struct usb_configuration *c;
600 struct usb_function *f; 603 struct usb_function *f;
601 int len; 604 int len;
605 const char *str;
602 606
603 /* Yes, not only is USB's I18N support probably more than most 607 /* Yes, not only is USB's I18N support probably more than most
604 * folk will ever care about ... also, it's all supported here. 608 * folk will ever care about ... also, it's all supported here.
@@ -638,9 +642,29 @@ static int get_string(struct usb_composite_dev *cdev,
638 return s->bLength; 642 return s->bLength;
639 } 643 }
640 644
641 /* Otherwise, look up and return a specified string. String IDs 645 /* Otherwise, look up and return a specified string. First
642 * are device-scoped, so we look up each string table we're told 646 * check if the string has not been overridden.
643 * about. These lookups are infrequent; simpler-is-better here. 647 */
648 if (cdev->manufacturer_override == id)
649 str = iManufacturer ?: composite->iManufacturer ?:
650 composite_manufacturer;
651 else if (cdev->product_override == id)
652 str = iProduct ?: composite->iProduct;
653 else if (cdev->serial_override == id)
654 str = iSerialNumber;
655 else
656 str = NULL;
657 if (str) {
658 struct usb_gadget_strings strings = {
659 .language = language,
660 .strings = &(struct usb_string) { 0xff, str }
661 };
662 return usb_gadget_get_string(&strings, 0xff, buf);
663 }
664
665 /* String IDs are device-scoped, so we look up each string
666 * table we're told about. These lookups are infrequent;
667 * simpler-is-better here.
644 */ 668 */
645 if (composite->strings) { 669 if (composite->strings) {
646 len = lookup_string(composite->strings, buf, language, id); 670 len = lookup_string(composite->strings, buf, language, id);
@@ -1025,26 +1049,17 @@ composite_unbind(struct usb_gadget *gadget)
1025 composite = NULL; 1049 composite = NULL;
1026} 1050}
1027 1051
1028static void 1052static u8 override_id(struct usb_composite_dev *cdev, u8 *desc)
1029string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
1030{ 1053{
1031 struct usb_string *str = tab->strings; 1054 if (!*desc) {
1032 1055 int ret = usb_string_id(cdev);
1033 for (str = tab->strings; str->s; str++) { 1056 if (unlikely(ret < 0))
1034 if (str->id == id) { 1057 WARNING(cdev, "failed to override string ID\n");
1035 str->s = s; 1058 else
1036 return; 1059 *desc = ret;
1037 }
1038 } 1060 }
1039}
1040 1061
1041static void 1062 return *desc;
1042string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
1043{
1044 while (*tab) {
1045 string_override_one(*tab, id, s);
1046 tab++;
1047 }
1048} 1063}
1049 1064
1050static int composite_bind(struct usb_gadget *gadget) 1065static int composite_bind(struct usb_gadget *gadget)
@@ -1107,19 +1122,34 @@ static int composite_bind(struct usb_gadget *gadget)
1107 cdev->desc = *composite->dev; 1122 cdev->desc = *composite->dev;
1108 cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; 1123 cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
1109 1124
1110 /* strings can't be assigned before bind() allocates the 1125 /* stirng overrides */
1111 * releavnt identifiers 1126 if (iManufacturer || !cdev->desc.iManufacturer) {
1112 */ 1127 if (!iManufacturer && !composite->iManufacturer &&
1113 if (cdev->desc.iManufacturer && iManufacturer) 1128 !*composite_manufacturer)
1114 string_override(composite->strings, 1129 snprintf(composite_manufacturer,
1115 cdev->desc.iManufacturer, iManufacturer); 1130 sizeof composite_manufacturer,
1116 if (cdev->desc.iProduct && iProduct) 1131 "%s %s with %s",
1117 string_override(composite->strings, 1132 init_utsname()->sysname,
1118 cdev->desc.iProduct, iProduct); 1133 init_utsname()->release,
1119 if (cdev->desc.iSerialNumber && iSerialNumber) 1134 gadget->name);
1120 string_override(composite->strings, 1135
1121 cdev->desc.iSerialNumber, iSerialNumber); 1136 cdev->manufacturer_override =
1137 override_id(cdev, &cdev->desc.iManufacturer);
1138 }
1139
1140 if (iProduct || (!cdev->desc.iProduct && composite->iProduct))
1141 cdev->product_override =
1142 override_id(cdev, &cdev->desc.iProduct);
1143
1144 if (iSerialNumber)
1145 cdev->serial_override =
1146 override_id(cdev, &cdev->desc.iSerialNumber);
1147
1148 /* has userspace failed to provide a serial number? */
1149 if (composite->needs_serial && !cdev->desc.iSerialNumber)
1150 WARNING(cdev, "userspace failed to provide iSerialNumber\n");
1122 1151
1152 /* finish up */
1123 status = device_create_file(&gadget->dev, &dev_attr_suspended); 1153 status = device_create_file(&gadget->dev, &dev_attr_suspended);
1124 if (status) 1154 if (status)
1125 goto fail; 1155 goto fail;
@@ -1217,6 +1247,8 @@ int usb_composite_register(struct usb_composite_driver *driver)
1217 if (!driver || !driver->dev || !driver->bind || composite) 1247 if (!driver || !driver->dev || !driver->bind || composite)
1218 return -EINVAL; 1248 return -EINVAL;
1219 1249
1250 if (!driver->iProduct)
1251 driver->iProduct = driver->name;
1220 if (!driver->name) 1252 if (!driver->name)
1221 driver->name = "composite"; 1253 driver->name = "composite";
1222 composite_driver.function = (char *) driver->name; 1254 composite_driver.function = (char *) driver->name;