You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/09/05 18:29:38 UTC

[nuttx] branch master updated: usbdev: Split usbdev descriptor information

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 0efd4d0e12 usbdev: Split usbdev descriptor information
0efd4d0e12 is described below

commit 0efd4d0e12c5f829f6cf20705e3de0043f2921a6
Author: zhangyuan21 <zh...@xiaomi.com>
AuthorDate: Thu Aug 24 19:30:54 2023 +0800

    usbdev: Split usbdev descriptor information
    
    The class device only handles descriptor information specific to the class,
    and shared descriptor information is passed through parameters and
    handled by the composite driver.
    
    Signed-off-by: zhangyuan21 <zh...@xiaomi.com>
---
 boards/arm/cxd56xx/spresense/src/cxd56_composite.c |   2 +-
 .../lpc17xx_40xx/lx_cpu/src/lpc17_40_composite.c   |   2 +-
 .../pnev5180b/src/lpc17_40_composite.c             |   2 +-
 .../lpc214x/mcu123-lpc214x/src/lpc2148_composite.c |   4 +-
 .../arduino-nano-33ble-rev2/src/nrf52_composite.c  |   2 +-
 .../nrf52/arduino-nano-33ble/src/nrf52_composite.c |   2 +-
 boards/arm/nrf52/nrf52840-dk/src/nrf52_composite.c |   2 +-
 .../nrf52/nrf52840-dongle/src/nrf52_composite.c    |   2 +-
 boards/arm/nrf53/nrf5340-dk/src/nrf53_composite.c  |   2 +-
 boards/arm/nrf53/thingy53/src/nrf53_composite.c    |   2 +-
 boards/arm/rp2040/common/src/rp2040_composite.c    |   2 +-
 boards/arm/samd5e5/metro-m4/src/sam_composite.c    |   4 +-
 boards/arm/samv7/samv71-xult/src/sam_composite.c   |   4 +-
 .../stm32/olimexino-stm32/src/stm32_composite.c    |   4 +-
 boards/arm/stm32/photon/src/stm32_composite.c      |   2 +-
 .../arm/stm32/stm3210e-eval/src/stm32_composite.c  |   4 +-
 .../stm32/stm32f411-minimum/src/stm32_composite.c  |   2 +-
 .../stm32/stm32f4discovery/src/stm32_composite.c   |   2 +-
 .../arm/stm32f7/nucleo-144/src/stm32_composite.c   |   2 +-
 .../stm32h7/nucleo-h743zi/src/stm32_composite.c    |   2 +-
 boards/risc-v/mpfs/common/src/mpfs_composite.c     |   2 +-
 boards/sim/sim/sim/src/sim_composite.c             |   4 +-
 drivers/usbdev/adb.c                               | 226 ++++++-------------
 drivers/usbdev/composite.c                         | 240 +++++++++++++++------
 drivers/usbdev/composite.h                         |  77 +------
 drivers/usbdev/composite_desc.c                    | 225 +++++--------------
 include/nuttx/usb/composite.h                      |  18 +-
 include/nuttx/usb/usbdev.h                         |  22 ++
 28 files changed, 368 insertions(+), 496 deletions(-)

diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_composite.c b/boards/arm/cxd56xx/spresense/src/cxd56_composite.c
index 12bf46b35e..a18fc3ec85 100644
--- a/boards/arm/cxd56xx/spresense/src/cxd56_composite.c
+++ b/boards/arm/cxd56xx/spresense/src/cxd56_composite.c
@@ -341,7 +341,7 @@ void *board_composite_connect(int port, int configid)
       dev_idx += 1;
 #endif
 
-      return composite_initialize(dev_idx, dev);
+      return composite_initialize(composite_getdevdescs(), dev, dev_idx);
     }
   else
     {
diff --git a/boards/arm/lpc17xx_40xx/lx_cpu/src/lpc17_40_composite.c b/boards/arm/lpc17xx_40xx/lx_cpu/src/lpc17_40_composite.c
index 328018173c..7d51415ec3 100644
--- a/boards/arm/lpc17xx_40xx/lx_cpu/src/lpc17_40_composite.c
+++ b/boards/arm/lpc17xx_40xx/lx_cpu/src/lpc17_40_composite.c
@@ -124,7 +124,7 @@ void *board_composite_connect(int port, int configid)
   dev[1].devinfo.epno[CDCECM_EP_BULKIN_IDX]  = 11;
   dev[1].devinfo.epno[CDCECM_EP_BULKOUT_IDX] = 8;
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 
 #endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
diff --git a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_composite.c b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_composite.c
index 110f30d7ee..a08d987b4c 100644
--- a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_composite.c
+++ b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_composite.c
@@ -125,7 +125,7 @@ void *board_composite_connect(int port, int configid)
   dev[1].devinfo.epno[CDCECM_EP_BULKIN_IDX]  = 11;
   dev[1].devinfo.epno[CDCECM_EP_BULKOUT_IDX] = 8;
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 
 #endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
diff --git a/boards/arm/lpc214x/mcu123-lpc214x/src/lpc2148_composite.c b/boards/arm/lpc214x/mcu123-lpc214x/src/lpc2148_composite.c
index 78cb588a0e..9f0f0555e5 100644
--- a/boards/arm/lpc214x/mcu123-lpc214x/src/lpc2148_composite.c
+++ b/boards/arm/lpc214x/mcu123-lpc214x/src/lpc2148_composite.c
@@ -256,7 +256,7 @@ static void *board_composite0_connect(int port)
   ifnobase += dev[1].devinfo.ninterfaces;
   strbase  += dev[1].devinfo.nstrings;
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 #endif
 
@@ -317,7 +317,7 @@ static void *board_composite1_connect(int port)
       strbase  += dev[i].devinfo.nstrings;
     }
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf52/arduino-nano-33ble-rev2/src/nrf52_composite.c b/boards/arm/nrf52/arduino-nano-33ble-rev2/src/nrf52_composite.c
index b1456ef679..fd59434ba0 100644
--- a/boards/arm/nrf52/arduino-nano-33ble-rev2/src/nrf52_composite.c
+++ b/boards/arm/nrf52/arduino-nano-33ble-rev2/src/nrf52_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF52_NENDPOINTS);
   DEBUGASSERT(epout <= NRF52_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf52/arduino-nano-33ble/src/nrf52_composite.c b/boards/arm/nrf52/arduino-nano-33ble/src/nrf52_composite.c
index 3f1c9399be..f8f0948e66 100644
--- a/boards/arm/nrf52/arduino-nano-33ble/src/nrf52_composite.c
+++ b/boards/arm/nrf52/arduino-nano-33ble/src/nrf52_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF52_NENDPOINTS);
   DEBUGASSERT(epout <= NRF52_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf52/nrf52840-dk/src/nrf52_composite.c b/boards/arm/nrf52/nrf52840-dk/src/nrf52_composite.c
index 3fb34c2362..44bef5af5c 100644
--- a/boards/arm/nrf52/nrf52840-dk/src/nrf52_composite.c
+++ b/boards/arm/nrf52/nrf52840-dk/src/nrf52_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF52_NENDPOINTS);
   DEBUGASSERT(epout <= NRF52_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf52/nrf52840-dongle/src/nrf52_composite.c b/boards/arm/nrf52/nrf52840-dongle/src/nrf52_composite.c
index 0d03224fa3..be5d7b6788 100644
--- a/boards/arm/nrf52/nrf52840-dongle/src/nrf52_composite.c
+++ b/boards/arm/nrf52/nrf52840-dongle/src/nrf52_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF52_NENDPOINTS);
   DEBUGASSERT(epout <= NRF52_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf53_composite.c b/boards/arm/nrf53/nrf5340-dk/src/nrf53_composite.c
index b3fce0506c..57b218a30c 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/nrf53_composite.c
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf53_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF53_NENDPOINTS);
   DEBUGASSERT(epout <= NRF53_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/nrf53/thingy53/src/nrf53_composite.c b/boards/arm/nrf53/thingy53/src/nrf53_composite.c
index 16ca149872..735ea2898d 100644
--- a/boards/arm/nrf53/thingy53/src/nrf53_composite.c
+++ b/boards/arm/nrf53/thingy53/src/nrf53_composite.c
@@ -126,7 +126,7 @@ void *board_composite0_connect(void)
   DEBUGASSERT(epin <= NRF53_NENDPOINTS);
   DEBUGASSERT(epout <= NRF53_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/rp2040/common/src/rp2040_composite.c b/boards/arm/rp2040/common/src/rp2040_composite.c
index 69a6f0847a..9b059f48fe 100644
--- a/boards/arm/rp2040/common/src/rp2040_composite.c
+++ b/boards/arm/rp2040/common/src/rp2040_composite.c
@@ -265,7 +265,7 @@ void *board_composite_connect(int port, int configid)
       n++;
 #endif
 
-      return composite_initialize(n, dev);
+      return composite_initialize(composite_getdevdescs(), dev, n);
     }
   else
     {
diff --git a/boards/arm/samd5e5/metro-m4/src/sam_composite.c b/boards/arm/samd5e5/metro-m4/src/sam_composite.c
index b576aaeebb..7f6e640d6d 100644
--- a/boards/arm/samd5e5/metro-m4/src/sam_composite.c
+++ b/boards/arm/samd5e5/metro-m4/src/sam_composite.c
@@ -264,7 +264,7 @@ void *board_composite_connect(int port, int configid)
       ifnobase += dev[1].devinfo.ninterfaces;
       strbase  += dev[1].devinfo.nstrings;
 
-      return composite_initialize(2, dev);
+      return composite_initialize(composite_getdevdescs(), dev, 2);
 #else
       return NULL;
 #endif
@@ -333,7 +333,7 @@ void *board_composite_connect(int port, int configid)
           strbase  += dev[ia].devinfo.nstrings;
         }
 
-      return composite_initialize(3, dev);
+      return composite_initialize(composite_getdevdescs(), dev, 3);
     }
   else
     {
diff --git a/boards/arm/samv7/samv71-xult/src/sam_composite.c b/boards/arm/samv7/samv71-xult/src/sam_composite.c
index fb4cae96a1..86d716fa0a 100644
--- a/boards/arm/samv7/samv71-xult/src/sam_composite.c
+++ b/boards/arm/samv7/samv71-xult/src/sam_composite.c
@@ -263,7 +263,7 @@ void *board_composite_connect(int port, int configid)
       ifnobase += dev[1].devinfo.ninterfaces;
       strbase  += dev[1].devinfo.nstrings;
 
-      return composite_initialize(2, dev);
+      return composite_initialize(composite_getdevdescs(), dev, 2);
 #else
       return NULL;
 #endif
@@ -332,7 +332,7 @@ void *board_composite_connect(int port, int configid)
           strbase  += dev[ia].devinfo.nstrings;
         }
 
-      return composite_initialize(3, dev);
+      return composite_initialize(composite_getdevdescs(), dev, 3);
     }
   else
     {
diff --git a/boards/arm/stm32/olimexino-stm32/src/stm32_composite.c b/boards/arm/stm32/olimexino-stm32/src/stm32_composite.c
index 280a3c1d5f..fa33184737 100644
--- a/boards/arm/stm32/olimexino-stm32/src/stm32_composite.c
+++ b/boards/arm/stm32/olimexino-stm32/src/stm32_composite.c
@@ -273,7 +273,7 @@ static void *board_composite0_connect(int port)
   ifnobase += dev[1].devinfo.ninterfaces;
   strbase  += dev[1].devinfo.nstrings;
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 #endif
 
@@ -341,7 +341,7 @@ static void *board_composite1_connect(int port)
       strbase  += dev[i].devinfo.nstrings;
     }
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 #else
   return NULL;
 #endif
diff --git a/boards/arm/stm32/photon/src/stm32_composite.c b/boards/arm/stm32/photon/src/stm32_composite.c
index 1a79696414..3dc8cdd0e4 100644
--- a/boards/arm/stm32/photon/src/stm32_composite.c
+++ b/boards/arm/stm32/photon/src/stm32_composite.c
@@ -113,7 +113,7 @@ static void *board_composite0_connect(int port)
 
   /* Add other composite devices here */
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/stm32/stm3210e-eval/src/stm32_composite.c b/boards/arm/stm32/stm3210e-eval/src/stm32_composite.c
index dd95fc2405..53e9bb40ad 100644
--- a/boards/arm/stm32/stm3210e-eval/src/stm32_composite.c
+++ b/boards/arm/stm32/stm3210e-eval/src/stm32_composite.c
@@ -268,7 +268,7 @@ static void *board_composite0_connect(int port)
   ifnobase += dev[1].devinfo.ninterfaces;
   strbase  += dev[1].devinfo.nstrings;
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 }
 #endif
 
@@ -336,7 +336,7 @@ static void *board_composite1_connect(int port)
       strbase  += dev[i].devinfo.nstrings;
     }
 
-  return composite_initialize(2, dev);
+  return composite_initialize(composite_getdevdescs(), dev, 2);
 #else
   return NULL;
 #endif
diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32_composite.c b/boards/arm/stm32/stm32f411-minimum/src/stm32_composite.c
index 107b1a4ad7..54a0a1eb13 100644
--- a/boards/arm/stm32/stm32f411-minimum/src/stm32_composite.c
+++ b/boards/arm/stm32/stm32f411-minimum/src/stm32_composite.c
@@ -265,7 +265,7 @@ void *board_composite_connect(int port, int configid)
       dev_idx++;
 #endif
 
-      return composite_initialize(dev_idx, dev);
+      return composite_initialize(composite_getdevdescs(), dev, dev_idx);
     }
   else
     {
diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_composite.c b/boards/arm/stm32/stm32f4discovery/src/stm32_composite.c
index ab4a34139d..32c217b09a 100644
--- a/boards/arm/stm32/stm32f4discovery/src/stm32_composite.c
+++ b/boards/arm/stm32/stm32f4discovery/src/stm32_composite.c
@@ -296,7 +296,7 @@ static void *board_composite0_connect(int port)
   DEBUGASSERT(epin < STM32_NENDPOINTS);
   DEBUGASSERT(epout < STM32_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_composite.c b/boards/arm/stm32f7/nucleo-144/src/stm32_composite.c
index 12d37b4ae1..3ffcb6e6f8 100644
--- a/boards/arm/stm32f7/nucleo-144/src/stm32_composite.c
+++ b/boards/arm/stm32f7/nucleo-144/src/stm32_composite.c
@@ -296,7 +296,7 @@ static void *board_composite0_connect(int port)
   DEBUGASSERT(epin < STM32_NENDPOINTS);
   DEBUGASSERT(epout < STM32_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_composite.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_composite.c
index 33582a526d..fa79ca1155 100644
--- a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_composite.c
+++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_composite.c
@@ -296,7 +296,7 @@ static void *board_composite0_connect(int port)
   DEBUGASSERT(epin < STM32_NENDPOINTS);
   DEBUGASSERT(epout < STM32_NENDPOINTS);
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/boards/risc-v/mpfs/common/src/mpfs_composite.c b/boards/risc-v/mpfs/common/src/mpfs_composite.c
index f280ab32ba..a8530f2849 100644
--- a/boards/risc-v/mpfs/common/src/mpfs_composite.c
+++ b/boards/risc-v/mpfs/common/src/mpfs_composite.c
@@ -294,7 +294,7 @@ void *board_composite_connect(int port, int configid)
       ifnobase += dev[1].devinfo.ninterfaces;
       strbase  += dev[1].devinfo.nstrings;
 
-      return composite_initialize(2, dev);
+      return composite_initialize(composite_getdevdescs(), dev, 2);
 #else
       return NULL;
 #endif
diff --git a/boards/sim/sim/sim/src/sim_composite.c b/boards/sim/sim/sim/src/sim_composite.c
index 073a11e95c..de32560f4b 100644
--- a/boards/sim/sim/sim/src/sim_composite.c
+++ b/boards/sim/sim/sim/src/sim_composite.c
@@ -120,7 +120,7 @@ static void *board_composite0_connect(int port)
   dev_idx += 1;
 #endif
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
@@ -207,7 +207,7 @@ static void *board_composite1_connect(int port)
   dev_idx += 1;
 #endif
 
-  return composite_initialize(dev_idx, dev);
+  return composite_initialize(composite_getdevdescs(), dev, dev_idx);
 }
 
 /****************************************************************************
diff --git a/drivers/usbdev/adb.c b/drivers/usbdev/adb.c
index 84452dc1bd..9ee8713275 100644
--- a/drivers/usbdev/adb.c
+++ b/drivers/usbdev/adb.c
@@ -103,10 +103,6 @@
 
 #define USBADB_NCONFIGS            (1)
 
-/* Length of ADB descriptor */
-
-#define USBADB_DESC_TOTALLEN       (32)
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -172,14 +168,6 @@ struct adb_driver_s
   struct usbdev_adb_s dev;
 };
 
-struct adb_cfgdesc_s
-{
-#ifndef CONFIG_USBADB_COMPOSITE
-  struct usb_cfgdesc_s cfgdesc;        /* Configuration descriptor */
-#endif
-  struct usb_ifdesc_s  ifdesc;         /* ADB interface descriptor */
-};
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -303,40 +291,61 @@ static const struct usb_qualdesc_s g_adb_qualdesc =
   0,                                 /* reserved */
 };
 #  endif
-#endif
 
-static const struct adb_cfgdesc_s g_adb_cfgdesc =
+static const struct usbdev_strdesc_s g_adb_strdesc[] =
 {
-#ifndef CONFIG_USBADB_COMPOSITE
-  {
-    .len          = USB_SIZEOF_CFGDESC,   /* Descriptor length    */
-    .type         = USB_DESC_TYPE_CONFIG, /* Descriptor type      */
-    .totallen     =
-    {
-      LSBYTE(USBADB_DESC_TOTALLEN),       /* LS Total length      */
-      MSBYTE(USBADB_DESC_TOTALLEN)        /* MS Total length      */
-    },
-    .ninterfaces  = 1,                    /* Number of interfaces */
-    .cfgvalue     = 1,                    /* Configuration value  */
-    .icfg         = USBADB_CONFIGSTRID,   /* Configuration        */
-    .attr         = USB_CONFIG_ATTR_ONE |
-                    USBADB_SELFPOWERED  |
-                    USBADB_REMOTEWAKEUP,  /* Attributes           */
-
-    .mxpower      = (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* Max power (mA/2) */
-  },
+  {USBADB_MANUFACTURERSTRID, CONFIG_USBADB_VENDORSTR},
+  {USBADB_PRODUCTSTRID,      CONFIG_USBADB_PRODUCTSTR},
+#  ifdef CONFIG_USBADB_SERIALSTR
+  {USBADB_SERIALSTRID,       CONFIG_USBADB_SERIALSTR},
+#  else
+  {USBADB_SERIALSTRID,       ""},
+#  endif
+  {USBADB_CONFIGSTRID,       CONFIG_USBADB_CONFIGSTR},
+  {}
+};
+
+static const struct usbdev_strdescs_s g_adb_strdescs =
+{
+  .language = USBADB_STR_LANGUAGE,
+  .strdesc  = g_adb_strdesc,
+};
+
+static const struct usb_cfgdesc_s g_adb_cfgdesc =
+{
+  .len      = USB_SIZEOF_CFGDESC,   /* Descriptor length    */
+  .type     = USB_DESC_TYPE_CONFIG, /* Descriptor type      */
+  .cfgvalue = 1,                    /* Configuration value  */
+  .icfg     = USBADB_CONFIGSTRID,   /* Configuration        */
+  .attr     = USB_CONFIG_ATTR_ONE |
+              USBADB_SELFPOWERED  |
+              USBADB_REMOTEWAKEUP,  /* Attributes           */
+
+  .mxpower  = (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* Max power (mA/2) */
+};
+
+static const struct usbdev_devdescs_s g_adb_devdescs =
+{
+  .cfgdesc  = &g_adb_cfgdesc,
+  .strdescs = &g_adb_strdescs,
+  .devdesc  = &g_adb_devdesc,
+#ifdef CONFIG_USBDEV_DUALSPEED
+  .qualdesc = &g_adb_qualdesc,
 #endif
-  {
-    .len            = USB_SIZEOF_IFDESC,
-    .type           = USB_DESC_TYPE_INTERFACE,
-    .ifno           = 0,
-    .alt            = 0,
-    .neps           = 2,
-    .classid        = USB_CLASS_VENDOR_SPEC,
-    .subclass       = 0x42,
-    .protocol       = 0x01,
-    .iif            = USBADB_INTERFACESTRID
-  }
+};
+#endif
+
+static const struct usb_ifdesc_s g_adb_ifdesc =
+{
+  .len      = USB_SIZEOF_IFDESC,
+  .type     = USB_DESC_TYPE_INTERFACE,
+  .ifno     = 0,
+  .alt      = 0,
+  .neps     = 2,
+  .classid  = USB_CLASS_VENDOR_SPEC,
+  .subclass = 0x42,
+  .protocol = 0x01,
+  .iif      = USBADB_INTERFACESTRID
 };
 
 /****************************************************************************
@@ -767,7 +776,7 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
 {
   bool hispeed = false;
   FAR struct usb_epdesc_s *epdesc;
-  FAR struct adb_cfgdesc_s *dest;
+  FAR struct usb_ifdesc_s *dest;
 
 #ifdef CONFIG_USBDEV_DUALSPEED
   hispeed = (speed == USB_SPEED_HIGH);
@@ -780,10 +789,10 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
     }
 #endif
 
-  dest = (FAR struct adb_cfgdesc_s *)buf;
-  epdesc = (FAR struct usb_epdesc_s *)(buf + sizeof(g_adb_cfgdesc));
+  dest = (FAR struct usb_ifdesc_s *)buf;
+  epdesc = (FAR struct usb_epdesc_s *)(buf + sizeof(g_adb_ifdesc));
 
-  memcpy(dest, &g_adb_cfgdesc, sizeof(g_adb_cfgdesc));
+  memcpy(dest, &g_adb_ifdesc, sizeof(g_adb_ifdesc));
 
   usbclass_copy_epdesc(USBADB_EP_BULKIN_IDX, &epdesc[0], devinfo, hispeed);
   usbclass_copy_epdesc(USBADB_EP_BULKOUT_IDX, &epdesc[1], devinfo, hispeed);
@@ -791,11 +800,11 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
 #ifdef CONFIG_USBADB_COMPOSITE
   /* For composite device, apply possible offset to the interface numbers */
 
-  dest->ifdesc.ifno = devinfo->ifnobase;
-  dest->ifdesc.iif  = devinfo->strbase + USBADB_INTERFACESTRID;
+  dest->ifno = devinfo->ifnobase;
+  dest->iif  = devinfo->strbase + USBADB_INTERFACESTRID;
 #endif
 
-  return sizeof(g_adb_cfgdesc)+2*USB_SIZEOF_EPDESC;
+  return sizeof(g_adb_ifdesc) + 2 * USB_SIZEOF_EPDESC;
 }
 
 /****************************************************************************
@@ -816,47 +825,14 @@ static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc)
 
   switch (id)
     {
-#ifndef CONFIG_USBADB_COMPOSITE
-    case 0:
-      {
-        /* Descriptor 0 is the language id */
-
-        strdesc->len  = 4;
-        strdesc->type = USB_DESC_TYPE_STRING;
-        data[0] = LSBYTE(USBADB_STR_LANGUAGE);
-        data[1] = MSBYTE(USBADB_STR_LANGUAGE);
-        return 4;
-      }
-
-    case USBADB_MANUFACTURERSTRID:
-      str = CONFIG_USBADB_VENDORSTR;
-      break;
-
-    case USBADB_PRODUCTSTRID:
-      str = CONFIG_USBADB_PRODUCTSTR;
-      break;
-
-    case USBADB_SERIALSTRID:
-#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
-      str = board_usbdev_serialstr();
-#else
-      str = CONFIG_USBADB_SERIALSTR;
-#endif
-      break;
+      /* Composite driver removes offset before calling mkstrdesc() */
 
-    case USBADB_CONFIGSTRID:
-      str = CONFIG_USBADB_CONFIGSTR;
-      break;
-#endif
-
-    /* Composite driver removes offset before calling mkstrdesc() */
-
-    case USBADB_INTERFACESTRID:
-      str = CONFIG_USBADB_INTERFACESTR;
-      break;
+      case USBADB_INTERFACESTRID:
+        str = CONFIG_USBADB_INTERFACESTR;
+        break;
 
-    default:
-      return -EINVAL;
+      default:
+        return -EINVAL;
     }
 
   /* The string is utf16-le.  The poor man's utf-8 to utf16-le
@@ -1938,7 +1914,7 @@ FAR void *usbdev_adb_initialize(void)
   struct composite_devdesc_s devdesc;
 
   usbdev_adb_get_composite_devdesc(&devdesc);
-  return composite_initialize(1, &devdesc);
+  return composite_initialize(&g_adb_devdescs, &devdesc, 1);
 }
 
 /****************************************************************************
@@ -1953,74 +1929,6 @@ void usbdev_adb_uninitialize(FAR void *handle)
 {
   composite_uninitialize(handle);
 }
-
-/****************************************************************************
- * Name: composite_getepdesc
- *
- * Description:
- *   Return a pointer to the raw device descriptor
- *
- ****************************************************************************/
-
-FAR const struct usb_devdesc_s *composite_getdevdesc(void)
-{
-  return &g_adb_devdesc;
-}
-
-/****************************************************************************
- * Name: composite_getqualdesc
- *
- * Description:
- *   Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#  ifdef CONFIG_USBDEV_DUALSPEED
-FAR const struct usb_qualdesc_s *composite_getqualdesc(void)
-{
-  return &g_adb_qualdesc;
-}
-#  endif
-
-/****************************************************************************
- * Name: composite_mkcfgdesc
- *
- * Description:
- *   Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#  ifdef CONFIG_USBDEV_DUALSPEED
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf,
-                            uint8_t speed, uint8_t type)
-#  else
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf)
-#  endif
-{
-#  ifdef CONFIG_USBDEV_DUALSPEED
-  return usbclass_mkcfgdesc(buf,
-                            &priv->device[0].compdesc.devinfo,
-                            speed, type);
-#  else
-  return usbclass_mkcfgdesc(buf,
-                            &priv->device[0].compdesc.devinfo);
-#  endif
-}
-
-/****************************************************************************
- * Name: composite_mkstrdesc
- *
- * Description:
- *   Construct a string descriptor
- *
- ****************************************************************************/
-
-int composite_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc)
-{
-  return usbclass_mkstrdesc(id, strdesc);
-}
 #endif
 
 /****************************************************************************
@@ -2048,7 +1956,7 @@ void usbdev_adb_get_composite_devdesc(struct composite_devdesc_s *dev)
   dev->uninitialize        = usbclass_uninitialize;
   dev->nconfigs            = USBADB_NCONFIGS;
   dev->configid            = 1;
-  dev->cfgdescsize         = sizeof(g_adb_cfgdesc)+2*USB_SIZEOF_EPDESC;
+  dev->cfgdescsize         = sizeof(g_adb_ifdesc) + 2 * USB_SIZEOF_EPDESC;
   dev->devinfo.ninterfaces = 1;
   dev->devinfo.nstrings    = USBADB_NSTRIDS;
   dev->devinfo.nendpoints  = USBADB_NUM_EPS;
diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c
index 2a30b6db9b..87e1ce8919 100644
--- a/drivers/usbdev/composite.c
+++ b/drivers/usbdev/composite.c
@@ -265,6 +265,164 @@ static int composite_msftdescriptor(FAR struct composite_dev_s *priv,
 }
 #endif
 
+/****************************************************************************
+ * Name: composite_mkcfgdesc
+ *
+ * Description:
+ *   Construct the configuration descriptor
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+static int16_t composite_mkcfgdesc(FAR struct usbdevclass_driver_s *driver,
+                                   FAR uint8_t *buf,
+                                   uint8_t speed, uint8_t type)
+#else
+static int16_t composite_mkcfgdesc(FAR struct usbdevclass_driver_s *driver,
+                                   FAR uint8_t *buf)
+#endif
+{
+  FAR struct composite_dev_s *priv =
+    ((FAR struct composite_driver_s *)driver)->dev;
+  FAR struct usb_cfgdesc_s *cfgdesc;
+  int16_t len;
+  int16_t total;
+  int i;
+
+  /* Configuration descriptor for the composite device */
+
+  memcpy(buf, priv->descs->cfgdesc, sizeof(struct usb_cfgdesc_s));
+
+  cfgdesc = (FAR struct usb_cfgdesc_s *)buf;
+  cfgdesc->totallen[0] = LSBYTE(priv->cfgdescsize);
+  cfgdesc->totallen[1] = MSBYTE(priv->cfgdescsize);
+  cfgdesc->ninterfaces = priv->ninterfaces;
+
+  /* Increment the size and buf to point right behind the information
+   * filled in
+   */
+
+  total = USB_SIZEOF_CFGDESC;
+  buf += USB_SIZEOF_CFGDESC;
+
+  /* Copy all contained interface descriptors into the buffer too */
+
+  for (i = 0; i < priv->ndevices; i++)
+    {
+      FAR struct composite_devobj_s *devobj = &priv->device[i];
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+      len = devobj->compdesc.mkconfdesc(buf,
+                                        &devobj->compdesc.devinfo,
+                                        speed, type);
+      total += len;
+      buf += len;
+#else
+      len = devobj->compdesc.mkconfdesc(buf,
+                                        &devobj->compdesc.devinfo);
+      total += len;
+      buf += len;
+#endif
+    }
+
+  return total;
+}
+
+/****************************************************************************
+ * Name: composite_mkstrdesc
+ *
+ * Description:
+ *   Construct a string descriptor
+ *
+ ****************************************************************************/
+
+static int composite_mkstrdesc(FAR struct usbdevclass_driver_s *driver,
+                               uint8_t id, FAR struct usb_strdesc_s *outdesc)
+{
+  FAR struct composite_dev_s *priv =
+    ((FAR struct composite_driver_s *)driver)->dev;
+  FAR const struct usbdev_strdescs_s *strdescs = priv->descs->strdescs;
+  FAR const struct usbdev_strdesc_s *strdesc;
+  FAR uint8_t *data = (FAR uint8_t *)(outdesc + 1);
+  int i;
+
+  if (id == 0)
+    {
+      outdesc->len = 4;
+      outdesc->type = USB_DESC_TYPE_STRING;
+      data[0] = LSBYTE(strdescs->language);
+      data[1] = MSBYTE(strdescs->language);
+      return 4;
+    }
+
+#ifdef CONFIG_COMPOSITE_MSFT_OS_DESCRIPTORS
+  if (id == USB_REQ_GETMSFTOSDESCRIPTOR)
+    {
+      /* Note: Windows has a habit of caching this response,
+       * so if you want to enable/disable it you'll usually
+       * need to change the device serial number afterwards.
+       */
+
+      static const uint8_t msft_response[16] =
+        {
+          'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0,
+          '0', 0, USB_REQ_GETMSFTOSDESCRIPTOR, 0
+        };
+
+      outdesc->len = 18;
+      outdesc->type = USB_DESC_TYPE_STRING;
+      memcpy(data, msft_response, 16);
+      return outdesc->len;
+    }
+#endif
+
+  for (strdesc = strdescs->strdesc;
+       strdesc != NULL && strdesc->string != NULL; strdesc++)
+    {
+      if (strdesc->id == id)
+        {
+          FAR const char *strval = strdesc->string;
+          int ndata;
+          int len;
+
+#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
+          if (strdesc->id == COMPOSITE_SERIALSTRID)
+            {
+              strval = board_usbdev_serialstr();
+            }
+#endif
+
+          len = strlen(strval);
+          for (i = 0, ndata = 0; i < len; i++, ndata += 2)
+            {
+              data[ndata]     = strval[i];
+              data[ndata + 1] = 0;
+            }
+
+          outdesc->len  = ndata + 2;
+          outdesc->type = USB_DESC_TYPE_STRING;
+          return outdesc->len;
+        }
+    }
+
+  for (i = 0; i < priv->ndevices; i++)
+    {
+      if (id >
+          priv->device[i].compdesc.devinfo.strbase &&
+          id <=
+          priv->device[i].compdesc.devinfo.strbase +
+          priv->device[i].compdesc.devinfo.nstrings)
+        {
+          return priv->device[i].compdesc.mkstrdesc(
+                   id -
+                   priv->device[i].compdesc.devinfo.strbase,
+                   outdesc);
+        }
+    }
+
+  return -EINVAL;
+}
+
 /****************************************************************************
  * USB Class Driver Methods
  ****************************************************************************/
@@ -481,7 +639,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
               case USB_DESC_TYPE_DEVICE:
                 {
                   ret = USB_SIZEOF_DEVDESC;
-                  memcpy(ctrlreq->buf, composite_getdevdesc(), ret);
+                  memcpy(ctrlreq->buf, priv->descs->devdesc, ret);
                 }
                 break;
 
@@ -489,7 +647,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
               case USB_DESC_TYPE_DEVICEQUALIFIER:
                 {
                   ret = USB_SIZEOF_QUALDESC;
-                  memcpy(ctrlreq->buf, composite_getqualdesc(), ret);
+                  memcpy(ctrlreq->buf, priv->descs->qualdesc, ret);
                 }
                 break;
 
@@ -499,10 +657,10 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
               case USB_DESC_TYPE_CONFIG:
                 {
 #ifdef CONFIG_USBDEV_DUALSPEED
-                    ret = composite_mkcfgdesc(priv, ctrlreq->buf, dev->speed,
-                                              ctrl->value[1]);
+                    ret = composite_mkcfgdesc(driver, ctrlreq->buf,
+                                              dev->speed, ctrl->value[1]);
 #else
-                    ret = composite_mkcfgdesc(priv, ctrlreq->buf);
+                    ret = composite_mkcfgdesc(driver, ctrlreq->buf);
 #endif
                 }
                 break;
@@ -515,54 +673,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
                   FAR struct usb_strdesc_s *buf =
                              (FAR struct usb_strdesc_s *)ctrlreq->buf;
 
-#ifdef CONFIG_USBDEV_COMPOSITE
-                  if (strid < COMPOSITE_NSTRIDS)
-                    {
-                      ret = composite_mkstrdesc(strid, buf);
-                    }
-#ifdef CONFIG_COMPOSITE_MSFT_OS_DESCRIPTORS
-                  else if (strid == USB_REQ_GETMSFTOSDESCRIPTOR)
-                    {
-                      /* Note: Windows has a habit of caching this response,
-                       * so if you want to enable/disable it you'll usually
-                       * need to change the device serial number afterwards.
-                       */
-
-                      static const uint8_t msft_response[16] =
-                      {
-                        'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0,
-                        '0', 0, USB_REQ_GETMSFTOSDESCRIPTOR, 0
-                      };
-
-                      buf->len = 18;
-                      buf->type = USB_DESC_TYPE_STRING;
-                      memcpy(buf + 1, msft_response, 16);
-                      ret = buf->len;
-                    }
-#endif
-                  else
-                    {
-                      int i;
-
-                      for (i = 0; i < priv->ndevices; i++)
-                        {
-                          if (strid >
-                              priv->device[i].compdesc.devinfo.strbase &&
-                              strid <=
-                              priv->device[i].compdesc.devinfo.strbase +
-                              priv->device[i].compdesc.devinfo.nstrings)
-                            {
-                              ret = priv->device[i].compdesc.mkstrdesc(
-                                    strid -
-                                    priv->device[i].compdesc.devinfo.strbase,
-                                    buf);
-                              break;
-                            }
-                        }
-                    }
-#else
-                  ret = composite_mkstrdesc(strid, buf);
-#endif
+                  ret = composite_mkstrdesc(driver, strid, buf);
                 }
                 break;
 
@@ -883,8 +994,9 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
  *
  ****************************************************************************/
 
-FAR void *composite_initialize(uint8_t ndevices,
-                               FAR struct composite_devdesc_s *pdevices)
+FAR void *composite_initialize(FAR const struct usbdev_devdescs_s *devdescs,
+                               FAR struct composite_devdesc_s *pdevices,
+                               uint8_t ndevices)
 {
   FAR struct composite_alloc_s *alloc;
   FAR struct composite_dev_s *priv;
@@ -914,6 +1026,9 @@ FAR void *composite_initialize(uint8_t ndevices,
 
   memset(priv, 0, sizeof(struct composite_dev_s));
 
+  /* Initialize USB device descriptor */
+
+  priv->descs       = devdescs;
   priv->cfgdescsize = USB_SIZEOF_CFGDESC;
   priv->ninterfaces = 0;
 
@@ -921,13 +1036,14 @@ FAR void *composite_initialize(uint8_t ndevices,
 
   for (i = 0; i < ndevices; i++)
     {
-      memcpy(&priv->device[i].compdesc, &pdevices[i],
-             sizeof(struct composite_devdesc_s));
+      FAR struct composite_devobj_s *devobj = &priv->device[i];
+
+      devobj->compdesc = pdevices[i];
 
       ret =
-        priv->device[i].compdesc.classobject(priv->device[i].compdesc.minor,
-                                        &priv->device[i].compdesc.devinfo,
-                                        &priv->device[i].dev);
+        devobj->compdesc.classobject(devobj->compdesc.minor,
+                                     &devobj->compdesc.devinfo,
+                                     &devobj->dev);
       if (ret < 0)
         {
           usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT),
@@ -935,8 +1051,8 @@ FAR void *composite_initialize(uint8_t ndevices,
           goto errout_with_alloc;
         }
 
-      priv->cfgdescsize += priv->device[i].compdesc.cfgdescsize;
-      priv->ninterfaces += priv->device[i].compdesc.devinfo.ninterfaces;
+      priv->cfgdescsize += devobj->compdesc.cfgdescsize;
+      priv->ninterfaces += devobj->compdesc.devinfo.ninterfaces;
     }
 
   priv->ndevices = ndevices;
diff --git a/drivers/usbdev/composite.h b/drivers/usbdev/composite.h
index f98bb595d0..ec885f87b4 100644
--- a/drivers/usbdev/composite.h
+++ b/drivers/usbdev/composite.h
@@ -71,75 +71,14 @@ struct composite_devobj_s
 
 struct composite_dev_s
 {
-  FAR struct usbdev_s      *usbdev;                         /* usbdev driver pointer */
-  FAR struct usbdev_req_s  *ctrlreq;                        /* Allocated control request */
-  int                       cfgdescsize;                    /* Total size of the configuration descriptor: */
-  int                       ninterfaces;                    /* The total number of interfaces in this composite device */
-  uint8_t                   config;                         /* Configuration number */
-  uint8_t                   ndevices;                       /* Num devices in this composite device */
-  struct composite_devobj_s device[NUM_DEVICES_TO_HANDLE];  /* Device class object */
+  FAR struct usbdev_s                *usbdev;                        /* usbdev driver pointer */
+  FAR struct usbdev_req_s            *ctrlreq;                       /* Allocated control request */
+  int                                 cfgdescsize;                   /* Total size of the configuration descriptor */
+  int                                 ninterfaces;                   /* The total number of interfaces in this composite device */
+  uint8_t                             config;                        /* Configuration number */
+  uint8_t                             ndevices;                      /* Num devices in this composite device */
+  struct composite_devobj_s           device[NUM_DEVICES_TO_HANDLE]; /* Device class object */
+  FAR const struct usbdev_devdescs_s *descs;                         /* Device descriptors */
 };
 
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_COMPOSITE
-extern const char g_compvendorstr[];
-extern const char g_compproductstr[];
-extern const char g_compserialstr[];
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_mkstrdesc
- *
- * Description:
- *   Construct a string descriptor
- *
- ****************************************************************************/
-
-int composite_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-
-/****************************************************************************
- * Name: composite_getepdesc
- *
- * Description:
- *   Return a pointer to the composite device descriptor
- *
- ****************************************************************************/
-
-FAR const struct usb_devdesc_s *composite_getdevdesc(void);
-
-/****************************************************************************
- * Name: composite_mkcfgdesc
- *
- * Description:
- *   Construct the composite configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf);
-#endif
-
-/****************************************************************************
- * Name: composite_getqualdesc
- *
- * Description:
- *   Return a pointer to the composite qual descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-FAR const struct usb_qualdesc_s *composite_getqualdesc(void);
-#endif
-
 #endif /* __DRIVERS_USBDEV_COMPOSITE_H */
diff --git a/drivers/usbdev/composite_desc.c b/drivers/usbdev/composite_desc.c
index cade7705c7..80ab316ec2 100644
--- a/drivers/usbdev/composite_desc.c
+++ b/drivers/usbdev/composite_desc.c
@@ -24,19 +24,8 @@
 
 #include <nuttx/config.h>
 
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
-#include <nuttx/board.h>
-#endif
-
-#include <nuttx/usb/usbdev_trace.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
 
 #include "composite.h"
 
@@ -153,6 +142,38 @@ static const struct usb_devdesc_s g_devdesc =
   COMPOSITE_NCONFIGS                            /* nconfigs */
 };
 
+static const struct usbdev_strdesc_s g_strdesc[] =
+{
+  {COMPOSITE_MANUFACTURERSTRID, CONFIG_COMPOSITE_VENDORSTR},
+  {COMPOSITE_PRODUCTSTRID,      CONFIG_COMPOSITE_PRODUCTSTR},
+#ifdef CONFIG_COMPOSITE_SERIALSTR
+  {COMPOSITE_SERIALSTRID,       CONFIG_COMPOSITE_SERIALSTR},
+#else
+  {COMPOSITE_SERIALSTRID,       ""},
+#endif
+  {COMPOSITE_CONFIGSTRID,       CONFIG_COMPOSITE_CONFIGSTR},
+  {}
+};
+
+static const struct usbdev_strdescs_s g_strdescs =
+{
+  .language = COMPOSITE_STR_LANGUAGE,
+  .strdesc  = g_strdesc,
+};
+
+static const struct usb_cfgdesc_s g_cfgdesc =
+{
+  .len      = USB_SIZEOF_CFGDESC,              /* Descriptor length    */
+  .type     = USB_DESC_TYPE_CONFIG,            /* Descriptor type      */
+  .cfgvalue = COMPOSITE_CONFIGID,              /* Configuration value  */
+  .icfg     = COMPOSITE_CONFIGSTRID,           /* Configuration        */
+  .attr     = USB_CONFIG_ATTR_ONE   |
+              COMPOSITE_SELFPOWERED |
+              COMPOSITE_REMOTEWAKEUP,          /* Attributes           */
+
+  .mxpower  = (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* Max power (mA/2) */
+};
+
 #ifdef CONFIG_USBDEV_DUALSPEED
 static const struct usb_qualdesc_s g_qualdesc =
 {
@@ -177,189 +198,41 @@ static const struct usb_qualdesc_s g_qualdesc =
 };
 #endif
 
+static const struct usbdev_devdescs_s g_composite_devdescs =
+{
+  &g_cfgdesc,
+  &g_strdescs,
+  &g_devdesc,
+#ifdef CONFIG_USBDEV_DUALSPEED
+  &g_qualdesc,
+#endif
+};
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
 
 const char g_compvendorstr[]  = CONFIG_COMPOSITE_VENDORSTR;
 const char g_compproductstr[] = CONFIG_COMPOSITE_PRODUCTSTR;
-#ifndef CONFIG_BOARD_USBDEV_SERIALSTR
+#ifndef CONFIG_COMPOSITE_BOARD_SERIALSTR
 const char g_compserialstr[]  = CONFIG_COMPOSITE_SERIALSTR;
 #endif
 
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: composite_mkstrdesc
- *
- * Description:
- *   Construct a string descriptor
- *
- ****************************************************************************/
-
-int composite_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc)
-{
-  FAR uint8_t *data = (FAR uint8_t *)(strdesc + 1);
-  FAR const char *str;
-  int len;
-  int ndata;
-  int i;
-
-  switch (id)
-    {
-    case 0:
-      {
-        /* Descriptor 0 is the language id */
-
-        strdesc->len  = 4;
-        strdesc->type = USB_DESC_TYPE_STRING;
-        data[0] = LSBYTE(COMPOSITE_STR_LANGUAGE);
-        data[1] = MSBYTE(COMPOSITE_STR_LANGUAGE);
-        return 4;
-      }
-
-    case COMPOSITE_MANUFACTURERSTRID:
-      str = g_compvendorstr;
-      break;
-
-    case COMPOSITE_PRODUCTSTRID:
-      str = g_compproductstr;
-      break;
-
-    case COMPOSITE_SERIALSTRID:
-#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
-      str = board_usbdev_serialstr();
-#else
-      str = g_compserialstr;
-#endif
-      break;
-
-    case COMPOSITE_CONFIGSTRID:
-      str = CONFIG_COMPOSITE_CONFIGSTR;
-      break;
-
-    default:
-      return -EINVAL;
-    }
-
-  /* The string is utf16-le.  The poor man's utf-8 to utf16-le
-   * conversion below will only handle 7-bit en-us ascii
-   */
-
-  len = strlen(str);
-  for (i = 0, ndata = 0; i < len; i++, ndata += 2)
-    {
-      data[ndata]     = str[i];
-      data[ndata + 1] = 0;
-    }
-
-  strdesc->len  = ndata + 2;
-  strdesc->type = USB_DESC_TYPE_STRING;
-  return strdesc->len;
-}
-
-/****************************************************************************
- * Name: composite_getepdesc
+ * Name: composite_getdevdescs
  *
  * Description:
- *   Return a pointer to the raw device descriptor
+ *   Return a pointer to the device descriptor
  *
  ****************************************************************************/
 
-FAR const struct usb_devdesc_s *composite_getdevdesc(void)
+FAR const struct usbdev_devdescs_s *composite_getdevdescs(void)
 {
-  return &g_devdesc;
+  return &g_composite_devdescs;
 }
 
-/****************************************************************************
- * Name: composite_mkcfgdesc
- *
- * Description:
- *   Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf,
-                            uint8_t speed, uint8_t type)
-#else
-int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv,
-                            FAR uint8_t *buf)
-#endif
-{
-  FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf;
-  int16_t len;
-  int16_t total;
-  int i;
-
-  /* Configuration descriptor for the composite device */
-
-  /* Fill in the values directly into the buf */
-
-  cfgdesc->len         = USB_SIZEOF_CFGDESC;               /* Descriptor length */
-#ifdef CONFIG_USBDEV_DUALSPEED
-  cfgdesc->type        = type;                             /* Descriptor type */
-#else
-  cfgdesc->type        = USB_DESC_TYPE_CONFIG;             /* Descriptor type */
-#endif
-  cfgdesc->totallen[0] = LSBYTE(priv->cfgdescsize);        /* Lower Byte of Total length */
-  cfgdesc->totallen[1] = MSBYTE(priv->cfgdescsize);        /* High Byte of Total length */
-  cfgdesc->ninterfaces = priv->ninterfaces;                /* Number of interfaces */
-  cfgdesc->cfgvalue    = COMPOSITE_CONFIGID;               /* Configuration value */
-  cfgdesc->icfg        = COMPOSITE_CONFIGSTRID;            /* Configuration */
-  cfgdesc->attr        = USB_CONFIG_ATTR_ONE |             /* Attributes */
-                         COMPOSITE_SELFPOWERED |
-                         COMPOSITE_REMOTEWAKEUP;
-  cfgdesc->mxpower     = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */
-
-  /* increment the size and buf to point right behind the information
-   * filled in
-   */
-
-  total = USB_SIZEOF_CFGDESC;
-  buf += USB_SIZEOF_CFGDESC;
-
-  /* Copy all contained interface descriptors into the buffer too */
-
-  for (i = 0; i < priv->ndevices; i++)
-    {
-#ifdef CONFIG_USBDEV_DUALSPEED
-      len = priv->device[i].compdesc.mkconfdesc(buf,
-                                        &priv->device[i].compdesc.devinfo,
-                                        speed, type);
-      total += len;
-      buf += len;
-#else
-      len = priv->device[i].compdesc.mkconfdesc(buf,
-                                        &priv->device[i].compdesc.devinfo);
-      total += len;
-      buf += len;
-#endif
-    }
-
-  return total;
-}
-
-/****************************************************************************
- * Name: composite_getqualdesc
- *
- * Description:
- *   Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-FAR const struct usb_qualdesc_s *composite_getqualdesc(void)
-{
-  return &g_qualdesc;
-}
-#endif
-
 #endif /* CONFIG_USBDEV_COMPOSITE */
diff --git a/include/nuttx/usb/composite.h b/include/nuttx/usb/composite.h
index 22a665dcd2..96ec222324 100644
--- a/include/nuttx/usb/composite.h
+++ b/include/nuttx/usb/composite.h
@@ -65,6 +65,7 @@ extern "C"
  ****************************************************************************/
 
 struct composite_devdesc_s;
+struct usbdev_devdescs_s;
 
 /****************************************************************************
  * Public Functions Definitions
@@ -91,8 +92,9 @@ struct composite_devdesc_s;
  *
  ****************************************************************************/
 
-FAR void *composite_initialize(uint8_t ndevices,
-                               FAR struct composite_devdesc_s *pdevices);
+FAR void *composite_initialize(FAR const struct usbdev_devdescs_s *devdescs,
+                               FAR struct composite_devdesc_s *pdevices,
+                               uint8_t ndevices);
 
 /****************************************************************************
  * Name: composite_uninitialize
@@ -135,6 +137,18 @@ int composite_ep0submit(FAR struct usbdevclass_driver_s *driver,
                         FAR struct usbdev_req_s *ctrlreq,
                         FAR const struct usb_ctrlreq_s *ctrl);
 
+#ifdef CONFIG_USBDEV_COMPOSITE
+/****************************************************************************
+ * Name: composite_getdevdescs
+ *
+ * Description:
+ *   Return a pointer to the device descriptor
+ *
+ ****************************************************************************/
+
+FAR const struct usbdev_devdescs_s *composite_getdevdescs(void);
+#endif
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/include/nuttx/usb/usbdev.h b/include/nuttx/usb/usbdev.h
index 9c2dc3f9b6..927d7b034e 100644
--- a/include/nuttx/usb/usbdev.h
+++ b/include/nuttx/usb/usbdev.h
@@ -168,6 +168,28 @@
 
 /* USB Controller Structures ************************************************/
 
+struct usbdev_strdesc_s
+{
+  uint8_t         id;
+  FAR const char *string;
+};
+
+struct usbdev_strdescs_s
+{
+  uint16_t                            language;
+  FAR const struct usbdev_strdesc_s  *strdesc;
+};
+
+struct usbdev_devdescs_s
+{
+  FAR const struct usb_cfgdesc_s     *cfgdesc;
+  FAR const struct usbdev_strdescs_s *strdescs;
+  FAR const struct usb_devdesc_s     *devdesc;
+#ifdef CONFIG_USBDEV_DUALSPEED
+  FAR const struct usb_qualdesc_s    *qualdesc;
+#endif
+};
+
 /* usbdev_devinfo_s - describes the low level bindings of an usb device */
 
 struct usbdev_devinfo_s