This patch pushes the iSerialNumber module argument from composite into
each gadget. Each gadgets holds a dummy strings in its "struct
usb_string" to ensure that usb_string_ids_tab() allocates a valid id.
Once the user uses the module paramter, the string is overwritten with
the final value.
This is mostly the same change in each gadget with some minor
exceptions:
- printer accepts two arguments: iSerialNumber like everyone else and
  iSerialNum which was used before it was converted to composite
- g_ffs got a few ifdefs and an enum in order to get the proper index
- mass_storage: gained a struct usb_gadget_strings

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
 drivers/usb/gadget/acm_ms.c         |    7 +++++++
 drivers/usb/gadget/audio.c          |    7 +++++++
 drivers/usb/gadget/cdc2.c           |    7 +++++++
 drivers/usb/gadget/composite.c      |   10 +++-------
 drivers/usb/gadget/ether.c          |    8 ++++++++
 drivers/usb/gadget/g_ffs.c          |   27 ++++++++++++++++++++++++---
 drivers/usb/gadget/gmidi.c          |    7 +++++++
 drivers/usb/gadget/hid.c            |    8 ++++++++
 drivers/usb/gadget/mass_storage.c   |   26 ++++++++++++++++++++++++++
 drivers/usb/gadget/multi.c          |    7 +++++++
 drivers/usb/gadget/ncm.c            |    8 ++++++++
 drivers/usb/gadget/nokia.c          |    8 ++++++++
 drivers/usb/gadget/printer.c        |    9 ++++-----
 drivers/usb/gadget/serial.c         |    6 ++++++
 drivers/usb/gadget/tcm_usb_gadget.c |    2 ++
 drivers/usb/gadget/webcam.c         |    7 +++++++
 drivers/usb/gadget/zero.c           |    2 ++
 include/linux/usb/composite.h       |    6 +++++-
 18 files changed, 146 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
index f34be59..63ef563 100644
--- a/drivers/usb/gadget/acm_ms.c
+++ b/drivers/usb/gadget/acm_ms.c
@@ -92,12 +92,14 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_PRODUCT_SERIAL          2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       [STRING_PRODUCT_SERIAL].s = "",
        {  } /* end of list */
 };
 
@@ -205,6 +207,11 @@ static int __init acm_ms_bind(struct usb_composite_dev 
*cdev)
                goto fail1;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
        dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
                        DRIVER_DESC);
        fsg_common_put(&fsg_common);
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index 2dc6d63..336206d 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -35,12 +35,14 @@ USB_GADGET_COMPOSITE_OPTIONS();
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_PRODUCT_SERIAL          2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       [STRING_PRODUCT_SERIAL].s = "",
        {  } /* end of list */
 };
 
@@ -177,6 +179,11 @@ static int __init audio_bind(struct usb_composite_dev 
*cdev)
        if (status < 0)
                goto fail;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
 
        INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION);
        return 0;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 03752db..692f817 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -93,12 +93,14 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_PRODUCT_SERIAL          2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       [STRING_PRODUCT_SERIAL].s = "",
        {  } /* end of list */
 };
 
@@ -204,6 +206,11 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
        status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config);
        if (status < 0)
                goto fail1;
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
        dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index aac450e..506be03 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -40,10 +40,6 @@ static char *iProduct;
 module_param(iProduct, charp, S_IRUGO);
 MODULE_PARM_DESC(iProduct, "USB Product string");
 
-static char *iSerialNumber;
-module_param(iSerialNumber, charp, S_IRUGO);
-MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
-
 static char composite_manufacturer[50];
 
 /*-------------------------------------------------------------------------*/
@@ -925,7 +921,7 @@ static int get_string(struct usb_composite_dev *cdev,
        else if (cdev->product_override == id)
                str = iProduct ?: cdriver->iProduct;
        else if (cdev->serial_override == id)
-               str = iSerialNumber ?: cdriver->iSerialNumber;
+               str = cdriver->iSerialNumber;
        else
                str = NULL;
        if (str) {
@@ -1008,6 +1004,7 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, 
struct usb_string *str)
 {
        int next = cdev->next_string_id;
 
+
        for (; str->s; ++str) {
                if (unlikely(next >= 254))
                        return -ENODEV;
@@ -1481,8 +1478,7 @@ static int composite_bind(struct usb_gadget *gadget,
                cdev->product_override =
                        override_id(cdev, &cdev->desc.iProduct);
 
-       if (iSerialNumber ||
-           (!cdev->desc.iSerialNumber && cdriver->iSerialNumber))
+       if (cdriver->iSerialNumber)
                cdev->serial_override =
                        override_id(cdev, &cdev->desc.iSerialNumber);
 
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3d896ac..a4d2d9f 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -198,12 +198,14 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_PRODUCT_SERIAL          2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = PREFIX DRIVER_DESC,
+       [STRING_PRODUCT_SERIAL].s = "",
        {  } /* end of list */
 };
 
@@ -365,6 +367,12 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
                goto fail;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
+
        dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
                        DRIVER_DESC);
 
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 563feb5..948414d 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -114,17 +114,33 @@ static const struct usb_descriptor_header *gfs_otg_desc[] 
= {
        NULL
 };
 
+enum {
+#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+       GFFS_FFS_RNDIS_IDX,
+#endif
+
+#ifdef CONFIG_USB_FUNCTIONFS_ETH
+       GFFS_FFS_ECM_IDX,
+#endif
+
+#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+       GFFS_FFS_ECM_GEN_IDX,
+#endif
+       GFFS_SERIAL_IDX,
+};
+
 /* String IDs are assigned dynamically */
 static struct usb_string gfs_strings[] = {
 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
-       { .s = "FunctionFS + RNDIS" },
+       [GFFS_FFS_RNDIS_IDX].s = "FunctionFS + RNDIS",
 #endif
 #ifdef CONFIG_USB_FUNCTIONFS_ETH
-       { .s = "FunctionFS + ECM" },
+       [GFFS_FFS_ECM_IDX].s = "FunctionFS + ECM",
 #endif
 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
-       { .s = "FunctionFS" },
+       [GFFS_FFS_ECM_IDX].s = "FunctionFS",
 #endif
+       [GFFS_SERIAL_IDX].s = "",
        {  } /* end of list */
 };
 
@@ -380,6 +396,11 @@ static int gfs_bind(struct usb_composite_dev *cdev)
                        goto error_unbind;
        }
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(gfs_dev_desc);
+       if (iSerialNumber) {
+               gfs_strings[GFFS_SERIAL_IDX].s = iSerialNumber;
+               gfs_dev_desc.iSerialNumber = gfs_strings[GFFS_SERIAL_IDX].id;
+       }
+
        return 0;
 
 error_unbind:
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 5981689..90a169f 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -87,6 +87,7 @@ MODULE_PARM_DESC(out_ports, "Number of MIDI output ports");
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
 #define STRING_DESCRIPTION_IDX         2
+#define STRING_SERIAL_IDX              3
 
 static struct usb_device_descriptor device_desc = {
        .bLength =              USB_DT_DEVICE_SIZE,
@@ -104,6 +105,7 @@ static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s     = "Grey Innovation",
        [STRING_PRODUCT_IDX].s          = "MIDI Gadget",
        [STRING_DESCRIPTION_IDX].s      = "MIDI",
+       [STRING_SERIAL_IDX].s           = "",
        {  } /* end of list */
 };
 
@@ -166,6 +168,11 @@ static int __init midi_bind(struct usb_composite_dev *cdev)
        if (status < 0)
                return status;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_SERIAL_IDX].s = iSerialNumber;
+               device_desc.iSerialNumber = strings_dev[STRING_SERIAL_IDX].id;
+       }
+
        pr_info("%s\n", longname);
        return 0;
 }
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index bf95235..d47ca92 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -94,12 +94,14 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_PRODUCT_SERIAL          2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       [STRING_PRODUCT_SERIAL].s = "",
        {  } /* end of list */
 };
 
@@ -190,6 +192,12 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
                return status;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
+
        dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
 
        return 0;
diff --git a/drivers/usb/gadget/mass_storage.c 
b/drivers/usb/gadget/mass_storage.c
index 2426927..d52a29a 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -83,6 +83,21 @@ static const struct usb_descriptor_header *otg_desc[] = {
        NULL,
 };
 
+#define STRING_PRODUCT_SERIAL  0
+static struct usb_string strings_dev[] = {
+       [STRING_PRODUCT_SERIAL].s = "",
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+       &stringtab_dev,
+       NULL,
+};
 
 /****************************** Configurations ******************************/
 
@@ -141,10 +156,20 @@ static int __init msg_bind(struct usb_composite_dev *cdev)
 {
        int status;
 
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+               return status;
+
        status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
        if (status < 0)
                return status;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(msg_device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_PRODUCT_SERIAL].s = iSerialNumber;
+               msg_device_desc.iSerialNumber =
+                       strings_dev[STRING_PRODUCT_SERIAL].id;
+       }
+
        dev_info(&cdev->gadget->dev,
                 DRIVER_DESC ", version: " DRIVER_VERSION "\n");
        set_bit(0, &msg_registered);
@@ -160,6 +185,7 @@ static __refdata struct usb_composite_driver msg_driver = {
        .iProduct       = DRIVER_DESC,
        .max_speed      = USB_SPEED_SUPER,
        .needs_serial   = 1,
+       .strings        = dev_strings,
        .bind           = msg_bind,
 };
 
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index e739771..5205882 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -115,6 +115,7 @@ enum {
 #ifdef CONFIG_USB_G_MULTI_CDC
        MULTI_STRING_CDC_CONFIG_IDX,
 #endif
+       MULTI_STRING_SERIAL_IDX,
 };
 
 static struct usb_string strings_dev[] = {
@@ -124,6 +125,7 @@ static struct usb_string strings_dev[] = {
 #ifdef CONFIG_USB_G_MULTI_CDC
        [MULTI_STRING_CDC_CONFIG_IDX].s   = "Multifunction with CDC ECM",
 #endif
+       [MULTI_STRING_SERIAL_IDX].s     = "",
        {  } /* end of list */
 };
 
@@ -308,6 +310,11 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
        if (unlikely(status < 0))
                goto fail2;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[MULTI_STRING_SERIAL_IDX].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[MULTI_STRING_SERIAL_IDX].id;
+       }
 
        /* we're done */
        dev_info(&gadget->dev, DRIVER_DESC "\n");
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
index 01ea2f2..4438715 100644
--- a/drivers/usb/gadget/ncm.c
+++ b/drivers/usb/gadget/ncm.c
@@ -100,12 +100,14 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
+#define STRING_SERIAL_IDX              2
 
 static char manufacturer[50];
 
 static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       [STRING_SERIAL_IDX].s = "",
        {  } /* end of list */
 };
 
@@ -193,6 +195,12 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
                goto fail;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_SERIAL_IDX].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_SERIAL_IDX].id;
+       }
+
        dev_info(&gadget->dev, "%s\n", DRIVER_DESC);
 
        return 0;
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index b732b46..c6b61dc 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -59,6 +59,7 @@ USB_GADGET_COMPOSITE_OPTIONS();
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
 #define STRING_DESCRIPTION_IDX         2
+#define STRING_SERIAL_IDX              3
 
 static char manufacturer_nokia[] = "Nokia";
 static const char product_nokia[] = NOKIA_LONG_NAME;
@@ -68,6 +69,7 @@ static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer_nokia,
        [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME,
        [STRING_DESCRIPTION_IDX].s = description_nokia,
+       [STRING_SERIAL_IDX].s = "",
        {  } /* end of list */
 };
 
@@ -199,6 +201,12 @@ static int __init nokia_bind(struct usb_composite_dev 
*cdev)
                goto err_usb;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_SERIAL_IDX].s = iSerialNumber;
+               device_desc.iSerialNumber =
+                       strings_dev[STRING_SERIAL_IDX].id;
+       }
+
        dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
 
        return 0;
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index aeeeae2..169de0a 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -118,8 +118,7 @@ static struct printer_dev usb_printer_gadget;
  * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
  */
 
-static char *iSerialNum;
-module_param(iSerialNum, charp, S_IRUGO);
+module_param_named(iSerialNum, iSerialNumber, charp, S_IRUGO);
 MODULE_PARM_DESC(iSerialNum, "1");
 
 static char *iPNPstring;
@@ -1174,9 +1173,6 @@ static int __init printer_bind_config(struct 
usb_configuration *c)
                init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
-       if (iSerialNum)
-               strlcpy(serial_num, iSerialNum, sizeof serial_num);
-
        if (iPNPstring)
                strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2);
 
@@ -1269,6 +1265,9 @@ static int __init printer_bind(struct usb_composite_dev 
*cdev)
        if (ret)
                return ret;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber)
+               strings[STRING_SERIALNUM].s = iSerialNumber;
+
        return 0;
 }
 
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index fa742f4..5d02f67 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -62,6 +62,7 @@ USB_GADGET_COMPOSITE_OPTIONS();
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
 #define STRING_DESCRIPTION_IDX         2
+#define STRING_SERIAL_IDX              3
 
 static char manufacturer[50];
 
@@ -69,6 +70,7 @@ static struct usb_string strings_dev[] = {
        [STRING_MANUFACTURER_IDX].s = manufacturer,
        [STRING_PRODUCT_IDX].s = GS_VERSION_NAME,
        [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */,
+       [STRING_SERIAL_IDX].s = "",
        {  } /* end of list */
 };
 
@@ -214,6 +216,10 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
                goto fail;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber) {
+               strings_dev[STRING_SERIAL_IDX].s = iSerialNumber;
+               device_desc.iSerialNumber = strings_dev[STRING_SERIAL_IDX].id;
+       }
        INFO(cdev, "%s\n", GS_VERSION_NAME);
 
        return 0;
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c 
b/drivers/usb/gadget/tcm_usb_gadget.c
index 82608dc..0d74d34 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -2442,6 +2442,8 @@ static int usb_target_bind(struct usb_composite_dev *cdev)
        if (ret)
                return ret;
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(usbg_device_desc);
+       if (iSerialNumber)
+               usbg_us_strings[USB_G_STR_SERIAL].s = iSerialNumber;
        return 0;
 }
 
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index cf8d5ce..9c42c17 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -48,11 +48,13 @@ static char webcam_config_label[] = "Video";
 #define STRING_MANUFACTURER_IDX                0
 #define STRING_PRODUCT_IDX             1
 #define STRING_DESCRIPTION_IDX         2
+#define STRING_SERIAL_IDX              3
 
 static struct usb_string webcam_strings[] = {
        [STRING_MANUFACTURER_IDX].s = webcam_vendor_label,
        [STRING_PRODUCT_IDX].s = webcam_product_label,
        [STRING_DESCRIPTION_IDX].s = webcam_config_label,
+       [STRING_SERIAL_IDX].s = "",
        {  }
 };
 
@@ -372,6 +374,11 @@ webcam_bind(struct usb_composite_dev *cdev)
                goto error;
 
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(webcam_device_descriptor);
+       if (iSerialNumber) {
+               webcam_strings[STRING_SERIAL_IDX].s = iSerialNumber;
+               webcam_device_descriptor.iSerialNumber =
+                       webcam_strings[STRING_SERIAL_IDX].id;
+       }
        INFO(cdev, "Webcam Video Gadget\n");
        return 0;
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index dd2d8c7..f9c53c8 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -307,6 +307,8 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
                device_desc.bcdDevice = cpu_to_le16(0x9999);
        }
        USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(device_desc);
+       if (iSerialNumber)
+               strings_dev[STRING_SERIAL_IDX].s = iSerialNumber;
 
        INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
 
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index fc25c54..eb13097 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -397,7 +397,11 @@ extern int usb_string_ids_n(struct usb_composite_dev *c, 
unsigned n);
                                                                        \
        static ushort bcdDevice;                                        \
        module_param(bcdDevice, ushort, S_IRUGO);                       \
-       MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)")
+       MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");        \
+                                                                       \
+       static char *iSerialNumber;                                     \
+       module_param(iSerialNumber, charp, S_IRUGO);                    \
+       MODULE_PARM_DESC(iSerialNumber, "SerialNumber string")
 
 #define USB_GADGET_COMPOSITE_OVERWRITE_OPTIONS(__usb_desc)             \
        do {                                                            \
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to