usbdev: fixed DUALSPEED issue for adb/cdcecm/rndis
Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
parent
3a7382e690
commit
b4aa5b0d0b
3 changed files with 66 additions and 11 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue