diff --git a/drivers/usbdev/Kconfig b/drivers/usbdev/Kconfig index 005fd22e470..41181aff7d1 100644 --- a/drivers/usbdev/Kconfig +++ b/drivers/usbdev/Kconfig @@ -345,6 +345,20 @@ config PL2303_EPBULK_SSSIZE Max package size for the bulk endpoint if super speed mode. Default 1024. +config PL2303_EPBULK_MAXBURST + int "BULK endpoints super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk endpoint if super speed mode. + Default 0. + +config PL2303_EPBULK_MAXSTREAM + int "BULK endpoints super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED config PL2303_NWRREQS @@ -500,6 +514,13 @@ config CDCACM_EPINTIN_SSSIZE Max package size for the interrupt IN endpoint if super speed mode. Default 64. +config CDCACM_EPINTIN_MAXBURST + int "Interrupt IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the interrupt IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCACM_COMPOSITE @@ -526,7 +547,7 @@ config CDCACM_EPBULKOUT_FSSIZE if USBDEV_DUALSPEED config CDCACM_EPBULKOUT_HSSIZE - int "Bulk OUT out high speed MAXPACKET size" + int "Bulk OUT high speed MAXPACKET size" default 512 ---help--- Max package size for the bulk OUT endpoint if high speed mode. @@ -537,12 +558,26 @@ endif # USBDEV_DUALSPEED if USBDEV_SUPERSPEED config CDCACM_EPBULKOUT_SSSIZE - int "Bulk OUT out super speed MAXPACKET size" + int "Bulk OUT super speed MAXPACKET size" default 1024 ---help--- Max package size for the bulk OUT endpoint if super speed mode. Default 1024. +config CDCACM_EPBULKOUT_MAXBURST + int "Bulk OUT super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk OUT endpoint if super speed mode. + Default 0. + +config CDCACM_EPBULKOUT_MAXSTREAM + int "Bulk OUT super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk OUT endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCACM_COMPOSITE @@ -586,6 +621,20 @@ config CDCACM_EPBULKIN_SSSIZE Max package size for the bulk IN endpoint if super speed mode. Default 1024. +config CDCACM_EPBULKIN_MAXBURST + int "Bulk IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk IN endpoint if super speed mode. + Default 0. + +config CDCACM_EPBULKIN_MAXSTREAM + int "Bulk IN super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED config CDCACM_NRDREQS @@ -749,6 +798,20 @@ config USBADB_EPBULKOUT_SSSIZE Max package size for the bulk OUT endpoint if super speed mode. Default 1024. +config USBADB_EPBULKOUT_MAXBURST + int "Bulk OUT super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk OUT endpoint if super speed mode. + Default 0. + +config USBADB_EPBULKOUT_MAXSTREAM + int "Bulk OUT super speed MAXBSTREAM size" + default 0 + ---help--- + Max stream size for the bulk OUT endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED config USBADB_EPBULKIN_FSSIZE @@ -778,6 +841,20 @@ config USBADB_EPBULKIN_SSSIZE Max package size for the bulk IN endpoint if super speed mode. Default 1024. +config USBADB_EPBULKIN_MAXBURST + int "Bulk IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk IN endpoint if super speed mode. + Default 0. + +config USBADB_EPBULKIN_MAXSTREAM + int "Bulk IN super speed MAXBSTREAM size" + default 0 + ---help--- + Max stream size for the bulk IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED config USBADB_NRDREQS @@ -1228,6 +1305,13 @@ config CDCECM_EPINTIN_SSSIZE Max package size for the interrupt IN endpoint if super speed mode. Default 64. +config CDCECM_EPINTIN_MAXBURST + int "Interrupt IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the interrupt IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCECM_COMPOSITE @@ -1271,6 +1355,20 @@ config CDCECM_EPBULKOUT_SSSIZE Max package size for the bulk OUT endpoint if super speed mode. Default 1024. +config CDCECM_EPBULKOUT_MAXBURST + int "Bulk OUT super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk OUT endpoint if super speed mode. + Default 0. + +config CDCECM_EPBULKOUT_MAXSTREAM + int "Bulk OUT super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk OUT endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCECM_COMPOSITE @@ -1314,6 +1412,20 @@ config CDCECM_EPBULKIN_SSSIZE Max package size for the bulk IN endpoint if super speed mode. Default 1024. +config CDCECM_EPBULKIN_MAXBURST + int "Bulk IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk IN endpoint if super speed mode. + Default 0. + +config CDCECM_EPBULKIN_MAXSTREAM + int "Bulk IN super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCECM_COMPOSITE @@ -1436,6 +1548,13 @@ config CDCNCM_EPINTIN_SSSIZE Max package size for the interrupt IN endpoint if super speed mode. Default 64. +config CDCNCM_EPINTIN_MAXBURST + int "Interrupt IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the interrupt IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCNCM_COMPOSITE @@ -1479,6 +1598,20 @@ config CDCNCM_EPBULKOUT_SSSIZE Max package size for the bulk OUT endpoint if super speed mode. Default 1024. +config CDCNCM_EPBULKOUT_MAXBURST + int "Bulk OUT super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk OUT endpoint if super speed mode. + Default 0. + +config CDCNCM_EPBULKOUT_MAXSTREAM + int "Bulk OUT super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk OUT endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCNCM_COMPOSITE @@ -1522,6 +1655,20 @@ config CDCNCM_EPBULKIN_SSSIZE Max package size for the bulk IN endpoint if super speed mode. Default 1024. +config CDCNCM_EPBULKIN_MAXBURST + int "Bulk IN super speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk IN endpoint if super speed mode. + Default 0. + +config CDCNCM_EPBULKIN_MAXSTREAM + int "Bulk IN super speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk IN endpoint if super speed mode. + Default 0. + endif # USBDEV_SUPERSPEED if !CDCNCM_COMPOSITE @@ -1678,7 +1825,21 @@ config USBMTP_EPBULKOUT_SSSIZE Max package size for the bulk OUT endpoint if Super Speed mode. Default 1024. -endif # USBDEV_DUALSPEED +config USBMTP_EPBULKOUT_MAXBURST + int "Bulk OUT Super Speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk OUT endpoint if Super Speed mode. + Default 0. + +config USBMTP_EPBULKOUT_MAXSTREAM + int "Bulk OUT Super Speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk OUT endpoint if Super Speed mode. + Default 0. + +endif # USBDEV_SUPERSPEED config USBMTP_EPBULKIN_FSSIZE int "Bulk IN Full Speed MAXPACKET size" @@ -1707,7 +1868,21 @@ config USBMTP_EPBULKIN_SSSIZE Max package size for the bulk IN endpoint if Super Speed mode. Default 1024. -endif # USBDEV_DUALSPEED +config USBMTP_EPBULKIN_MAXBURST + int "Bulk IN Super Speed MAXBURST size" + default 0 + ---help--- + Max burst size for the bulk IN endpoint if Super Speed mode. + Default 0. + +config USBMTP_EPBULKIN_MAXSTREAM + int "Bulk IN Super Speed MAXSTREAM size" + default 0 + ---help--- + Max stream size for the bulk IN endpoint if Super Speed mode. + Default 0. + +endif # USBDEV_SUPERSPEED config USBMTP_EPINTIN_SIZE int "Interrupt IN MAXPACKET size" @@ -1721,6 +1896,17 @@ config USBMTP_EPINTIN_INTERVAL ---help--- The poll interval for the Interrupt IN endpoint, Default 10. +if USBDEV_SUPERSPEED + +config USBMTP_EPINTIN_MAXBURST + int "Interrupt IN Super Speed MAXBURST size" + default 0 + ---help--- + Max burst size for the Interrupt IN endpoint if Super Speed mode. + Default 0. + +endif # USBDEV_SUPERSPEED + config USBMTP_NRDREQS int "Number of read requests that can be in flight" default 4 diff --git a/drivers/usbdev/adb.c b/drivers/usbdev/adb.c index 080854302f7..4ceacfb45dc 100644 --- a/drivers/usbdev/adb.c +++ b/drivers/usbdev/adb.c @@ -227,44 +227,62 @@ static const struct usbdev_epinfo_s g_adb_epbulkin = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, - .addr = USB_DIR_IN, - .attr = USB_EP_ATTR_XFER_BULK | - USB_EP_ATTR_NO_SYNC | - USB_EP_ATTR_USAGE_DATA, - .interval = 0, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = USB_DIR_IN, + .attr = USB_EP_ATTR_XFER_BULK | + USB_EP_ATTR_NO_SYNC | + USB_EP_ATTR_USAGE_DATA, + .interval = 0, }, - .fssize = CONFIG_USBADB_EPBULKIN_FSSIZE, + .reqnum = CONFIG_USBADB_NWRREQS, + .fssize = CONFIG_USBADB_EPBULKIN_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_USBADB_EPBULKIN_HSSIZE, + .hssize = CONFIG_USBADB_EPBULKIN_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_USBADB_EPBULKIN_SSSIZE, + .sssize = CONFIG_USBADB_EPBULKIN_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_USBADB_EPBULKIN_MAXBURST, + .attr = CONFIG_USBADB_EPBULKIN_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = CONFIG_USBADB_NWRREQS, }; static const struct usbdev_epinfo_s g_adb_epbulkout = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, - .addr = USB_DIR_OUT, - .attr = USB_EP_ATTR_XFER_BULK | - USB_EP_ATTR_NO_SYNC | - USB_EP_ATTR_USAGE_DATA, - .interval = 0, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = USB_DIR_OUT, + .attr = USB_EP_ATTR_XFER_BULK | + USB_EP_ATTR_NO_SYNC | + USB_EP_ATTR_USAGE_DATA, + .interval = 0, }, - .fssize = CONFIG_USBADB_EPBULKOUT_FSSIZE, + .reqnum = CONFIG_USBADB_NRDREQS, + .fssize = CONFIG_USBADB_EPBULKOUT_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_USBADB_EPBULKOUT_HSSIZE, + .hssize = CONFIG_USBADB_EPBULKOUT_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_USBADB_EPBULKOUT_SSSIZE, + .sssize = CONFIG_USBADB_EPBULKOUT_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_USBADB_EPBULKOUT_MAXBURST, + .attr = CONFIG_USBADB_EPBULKOUT_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = CONFIG_USBADB_NRDREQS, }; static const FAR struct usbdev_epinfo_s *g_adb_epinfos[USBADB_NUM_EPS] = @@ -289,8 +307,10 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed, uint8_t type) { - FAR struct usb_epdesc_s *epdesc; + FAR uint8_t *epdesc; FAR struct usb_ifdesc_s *dest; + uint32_t totallen = 0; + int ret; /* Check for switches between high and full speed */ @@ -300,14 +320,24 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, } dest = (FAR struct usb_ifdesc_s *)buf; - epdesc = (FAR struct usb_epdesc_s *)(buf + sizeof(g_adb_ifdesc)); + epdesc = (FAR uint8_t *)(buf + sizeof(g_adb_ifdesc)); memcpy(dest, &g_adb_ifdesc, sizeof(g_adb_ifdesc)); + totallen += sizeof(g_adb_ifdesc); - usbdev_copy_epdesc(&epdesc[0], devinfo->epno[USBADB_EP_BULKIN_IDX], - speed, &g_adb_epbulkin); - usbdev_copy_epdesc(&epdesc[1], devinfo->epno[USBADB_EP_BULKOUT_IDX], - speed, &g_adb_epbulkout); + ret = usbdev_copy_epdesc((FAR struct usb_epdesc_s *)epdesc, + devinfo->epno[USBADB_EP_BULKIN_IDX], + speed, + &g_adb_epbulkin); + totallen += ret; + epdesc += ret; + + ret = usbdev_copy_epdesc((FAR struct usb_epdesc_s *)epdesc, + devinfo->epno[USBADB_EP_BULKOUT_IDX], + speed, + &g_adb_epbulkout); + totallen += ret; + epdesc += ret; #ifdef CONFIG_USBADB_COMPOSITE /* For composite device, apply possible offset to the interface numbers */ @@ -316,7 +346,7 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, dest->iif = devinfo->strbase + USBADB_INTERFACESTRID; #endif - return sizeof(g_adb_ifdesc) + 2 * USB_SIZEOF_EPDESC; + return totallen; } /**************************************************************************** @@ -430,7 +460,13 @@ void usbdev_adb_get_composite_devdesc(FAR struct composite_devdesc_s *dev) dev->mkstrdesc = usbclass_mkstrdesc, dev->nconfigs = USBADB_NCONFIGS; dev->configid = 1; +#ifdef CONFIG_USBDEV_SUPERSPEED + dev->cfgdescsize = sizeof(g_adb_ifdesc) + + USB_SIZEOF_EPDESC * 2 + + USB_SIZEOF_SS_EPCOMPDESC * 2; +#else dev->cfgdescsize = sizeof(g_adb_ifdesc) + 2 * USB_SIZEOF_EPDESC; +#endif dev->devinfo.ninterfaces = 1; dev->devinfo.nstrings = USBADB_NSTRIDS; dev->devinfo.nendpoints = USBADB_NUM_EPS; diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c index 43509a4172c..9f82f365d9e 100644 --- a/drivers/usbdev/cdcacm.c +++ b/drivers/usbdev/cdcacm.c @@ -917,9 +917,9 @@ static int cdcacm_epconfigure(FAR struct usbdev_ep_s *ep, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed) { - struct usb_epdesc_s epdesc; - cdcacm_copy_epdesc(epid, &epdesc, devinfo, speed); - return EP_CONFIGURE(ep, &epdesc, last); + struct usb_ss_epdesc_s epdesc; + cdcacm_copy_epdesc(epid, &epdesc.epdesc, devinfo, speed); + return EP_CONFIGURE(ep, &epdesc.epdesc, last); } /**************************************************************************** @@ -1307,12 +1307,32 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver, /* Pre-allocate read requests. The buffer size is one full packet. */ #if defined(CONFIG_USBDEV_SUPERSPEED) - reqlen = CONFIG_CDCACM_EPBULKOUT_SSSIZE; -#elif defined(CONFIG_USBDEV_DUALSPEED) - reqlen = CONFIG_CDCACM_EPBULKOUT_HSSIZE; -#else - reqlen = CONFIG_CDCACM_EPBULKOUT_FSSIZE; + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + if (CONFIG_CDCACM_EPBULKOUT_MAXBURST < USB_SS_BULK_EP_MAXBURST) + { + reqlen = CONFIG_CDCACM_EPBULKOUT_SSSIZE * + (CONFIG_CDCACM_EPBULKOUT_MAXBURST + 1); + } + else + { + reqlen = CONFIG_CDCACM_EPBULKOUT_SSSIZE * + USB_SS_BULK_EP_MAXBURST; + } + } + else #endif +#if defined(CONFIG_USBDEV_DUALSPEED) + if (dev->speed == USB_SPEED_HIGH) + { + reqlen = CONFIG_CDCACM_EPBULKOUT_HSSIZE; + } + else +#endif + { + reqlen = CONFIG_CDCACM_EPBULKOUT_FSSIZE; + } for (i = 0; i < CONFIG_CDCACM_NRDREQS; i++) { @@ -1341,12 +1361,32 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver, */ #if defined(CONFIG_USBDEV_SUPERSPEED) - reqlen = CONFIG_CDCACM_EPBULKIN_SSSIZE; -#elif defined(CONFIG_USBDEV_DUALSPEED) - reqlen = CONFIG_CDCACM_EPBULKIN_HSSIZE; -#else - reqlen = CONFIG_CDCACM_EPBULKIN_FSSIZE; + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + if (CONFIG_CDCACM_EPBULKIN_MAXBURST < USB_SS_BULK_EP_MAXBURST) + { + reqlen = CONFIG_CDCACM_EPBULKOUT_SSSIZE * + (CONFIG_CDCACM_EPBULKIN_MAXBURST + 1); + } + else + { + reqlen = CONFIG_CDCACM_EPBULKOUT_SSSIZE * + USB_SS_BULK_EP_MAXBURST; + } + } + else #endif +#if defined(CONFIG_USBDEV_DUALSPEED) + if (dev->speed == USB_SPEED_HIGH) + { + reqlen = CONFIG_CDCACM_EPBULKIN_HSSIZE; + } + else +#endif + { + reqlen = CONFIG_CDCACM_EPBULKIN_FSSIZE; + } if (CONFIG_CDCACM_BULKIN_REQLEN > reqlen) { diff --git a/drivers/usbdev/cdcacm_desc.c b/drivers/usbdev/cdcacm_desc.c index 8dc9890d634..a1570182c5b 100644 --- a/drivers/usbdev/cdcacm_desc.c +++ b/drivers/usbdev/cdcacm_desc.c @@ -215,6 +215,106 @@ FAR const struct usb_devdesc_s *cdcacm_getdevdesc(void) } #endif +/**************************************************************************** + * Name: cdcacm_copy_epcompdesc + * + * Description: + * Copies the Endpoint Companion Description into the buffer given. + * Returns the number of Bytes filled in. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_SUPERSPEED +static void +cdcacm_copy_epcompdesc(enum cdcacm_epdesc_e epid, + FAR struct usb_ss_epcompdesc_s *epcompdesc) +{ + switch (epid) + { + case CDCACM_EPINTIN: /* Interrupt IN endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCACM_EPINTIN_MAXBURST >= USB_SS_INT_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_INT_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCACM_EPINTIN_MAXBURST; + } + + epcompdesc->attr = 0; + epcompdesc->wbytes[0] = LSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCACM_EPINTIN_SSSIZE); + epcompdesc->wbytes[1] = MSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCACM_EPINTIN_SSSIZE); + } + break; + + case CDCACM_EPBULKOUT: /* Bulk OUT endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCACM_EPBULKOUT_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCACM_EPBULKOUT_MAXBURST; + } + + if (CONFIG_CDCACM_EPBULKOUT_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCACM_EPBULKOUT_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + case CDCACM_EPBULKIN: /* Bulk IN endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCACM_EPBULKIN_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCACM_EPBULKIN_MAXBURST; + } + + if (CONFIG_CDCACM_EPBULKIN_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCACM_EPBULKIN_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + default: + break; + } +} +#endif + /**************************************************************************** * Name: cdcacm_copy_epdesc * @@ -229,53 +329,73 @@ int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed) { + int len = sizeof(struct usb_epdesc_s); + #if !defined(CONFIG_USBDEV_DUALSPEED) && !defined(CONFIG_USBDEV_SUPERSPEED) UNUSED(speed); #endif - switch (epid) +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + len += sizeof(struct usb_ss_epcompdesc_s); + } +#endif + + if (epdesc == NULL) + { + return len; + } + + switch (epid) { case CDCACM_EPINTIN: /* Interrupt IN endpoint */ - { - epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ - epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ - epdesc->addr = CDCACM_MKEPINTIN(devinfo); /* Endpoint address */ - epdesc->attr = CDCACM_EPINTIN_ATTR; /* Endpoint attributes */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = CDCACM_MKEPINTIN(devinfo); /* Endpoint address */ + epdesc->attr = CDCACM_EPINTIN_ATTR; /* Endpoint attributes */ #ifdef CONFIG_USBDEV_SUPERSPEED - if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) - { - /* Maximum packet size (super speed) */ + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + /* Maximum packet size (super speed) */ - epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_SSSIZE); - epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_SSSIZE); - } - else + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_SSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_SSSIZE); + + /* Copy endpoint companion description */ + + epdesc++; + cdcacm_copy_epcompdesc(epid, + (FAR struct usb_ss_epcompdesc_s *)epdesc); + } + else #endif #ifdef CONFIG_USBDEV_DUALSPEED - if (speed == USB_SPEED_HIGH) - { - /* Maximum packet size (high speed) */ + if (speed == USB_SPEED_HIGH) + { + /* Maximum packet size (high speed) */ - epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE); - epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE); - } - else + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE); + } + else #endif - { - /* Maximum packet size (full speed) */ + { + /* Maximum packet size (full speed) */ - epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE); - epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE); - } + epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE); + epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE); + } - epdesc->interval = 10; /* Interval */ + epdesc->interval = 10; /* Interval */ } break; case CDCACM_EPBULKOUT: /* Bulk OUT endpoint */ { - epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ epdesc->addr = CDCACM_MKEPBULKOUT(devinfo); /* Endpoint address */ epdesc->attr = CDCACM_EPOUTBULK_ATTR; /* Endpoint attributes */ @@ -287,6 +407,12 @@ int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid, epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKOUT_SSSIZE); epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKOUT_SSSIZE); + + /* Copy endpoint companion description */ + + epdesc++; + cdcacm_copy_epcompdesc(epid, + (FAR struct usb_ss_epcompdesc_s *)epdesc); } else #endif @@ -325,6 +451,12 @@ int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid, epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKIN_SSSIZE); epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKIN_SSSIZE); + + /* Copy endpoint companion description */ + + epdesc++; + cdcacm_copy_epcompdesc(epid, + (FAR struct usb_ss_epcompdesc_s *)epdesc); } else #endif @@ -353,7 +485,7 @@ int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid, return 0; } - return sizeof(struct usb_epdesc_s); + return len; } /**************************************************************************** @@ -369,6 +501,7 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type) { int length = 0; + int ret; if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG && speed < USB_SPEED_SUPER) { @@ -544,16 +677,16 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, /* Interrupt IN endpoint descriptor */ + ret = cdcacm_copy_epdesc(CDCACM_EPINTIN, + (FAR struct usb_epdesc_s *)buf, + devinfo, + speed); if (buf != NULL) { - cdcacm_copy_epdesc(CDCACM_EPINTIN, (struct usb_epdesc_s *)buf, - devinfo, - speed); - - buf += USB_SIZEOF_EPDESC; + buf += ret; } - length += USB_SIZEOF_EPDESC; + length += ret; /* Data interface descriptor */ @@ -582,27 +715,30 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, /* Bulk OUT endpoint descriptor */ + ret = cdcacm_copy_epdesc(CDCACM_EPBULKOUT, + (FAR struct usb_epdesc_s *)buf, + devinfo, + speed); if (buf != NULL) { - cdcacm_copy_epdesc(CDCACM_EPBULKOUT, (struct usb_epdesc_s *)buf, - devinfo, - speed); - buf += USB_SIZEOF_EPDESC; + buf += ret; } - length += USB_SIZEOF_EPDESC; + length += ret; /* Bulk IN endpoint descriptor */ + ret = cdcacm_copy_epdesc(CDCACM_EPBULKIN, + (FAR struct usb_epdesc_s *)buf, + devinfo, + speed); if (buf != NULL) { - cdcacm_copy_epdesc(CDCACM_EPBULKIN, (struct usb_epdesc_s *)buf, - devinfo, - speed); - buf += USB_SIZEOF_EPDESC; + buf += ret; } - length += USB_SIZEOF_EPDESC; + length += ret; + return length; } diff --git a/drivers/usbdev/cdcecm.c b/drivers/usbdev/cdcecm.c index 70b4754cc58..e3ace183d69 100644 --- a/drivers/usbdev/cdcecm.c +++ b/drivers/usbdev/cdcecm.c @@ -206,9 +206,10 @@ static void cdcecm_rdcomplete(FAR struct usbdev_ep_s *ep, static void cdcecm_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); -static void cdcecm_mkepdesc(int epidx, +static int cdcecm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, - FAR struct usbdev_devinfo_s *devinfo, uint8_t speed); + FAR struct usbdev_devinfo_s *devinfo, + uint8_t speed); /**************************************************************************** * Private Data @@ -948,7 +949,7 @@ static void cdcecm_resetconfig(FAR struct cdcecm_driver_s *self) static int cdcecm_setconfig(FAR struct cdcecm_driver_s *self, uint8_t config) { - struct usb_epdesc_s epdesc; + struct usb_ss_epdesc_s epdesc; int ret = OK; if (config == self->config) @@ -969,8 +970,8 @@ static int cdcecm_setconfig(FAR struct cdcecm_driver_s *self, uint8_t config) } cdcecm_mkepdesc(CDCECM_EP_INTIN_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epint, &epdesc, false); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epint, &epdesc.epdesc, false); if (ret < 0) { @@ -980,8 +981,8 @@ static int cdcecm_setconfig(FAR struct cdcecm_driver_s *self, uint8_t config) self->epint->priv = self; cdcecm_mkepdesc(CDCECM_EP_BULKIN_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epbulkin, &epdesc, false); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epbulkin, &epdesc.epdesc, false); if (ret < 0) { @@ -991,8 +992,8 @@ static int cdcecm_setconfig(FAR struct cdcecm_driver_s *self, uint8_t config) self->epbulkin->priv = self; cdcecm_mkepdesc(CDCECM_EP_BULKOUT_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epbulkout, &epdesc, true); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epbulkout, &epdesc.epdesc, true); if (ret < 0) { @@ -1129,6 +1130,104 @@ static int cdcecm_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) return strdesc->len; } +/**************************************************************************** + * Name: cdcecm_mkepcompdesc + * + * Description: + * Construct the endpoint companion descriptor + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_SUPERSPEED +static void cdcecm_mkepcompdesc(int epidx, + FAR struct usb_ss_epcompdesc_s *epcompdesc) +{ + switch (epidx) + { + case CDCECM_EP_INTIN_IDX: /* Interrupt IN endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCECM_EPINTIN_MAXBURST >= USB_SS_INT_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_INT_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCECM_EPINTIN_MAXBURST; + } + + epcompdesc->attr = 0; + epcompdesc->wbytes[0] = LSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCECM_EPINTIN_SSSIZE); + epcompdesc->wbytes[1] = MSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCECM_EPINTIN_SSSIZE); + } + break; + + case CDCECM_EP_BULKOUT_IDX: + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCECM_EPBULKOUT_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCECM_EPBULKOUT_MAXBURST; + } + + if (CONFIG_CDCECM_EPBULKOUT_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCECM_EPBULKOUT_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + case CDCECM_EP_BULKIN_IDX: + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCECM_EPBULKIN_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCECM_EPBULKIN_MAXBURST; + } + + if (CONFIG_CDCECM_EPBULKIN_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCECM_EPBULKIN_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + default: + break; + } +} +#endif + /**************************************************************************** * Name: cdcecm_mkepdesc * @@ -1137,14 +1236,15 @@ static int cdcecm_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) * ****************************************************************************/ -static void cdcecm_mkepdesc(int epidx, - FAR struct usb_epdesc_s *epdesc, - FAR struct usbdev_devinfo_s *devinfo, - uint8_t speed) +static int cdcecm_mkepdesc(int epidx, + FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_devinfo_s *devinfo, + uint8_t speed) { uint16_t intin_mxpktsz = CONFIG_CDCECM_EPINTIN_FSSIZE; uint16_t bulkout_mxpktsz = CONFIG_CDCECM_EPBULKOUT_FSSIZE; uint16_t bulkin_mxpktsz = CONFIG_CDCECM_EPBULKIN_FSSIZE; + int len = sizeof(struct usb_epdesc_s); #ifdef CONFIG_USBDEV_SUPERSPEED if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) @@ -1154,6 +1254,7 @@ static void cdcecm_mkepdesc(int epidx, intin_mxpktsz = CONFIG_CDCECM_EPINTIN_SSSIZE; bulkout_mxpktsz = CONFIG_CDCECM_EPBULKOUT_SSSIZE; bulkin_mxpktsz = CONFIG_CDCECM_EPBULKIN_SSSIZE; + len += sizeof(struct usb_ss_epcompdesc_s); } else #endif @@ -1170,6 +1271,11 @@ static void cdcecm_mkepdesc(int epidx, UNUSED(speed); #endif + if (epdesc == NULL) + { + return len; + } + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ @@ -1211,6 +1317,16 @@ static void cdcecm_mkepdesc(int epidx, default: DEBUGPANIC(); } + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + epdesc++; + cdcecm_mkepcompdesc(epidx, (FAR struct usb_ss_epcompdesc_s *)epdesc); + } +#endif + + return len; } /**************************************************************************** @@ -1227,6 +1343,7 @@ static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc, { FAR struct usb_cfgdesc_s *cfgdesc = NULL; int16_t len = 0; + int ret; /* Check for switches between high and full speed */ @@ -1353,15 +1470,15 @@ static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc, len += SIZEOF_ECM_FUNCDESC; + ret = cdcecm_mkepdesc(CDCECM_EP_INTIN_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcecm_mkepdesc(CDCECM_EP_INTIN_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; /* Data Class Interface */ @@ -1405,25 +1522,25 @@ static int16_t cdcecm_mkcfgdesc(FAR uint8_t *desc, len += USB_SIZEOF_IFDESC; + ret = cdcecm_mkepdesc(CDCECM_EP_BULKIN_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcecm_mkepdesc(CDCECM_EP_BULKIN_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; + ret = cdcecm_mkepdesc(CDCECM_EP_BULKOUT_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcecm_mkepdesc(CDCECM_EP_BULKOUT_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; if (cfgdesc) { diff --git a/drivers/usbdev/cdcncm.c b/drivers/usbdev/cdcncm.c index 4c9479e11c0..bffb34441e1 100644 --- a/drivers/usbdev/cdcncm.c +++ b/drivers/usbdev/cdcncm.c @@ -425,9 +425,9 @@ static void cdcncm_rdcomplete(FAR struct usbdev_ep_s *ep, static void cdcncm_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); -static void cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, - FAR struct usbdev_devinfo_s *devinfo, - uint8_t speed); +static int cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_devinfo_s *devinfo, + uint8_t speed); /**************************************************************************** * Private Data @@ -1581,7 +1581,7 @@ static void cdcncm_resetconfig(FAR struct cdcncm_driver_s *self) static int cdcncm_setconfig(FAR struct cdcncm_driver_s *self, uint8_t config) { - struct usb_epdesc_s epdesc; + struct usb_ss_epdesc_s epdesc; int ret; if (config == self->config) @@ -1602,8 +1602,8 @@ static int cdcncm_setconfig(FAR struct cdcncm_driver_s *self, uint8_t config) } cdcncm_mkepdesc(CDCNCM_EP_INTIN_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epint, &epdesc, false); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epint, &epdesc.epdesc, false); if (ret < 0) { @@ -1612,8 +1612,8 @@ static int cdcncm_setconfig(FAR struct cdcncm_driver_s *self, uint8_t config) self->epint->priv = self; cdcncm_mkepdesc(CDCNCM_EP_BULKIN_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epbulkin, &epdesc, false); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epbulkin, &epdesc.epdesc, false); if (ret < 0) { @@ -1623,8 +1623,8 @@ static int cdcncm_setconfig(FAR struct cdcncm_driver_s *self, uint8_t config) self->epbulkin->priv = self; cdcncm_mkepdesc(CDCNCM_EP_BULKOUT_IDX, - &epdesc, &self->devinfo, self->usbdev.speed); - ret = EP_CONFIGURE(self->epbulkout, &epdesc, true); + &epdesc.epdesc, &self->devinfo, self->usbdev.speed); + ret = EP_CONFIGURE(self->epbulkout, &epdesc.epdesc, true); if (ret < 0) { @@ -1901,6 +1901,104 @@ static int cdcmbim_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) } #endif +/**************************************************************************** + * Name: cdcecm_mkepcompdesc + * + * Description: + * Construct the endpoint companion descriptor + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_SUPERSPEED +static void cdcncm_mkepcompdesc(int epidx, + FAR struct usb_ss_epcompdesc_s *epcompdesc) +{ + switch (epidx) + { + case CDCNCM_EP_INTIN_IDX: /* Interrupt IN endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCNCM_EPINTIN_MAXBURST >= USB_SS_INT_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_INT_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCNCM_EPINTIN_MAXBURST; + } + + epcompdesc->attr = 0; + epcompdesc->wbytes[0] = LSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCNCM_EPINTIN_SSSIZE); + epcompdesc->wbytes[1] = MSBYTE((epcompdesc->mxburst + 1) * + CONFIG_CDCNCM_EPINTIN_SSSIZE); + } + break; + + case CDCNCM_EP_BULKOUT_IDX: + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCNCM_EPBULKOUT_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCNCM_EPBULKOUT_MAXBURST; + } + + if (CONFIG_CDCNCM_EPBULKOUT_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCNCM_EPBULKOUT_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + case CDCNCM_EP_BULKIN_IDX: + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (CONFIG_CDCNCM_EPBULKIN_MAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = CONFIG_CDCNCM_EPBULKIN_MAXBURST; + } + + if (CONFIG_CDCNCM_EPBULKIN_MAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = CONFIG_CDCNCM_EPBULKIN_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + default: + break; + } +} +#endif + /**************************************************************************** * Name: cdcncm_mkepdesc * @@ -1909,13 +2007,14 @@ static int cdcmbim_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) * ****************************************************************************/ -static void cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, - FAR struct usbdev_devinfo_s *devinfo, - uint8_t speed) +static int cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_devinfo_s *devinfo, + uint8_t speed) { uint16_t intin_mxpktsz = CONFIG_CDCNCM_EPINTIN_FSSIZE; uint16_t bulkout_mxpktsz = CONFIG_CDCNCM_EPBULKOUT_FSSIZE; uint16_t bulkin_mxpktsz = CONFIG_CDCNCM_EPBULKIN_FSSIZE; + int len = sizeof(struct usb_epdesc_s); #ifdef CONFIG_USBDEV_SUPERSPEED if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) @@ -1925,6 +2024,7 @@ static void cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, intin_mxpktsz = CONFIG_CDCNCM_EPINTIN_SSSIZE; bulkout_mxpktsz = CONFIG_CDCNCM_EPBULKOUT_SSSIZE; bulkin_mxpktsz = CONFIG_CDCNCM_EPBULKIN_SSSIZE; + len += sizeof(struct usb_ss_epcompdesc_s); } else #endif @@ -1941,6 +2041,11 @@ static void cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, UNUSED(speed); #endif + if (epdesc == NULL) + { + return len; + } + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ @@ -1982,6 +2087,16 @@ static void cdcncm_mkepdesc(int epidx, FAR struct usb_epdesc_s *epdesc, default: DEBUGPANIC(); } + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + epdesc++; + cdcncm_mkepcompdesc(epidx, (FAR struct usb_ss_epcompdesc_s *)epdesc); + } +#endif + + return len; } /**************************************************************************** @@ -1998,6 +2113,7 @@ static int16_t cdcnm_mkcfgdesc(FAR uint8_t *desc, { FAR struct usb_cfgdesc_s *cfgdesc = NULL; int16_t len = 0; + int ret; /* Check for switches between high and full speed */ @@ -2170,15 +2286,15 @@ static int16_t cdcnm_mkcfgdesc(FAR uint8_t *desc, len += SIZEOF_MBIM_FUNCDESC; } + ret = cdcncm_mkepdesc(CDCNCM_EP_INTIN_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcncm_mkepdesc(CDCNCM_EP_INTIN_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; /* Data Class Interface */ @@ -2224,25 +2340,25 @@ static int16_t cdcnm_mkcfgdesc(FAR uint8_t *desc, len += USB_SIZEOF_IFDESC; + ret = cdcncm_mkepdesc(CDCNCM_EP_BULKIN_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcncm_mkepdesc(CDCNCM_EP_BULKIN_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; + ret = cdcncm_mkepdesc(CDCNCM_EP_BULKOUT_IDX, + (FAR struct usb_epdesc_s *)desc, + devinfo, speed); if (desc) { - FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)desc; - - cdcncm_mkepdesc(CDCNCM_EP_BULKOUT_IDX, epdesc, devinfo, speed); - desc += USB_SIZEOF_EPDESC; + desc += ret; } - len += USB_SIZEOF_EPDESC; + len += ret; if (cfgdesc) { diff --git a/drivers/usbdev/mtp.c b/drivers/usbdev/mtp.c index 86967d119d7..0ac07647d51 100644 --- a/drivers/usbdev/mtp.c +++ b/drivers/usbdev/mtp.c @@ -215,73 +215,102 @@ static const struct usbdev_epinfo_s g_mtp_epbulkin = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, - .addr = USB_DIR_IN, - .attr = USB_EP_ATTR_XFER_BULK | - USB_EP_ATTR_NO_SYNC | - USB_EP_ATTR_USAGE_DATA, - .interval = 0, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = USB_DIR_IN, + .attr = USB_EP_ATTR_XFER_BULK | + USB_EP_ATTR_NO_SYNC | + USB_EP_ATTR_USAGE_DATA, + .interval = 0, }, - .fssize = CONFIG_USBMTP_EPBULKIN_FSSIZE, + .reqnum = CONFIG_USBMTP_NWRREQS, + .fssize = CONFIG_USBMTP_EPBULKIN_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_USBMTP_EPBULKIN_HSSIZE, + .hssize = CONFIG_USBMTP_EPBULKIN_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_USBMTP_EPBULKIN_SSSIZE, + .sssize = CONFIG_USBMTP_EPBULKIN_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_USBMTP_EPBULKIN_MAXBURST, + .attr = CONFIG_USBMTP_EPBULKIN_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = CONFIG_USBMTP_NWRREQS, }; static const struct usbdev_epinfo_s g_mtp_epbulkout = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, - .addr = USB_DIR_OUT, - .attr = USB_EP_ATTR_XFER_BULK | - USB_EP_ATTR_NO_SYNC | - USB_EP_ATTR_USAGE_DATA, - .interval = 0, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = USB_DIR_OUT, + .attr = USB_EP_ATTR_XFER_BULK | + USB_EP_ATTR_NO_SYNC | + USB_EP_ATTR_USAGE_DATA, + .interval = 0, }, - .fssize = CONFIG_USBMTP_EPBULKOUT_FSSIZE, + .reqnum = CONFIG_USBMTP_NRDREQS, + .fssize = CONFIG_USBMTP_EPBULKOUT_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_USBMTP_EPBULKOUT_HSSIZE, + .hssize = CONFIG_USBMTP_EPBULKOUT_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_USBMTP_EPBULKOUT_SSSIZE, + .sssize = CONFIG_USBMTP_EPBULKOUT_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_USBMTP_EPBULKOUT_MAXBURST, + .attr = CONFIG_USBMTP_EPBULKOUT_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = CONFIG_USBMTP_NRDREQS, }; -static const struct usbdev_epinfo_s g_mtp_epbulkintin = +static const struct usbdev_epinfo_s g_mtp_epintin = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, - .addr = USB_DIR_IN, - .attr = USB_EP_ATTR_XFER_INT | - USB_EP_ATTR_NO_SYNC | - USB_EP_ATTR_USAGE_DATA, - .interval = CONFIG_USBMTP_EPINTIN_INTERVAL, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = USB_DIR_IN, + .attr = USB_EP_ATTR_XFER_INT | + USB_EP_ATTR_NO_SYNC | + USB_EP_ATTR_USAGE_DATA, + .interval = CONFIG_USBMTP_EPINTIN_INTERVAL, }, - .fssize = CONFIG_USBMTP_EPINTIN_SIZE, + .reqnum = CONFIG_USBMTP_NWRREQS, + .fssize = CONFIG_USBMTP_EPINTIN_SIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_USBMTP_EPINTIN_SIZE, + .hssize = CONFIG_USBMTP_EPINTIN_SIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_USBMTP_EPINTIN_SIZE, + .sssize = CONFIG_USBMTP_EPINTIN_SIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_USBMTP_EPINTIN_MAXBURST, + .attr = 0, + .wbytes[0] = LSBYTE((CONFIG_USBMTP_EPINTIN_MAXBURST + 1) * + CONFIG_USBMTP_EPINTIN_SIZE), + .wbytes[1] = MSBYTE((CONFIG_USBMTP_EPINTIN_MAXBURST + 1) * + CONFIG_USBMTP_EPINTIN_SIZE), + }, #endif - .reqnum = CONFIG_USBMTP_NWRREQS, }; static const FAR struct usbdev_epinfo_s *g_mtp_epinfos[USBMTP_NUM_EPS] = { &g_mtp_epbulkin, &g_mtp_epbulkout, - &g_mtp_epbulkintin, + &g_mtp_epintin, }; /**************************************************************************** @@ -300,8 +329,10 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed, uint8_t type) { - FAR struct usb_epdesc_s *epdesc; + FAR uint8_t *epdesc; FAR struct usb_ifdesc_s *dest; + uint32_t totallen = 0; + int ret; /* Check for switches between high and full speed */ @@ -311,16 +342,28 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, } dest = (FAR struct usb_ifdesc_s *)buf; - epdesc = (FAR struct usb_epdesc_s *)(buf + sizeof(g_mtp_ifdesc)); + epdesc = (FAR uint8_t *)(buf + sizeof(g_mtp_ifdesc)); memcpy(dest, &g_mtp_ifdesc, sizeof(g_mtp_ifdesc)); + totallen += sizeof(struct usb_ifdesc_s); - usbdev_copy_epdesc(&epdesc[0], devinfo->epno[USBMTP_EP_BULKIN_IDX], - speed, &g_mtp_epbulkin); - usbdev_copy_epdesc(&epdesc[1], devinfo->epno[USBMTP_EP_BULKOUT_IDX], - speed, &g_mtp_epbulkout); - usbdev_copy_epdesc(&epdesc[2], devinfo->epno[USBMTP_EP_INTIN_IDX], - speed, &g_mtp_epbulkintin); + ret = usbdev_copy_epdesc((FAR struct usb_epdesc_s *)epdesc, + devinfo->epno[USBMTP_EP_BULKIN_IDX], + speed, &g_mtp_epbulkin); + totallen += ret; + epdesc += ret; + + ret = usbdev_copy_epdesc((FAR struct usb_epdesc_s *)epdesc, + devinfo->epno[USBMTP_EP_BULKOUT_IDX], + speed, &g_mtp_epbulkout); + totallen += ret; + epdesc += ret; + + ret = usbdev_copy_epdesc((FAR struct usb_epdesc_s *)epdesc, + devinfo->epno[USBMTP_EP_INTIN_IDX], + speed, &g_mtp_epintin); + totallen += ret; + epdesc += ret; #ifdef CONFIG_USBMTP_COMPOSITE /* For composite device, apply possible offset to the interface numbers */ @@ -329,7 +372,7 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, dest->iif = devinfo->strbase + USBMTP_INTERFACESTRID; #endif - return sizeof(g_mtp_ifdesc) + 3 * USB_SIZEOF_EPDESC; + return totallen; } /**************************************************************************** @@ -452,7 +495,13 @@ void usbdev_mtp_get_composite_devdesc(FAR struct composite_devdesc_s *dev) dev->uninitialize = usbdev_fs_classuninitialize; dev->nconfigs = USBMTP_NCONFIGS; dev->configid = 1; +#ifdef CONFIG_USBDEV_SUPERSPEED + dev->cfgdescsize = sizeof(g_mtp_ifdesc) + + USB_SIZEOF_EPDESC * 3 + + USB_SIZEOF_SS_EPCOMPDESC * 3; +#else dev->cfgdescsize = sizeof(g_mtp_ifdesc) + 3 * USB_SIZEOF_EPDESC; +#endif dev->devinfo.ninterfaces = 1; dev->devinfo.nstrings = USBMTP_NSTRIDS; dev->devinfo.nendpoints = USBMTP_NUM_EPS; diff --git a/drivers/usbdev/pl2303.c b/drivers/usbdev/pl2303.c index 09f88fd3f17..35fb306c6ae 100644 --- a/drivers/usbdev/pl2303.c +++ b/drivers/usbdev/pl2303.c @@ -165,6 +165,7 @@ #define PL2303_EPINTIN_ADDR (USB_DIR_IN|CONFIG_PL2303_EPINTIN) #define PL2303_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT) #define PL2303_EPINTIN_MXPACKET (10) +#define PL2303_EPINTIN_MXBURST (0) #define PL2303_EPOUTBULK_ADDR (CONFIG_PL2303_EPBULKOUT) #define PL2303_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK) @@ -293,8 +294,13 @@ static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv, /* Configuration ************************************************************/ static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc); -static void usbclass_mkepbulkdesc(const struct usb_epdesc_s *indesc, - uint16_t mxpacket, struct usb_epdesc_s *outdesc); +static int usbclass_mkepbulkdesc( + FAR const struct usb_epdesc_s *indesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + FAR const struct usb_ss_epcompdesc_s *incompdesc, +#endif + uint8_t speed, + FAR struct usb_epdesc_s *outdesc); static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type); static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv); static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, @@ -441,6 +447,18 @@ static const struct usb_epdesc_s g_epintindesc = 1 /* interval */ }; +#ifdef CONFIG_USBDEV_SUPERSPEED +static const struct usb_ss_epcompdesc_s g_epintincompdesc = +{ + USB_SIZEOF_SS_EPCOMPDESC, + USB_DESC_TYPE_ENDPOINT_COMPANION, + PL2303_EPINTIN_MXBURST, + 0, + { LSBYTE((PL2303_EPINTIN_MXBURST + 1) * PL2303_EPINTIN_MXPACKET), + MSBYTE((PL2303_EPINTIN_MXBURST + 1) * PL2303_EPINTIN_MXPACKET) }, +}; +#endif + static const struct usb_epdesc_s g_epbulkoutdesc = { USB_SIZEOF_EPDESC, /* len */ @@ -451,6 +469,17 @@ static const struct usb_epdesc_s g_epbulkoutdesc = 0 /* interval */ }; +#ifdef CONFIG_USBDEV_SUPERSPEED +static const struct usb_ss_epcompdesc_s g_epbulkoutcompdesc = +{ + USB_SIZEOF_SS_EPCOMPDESC, + USB_DESC_TYPE_ENDPOINT_COMPANION, + CONFIG_PL2303_EPBULK_MAXBURST, + CONFIG_PL2303_EPBULK_MAXSTREAM, + { 0, 0 }, +}; +#endif + static const struct usb_epdesc_s g_epbulkindesc = { USB_SIZEOF_EPDESC, /* len */ @@ -461,6 +490,17 @@ static const struct usb_epdesc_s g_epbulkindesc = 0 /* interval */ }; +#ifdef CONFIG_USBDEV_SUPERSPEED +static const struct usb_ss_epcompdesc_s g_epbulkincompdesc = +{ + USB_SIZEOF_SS_EPCOMPDESC, + USB_DESC_TYPE_ENDPOINT_COMPANION, + CONFIG_PL2303_EPBULK_MAXBURST, + CONFIG_PL2303_EPBULK_MAXSTREAM, + { 0, 0 }, +}; +#endif + #ifdef CONFIG_USBDEV_DUALSPEED static const struct usb_qualdesc_s g_qualdesc = { @@ -823,6 +863,41 @@ static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) return strdesc->len; } +/**************************************************************************** + * Name: usbclass_mkepintdesc + * + * Description: + * Construct the interrupt endpoint descriptor + * + ****************************************************************************/ + +static int usbclass_mkepintdesc( + FAR const struct usb_epdesc_s *indesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + FAR const struct usb_ss_epcompdesc_s *incompdesc, +#endif + uint8_t speed, + FAR struct usb_epdesc_s *outdesc) +{ + int len = sizeof(struct usb_epdesc_s); + + memcpy(outdesc, indesc, USB_SIZEOF_EPDESC); + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed >= USB_SPEED_SUPER) + { + FAR struct usb_ss_epcompdesc_s *outcompdesc = + (FAR struct usb_ss_epcompdesc_s *)(outdesc++); + memcpy(outcompdesc, incompdesc, USB_SIZEOF_SS_EPCOMPDESC); + len += sizeof(struct usb_ss_epcompdesc_s); + } +#else + UNUSED(speed); +#endif + + return len; +} + /**************************************************************************** * Name: usbclass_mkepbulkdesc * @@ -831,11 +906,33 @@ static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc) * ****************************************************************************/ -static inline void usbclass_mkepbulkdesc( - FAR const struct usb_epdesc_s *indesc, - uint16_t mxpacket, - FAR struct usb_epdesc_s *outdesc) +static int usbclass_mkepbulkdesc( + FAR const struct usb_epdesc_s *indesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + FAR const struct usb_ss_epcompdesc_s *incompdesc, +#endif + uint8_t speed, + FAR struct usb_epdesc_s *outdesc) { + int len = sizeof(struct usb_epdesc_s); + uint16_t mxpacket = CONFIG_PL2303_EPBULK_FSSIZE; + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed >= USB_SPEED_SUPER) + { + mxpacket = CONFIG_PL2303_EPBULK_SSSIZE; + } + else +#endif +#ifdef CONFIG_USBDEV_DUALSPEED + if (speed == USB_SPEED_HIGH) + { + mxpacket = CONFIG_PL2303_EPBULK_HSSIZE; + } +#else + UNUSED(speed); +#endif + /* Copy the canned descriptor */ memcpy(outdesc, indesc, USB_SIZEOF_EPDESC); @@ -844,6 +941,34 @@ static inline void usbclass_mkepbulkdesc( outdesc->mxpacketsize[0] = LSBYTE(mxpacket); outdesc->mxpacketsize[1] = MSBYTE(mxpacket); + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed >= USB_SPEED_SUPER) + { + /* Copy the descriptor */ + + FAR struct usb_ss_epcompdesc_s *outcompdesc = + (FAR struct usb_ss_epcompdesc_s *)(outdesc++); + memcpy(outcompdesc, incompdesc, USB_SIZEOF_SS_EPCOMPDESC); + + if (outcompdesc->mxburst >= USB_SS_BULK_EP_MAXBURST) + { + outcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + + if (outcompdesc->attr > USB_SS_BULK_EP_MAXSTREAM) + { + outcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + + outcompdesc->wbytes[0] = 0; + outcompdesc->wbytes[1] = 0; + + len += sizeof(struct usb_ss_epcompdesc_s); + } +#endif + + return len; } /**************************************************************************** @@ -857,8 +982,8 @@ static inline void usbclass_mkepbulkdesc( static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) { FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf; - uint16_t bulkmxpacket = CONFIG_PL2303_EPBULK_FSSIZE; - uint16_t totallen; + uint16_t totallen = 0; + int ret; /* Check for switches between high and full speed */ @@ -867,13 +992,6 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) speed = speed == USB_SPEED_HIGH ? USB_SPEED_FULL : USB_SPEED_HIGH; } - /* This is the total length of the configuration (not necessarily the - * size that we will be sending now. - */ - - totallen = USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + - PL2303_NENDPOINTS * USB_SIZEOF_EPDESC; - /* Configuration descriptor -- Copy the canned descriptor and fill in the * type (we'll also need to update the size below */ @@ -881,34 +999,41 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) memcpy(cfgdesc, &g_cfgdesc, USB_SIZEOF_CFGDESC); cfgdesc->type = type; buf += USB_SIZEOF_CFGDESC; + totallen += USB_SIZEOF_CFGDESC; /* Copy the canned interface descriptor */ memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC); buf += USB_SIZEOF_IFDESC; + totallen += USB_SIZEOF_IFDESC; - memcpy(buf, &g_epintindesc, USB_SIZEOF_EPDESC); - buf += USB_SIZEOF_EPDESC; - + ret = usbclass_mkepintdesc(&g_epintindesc, #ifdef CONFIG_USBDEV_SUPERSPEED - if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) - { - bulkmxpacket = CONFIG_PL2303_EPBULK_SSSIZE; - } - else -#endif -#ifdef CONFIG_USBDEV_DUALSPEED - if (speed == USB_SPEED_HIGH) - { - bulkmxpacket = CONFIG_PL2303_EPBULK_HSSIZE; - } + &g_epintincompdesc, #endif + speed, + (FAR struct usb_epdesc_s *)buf); - usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, - (FAR struct usb_epdesc_s *)buf); - buf += USB_SIZEOF_EPDESC; - usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, - (FAR struct usb_epdesc_s *)buf); + buf += ret; + totallen += ret; + + ret = usbclass_mkepbulkdesc(&g_epbulkoutdesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + &g_epbulkoutcompdesc, +#endif + speed, + (FAR struct usb_epdesc_s *)buf); + buf += ret; + totallen += ret; + + ret = usbclass_mkepbulkdesc(&g_epbulkindesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + &g_epbulkincompdesc, +#endif + speed, + (FAR struct usb_epdesc_s *)buf); + buf += ret; + totallen += ret; /* Finally, fill in the total size of the configuration descriptor */ @@ -965,8 +1090,7 @@ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv) static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) { FAR struct usbdev_req_s *req; - struct usb_epdesc_s epdesc; - uint16_t bulkmxpacket = CONFIG_PL2303_EPBULK_FSSIZE; + struct usb_ss_epdesc_s epdesc; int i; int ret = 0; @@ -1008,7 +1132,13 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) /* Configure the IN interrupt endpoint */ - ret = EP_CONFIGURE(priv->epintin, &g_epintindesc, false); + usbclass_mkepintdesc(&g_epintindesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + &g_epintincompdesc, +#endif + priv->usbdev->speed, + &epdesc.epdesc); + ret = EP_CONFIGURE(priv->epintin, &epdesc.epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0); @@ -1019,23 +1149,14 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) /* Configure the IN bulk endpoint */ + usbclass_mkepbulkdesc(&g_epbulkindesc, #ifdef CONFIG_USBDEV_SUPERSPEED - if (priv->usbdev->speed == USB_SPEED_SUPER || - priv->usbdev->speed == USB_SPEED_SUPER_PLUS) - { - bulkmxpacket = CONFIG_PL2303_EPBULK_SSSIZE; - } - else -#endif -#ifdef CONFIG_USBDEV_DUALSPEED - if (priv->usbdev->speed == USB_SPEED_HIGH) - { - bulkmxpacket = CONFIG_PL2303_EPBULK_HSSIZE; - } + &g_epbulkincompdesc, #endif + priv->usbdev->speed, + &epdesc.epdesc); - usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, &epdesc); - ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false); + ret = EP_CONFIGURE(priv->epbulkin, &epdesc.epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0); @@ -1046,8 +1167,13 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) /* Configure the OUT bulk endpoint */ - usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, &epdesc); - ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true); + usbclass_mkepbulkdesc(&g_epbulkoutdesc, +#ifdef CONFIG_USBDEV_SUPERSPEED + &g_epbulkoutcompdesc, +#endif + priv->usbdev->speed, + &epdesc.epdesc); + ret = EP_CONFIGURE(priv->epbulkout, &epdesc.epdesc, true); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0); @@ -1330,20 +1456,32 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, /* Pre-allocate read requests. The buffer size is one full packet. */ -#ifdef CONFIG_USBDEV_SUPERSPEED +#if defined(CONFIG_USBDEV_SUPERSPEED) if (dev->speed == USB_SPEED_SUPER || dev->speed == USB_SPEED_SUPER_PLUS) { - reqlen = CONFIG_PL2303_EPBULK_SSSIZE; + if (CONFIG_PL2303_EPBULK_MAXBURST < USB_SS_BULK_EP_MAXBURST) + { + reqlen = CONFIG_PL2303_EPBULK_SSSIZE * + (CONFIG_PL2303_EPBULK_MAXBURST + 1); + } + else + { + reqlen = CONFIG_PL2303_EPBULK_SSSIZE * USB_SS_BULK_EP_MAXBURST; + } } else #endif -#ifdef CONFIG_USBDEV_DUALSPEED +#if defined(CONFIG_USBDEV_DUALSPEED) if (dev->speed == USB_SPEED_HIGH) { reqlen = CONFIG_PL2303_EPBULK_HSSIZE; } + else #endif + { + reqlen = CONFIG_PL2303_EPBULK_FSSIZE; + } for (i = 0; i < CONFIG_PL2303_NRDREQS; i++) { diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c index 3ad72229c5f..4b355fb12ba 100644 --- a/drivers/usbdev/rndis.c +++ b/drivers/usbdev/rndis.c @@ -343,22 +343,33 @@ static const struct usbdev_epinfo_s g_rndis_epintindesc = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, #ifndef CONFIG_RNDIS_COMPOSITE - .addr = RNDIS_EPINTIN_ADDR, + .addr = RNDIS_EPINTIN_ADDR, #endif - .attr = USB_EP_ATTR_XFER_INT, - .interval = 1 + .attr = USB_EP_ATTR_XFER_INT, + .interval = 1 }, - .fssize = CONFIG_RNDIS_EPINTIN_FSSIZE, + .reqnum = 1, + .fssize = CONFIG_RNDIS_EPINTIN_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_RNDIS_EPINTIN_HSSIZE, + .hssize = CONFIG_RNDIS_EPINTIN_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_RNDIS_EPINTIN_HSSIZE, + .sssize = CONFIG_RNDIS_EPINTIN_HSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_RNDIS_EPINTIN_MAXBURST, + .attr = 0, + .wbytes[0] = LSBYTE((CONFIG_RNDIS_EPINTIN_MAXBURST + 1) * + CONFIG_RNDIS_EPINTIN_HSSIZE), + .wbytes[1] = MSBYTE((CONFIG_RNDIS_EPINTIN_MAXBURST + 1) * + CONFIG_RNDIS_EPINTIN_HSSIZE), + }, #endif - .reqnum = 1, }; /* Data interface descriptor */ @@ -382,26 +393,35 @@ static const struct usbdev_epinfo_s g_rndis_epbulkindesc = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, #ifndef CONFIG_RNDIS_COMPOSITE - .addr = RNDIS_EPBULKIN_ADDR, + .addr = RNDIS_EPBULKIN_ADDR, #endif - .attr = USB_EP_ATTR_XFER_BULK, + .attr = USB_EP_ATTR_XFER_BULK, #ifdef CONFIG_USBDEV_DUALSPEED - .interval = 0 + .interval = 0 #else - .interval = 1 + .interval = 1 #endif }, - .fssize = CONFIG_RNDIS_EPBULKIN_FSSIZE, + .reqnum = 1, + .fssize = CONFIG_RNDIS_EPBULKIN_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_RNDIS_EPBULKIN_HSSIZE, + .hssize = CONFIG_RNDIS_EPBULKIN_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_RNDIS_EPBULKIN_SSSIZE, + .sssize = CONFIG_RNDIS_EPBULKIN_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_RNDIS_EPBULKIN_MAXBURST, + .attr = CONFIG_RNDIS_EPBULKIN_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = 1, }; /* Bulk out interface descriptor */ @@ -410,26 +430,35 @@ static const struct usbdev_epinfo_s g_rndis_epbulkoutdesc = { .desc = { - .len = USB_SIZEOF_EPDESC, - .type = USB_DESC_TYPE_ENDPOINT, + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, #ifndef CONFIG_RNDIS_COMPOSITE - .addr = RNDIS_EPBULKOUT_ADDR, + .addr = RNDIS_EPBULKOUT_ADDR, #endif - .attr = USB_EP_ATTR_XFER_BULK, + .attr = USB_EP_ATTR_XFER_BULK, #ifdef CONFIG_USBDEV_DUALSPEED - .interval = 0 + .interval = 0 #else - .interval = 1 + .interval = 1 #endif }, - .fssize = CONFIG_RNDIS_EPBULKOUT_FSSIZE, + .reqnum = 1, + .fssize = CONFIG_RNDIS_EPBULKOUT_FSSIZE, #ifdef CONFIG_USBDEV_DUALSPEED - .hssize = CONFIG_RNDIS_EPBULKOUT_HSSIZE, + .hssize = CONFIG_RNDIS_EPBULKOUT_HSSIZE, #endif #ifdef CONFIG_USBDEV_SUPERSPEED - .sssize = CONFIG_RNDIS_EPBULKOUT_SSSIZE, + .sssize = CONFIG_RNDIS_EPBULKOUT_SSSIZE, + .compdesc = + { + .len = USB_SIZEOF_SS_EPCOMPDESC, + .type = USB_DESC_TYPE_ENDPOINT_COMPANION, + .mxburst = CONFIG_RNDIS_EPBULKOUT_MAXBURST, + .attr = CONFIG_RNDIS_EPBULKOUT_MAXSTREAM, + .wbytes[0] = 0, + .wbytes[1] = 0, + }, #endif - .reqnum = 1, }; /* Default MAC address given to the host side of the interface. */ @@ -1915,6 +1944,7 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type) { uint16_t totallen = 0; + int ret; /* Check for switches between high and full speed */ @@ -1977,18 +2007,17 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, totallen += sizeof(struct usb_ifdesc_s); + ret = usbdev_copy_epdesc((struct usb_epdesc_s *)buf, + devinfo->epno[RNDIS_EP_INTIN_IDX], + speed, + &g_rndis_epintindesc); + if (buf != NULL) { - usbdev_copy_epdesc((struct usb_epdesc_s *)buf, - devinfo->epno[RNDIS_EP_INTIN_IDX], - speed, - &g_rndis_epintindesc - ); - - buf += USB_SIZEOF_EPDESC; + buf += ret; } - totallen += USB_SIZEOF_EPDESC; + totallen += ret; if (buf != NULL) { @@ -2003,31 +2032,27 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, totallen += sizeof(struct usb_ifdesc_s); + ret = usbdev_copy_epdesc((struct usb_epdesc_s *)buf, + devinfo->epno[RNDIS_EP_BULKIN_IDX], + speed, + &g_rndis_epbulkindesc); if (buf != NULL) { - usbdev_copy_epdesc((struct usb_epdesc_s *)buf, - devinfo->epno[RNDIS_EP_BULKIN_IDX], - speed, - &g_rndis_epbulkindesc - ); - - buf += USB_SIZEOF_EPDESC; + buf += ret; } - totallen += USB_SIZEOF_EPDESC; + totallen += ret; + ret = usbdev_copy_epdesc((struct usb_epdesc_s *)buf, + devinfo->epno[RNDIS_EP_BULKOUT_IDX], + speed, + &g_rndis_epbulkoutdesc); if (buf != NULL) { - usbdev_copy_epdesc((struct usb_epdesc_s *)buf, - devinfo->epno[RNDIS_EP_BULKOUT_IDX], - speed, - &g_rndis_epbulkoutdesc - ); - - buf += USB_SIZEOF_EPDESC; + buf += ret; } - totallen += USB_SIZEOF_EPDESC; + totallen += ret; return totallen; } @@ -2140,7 +2165,32 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, /* Pre-allocate read requests. The buffer size is one full packet. */ - reqlen = 64; +#if defined(CONFIG_USBDEV_SUPERSPEED) + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + if (CONFIG_RNDIS_EPBULKOUT_MAXBURST < USB_SS_BULK_EP_MAXBURST) + { + reqlen = CONFIG_RNDIS_EPBULKOUT_SSSIZE * + (CONFIG_RNDIS_EPBULKOUT_MAXBURST + 1); + } + else + { + reqlen = CONFIG_RNDIS_EPBULKOUT_SSSIZE * USB_SS_BULK_EP_MAXBURST; + } + } + else +#endif +#if defined(CONFIG_USBDEV_DUALSPEED) + if (dev->speed == USB_SPEED_HIGH) + { + reqlen = CONFIG_RNDIS_EPBULKOUT_HSSIZE; + } + else +#endif + { + reqlen = CONFIG_RNDIS_EPBULKOUT_FSSIZE; + } if (CONFIG_RNDIS_BULKOUT_REQLEN > reqlen) { @@ -2171,6 +2221,37 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, } else { +#if defined(CONFIG_USBDEV_SUPERSPEED) + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + if (CONFIG_RNDIS_EPBULKIN_MAXBURST < USB_SS_BULK_EP_MAXBURST) + { + reqlen = CONFIG_RNDIS_EPBULKIN_SSSIZE * + (CONFIG_RNDIS_EPBULKIN_MAXBURST + 1); + } + else + { + reqlen = CONFIG_RNDIS_EPBULKIN_SSSIZE * + USB_SS_BULK_EP_MAXBURST; + } + } + else + #endif + #if defined(CONFIG_USBDEV_DUALSPEED) + if (dev->speed == USB_SPEED_HIGH) + { + reqlen = CONFIG_RNDIS_EPBULKIN_HSSIZE; + } + else + #endif + { + reqlen = CONFIG_RNDIS_EPBULKIN_FSSIZE; + } + } + + if (CONFIG_RNDIS_BULKIN_REQLEN > reqlen) + { reqlen = CONFIG_RNDIS_BULKIN_REQLEN; } @@ -2665,7 +2746,7 @@ 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; + struct usb_ss_epdesc_s epdesc; int ret = 0; #ifdef CONFIG_DEBUG_FEATURES @@ -2706,11 +2787,11 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the IN interrupt endpoint */ - usbdev_copy_epdesc(&epdesc, + usbdev_copy_epdesc(&epdesc.epdesc, priv->devinfo.epno[RNDIS_EP_INTIN_IDX], priv->usbdev->speed, &g_rndis_epintindesc); - ret = EP_CONFIGURE(priv->epintin, &epdesc, false); + ret = EP_CONFIGURE(priv->epintin, &epdesc.epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0); @@ -2721,12 +2802,11 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the IN bulk endpoint */ - usbdev_copy_epdesc(&epdesc, + usbdev_copy_epdesc(&epdesc.epdesc, priv->devinfo.epno[RNDIS_EP_BULKIN_IDX], priv->usbdev->speed, &g_rndis_epbulkindesc); - ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false); - + ret = EP_CONFIGURE(priv->epbulkin, &epdesc.epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0); @@ -2737,12 +2817,11 @@ static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config) /* Configure the OUT bulk endpoint */ - usbdev_copy_epdesc(&epdesc, + usbdev_copy_epdesc(&epdesc.epdesc, priv->devinfo.epno[RNDIS_EP_BULKOUT_IDX], priv->usbdev->speed, &g_rndis_epbulkoutdesc); - ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true); - + ret = EP_CONFIGURE(priv->epbulkout, &epdesc.epdesc, true); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0); diff --git a/drivers/usbdev/usbdev_desc.c b/drivers/usbdev/usbdev_desc.c index 7d2594e1179..206b49d203e 100644 --- a/drivers/usbdev/usbdev_desc.c +++ b/drivers/usbdev/usbdev_desc.c @@ -65,6 +65,57 @@ int usbdev_copy_devdesc(FAR void *dest, return USB_SIZEOF_DEVDESC; } +/**************************************************************************** + * Name: usbdev_copy_epcompdesc + * + * Description: + * Copies the Endpoint Companion Description into the buffer given. + * Returns the number of Bytes filled in. + * This function is provided by various classes. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_SUPERSPEED +static void +usbdev_copy_epcompdesc(FAR struct usb_ss_epcompdesc_s *epcompdesc, + FAR const struct usbdev_epinfo_s *epinfo) +{ + uint8_t transtpye; + + memcpy(epcompdesc, &epinfo->compdesc, sizeof(struct usb_ss_epcompdesc_s)); + + transtpye = epinfo->desc.attr & USB_EP_ATTR_XFERTYPE_MASK; + if (transtpye == USB_EP_ATTR_XFER_BULK) + { + if (epcompdesc->mxburst >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + + if (epcompdesc->attr > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + else if(transtpye == USB_EP_ATTR_XFER_INT) + { + if (epcompdesc->mxburst >= USB_SS_INT_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_INT_EP_MAXBURST - 1; + epcompdesc->wbytes[0] = LSBYTE((epcompdesc->mxburst + 1) * + epinfo->sssize); + epcompdesc->wbytes[1] = MSBYTE((epcompdesc->mxburst + 1) * + epinfo->sssize); + } + + epcompdesc->attr = 0; + } +} +#endif + /**************************************************************************** * Name: usbdev_copy_epdesc * @@ -75,14 +126,28 @@ int usbdev_copy_devdesc(FAR void *dest, * ****************************************************************************/ -void usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, - uint8_t epno, uint8_t speed, - FAR const struct usbdev_epinfo_s *epinfo) +int usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, + uint8_t epno, uint8_t speed, + FAR const struct usbdev_epinfo_s *epinfo) { #if !defined(CONFIG_USBDEV_DUALSPEED) && !defined(CONFIG_USBDEV_SUPERSPEED) UNUSED(speed); #endif + int len = sizeof(struct usb_epdesc_s); + +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + len += sizeof(struct usb_ss_epcompdesc_s); + } +#endif + + if (epdesc == NULL) + { + return len; + } + memcpy(epdesc, &epinfo->desc, sizeof(struct usb_epdesc_s)); epdesc->addr |= epno; @@ -93,6 +158,12 @@ void usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, epdesc->mxpacketsize[0] = LSBYTE(epinfo->sssize); epdesc->mxpacketsize[1] = MSBYTE(epinfo->sssize); + + /* Copy endpoint companion description */ + + epdesc++; + usbdev_copy_epcompdesc((FAR struct usb_ss_epcompdesc_s *)epdesc, + epinfo); } else #endif @@ -112,4 +183,6 @@ void usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, epdesc->mxpacketsize[0] = LSBYTE(epinfo->fssize); epdesc->mxpacketsize[1] = MSBYTE(epinfo->fssize); } + + return len; } diff --git a/drivers/usbdev/usbdev_fs.c b/drivers/usbdev/usbdev_fs.c index 02b53885f6f..16e3a4de099 100644 --- a/drivers/usbdev/usbdev_fs.c +++ b/drivers/usbdev/usbdev_fs.c @@ -961,6 +961,38 @@ static int usbdev_fs_ep_bind(FAR struct usbdev_s *dev, uint8_t epno, return -ENODEV; } +#ifdef CONFIG_USBDEV_SUPERSPEED + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + uint8_t transtpye; + + transtpye = epinfo->desc.attr & USB_EP_ATTR_XFERTYPE_MASK; + if (transtpye == USB_EP_ATTR_XFER_BULK) + { + if (epinfo->compdesc.mxburst >= USB_SS_BULK_EP_MAXBURST) + { + reqsize = reqsize * USB_SS_BULK_EP_MAXBURST; + } + else + { + reqsize = reqsize * (epinfo->compdesc.mxburst + 1); + } + } + else if (transtpye == USB_EP_ATTR_XFER_INT) + { + if (epinfo->compdesc.mxburst >= USB_SS_INT_EP_MAXBURST) + { + reqsize = reqsize * USB_SS_INT_EP_MAXBURST; + } + else + { + reqsize = reqsize * (epinfo->compdesc.mxburst + 1); + } + } + } +#endif + fs_ep->ep->fs = fs_ep; /* Initialize request buffer */ @@ -1144,7 +1176,7 @@ static int usbdev_fs_classsetconfig(FAR struct usbdev_fs_dev_s *fs, uint8_t config) { FAR struct usbdev_devinfo_s *devinfo = &fs->devinfo; - struct usb_epdesc_s epdesc; + struct usb_ss_epdesc_s epdesc; uint16_t i; uint16_t j; int ret; @@ -1165,9 +1197,9 @@ static int usbdev_fs_classsetconfig(FAR struct usbdev_fs_dev_s *fs, { FAR struct usbdev_fs_ep_s *fs_ep = &fs->eps[i]; - usbdev_copy_epdesc(&epdesc, devinfo->epno[i], + usbdev_copy_epdesc(&epdesc.epdesc, devinfo->epno[i], fs->cdev->usbdev->speed, devinfo->epinfos[i]); - ret = EP_CONFIGURE(fs_ep->ep, &epdesc, + ret = EP_CONFIGURE(fs_ep->ep, &epdesc.epdesc, (i == (devinfo->nendpoints - 1))); if (ret < 0) { diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index a9ff5888e94..ff7dc703fc7 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -260,9 +260,22 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++) { - reqcontainer = &priv->rdreqs[i]; - reqcontainer->req = usbdev_allocreq(priv->epbulkout, - CONFIG_USBMSC_BULKOUTREQLEN); + reqcontainer = &priv->rdreqs[i]; +#ifdef CONFIG_USBDEV_SUPERSPEED + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + reqcontainer->req = usbdev_allocreq(priv->epbulkout, + USBMSC_SSBULKMAXPACKET * + (USBMSC_SSBULKMAXBURST + 1)); + } + else +#endif + { + reqcontainer->req = usbdev_allocreq(priv->epbulkout, + CONFIG_USBMSC_BULKOUTREQLEN); + } + if (reqcontainer->req == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDALLOCREQ), @@ -279,9 +292,22 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, for (i = 0; i < CONFIG_USBMSC_NWRREQS; i++) { - reqcontainer = &priv->wrreqs[i]; - reqcontainer->req = usbdev_allocreq(priv->epbulkin, - CONFIG_USBMSC_BULKINREQLEN); + reqcontainer = &priv->wrreqs[i]; +#ifdef CONFIG_USBDEV_SUPERSPEED + if (dev->speed == USB_SPEED_SUPER || + dev->speed == USB_SPEED_SUPER_PLUS) + { + reqcontainer->req = usbdev_allocreq(priv->epbulkin, + USBMSC_SSBULKMAXPACKET * + (USBMSC_SSBULKMAXBURST + 1)); + } + else +#endif + { + reqcontainer->req = usbdev_allocreq(priv->epbulkin, + CONFIG_USBMSC_BULKINREQLEN); + } + if (reqcontainer->req == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRALLOCREQ), @@ -869,7 +895,7 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) { FAR struct usbmsc_req_s *privreq; FAR struct usbdev_req_s *req; - struct usb_epdesc_s epdesc; + struct usb_ss_epdesc_s epdesc; int i; int ret = 0; @@ -911,9 +937,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) /* Configure the IN bulk endpoint */ - usbmsc_copy_epdesc(USBMSC_EPBULKIN, &epdesc, &priv->devinfo, + usbmsc_copy_epdesc(USBMSC_EPBULKIN, &epdesc.epdesc, &priv->devinfo, priv->usbdev->speed); - ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false); + ret = EP_CONFIGURE(priv->epbulkin, &epdesc.epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0); @@ -924,9 +950,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) /* Configure the OUT bulk endpoint */ - usbmsc_copy_epdesc(USBMSC_EPBULKOUT, &epdesc, &priv->devinfo, + usbmsc_copy_epdesc(USBMSC_EPBULKOUT, &epdesc.epdesc, &priv->devinfo, priv->usbdev->speed); - ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true); + ret = EP_CONFIGURE(priv->epbulkout, &epdesc.epdesc, true); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0); diff --git a/drivers/usbdev/usbmsc.h b/drivers/usbdev/usbmsc.h index 2ebf741ed20..80d67c9a592 100644 --- a/drivers/usbdev/usbmsc.h +++ b/drivers/usbdev/usbmsc.h @@ -197,12 +197,6 @@ # define CONFIG_USBMSC_SCSI_STACKSIZE 2048 #endif -/* Packet and request buffer sizes */ - -#ifndef CONFIG_USBMSC_EP0MAXPACKET -# define CONFIG_USBMSC_EP0MAXPACKET 64 -#endif - /* USB Controller */ #ifdef CONFIG_USBDEV_SELFPOWERED @@ -301,6 +295,8 @@ #define USBMSC_MKEPBULKIN(devDesc) (USB_DIR_IN | (devDesc)->epno[USBMSC_EP_BULKIN_IDX]) #define USBMSC_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK) +#define USBMSC_SSBULKMAXSTREAM (0) +#define USBMSC_SSBULKMAXBURST (0) #define USBMSC_SSBULKMAXPACKET (1024) #define USBMSC_SSBULKMXPKTSHIFT (10) #define USBMSC_SSBULKMXPKTMASK (0x000003ff) diff --git a/drivers/usbdev/usbmsc_desc.c b/drivers/usbdev/usbmsc_desc.c index b6e211d21e7..945241249e8 100644 --- a/drivers/usbdev/usbmsc_desc.c +++ b/drivers/usbdev/usbmsc_desc.c @@ -213,6 +213,56 @@ FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void) } #endif +/**************************************************************************** + * Name: usbmsc_copy_epcompdesc + * + * Description: + * Construct the endpoint companion descriptor + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_SUPERSPEED +static void +usbmsc_copy_epcompdesc(enum usbmsc_epdesc_e epid, + FAR struct usb_ss_epcompdesc_s *epcompdesc) +{ + switch (epid) + { + case USBMSC_EPBULKOUT: /* Bulk OUT endpoint */ + case USBMSC_EPBULKIN: /* Bulk IN endpoint */ + { + epcompdesc->len = USB_SIZEOF_SS_EPCOMPDESC; /* Descriptor length */ + epcompdesc->type = USB_DESC_TYPE_ENDPOINT_COMPANION; /* Descriptor type */ + + if (USBMSC_SSBULKMAXBURST >= USB_SS_BULK_EP_MAXBURST) + { + epcompdesc->mxburst = USB_SS_BULK_EP_MAXBURST - 1; + } + else + { + epcompdesc->mxburst = USBMSC_SSBULKMAXBURST; + } + + if (USBMSC_SSBULKMAXSTREAM > USB_SS_BULK_EP_MAXSTREAM) + { + epcompdesc->attr = USB_SS_BULK_EP_MAXSTREAM; + } + else + { + epcompdesc->attr = USBMSC_SSBULKMAXSTREAM; + } + + epcompdesc->wbytes[0] = 0; + epcompdesc->wbytes[1] = 0; + } + break; + + default: + break; + } +} +#endif + /**************************************************************************** * Name: usbmsc_copy_epdesc * @@ -227,10 +277,24 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed) { + int len = sizeof(struct usb_epdesc_s); + #if !defined(CONFIG_USBDEV_DUALSPEED) && !defined(CONFIG_USBDEV_SUPERSPEED) UNUSED(speed); #endif +#ifdef CONFIG_USBDEV_SUPERSPEED + if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) + { + len += sizeof(struct usb_ss_epcompdesc_s); + } +#endif + + if (epdesc == NULL) + { + return len; + } + switch (epid) { case USBMSC_EPBULKOUT: /* Bulk OUT endpoint */ @@ -247,6 +311,12 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, epdesc->mxpacketsize[0] = LSBYTE(USBMSC_SSBULKMAXPACKET); epdesc->mxpacketsize[1] = MSBYTE(USBMSC_SSBULKMAXPACKET); + + /* Copy endpoint companion description */ + + epdesc++; + usbmsc_copy_epcompdesc(epid, + (FAR struct usb_ss_epcompdesc_s *)epdesc); } else #endif @@ -285,6 +355,12 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, epdesc->mxpacketsize[0] = LSBYTE(USBMSC_SSBULKMAXPACKET); epdesc->mxpacketsize[1] = MSBYTE(USBMSC_SSBULKMAXPACKET); + + /* Copy endpoint companion description */ + + epdesc++; + usbmsc_copy_epcompdesc(epid, + (FAR struct usb_ss_epcompdesc_s *)epdesc); } else #endif @@ -313,7 +389,7 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, return 0; } - return sizeof(struct usb_epdesc_s); + return len; } /**************************************************************************** @@ -328,6 +404,9 @@ int16_t usbmsc_mkcfgdesc(uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo, uint8_t speed, uint8_t type) { + int16_t totallen = 0; + int ret; + /* Check for switches between high and full speed */ if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG && speed != USB_SPEED_HIGH) @@ -359,11 +438,12 @@ int16_t usbmsc_mkcfgdesc(uint8_t *buf, dest->cfgvalue = USBMSC_CONFIGID; /* Configuration value */ dest->icfg = USBMSC_CONFIGSTRID; /* Configuration */ dest->attr = USB_CONFIG_ATTR_ONE | /* Attributes */ - USBMSC_SELFPOWERED | - USBMSC_REMOTEWAKEUP; + USBMSC_SELFPOWERED | + USBMSC_REMOTEWAKEUP; dest->mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */ buf += sizeof(struct usb_cfgdesc_s); + totallen += sizeof(struct usb_cfgdesc_s); } #endif @@ -385,6 +465,7 @@ int16_t usbmsc_mkcfgdesc(uint8_t *buf, dest->iif = devinfo->strbase + USBMSC_INTERFACESTRID; /* iInterface */ buf += sizeof(struct usb_ifdesc_s); + totallen += sizeof(struct usb_ifdesc_s); } /* Make the two endpoint configurations */ @@ -392,24 +473,26 @@ int16_t usbmsc_mkcfgdesc(uint8_t *buf, /* Bulk IN endpoint descriptor */ { - int len = usbmsc_copy_epdesc(USBMSC_EPBULKIN, - (FAR struct usb_epdesc_s *)buf, - devinfo, speed); + ret = usbmsc_copy_epdesc(USBMSC_EPBULKIN, + (FAR struct usb_epdesc_s *)buf, + devinfo, speed); - buf += len; + buf += ret; + totallen += ret; } /* Bulk OUT endpoint descriptor */ { - int len = usbmsc_copy_epdesc(USBMSC_EPBULKOUT, - (FAR struct usb_epdesc_s *)buf, devinfo, - speed); + ret = usbmsc_copy_epdesc(USBMSC_EPBULKOUT, + (FAR struct usb_epdesc_s *)buf, devinfo, + speed); - buf += len; + buf += ret; + totallen += ret; } - return SIZEOF_USBMSC_CFGDESC; + return totallen; } /**************************************************************************** diff --git a/include/nuttx/usb/rndis.h b/include/nuttx/usb/rndis.h index aaa17460279..a23146ba3f4 100644 --- a/include/nuttx/usb/rndis.h +++ b/include/nuttx/usb/rndis.h @@ -50,10 +50,18 @@ # define CONFIG_RNDIS_EPINTIN_HSSIZE 16 #endif +#ifdef CONFIG_USBDEV_SUPERSPEED + #ifndef CONFIG_RNDIS_EPINTIN_SSSIZE # define CONFIG_RNDIS_EPINTIN_SSSIZE 16 #endif +#ifndef CONFIG_RNDIS_EPINTIN_MAXBURST +# define CONFIG_RNDIS_EPINTIN_MAXBURST 0 +#endif + +#endif + #ifndef CONFIG_RNDIS_EPBULKIN_FSSIZE # define CONFIG_RNDIS_EPBULKIN_FSSIZE 64 #endif @@ -62,10 +70,22 @@ # define CONFIG_RNDIS_EPBULKIN_HSSIZE 512 #endif +#ifdef CONFIG_USBDEV_SUPERSPEED + #ifndef CONFIG_RNDIS_EPBULKIN_SSSIZE # define CONFIG_RNDIS_EPBULKIN_SSSIZE 1024 #endif +#ifndef CONFIG_RNDIS_EPBULKIN_MAXBURST +# define CONFIG_RNDIS_EPBULKIN_MAXBURST 0 +#endif + +#ifndef CONFIG_RNDIS_EPBULKIN_MAXSTREAM +# define CONFIG_RNDIS_EPBULKIN_MAXSTREAM 0 +#endif + +#endif + #ifndef CONFIG_RNDIS_EPBULKOUT_FSSIZE # define CONFIG_RNDIS_EPBULKOUT_FSSIZE 64 #endif @@ -74,10 +94,22 @@ # define CONFIG_RNDIS_EPBULKOUT_HSSIZE 512 #endif +#ifdef CONFIG_USBDEV_SUPERSPEED + #ifndef CONFIG_RNDIS_EPBULKOUT_SSSIZE # define CONFIG_RNDIS_EPBULKOUT_SSSIZE 1024 #endif +#ifndef CONFIG_RNDIS_EPBULKOUT_MAXBURST +# define CONFIG_RNDIS_EPBULKOUT_MAXBURST 0 +#endif + +#ifndef CONFIG_RNDIS_EPBULKOUT_MAXSTREAM +# define CONFIG_RNDIS_EPBULKOUT_MAXSTREAM 0 +#endif + +#endif + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/include/nuttx/usb/usb.h b/include/nuttx/usb/usb.h index d9286bcebfc..be6888332c6 100644 --- a/include/nuttx/usb/usb.h +++ b/include/nuttx/usb/usb.h @@ -198,6 +198,8 @@ #define USB_DESC_TYPE_CSSTRING (0x23) #define USB_DESC_TYPE_CSINTERFACE (0x24) #define USB_DESC_TYPE_CSENDPOINT (0x25) +#define USB_DESC_TYPE_ENDPOINT_COMPANION (0x30) +#define USB_DESC_TYPE_ISO_ENDPOINT_COMPANION (0x31) /* Device and interface descriptor class codes */ @@ -274,6 +276,12 @@ #define USB_MAX_DEVICES (127) +/* Maximum burst number of super speed devices */ + +#define USB_SS_INT_EP_MAXBURST (3) +#define USB_SS_BULK_EP_MAXBURST (16) +#define USB_SS_BULK_EP_MAXSTREAM (16) + /* Microsoft OS Descriptor specific values */ #define USB_REQ_GETMSFTOSDESCRIPTOR (0xEE) @@ -407,6 +415,35 @@ struct usb_audioepdesc_s #define USB_SIZEOF_AUDIOEPDESC 9 +/* Super speed endpoint companion descriptor */ + +struct usb_ss_epcompdesc_s +{ + uint8_t len; + uint8_t type; + uint8_t mxburst; + uint8_t attr; + uint8_t wbytes[2]; +}; + +#define USB_SIZEOF_SS_EPCOMPDESC 6 + +/* Super speed endpoint descriptor */ + +struct usb_ss_epdesc_s +{ + struct usb_epdesc_s epdesc; +#ifdef CONFIG_USBDEV_SUPERSPEED + struct usb_ss_epcompdesc_s epcompdesc; +#endif +}; + +#ifdef CONFIG_USBDEV_SUPERSPEED + #define USB_SIZEOF_SS_EPDESC 13 +#else + #define USB_SIZEOF_SS_EPDESC 7 +#endif + /* Device qualifier descriptor */ struct usb_qualdesc_s diff --git a/include/nuttx/usb/usbdev.h b/include/nuttx/usb/usbdev.h index d75e0e3f76c..dffb391c3f1 100644 --- a/include/nuttx/usb/usbdev.h +++ b/include/nuttx/usb/usbdev.h @@ -193,14 +193,15 @@ struct usbdev_devdescs_s struct usbdev_epinfo_s { struct usb_epdesc_s desc; + uint16_t reqnum; uint16_t fssize; #ifdef CONFIG_USBDEV_DUALSPEED uint16_t hssize; #endif #ifdef CONFIG_USBDEV_SUPERSPEED uint16_t sssize; + struct usb_ss_epcompdesc_s compdesc; #endif - uint16_t reqnum; }; /* usbdev_devinfo_s - describes the low level bindings of an usb device */ @@ -434,9 +435,9 @@ int usbdev_copy_devdesc(FAR void *dest, * ****************************************************************************/ -void usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, - uint8_t epno, uint8_t speed, - FAR const struct usbdev_epinfo_s *epinfo); +int usbdev_copy_epdesc(FAR struct usb_epdesc_s *epdesc, + uint8_t epno, uint8_t speed, + FAR const struct usbdev_epinfo_s *epinfo); /**************************************************************************** * Name: usbdevclass_register