From 1be465a41903d39a86d75b5dc031093658095bd1 Mon Sep 17 00:00:00 2001
From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>
Date: Tue, 27 Sep 2011 20:11:14 +0000
Subject: [PATCH] Separate all CDC ACM descriptors into a separate C file

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3982 42af7a65-404d-4744-a932-0658087f49c3
---
 drivers/usbdev/Make.defs          |   2 +-
 drivers/usbdev/cdc_serdesc.c      | 591 ++++++++++++++++++++++++++++++
 drivers/usbdev/cdc_serial.c       | 541 +--------------------------
 drivers/usbdev/usbdev_composite.c |  85 +++++
 drivers/usbdev/usbdev_composite.h |  86 +++++
 5 files changed, 780 insertions(+), 525 deletions(-)
 create mode 100644 drivers/usbdev/cdc_serdesc.c
 create mode 100644 drivers/usbdev/usbdev_composite.c
 create mode 100644 drivers/usbdev/usbdev_composite.h

diff --git a/drivers/usbdev/Make.defs b/drivers/usbdev/Make.defs
index 1a0a8d4124..6771c2fb91 100644
--- a/drivers/usbdev/Make.defs
+++ b/drivers/usbdev/Make.defs
@@ -42,7 +42,7 @@ ifeq ($(CONFIG_USBSER),y)
 endif
 
 ifeq ($(CONFIG_CDCSER),y)
-  CSRCS  += cdc_serial.c
+  CSRCS  += cdc_serial.c cdc_serdesc.c
 endif
 
 ifeq ($(CONFIG_USBSTRG),y)
diff --git a/drivers/usbdev/cdc_serdesc.c b/drivers/usbdev/cdc_serdesc.c
new file mode 100644
index 0000000000..03bac3006f
--- /dev/null
+++ b/drivers/usbdev/cdc_serdesc.c
@@ -0,0 +1,591 @@
+/****************************************************************************
+ * drivers/usbdev/cdc_serdesc.c
+ *
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/cdc.h>
+#include <nuttx/usb/cdc_serial.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include "cdc_serial.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+/* Descriptors **************************************************************/
+/* These settings are not modifiable via the NuttX configuration */
+
+#define CDC_VERSIONNO              0x0110   /* CDC version number 1.10 (BCD) */
+
+/* Device descriptor values */
+
+#define CDCSER_VERSIONNO           (0x0101) /* Device version number 1.1 (BCD) */
+#define CDCSER_NCONFIGS            (1)      /* Number of configurations supported */
+
+/* Configuration descriptor values */
+
+#define CDCSER_NINTERFACES         (2)      /* Number of interfaces in the configuration */
+
+/* String language */
+
+#define CDCSER_STR_LANGUAGE        (0x0409) /* en-us */
+
+/* Descriptor strings */
+
+#define CDCSER_MANUFACTURERSTRID   (1)
+#define CDCSER_PRODUCTSTRID        (2)
+#define CDCSER_SERIALSTRID         (3)
+#define CDCSER_CONFIGSTRID         (4)
+#define CDCSER_NOTIFSTRID          (5)
+#define CDCSER_DATAIFSTRID         (6)
+
+/* Number of individual descriptors in the configuration descriptor */
+
+#define CDCSER_CFGGROUP_SIZE       (9)
+
+/* The size of the config descriptor: (9 + 2*9 + 3*7 + 4 + 5 + 5) = 62 */
+
+#define SIZEOF_CDCSER_CFGDESC \
+   (USB_SIZEOF_CFGDESC + 2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Describes one description in the group of descriptors forming the
+ * total configuration descriptor.
+ */
+
+struct cfgdecsc_group_s
+{
+  uint16_t  descsize; /* Size of the descriptor in bytes */
+  uint16_t  hsepsize; /* High speed max packet size */
+  FAR void *desc;     /* A pointer to the descriptor */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* USB descriptor templates these will be copied and modified **************/
+
+static const struct usb_devdesc_s g_devdesc =
+{
+  USB_SIZEOF_DEVDESC,                           /* len */
+  USB_DESC_TYPE_DEVICE,                         /* type */
+  {                                             /* usb */
+    LSBYTE(0x0200),
+    MSBYTE(0x0200)
+  },
+  USB_CLASS_CDC,                                /* class */
+  CDC_SUBCLASS_NONE,                            /* subclass */
+  CDC_PROTO_NONE,                               /* protocol */
+  CONFIG_CDCSER_EP0MAXPACKET,                   /* maxpacketsize */
+  {
+    LSBYTE(CONFIG_CDCSER_VENDORID),             /* vendor */
+    MSBYTE(CONFIG_CDCSER_VENDORID)
+  },
+  {
+    LSBYTE(CONFIG_CDCSER_PRODUCTID),            /* product */
+    MSBYTE(CONFIG_CDCSER_PRODUCTID)
+  },
+  {
+    LSBYTE(CDCSER_VERSIONNO),                   /* device */
+    MSBYTE(CDCSER_VERSIONNO)
+  },
+  CDCSER_MANUFACTURERSTRID,                     /* imfgr */
+  CDCSER_PRODUCTSTRID,                          /* iproduct */
+  CDCSER_SERIALSTRID,                           /* serno */
+  CDCSER_NCONFIGS                               /* nconfigs */
+};
+
+/* Configuration descriptor */
+
+static const struct usb_cfgdesc_s g_cfgdesc =
+{
+  USB_SIZEOF_CFGDESC,                           /* len */
+  USB_DESC_TYPE_CONFIG,                         /* type */
+  {
+    LSBYTE(SIZEOF_CDCSER_CFGDESC),              /* LS totallen */
+    MSBYTE(SIZEOF_CDCSER_CFGDESC)               /* MS totallen */
+  },
+  CDCSER_NINTERFACES,                           /* ninterfaces */
+  CDCSER_CONFIGID,                              /* cfgvalue */
+  CDCSER_CONFIGSTRID,                           /* icfg */
+  USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
+  (CONFIG_USBDEV_MAXPOWER + 1) / 2              /* mxpower */
+};
+
+/* Notification interface */
+
+static const struct usb_ifdesc_s g_notifdesc =
+{
+  USB_SIZEOF_IFDESC,                            /* len */
+  USB_DESC_TYPE_INTERFACE,                      /* type */
+  0,                                            /* ifno */
+  0,                                            /* alt */
+  1,                                            /* neps */
+  USB_CLASS_CDC,                                /* class */
+  CDC_SUBCLASS_ACM,                             /* subclass */
+  CDC_PROTO_ATM,                                /* proto */
+#ifdef CONFIG_CDCSER_NOTIFSTR
+  CDCSER_NOTIFSTRID                             /* iif */
+#else
+  0                                             /* iif */
+#endif
+};
+
+/* Header functional descriptor */
+
+static const struct cdc_hdr_funcdesc_s g_funchdr =
+{
+  SIZEOF_HDR_FUNCDESC,                          /* size */
+  USB_DESC_TYPE_CSINTERFACE,                    /* type */
+  CDC_DSUBTYPE_HDR,                             /* subtype */
+  {
+    LSBYTE(CDC_VERSIONNO),                      /* LS cdc */
+    MSBYTE(CDC_VERSIONNO)                       /* MS cdc */
+  }
+};
+ 
+/* ACM functional descriptor */
+
+static const struct cdc_acm_funcdesc_s g_acmfunc =
+{
+  SIZEOF_ACM_FUNCDESC,                          /* size */
+  USB_DESC_TYPE_CSINTERFACE,                    /* type */
+  CDC_DSUBTYPE_ACM,                             /* subtype */
+  0x06                                          /* caps */
+};
+
+/* Union functional descriptor */
+
+static const struct cdc_union_funcdesc_s g_unionfunc =
+{
+  SIZEOF_UNION_FUNCDESC(1),                     /* size */
+  USB_DESC_TYPE_CSINTERFACE,                    /* type */
+  CDC_DSUBTYPE_UNION,                           /* subtype */
+  0,                                            /* master */
+  {1}                                           /* slave[0] */
+};
+
+/* Interrupt IN endpoint descriptor */
+
+static const struct usb_epdesc_s g_epintindesc =
+{
+  USB_SIZEOF_EPDESC,                            /* len */
+  USB_DESC_TYPE_ENDPOINT,                       /* type */
+  CDCSER_EPINTIN_ADDR,                          /* addr */
+  CDCSER_EPINTIN_ATTR,                          /* attr */
+  {
+    LSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE),       /* maxpacket (full speed) */
+    MSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE)
+  },
+  0xff                                          /* interval */
+};
+
+/* Data interface descriptor */
+
+static const struct usb_ifdesc_s g_dataifdesc =
+{
+  USB_SIZEOF_IFDESC,                            /* len */
+  USB_DESC_TYPE_INTERFACE,                      /* type */
+  1,                                            /* ifno */
+  0,                                            /* alt */
+  2,                                            /* neps */
+  USB_CLASS_CDC_DATA,                           /* class */
+  CDC_DATA_SUBCLASS_NONE,                       /* subclass */
+  CDC_DATA_PROTO_NONE,                          /* proto */
+#ifdef CONFIG_CDCSER_DATAIFSTR
+  CDCSER_DATAIFSTRID                            /* iif */
+#else
+  0                                             /* iif */
+#endif
+};
+
+/* Bulk OUT endpoint descriptor */
+
+static const struct usb_epdesc_s g_epbulkoutdesc =
+{
+  USB_SIZEOF_EPDESC,                            /* len */
+  USB_DESC_TYPE_ENDPOINT,                       /* type */
+  CDCSER_EPOUTBULK_ADDR,                        /* addr */
+  CDCSER_EPOUTBULK_ATTR,                        /* attr */
+  {
+    LSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE),     /* maxpacket (full speed) */
+    MSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE)
+  },
+  1                                             /* interval */
+};
+
+/* Bulk IN endpoint descriptor */
+
+static const struct usb_epdesc_s g_epbulkindesc =
+{
+  USB_SIZEOF_EPDESC,                            /* len */
+  USB_DESC_TYPE_ENDPOINT,                       /* type */
+  CDCSER_EPINBULK_ADDR,                         /* addr */
+  CDCSER_EPINBULK_ATTR,                         /* attr */
+  {
+    LSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE),      /* maxpacket (full speed) */
+    MSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE)
+  },
+  1                                             /* interval */
+};
+
+/* The components of the the configuration descriptor are maintained as
+ * a collection of separate descriptor structure coordinated by the
+ * following array.  These descriptors could have been combined into
+ * one larger "super" configuration descriptor structure.  However, I
+ * have concerns about compiler-dependent alignment and packing.  Since
+ * the individual structures consist only of byte types, alignment and
+ * packing is not an issue.  And since the are concatentated at run time
+ * instead of compile time, there should no issues there either.
+ */
+
+static const struct cfgdecsc_group_s g_cfggroup[CDCSER_CFGGROUP_SIZE] = {
+  {
+    USB_SIZEOF_CFGDESC,            /* 1. Configuration descriptor */
+    0,
+    (FAR void *)&g_cfgdesc
+  },
+  {
+    USB_SIZEOF_IFDESC,             /* 2. Notification interface */
+    0,
+    (FAR void *)&g_notifdesc
+  },
+  {
+    SIZEOF_HDR_FUNCDESC,           /* 3. Header functional descriptor */
+    0,
+    (FAR void *)&g_funchdr
+  },
+  {
+    SIZEOF_ACM_FUNCDESC,           /* 4. ACM functional descriptor */
+    0,
+    (FAR void *)&g_acmfunc
+  },
+  {
+    SIZEOF_UNION_FUNCDESC(1),      /* 5. Union functional descriptor */
+    0,
+    (FAR void *)&g_unionfunc
+  },
+  {
+    USB_SIZEOF_EPDESC,             /* 6. Interrupt IN endpoint descriptor */
+    CONFIG_CDCSER_EPINTIN_HSSIZE,
+    (FAR void *)&g_epintindesc
+  },
+  {
+    USB_SIZEOF_IFDESC,             /* 7. Data interface descriptor */
+    0,
+    (FAR void *)&g_dataifdesc
+  },
+  {
+    USB_SIZEOF_EPDESC,             /* 8. Bulk OUT endpoint descriptor */
+    CONFIG_CDCSER_EPBULKOUT_HSSIZE,
+    (FAR void *)&g_epbulkoutdesc
+  },
+  {
+    USB_SIZEOF_EPDESC,             /* 9. Bulk OUT endpoint descriptor */
+    CONFIG_CDCSER_EPBULKIN_HSSIZE,
+    (FAR void *)&g_epbulkindesc
+  }
+};
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+static const struct usb_qualdesc_s g_qualdesc =
+{
+  USB_SIZEOF_QUALDESC,                          /* len */
+  USB_DESC_TYPE_DEVICEQUALIFIER,                /* type */
+  {                                             /* usb */
+     LSBYTE(0x0200),
+     MSBYTE(0x0200)
+  },
+  USB_CLASS_VENDOR_SPEC,                        /* class */
+  0,                                            /* subclass */
+  0,                                            /* protocol */
+  CONFIG_CDCSER_EP0MAXPACKET,                   /* mxpacketsize */
+  CDCSER_NCONFIGS,                              /* nconfigs */
+  0,                                            /* reserved */
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: usbclass_mkstrdesc
+ *
+ * Description:
+ *   Construct a string descriptor
+ *
+ ****************************************************************************/
+
+int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
+{
+  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;
+        strdesc->data[0] = LSBYTE(CDCSER_STR_LANGUAGE);
+        strdesc->data[1] = MSBYTE(CDCSER_STR_LANGUAGE);
+        return 4;
+      }
+
+    case CDCSER_MANUFACTURERSTRID:
+      str = CONFIG_CDCSER_VENDORSTR;
+      break;
+
+    case CDCSER_PRODUCTSTRID:
+      str = CONFIG_CDCSER_PRODUCTSTR;
+      break;
+
+    case CDCSER_SERIALSTRID:
+      str = CONFIG_CDCSER_SERIALSTR;
+      break;
+
+    case CDCSER_CONFIGSTRID:
+      str = CONFIG_CDCSER_CONFIGSTR;
+      break;
+
+#ifdef CONFIG_CDCSER_NOTIFSTR
+    case CDCSER_NOTIFSTRID:
+      str = CONFIG_CDCSER_NOTIFSTR;
+      break;
+#endif
+
+#ifdef CONFIG_CDCSER_DATAIFSTR
+    case CDCSER_DATAIFSTRID:
+      str = CONFIG_CDCSER_DATAIFSTR;
+      break;
+#endif
+
+    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)
+     {
+       strdesc->data[ndata]   = str[i];
+       strdesc->data[ndata+1] = 0;
+     }
+
+   strdesc->len  = ndata+2;
+   strdesc->type = USB_DESC_TYPE_STRING;
+   return strdesc->len;
+}
+
+/****************************************************************************
+ * Name: usbclass_getepdesc
+ *
+ * Description:
+ *   Return a pointer to the raw device descriptor
+ *
+ ****************************************************************************/
+
+FAR const struct usb_devdesc_s *usbclass_getdevdesc(void)
+{
+  return &g_devdesc;
+}
+
+/****************************************************************************
+ * Name: usbclass_getepdesc
+ *
+ * Description:
+ *   Return a pointer to the raw endpoint struct (used for configuring
+ *   endpoints)
+ *
+ ****************************************************************************/
+
+FAR const struct usb_epdesc_s *usbclass_getepdesc(enum cdcser_epdesc_e epid)
+{
+  switch (epid)
+    {
+      case CDCSER_EPINTIN:       /* Interrupt IN endpoint */
+        return &g_epintindesc;
+
+      case CDCSER_EPBULKOUT:     /* Bulk OUT endpoint */
+        return &g_epbulkoutdesc;
+
+      case CDCSER_EPBULKIN:      /* Bulk IN endpoint */
+        return &g_epbulkindesc;
+
+      default:
+        return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: usbclass_mkepdesc
+ *
+ * Description:
+ *   Construct the endpoint descriptor using the correct max packet size.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+void usbclass_mkepdesc(num cdcser_epdesc_e epid,
+                       uint16_t mxpacket,
+                       FAR struct usb_epdesc_s *outdesc)
+{
+  FAR const struct usb_epdesc_s *indesc;
+
+  /* Copy the "canned" descriptor */
+
+  indesc = usbclass_getepdesc(epid)
+  memcpy(outdesc, indesc, USB_SIZEOF_EPDESC);
+
+  /* Then add the correct max packet size */
+
+  outdesc->mxpacketsize[0] = LSBYTE(mxpacket);
+  outdesc->mxpacketsize[1] = MSBYTE(mxpacket);
+}
+#endif
+
+/****************************************************************************
+ * Name: usbclass_mkcfgdesc
+ *
+ * Description:
+ *   Construct the configuration descriptor
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type)
+#else
+int16_t usbclass_mkcfgdesc(FAR uint8_t *buf)
+#endif
+{
+  FAR const struct cfgdecsc_group_s *group;
+  FAR uint8_t *dest = buf;
+  int i;
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+  bool hispeed = (speed == USB_SPEED_HIGH);
+
+  /* Check for switches between high and full speed */
+
+  if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
+    {
+      hispeed = !hispeed;
+    }
+#endif
+
+  /* Copy all of the descriptors in the group */
+
+  for (i = 0, dest = buf; i < CDCSER_CFGGROUP_SIZE; i++)
+    {
+      group = &g_cfggroup[i];
+
+      /* The "canned" descriptors all have full speed endpoint maxpacket
+       * sizes. If high speed is selected, we will have to change the
+       * endpoint maxpacket size.
+       *
+       * Is there a alternative high speed maxpacket size in the table?
+       * If so, that is sufficient proof that the descriptor that we
+       * just copied is an endpoint descriptor and needs the fixup
+       */
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+      if (highspeed && group->hsepsize != 0)
+        {
+          usbclass_mkepdesc(group->desc, group->hsepsize,
+                            (FAR struct usb_epdesc_s*)dest);
+        }
+      else
+#endif
+      /* Copy the "canned" descriptor with the full speed max packet
+       * size
+       */
+
+        {
+          memcpy(dest, group->desc, group->descsize);
+        }
+
+      /* Advance to the destination location for the next descriptor */
+
+      dest += group->descsize;
+    }
+
+  return SIZEOF_CDCSER_CFGDESC;
+}
+
+/****************************************************************************
+ * Name: usbclass_getqualdesc
+ *
+ * Description:
+ *   Return a pointer to the raw qual descriptor
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+FAR const struct usb_qualdesc_s *usbclass_getqualdesc(void)
+{
+  return &g_qualdesc;
+}
+#endif
diff --git a/drivers/usbdev/cdc_serial.c b/drivers/usbdev/cdc_serial.c
index a4b549d27e..80a61e1f04 100644
--- a/drivers/usbdev/cdc_serial.c
+++ b/drivers/usbdev/cdc_serial.c
@@ -61,91 +61,11 @@
 #include <nuttx/usb/cdc_serial.h>
 #include <nuttx/usb/usbdev_trace.h>
 
+#include "cdc_serial.h"
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
-/* Descriptors ****************************************************************/
-/* These settings are not modifiable via the NuttX configuration */
-
-#define CDC_VERSIONNO              0x0110   /* CDC version number 1.10 (BCD) */
-#define CDCSER_CONFIGIDNONE        (0)      /* Config ID means to return to address mode */
-#define CDCSER_INTERFACEID         (0)
-#define CDCSER_ALTINTERFACEID      (0)
-
-/* Device descriptor values */
-
-#define CDCSER_VERSIONNO           (0x0101) /* Device version number 1.1 (BCD) */
-#define CDCSER_NCONFIGS            (1)      /* Number of configurations supported */
-
-/* Configuration descriptor values */
-
-#define CDCSER_NINTERFACES         (2)      /* Number of interfaces in the configuration */
-#define CDCSER_CONFIGID            (1)      /* The only supported configuration ID */
-
-/* Endpoint configuration */
-
-#define CDCSER_EPINTIN_ADDR        (USB_DIR_IN|CONFIG_CDCSER_EPINTIN)
-#define CDCSER_EPINTIN_ATTR        (USB_EP_ATTR_XFER_INT)
-
-#define CDCSER_EPOUTBULK_ADDR      (CONFIG_CDCSER_EPBULKOUT)
-#define CDCSER_EPOUTBULK_ATTR      (USB_EP_ATTR_XFER_BULK)
-
-#define CDCSER_EPINBULK_ADDR       (USB_DIR_IN|CONFIG_CDCSER_EPBULKIN)
-#define CDCSER_EPINBULK_ATTR       (USB_EP_ATTR_XFER_BULK)
-
-/* String language */
-
-#define CDCSER_STR_LANGUAGE        (0x0409) /* en-us */
-
-/* Descriptor strings */
-
-#define CDCSER_MANUFACTURERSTRID   (1)
-#define CDCSER_PRODUCTSTRID        (2)
-#define CDCSER_SERIALSTRID         (3)
-#define CDCSER_CONFIGSTRID         (4)
-#define CDCSER_NOTIFSTRID          (5)
-#define CDCSER_DATAIFSTRID         (6)
-
-/* Number of individual descriptors in the configuration descriptor */
-
-#define CDCSER_CFGGROUP_SIZE       (9)
-
-/* The size of the config descriptor: (9 + 2*9 + 3*7 + 4 + 5 + 5) = 62 */
-
-#define SIZEOF_CDCSER_CFGDESC \
-   (USB_SIZEOF_CFGDESC + 2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
-
-/* Buffer big enough for any of our descriptors (the config descriptor is the
- * biggest).
- */
-
-#define CDCSER_MXDESCLEN           (64)
-
-/* Misc Macros ****************************************************************/
-/* min/max macros */
-
-#ifndef min
-#  define min(a,b) ((a)<(b)?(a):(b))
-#endif
-
-#ifndef max
-#  define max(a,b) ((a)>(b)?(a):(b))
-#endif
-
-/* Trace values *************************************************************/
-
-#define CDCSER_CLASSAPI_SETUP       TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SETUP)
-#define CDCSER_CLASSAPI_SHUTDOWN    TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SHUTDOWN)
-#define CDCSER_CLASSAPI_ATTACH      TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_ATTACH)
-#define CDCSER_CLASSAPI_DETACH      TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_DETACH)
-#define CDCSER_CLASSAPI_IOCTL       TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_IOCTL)
-#define CDCSER_CLASSAPI_RECEIVE     TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RECEIVE)
-#define CDCSER_CLASSAPI_RXINT       TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXINT)
-#define CDCSER_CLASSAPI_RXAVAILABLE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXAVAILABLE)
-#define CDCSER_CLASSAPI_SEND        TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SEND)
-#define CDCSER_CLASSAPI_TXINT       TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXINT)
-#define CDCSER_CLASSAPI_TXREADY     TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXREADY)
-#define CDCSER_CLASSAPI_TXEMPTY     TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXEMPTY)
 
 /****************************************************************************
  * Private Types
@@ -212,17 +132,6 @@ struct usbser_alloc_s
   struct usbser_driver_s drvr;
 };
 
-/* Describes one description in the group of descriptors forming the
- * total configuration descriptor.
- */
-
-struct cfgdecsc_group_s
-{
-  uint16_t  descsize; /* Size of the descriptor in bytes */
-  uint16_t  hsepsize; /* High speed max packet size */
-  FAR void *desc;     /* A pointer to the descriptor */
-};
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -244,19 +153,10 @@ static void    usbclass_freereq(FAR struct usbdev_ep_s *ep,
 
 /* Configuration ***********************************************************/
 
-static int     usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-#ifdef CONFIG_USBDEV_DUALSPEED
-static void    usbclass_mkepdesc(FAR const struct usb_epdesc_s *indesc,
-                 uint16_t mxpacket, FAR struct usb_epdesc_s *outdesc);
-static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf);
-#endif
 static void    usbclass_resetconfig(FAR struct usbser_dev_s *priv);
 #ifdef CONFIG_USBDEV_DUALSPEED
 static int     usbclass_epconfigure(FAR struct usbdev_ep_s *ep,
-                 FAR const struct usb_epdesc_s *indesc, uint16_t mxpacket,
-                 bool last);
+                 enum cdcser_epdesc_e epid, uint16_t mxpacket, bool last);
 #endif
 static int     usbclass_setconfig(FAR struct usbser_dev_s *priv,
                  uint8_t config);
@@ -324,248 +224,6 @@ static const struct uart_ops_s g_uartops =
   usbser_txempty        /* txempty */
 };
 
-/* USB descriptor templates these will be copied and modified **************/
-
-static const struct usb_devdesc_s g_devdesc =
-{
-  USB_SIZEOF_DEVDESC,                           /* len */
-  USB_DESC_TYPE_DEVICE,                         /* type */
-  {                                             /* usb */
-    LSBYTE(0x0200),
-    MSBYTE(0x0200)
-  },
-  USB_CLASS_CDC,                                /* class */
-  CDC_SUBCLASS_NONE,                            /* subclass */
-  CDC_PROTO_NONE,                               /* protocol */
-  CONFIG_CDCSER_EP0MAXPACKET,                   /* maxpacketsize */
-  {
-    LSBYTE(CONFIG_CDCSER_VENDORID),             /* vendor */
-    MSBYTE(CONFIG_CDCSER_VENDORID)
-  },
-  {
-    LSBYTE(CONFIG_CDCSER_PRODUCTID),            /* product */
-    MSBYTE(CONFIG_CDCSER_PRODUCTID)
-  },
-  {
-    LSBYTE(CDCSER_VERSIONNO),                   /* device */
-    MSBYTE(CDCSER_VERSIONNO)
-  },
-  CDCSER_MANUFACTURERSTRID,                     /* imfgr */
-  CDCSER_PRODUCTSTRID,                          /* iproduct */
-  CDCSER_SERIALSTRID,                           /* serno */
-  CDCSER_NCONFIGS                               /* nconfigs */
-};
-
-/* Configuration descriptor */
-
-static const struct usb_cfgdesc_s g_cfgdesc =
-{
-  USB_SIZEOF_CFGDESC,                           /* len */
-  USB_DESC_TYPE_CONFIG,                         /* type */
-  {
-    LSBYTE(SIZEOF_CDCSER_CFGDESC),              /* LS totallen */
-    MSBYTE(SIZEOF_CDCSER_CFGDESC)               /* MS totallen */
-  },
-  CDCSER_NINTERFACES,                           /* ninterfaces */
-  CDCSER_CONFIGID,                              /* cfgvalue */
-  CDCSER_CONFIGSTRID,                           /* icfg */
-  USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
-  (CONFIG_USBDEV_MAXPOWER + 1) / 2              /* mxpower */
-};
-
-/* Notification interface */
-
-static const struct usb_ifdesc_s g_notifdesc =
-{
-  USB_SIZEOF_IFDESC,                            /* len */
-  USB_DESC_TYPE_INTERFACE,                      /* type */
-  0,                                            /* ifno */
-  0,                                            /* alt */
-  1,                                            /* neps */
-  USB_CLASS_CDC,                                /* class */
-  CDC_SUBCLASS_ACM,                             /* subclass */
-  CDC_PROTO_ATM,                                /* proto */
-#ifdef CONFIG_CDCSER_NOTIFSTR
-  CDCSER_NOTIFSTRID                             /* iif */
-#else
-  0                                             /* iif */
-#endif
-};
-
-/* Header functional descriptor */
-
-static const struct cdc_hdr_funcdesc_s g_funchdr =
-{
-  SIZEOF_HDR_FUNCDESC,                          /* size */
-  USB_DESC_TYPE_CSINTERFACE,                    /* type */
-  CDC_DSUBTYPE_HDR,                             /* subtype */
-  {
-    LSBYTE(CDC_VERSIONNO),                      /* LS cdc */
-    MSBYTE(CDC_VERSIONNO)                       /* MS cdc */
-  }
-};
- 
-/* ACM functional descriptor */
-
-static const struct cdc_acm_funcdesc_s g_acmfunc =
-{
-  SIZEOF_ACM_FUNCDESC,                          /* size */
-  USB_DESC_TYPE_CSINTERFACE,                    /* type */
-  CDC_DSUBTYPE_ACM,                             /* subtype */
-  0x06                                          /* caps */
-};
-
-/* Union functional descriptor */
-
-static const struct cdc_union_funcdesc_s g_unionfunc =
-{
-  SIZEOF_UNION_FUNCDESC(1),                     /* size */
-  USB_DESC_TYPE_CSINTERFACE,                    /* type */
-  CDC_DSUBTYPE_UNION,                           /* subtype */
-  0,                                            /* master */
-  {1}                                           /* slave[0] */
-};
-
-/* Interrupt IN endpoint descriptor */
-
-static const struct usb_epdesc_s g_epintindesc =
-{
-  USB_SIZEOF_EPDESC,                            /* len */
-  USB_DESC_TYPE_ENDPOINT,                       /* type */
-  CDCSER_EPINTIN_ADDR,                          /* addr */
-  CDCSER_EPINTIN_ATTR,                          /* attr */
-  {
-    LSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE),       /* maxpacket (full speed) */
-    MSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE)
-  },
-  0xff                                          /* interval */
-};
-
-/* Data interface descriptor */
-
-static const struct usb_ifdesc_s g_dataifdesc =
-{
-  USB_SIZEOF_IFDESC,                            /* len */
-  USB_DESC_TYPE_INTERFACE,                      /* type */
-  1,                                            /* ifno */
-  0,                                            /* alt */
-  2,                                            /* neps */
-  USB_CLASS_CDC_DATA,                           /* class */
-  CDC_DATA_SUBCLASS_NONE,                       /* subclass */
-  CDC_DATA_PROTO_NONE,                          /* proto */
-#ifdef CONFIG_CDCSER_DATAIFSTR
-  CDCSER_DATAIFSTRID                            /* iif */
-#else
-  0                                             /* iif */
-#endif
-};
-
-/* Bulk OUT endpoint descriptor */
-
-static const struct usb_epdesc_s g_epbulkoutdesc =
-{
-  USB_SIZEOF_EPDESC,                            /* len */
-  USB_DESC_TYPE_ENDPOINT,                       /* type */
-  CDCSER_EPOUTBULK_ADDR,                        /* addr */
-  CDCSER_EPOUTBULK_ATTR,                        /* attr */
-  {
-    LSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE),     /* maxpacket (full speed) */
-    MSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE)
-  },
-  1                                             /* interval */
-};
-
-/* Bulk IN endpoint descriptor */
-
-static const struct usb_epdesc_s g_epbulkindesc =
-{
-  USB_SIZEOF_EPDESC,                            /* len */
-  USB_DESC_TYPE_ENDPOINT,                       /* type */
-  CDCSER_EPINBULK_ADDR,                         /* addr */
-  CDCSER_EPINBULK_ATTR,                         /* attr */
-  {
-    LSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE),      /* maxpacket (full speed) */
-    MSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE)
-  },
-  1                                             /* interval */
-};
-
-/* The components of the the configuration descriptor are maintained as
- * a collection of separate descriptor structure coordinated by the
- * following array.  These descriptors could have been combined into
- * one larger "super" configuration descriptor structure.  However, I
- * have concerns about compiler-dependent alignment and packing.  Since
- * the individual structures consist only of byte types, alignment and
- * packing is not an issue.  And since the are concatentated at run time
- * instead of compile time, there should no issues there either.
- */
-
-static const struct cfgdecsc_group_s g_cfggroup[CDCSER_CFGGROUP_SIZE] = {
-  {
-    USB_SIZEOF_CFGDESC,            /* 1. Configuration descriptor */
-    0,
-    (FAR void *)&g_cfgdesc
-  },
-  {
-    USB_SIZEOF_IFDESC,             /* 2. Notification interface */
-    0,
-    (FAR void *)&g_notifdesc
-  },
-  {
-    SIZEOF_HDR_FUNCDESC,           /* 3. Header functional descriptor */
-    0,
-    (FAR void *)&g_funchdr
-  },
-  {
-    SIZEOF_ACM_FUNCDESC,           /* 4. ACM functional descriptor */
-    0,
-    (FAR void *)&g_acmfunc
-  },
-  {
-    SIZEOF_UNION_FUNCDESC(1),      /* 5. Union functional descriptor */
-    0,
-    (FAR void *)&g_unionfunc
-  },
-  {
-    USB_SIZEOF_EPDESC,             /* 6. Interrupt IN endpoint descriptor */
-    CONFIG_CDCSER_EPINTIN_HSSIZE,
-    (FAR void *)&g_epintindesc
-  },
-  {
-    USB_SIZEOF_IFDESC,             /* 7. Data interface descriptor */
-    0,
-    (FAR void *)&g_dataifdesc
-  },
-  {
-    USB_SIZEOF_EPDESC,             /* 8. Bulk OUT endpoint descriptor */
-    CONFIG_CDCSER_EPBULKOUT_HSSIZE,
-    (FAR void *)&g_epbulkoutdesc
-  },
-  {
-    USB_SIZEOF_EPDESC,             /* 9. Bulk OUT endpoint descriptor */
-    CONFIG_CDCSER_EPBULKIN_HSSIZE,
-    (FAR void *)&g_epbulkindesc
-  }
-};
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static const struct usb_qualdesc_s g_qualdesc =
-{
-  USB_SIZEOF_QUALDESC,                          /* len */
-  USB_DESC_TYPE_DEVICEQUALIFIER,                /* type */
-  {                                             /* usb */
-     LSBYTE(0x0200),
-     MSBYTE(0x0200)
-  },
-  USB_CLASS_VENDOR_SPEC,                        /* class */
-  0,                                            /* subclass */
-  0,                                            /* protocol */
-  CONFIG_CDCSER_EP0MAXPACKET,                   /* mxpacketsize */
-  CDCSER_NCONFIGS,                              /* nconfigs */
-  0,                                            /* reserved */
-};
-#endif
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -876,174 +534,6 @@ static void usbclass_freereq(FAR struct usbdev_ep_s *ep,
     }
 }
 
-/****************************************************************************
- * Name: usbclass_mkstrdesc
- *
- * Description:
- *   Construct a string descriptor
- *
- ****************************************************************************/
-
-static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
-{
-  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;
-        strdesc->data[0] = LSBYTE(CDCSER_STR_LANGUAGE);
-        strdesc->data[1] = MSBYTE(CDCSER_STR_LANGUAGE);
-        return 4;
-      }
-
-    case CDCSER_MANUFACTURERSTRID:
-      str = CONFIG_CDCSER_VENDORSTR;
-      break;
-
-    case CDCSER_PRODUCTSTRID:
-      str = CONFIG_CDCSER_PRODUCTSTR;
-      break;
-
-    case CDCSER_SERIALSTRID:
-      str = CONFIG_CDCSER_SERIALSTR;
-      break;
-
-    case CDCSER_CONFIGSTRID:
-      str = CONFIG_CDCSER_CONFIGSTR;
-      break;
-
-#ifdef CONFIG_CDCSER_NOTIFSTR
-    case CDCSER_NOTIFSTRID:
-      str = CONFIG_CDCSER_NOTIFSTR;
-      break;
-#endif
-
-#ifdef CONFIG_CDCSER_DATAIFSTR
-    case CDCSER_DATAIFSTRID:
-      str = CONFIG_CDCSER_DATAIFSTR;
-      break;
-#endif
-
-    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)
-     {
-       strdesc->data[ndata]   = str[i];
-       strdesc->data[ndata+1] = 0;
-     }
-
-   strdesc->len  = ndata+2;
-   strdesc->type = USB_DESC_TYPE_STRING;
-   return strdesc->len;
-}
-
-/****************************************************************************
- * Name: usbclass_mkepdesc
- *
- * Description:
- *   Construct the endpoint descriptor using the correct max packet size.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static inline void usbclass_mkepdesc(FAR const FAR struct usb_epdesc_s *indesc,
-                                     uint16_t mxpacket,
-                                     FAR struct usb_epdesc_s *outdesc)
-{
-  /* Copy the "canned" descriptor */
-
-  memcpy(outdesc, indesc, USB_SIZEOF_EPDESC);
-
-  /* Then add the correct max packet size */
-
-  outdesc->mxpacketsize[0] = LSBYTE(mxpacket);
-  outdesc->mxpacketsize[1] = MSBYTE(mxpacket);
-}
-#endif
-
-/****************************************************************************
- * Name: usbclass_mkcfgdesc
- *
- * Description:
- *   Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type)
-#else
-static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf)
-#endif
-{
-  FAR const struct cfgdecsc_group_s *group;
-  FAR uint8_t *dest = buf;
-  int i;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-  bool hispeed = (speed == USB_SPEED_HIGH);
-
-  /* Check for switches between high and full speed */
-
-  if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
-    {
-      hispeed = !hispeed;
-    }
-#endif
-
-  /* Copy all of the descriptors in the group */
-
-  for (i = 0, dest = buf; i < CDCSER_CFGGROUP_SIZE; i++)
-    {
-      group = &g_cfggroup[i];
-
-      /* The "canned" descriptors all have full speed endpoint maxpacket
-       * sizes. If high speed is selected, we will have to change the
-       * endpoint maxpacket size.
-       *
-       * Is there a alternative high speed maxpacket size in the table?
-       * If so, that is sufficient proof that the descriptor that we
-       * just copied is an endpoint descriptor and needs the fixup
-       */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-      if (highspeed && group->hsepsize != 0)
-        {
-          usbclass_mkepdesc(group->desc, group->hsepsize,
-                            (FAR struct usb_epdesc_s*)dest);
-        }
-      else
-#endif
-      /* Copy the "canned" descriptor with the full speed max packet
-       * size
-       */
-
-        {
-          memcpy(dest, group->desc, group->descsize);
-        }
-
-      /* Advance to the destination location for the next descriptor */
-
-      dest += group->descsize;
-    }
-
-  return SIZEOF_CDCSER_CFGDESC;
-}
-
 /****************************************************************************
  * Name: usbclass_resetconfig
  *
@@ -1082,11 +572,11 @@ static void usbclass_resetconfig(FAR struct usbser_dev_s *priv)
 
 #ifdef CONFIG_USBDEV_DUALSPEED
 static int usbclass_epconfigure(FAR struct usbdev_ep_s *ep,
-                                FAR const struct usb_epdesc_s *indesc,
-                                uint16_t mxpacket, bool last)
+                                enum cdcser_epdesc_e epid, uint16_t mxpacket,
+                                bool last)
 {
   struct usb_epdesc_s epdesc;
-  usbclass_mkepdesc(indesc, mxpacket, &epdesc);
+  usbclass_mkepdesc(epid, mxpacket, &epdesc);
   return EP_CONFIGURE(ep, &epdesc, last);
 }
 #endif
@@ -1147,13 +637,14 @@ static int usbclass_setconfig(FAR struct usbser_dev_s *priv, uint8_t config)
 #ifdef CONFIG_USBDEV_DUALSPEED
   if (priv->usbdev->speed == USB_SPEED_HIGH)
     {
-      ret = usbclass_epconfigure(priv->epintin, &g_epintindesc,
+      ret = usbclass_epconfigure(priv->epintin, CDCSER_EPINTIN,
                                  CONFIG_CDCSER_EPINTIN_HSSIZE, false);
     }
   else
 #endif
     {
-      ret = EP_CONFIGURE(priv->epintin, &g_epintindesc, false);
+      ret = EP_CONFIGURE(priv->epintin,
+                         usbclass_getepdesc(CDCSER_EPINTIN), false);
     }
 
   if (ret < 0)
@@ -1168,13 +659,14 @@ static int usbclass_setconfig(FAR struct usbser_dev_s *priv, uint8_t config)
 #ifdef CONFIG_USBDEV_DUALSPEED
   if (priv->usbdev->speed == USB_SPEED_HIGH)
     {
-      ret = usbclass_epconfigure(priv->epbulkin, &g_epbulkindesc,
+      ret = usbclass_epconfigure(priv->epbulkin, CDCSER_EPBULKIN,
                                  CONFIG_CDCSER_EPBULKIN_HSSIZE, false);
     }
   else
 #endif
     {
-      ret = EP_CONFIGURE(priv->epbulkin, &g_epbulkindesc, false);
+      ret = EP_CONFIGURE(priv->epbulkin,
+                         usbclass_getepdesc(CDCSER_EPBULKIN), false);
     }
 
   if (ret < 0)
@@ -1190,13 +682,14 @@ static int usbclass_setconfig(FAR struct usbser_dev_s *priv, uint8_t config)
 #ifdef CONFIG_USBDEV_DUALSPEED
   if (priv->usbdev->speed == USB_SPEED_HIGH)
     {
-      ret = usbclass_epconfigure(priv->epbulkout, &g_epbulkoutdesc,
+      ret = usbclass_epconfigure(priv->epbulkout, CDCSER_EPBULKOUT,
                                  CONFIG_CDCSER_EPBULKOUT_HSSIZE, true);
     }
   else
 #endif
     {
-      ret = EP_CONFIGURE(priv->epbulkout, &g_epbulkoutdesc, true);
+      ret = EP_CONFIGURE(priv->epbulkout,
+                         usbclass_getepdesc(CDCSER_EPBULKOUT), true);
     }
 
   if (ret < 0)
@@ -1711,7 +1204,7 @@ static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *
                 case USB_DESC_TYPE_DEVICE:
                   {
                     ret = USB_SIZEOF_DEVDESC;
-                    memcpy(ctrlreq->buf, &g_devdesc, ret);
+                    memcpy(ctrlreq->buf, usbclass_getdevdesc(), ret);
                   }
                   break;
 
@@ -1719,7 +1212,7 @@ static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *
                 case USB_DESC_TYPE_DEVICEQUALIFIER:
                   {
                     ret = USB_SIZEOF_QUALDESC;
-                    memcpy(ctrlreq->buf, &g_qualdesc, ret);
+                    memcpy(ctrlreq->buf, usbclass_getqualdesc(), ret);
                   }
                   break;
 
diff --git a/drivers/usbdev/usbdev_composite.c b/drivers/usbdev/usbdev_composite.c
new file mode 100644
index 0000000000..de531b8a4d
--- /dev/null
+++ b/drivers/usbdev/usbdev_composite.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * drivers/usbdev/usbdev_composite.c
+ *
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/usb/usbdev_trace.h>
+
+#include "usbdev_composite.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/*******************************************************************************
+ * Name: 
+ *
+ * Description:
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ *******************************************************************************/
+
diff --git a/drivers/usbdev/usbdev_composite.h b/drivers/usbdev/usbdev_composite.h
new file mode 100644
index 0000000000..472f523b2e
--- /dev/null
+++ b/drivers/usbdev/usbdev_composite.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * drivers/usbdev/usbdev_composite.h
+ *
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_USBDEV_USBDEV_COMPOSITE_H
+#define __DRIVERS_USBDEV_USBDEV_COMPOSITE_H 1
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <nuttx/usb/usbdev_trace.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_USBDEV_TRACE_NRECORDS
+#  define CONFIG_USBDEV_TRACE_NRECORDS 128
+#endif
+
+#ifndef CONFIG_USBDEV_TRACE_INITIALIDSET
+#  define CONFIG_USBDEV_TRACE_INITIALIDSET 0
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/*******************************************************************************
+ * Name: 
+ *
+ * Description:
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ *******************************************************************************/
+
+#endif /* __DRIVERS_USBDEV_USBDEV_COMPOSITE_H */
-- 
GitLab