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/02/13 10:47:49 UTC

[nuttx] branch master updated: usbdev: fixed DUALSPEED issue for adb/cdcecm/rndis

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 b4aa5b0d0b usbdev: fixed DUALSPEED issue for adb/cdcecm/rndis
b4aa5b0d0b is described below

commit b4aa5b0d0b461c0a95eef52e39dfbf340cbd1913
Author: zhangyuan21 <zh...@xiaomi.com>
AuthorDate: Wed Feb 1 21:11:54 2023 +0800

    usbdev: fixed DUALSPEED issue for adb/cdcecm/rndis
    
    Signed-off-by: zhangyuan21 <zh...@xiaomi.com>
---
 drivers/usbdev/adb.c    |  4 ++--
 drivers/usbdev/cdcecm.c | 32 ++++++++++++++++++++++++++------
 drivers/usbdev/rndis.c  | 41 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/drivers/usbdev/adb.c b/drivers/usbdev/adb.c
index 4c87042553..490819b983 100644
--- a/drivers/usbdev/adb.c
+++ b/drivers/usbdev/adb.c
@@ -1189,11 +1189,11 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
                     }
                     break;
 
+#ifdef CONFIG_USBDEV_DUALSPEED
                   case USB_DESC_TYPE_DEVICEQUALIFIER:
                     break;
                   case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-                    break;
-
+#endif /* CONFIG_USBDEV_DUALSPEED */
                   /* If the serial device is used in as part of a composite
                    * device, then the configuration descriptor is provided by
                    * logic in the composite device implementation.
diff --git a/drivers/usbdev/cdcecm.c b/drivers/usbdev/cdcecm.c
index a3b9b0c3ea..0f8203c3f2 100644
--- a/drivers/usbdev/cdcecm.c
+++ b/drivers/usbdev/cdcecm.c
@@ -1353,11 +1353,29 @@ static void cdcecm_mkepdesc(int epidx,
  *
  ****************************************************************************/
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc,
+                                FAR struct usbdev_devinfo_s *devinfo,
+                                uint8_t speed, uint8_t type)
+#else
 static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc,
                                 FAR struct usbdev_devinfo_s *devinfo)
+#endif
 {
   FAR struct usb_cfgdesc_s *cfgdesc = NULL;
   int16_t len = 0;
+  bool is_high_speed = false;
+
+#ifdef CONFIG_USBDEV_DUALSPEED
+  is_high_speed = (speed == USB_SPEED_HIGH);
+
+  /* Check for switches between high and full speed */
+
+  if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
+    {
+      is_high_speed = !is_high_speed;
+    }
+#endif
 
 #ifndef CONFIG_CDCECM_COMPOSITE
   if (desc)
@@ -1529,12 +1547,6 @@ static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc,
 
   len += USB_SIZEOF_IFDESC;
 
-  #ifdef CONFIG_USBDEV_DUALSPEED
-  bool is_high_speed = USB_SPEED_HIGH;
-  #else
-  bool is_high_speed = USB_SPEED_LOW;
-  #endif
-
   if (desc)
     {
       FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc;
@@ -1601,9 +1613,17 @@ static int cdcecm_getdescriptor(FAR struct cdcecm_driver_s *self,
       break;
 #endif
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+    case USB_DESC_TYPE_OTHERSPEEDCONFIG:
+#endif /* CONFIG_USBDEV_DUALSPEED */
     case USB_DESC_TYPE_CONFIG:
       {
+#ifdef CONFIG_USBDEV_DUALSPEED
+        return cdcecm_mkcfgdesc((FAR uint8_t *)desc, &self->devinfo,
+                                self->usbdev.speed, type);
+#else
         return cdcecm_mkcfgdesc((FAR uint8_t *)desc, &self->devinfo);
+#endif
       }
       break;
 
diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c
index 8ca3968458..de31b6ea3b 100644
--- a/drivers/usbdev/rndis.c
+++ b/drivers/usbdev/rndis.c
@@ -1924,12 +1924,30 @@ static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc,
  *
  ****************************************************************************/
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
+                                  FAR struct usbdev_devinfo_s *devinfo,
+                                  uint8_t speed, uint8_t type)
+#else
 static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
                                   FAR struct usbdev_devinfo_s *devinfo)
+#endif
 {
   FAR struct rndis_cfgdesc_s *dest = (FAR struct rndis_cfgdesc_s *)buf;
+  bool hispeed = false;
   uint16_t totallen;
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+  hispeed = (speed == USB_SPEED_HIGH);
+
+  /* Check for switches between high and full speed */
+
+  if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
+    {
+      hispeed = !hispeed;
+    }
+#endif
+
   /* This is the total length of the configuration (not necessarily the
    * size that we will be sending now).
    */
@@ -1937,6 +1955,13 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
   totallen = sizeof(g_rndis_cfgdesc);
   memcpy(dest, &g_rndis_cfgdesc, totallen);
 
+  usbclass_copy_epdesc(RNDIS_EP_INTIN_IDX, &dest->epintindesc,
+                       devinfo, hispeed);
+  usbclass_copy_epdesc(RNDIS_EP_BULKIN_IDX, &dest->epbulkindesc,
+                       devinfo, hispeed);
+  usbclass_copy_epdesc(RNDIS_EP_BULKOUT_IDX, &dest->epbulkoutdesc,
+                       devinfo, hispeed);
+
 #ifndef CONFIG_RNDIS_COMPOSITE
   /* For a stand-alone device, just fill in the total length */
 
@@ -1947,10 +1972,7 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
 
   dest->assoc_desc.firstif += devinfo->ifnobase;
   dest->comm_ifdesc.ifno   += devinfo->ifnobase;
-  dest->epintindesc.addr    = USB_EPIN(devinfo->epno[RNDIS_EP_INTIN_IDX]);
   dest->data_ifdesc.ifno   += devinfo->ifnobase;
-  dest->epbulkindesc.addr   = USB_EPIN(devinfo->epno[RNDIS_EP_BULKIN_IDX]);
-  dest->epbulkoutdesc.addr  = USB_EPOUT(devinfo->epno[RNDIS_EP_BULKOUT_IDX]);
 #endif
 
   return totallen;
@@ -2334,9 +2356,17 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
                   break;
 #endif
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+                case USB_DESC_TYPE_OTHERSPEEDCONFIG:
+#endif /* CONFIG_USBDEV_DUALSPEED */
                 case USB_DESC_TYPE_CONFIG:
                   {
+#ifdef CONFIG_USBDEV_DUALSPEED
+                    ret = usbclass_mkcfgdesc(ctrlreq->buf, &priv->devinfo,
+                                             dev->speed, ctrl->req);
+#else
                     ret = usbclass_mkcfgdesc(ctrlreq->buf, &priv->devinfo);
+#endif
                   }
                   break;
 
@@ -2719,7 +2749,12 @@ static int usbclass_classobject(int minor,
 
   /* Initialize the USB class driver structure */
 
+#ifdef CONFIG_USBDEV_DUALSPEED
+  drvr->drvr.speed         = USB_SPEED_HIGH;
+#else
   drvr->drvr.speed         = USB_SPEED_FULL;
+#endif
+
   drvr->drvr.ops           = &g_driverops;
   drvr->dev                = priv;