usbdev: fixed DUALSPEED issue for adb/cdcecm/rndis

Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
zhangyuan21 2023-02-01 21:11:54 +08:00 committed by Xiang Xiao
parent 3a7382e690
commit b4aa5b0d0b
3 changed files with 66 additions and 11 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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;