diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c index 8cdef8a032..de6e2ad35c 100644 --- a/drivers/usbdev/rndis.c +++ b/drivers/usbdev/rndis.c @@ -239,6 +239,12 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config); static void usbclass_resetconfig(FAR struct rndis_dev_s *priv); +/* usbclass helpers */ + +static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_devinfo_s *devinfo, + bool hispeed); + /**************************************************************************** * Private Data ****************************************************************************/ @@ -1839,6 +1845,116 @@ static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) return strdesc->len; } +/**************************************************************************** + * Name: usbclass_copy_epdesc + * + * Description: + * Copies the requested Endpoint Description into the buffer given. + * Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ). + * + ****************************************************************************/ + +static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_devinfo_s *devinfo, + bool hispeed) +{ +#ifndef CONFIG_USBDEV_DUALSPEED + UNUSED(hispeed); +#endif + + switch (epid) + { + case RNDIS_EP_INTIN_IDX: /* Interrupt IN endpoint */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = RNDIS_MKEPINTIN(devinfo); /* Endpoint address */ + epdesc->attr = RNDIS_EPINTIN_ATTR; /* Endpoint attributes */ + +#ifdef CONFIG_USBDEV_DUALSPEED + if (hispeed) + { + /* Maximum packet size (high speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPINTIN_HSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPINTIN_HSSIZE); + } + else +#endif + { + /* Maximum packet size (full speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPINTIN_FSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPINTIN_FSSIZE); + } + + epdesc->interval = 10; /* Interval */ + } + break; + + case RNDIS_EP_BULKOUT_IDX: /* Bulk OUT endpoint */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = RNDIS_MKEPBULKOUT(devinfo); /* Endpoint address */ + epdesc->attr = RNDIS_EPOUTBULK_ATTR; /* Endpoint attributes */ + +#ifdef CONFIG_USBDEV_DUALSPEED + if (hispeed) + { + /* Maximum packet size (high speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKOUT_HSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKOUT_HSSIZE); + } + else +#endif + { + /* Maximum packet size (full speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKOUT_FSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKOUT_FSSIZE); + } + + epdesc->interval = 0; /* Interval */ + } + break; + + case RNDIS_EP_BULKIN_IDX: /* Bulk IN endpoint */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = RNDIS_MKEPBULKIN(devinfo); /* Endpoint address */ + epdesc->attr = RNDIS_EPINBULK_ATTR; /* Endpoint attributes */ + +#ifdef CONFIG_USBDEV_DUALSPEED + if (hispeed) + { + /* Maximum packet size (high speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE); + } + else +#endif + { + /* Maximum packet size (full speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE); + } + + epdesc->interval = 0; /* Interval */ + } + break; + + default: + return 0; + } + + return sizeof(struct usb_epdesc_s); +} + /**************************************************************************** * Name: usbclass_mkcfgdesc * @@ -2455,6 +2571,8 @@ static void usbclass_resetconfig(FAR struct rndis_dev_s *priv) static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) { + struct usb_epdesc_s epdesc; + bool hispeed = false; int ret = 0; #ifdef CONFIG_DEBUG_FEATURES @@ -2465,6 +2583,10 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) } #endif +#ifdef CONFIG_USBDEV_DUALSPEED + hispeed = (priv->usbdev->speed == USB_SPEED_HIGH); +#endif + if (config == priv->config) { /* Already configured -- Do nothing */ @@ -2495,7 +2617,8 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the IN interrupt endpoint */ - ret = EP_CONFIGURE(priv->epintin, &g_rndis_cfgdesc.epintindesc, false); + usbclass_copy_epdesc(RNDIS_EP_INTIN_IDX, &epdesc, &priv->devinfo, hispeed); + ret = EP_CONFIGURE(priv->epintin, &epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0); @@ -2506,7 +2629,8 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the IN bulk endpoint */ - ret = EP_CONFIGURE(priv->epbulkin, &g_rndis_cfgdesc.epbulkindesc, false); + usbclass_copy_epdesc(RNDIS_EP_BULKIN_IDX, &epdesc, &priv->devinfo, hispeed); + ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false); if (ret < 0) { @@ -2518,7 +2642,8 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the OUT bulk endpoint */ - ret = EP_CONFIGURE(priv->epbulkout, &g_rndis_cfgdesc.epbulkoutdesc, true); + usbclass_copy_epdesc(RNDIS_EP_BULKOUT_IDX, &epdesc, &priv->devinfo, hispeed); + ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true); if (ret < 0) { diff --git a/include/nuttx/usb/rndis.h b/include/nuttx/usb/rndis.h index 4e32a00a93..e817f87b90 100644 --- a/include/nuttx/usb/rndis.h +++ b/include/nuttx/usb/rndis.h @@ -54,6 +54,41 @@ #define RNDIS_EP_BULKIN_IDX (1) #define RNDIS_EP_BULKOUT_IDX (2) +/* Endpoint configuration ****************************************************/ + +#define RNDIS_MKEPINTIN(desc) (USB_DIR_IN | (desc)->epno[RNDIS_EP_INTIN_IDX]) +#define RNDIS_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT) + +#define RNDIS_MKEPBULKIN(desc) (USB_DIR_IN | (desc)->epno[RNDIS_EP_BULKIN_IDX]) +#define RNDIS_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK) + +#define RNDIS_MKEPBULKOUT(desc) ((desc)->epno[RNDIS_EP_BULKOUT_IDX]) +#define RNDIS_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK) + +#ifndef CONFIG_RNDIS_EPINTIN_FSSIZE +# define CONFIG_RNDIS_EPINTIN_FSSIZE 16 +#endif + +#ifndef CONFIG_RNDIS_EPINTIN_HSSIZE +# define CONFIG_RNDIS_EPINTIN_HSSIZE 16 +#endif + +#ifndef CONFIG_RNDIS_EPBULKIN_FSSIZE +# define CONFIG_RNDIS_EPBULKIN_FSSIZE 64 +#endif + +#ifndef CONFIG_RNDIS_EPBULKIN_HSSIZE +# define CONFIG_RNDIS_EPBULKIN_HSSIZE 512 +#endif + +#ifndef CONFIG_RNDIS_EPBULKOUT_FSSIZE +# define CONFIG_RNDIS_EPBULKOUT_FSSIZE 64 +#endif + +#ifndef CONFIG_RNDIS_EPBULKOUT_HSSIZE +# define CONFIG_RNDIS_EPBULKOUT_HSSIZE 512 +#endif + /************************************************************************************ * Public Data ************************************************************************************/