diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c index 54bc3c827e..94462e7167 100644 --- a/drivers/usbdev/composite.c +++ b/drivers/usbdev/composite.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/composite.c * - * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -60,16 +60,6 @@ * Private Types ****************************************************************************/ -/* This structure describes the internal state of the driver */ - -struct composite_dev_s -{ - FAR struct usbdev_s *usbdev; /* usbdev driver pointer */ - uint8_t config; /* Configuration number */ - FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */ - struct usbdevclass_driver_s *dev1; /* Device 1 class object */ - struct usbdevclass_driver_s *dev2; /* Device 2 class object */ -}; /* The internal version of the class driver */ @@ -146,9 +136,6 @@ const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Helpers - ****************************************************************************/ /**************************************************************************** * Name: composite_ep0incomplete @@ -165,7 +152,8 @@ static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep, if (req->result || req->xfrd != req->len) { - usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT), (uint16_t)-req->result); + usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT), + (uint16_t)-req->result); } } @@ -185,17 +173,20 @@ static int composite_classsetup(FAR struct composite_dev_s *priv, uint16_t index; uint8_t interface; int ret = -EOPNOTSUPP; + int i; index = GETUINT16(ctrl->index); interface = (uint8_t)(index & 0xff); - if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES)) + for (i = 0; i < priv->ndevices; i++) { - ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen); - } - else if (interface >= DEV2_FIRSTINTERFACE && interface < (DEV2_FIRSTINTERFACE + DEV2_NINTERFACES)) - { - ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen); + if (interface >= priv->device[i].compdesc.devdesc.ifnobase && + interface < (priv->device[i].compdesc.devdesc.ifnobase + + priv->device[i].compdesc.devdesc.ninterfaces)) + { + ret = CLASS_SETUP(priv->device[i].dev, dev, ctrl, dataout, outlen); + break; + } } return ret; @@ -225,6 +216,7 @@ static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep, req = NULL; } } + return req; } @@ -245,6 +237,7 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep, { EP_FREEBUFFER(ep, req->buf); } + EP_FREEREQ(ep, req); } } @@ -266,6 +259,7 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver, { FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s *)driver)->dev; int ret; + int i; usbtrace(TRACE_CLASSBIND, 0); @@ -281,7 +275,7 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver, /* Preallocate one control request */ - priv->ctrlreq = composite_allocreq(dev->ep0, COMPOSITE_CFGDESCSIZE); + priv->ctrlreq = composite_allocreq(dev->ep0, priv->cfgdescsize); if (priv->ctrlreq == NULL) { usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCCTRLREQ), 0); @@ -295,16 +289,13 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver, /* Then bind each of the constituent class drivers */ - ret = CLASS_BIND(priv->dev1, dev); - if (ret < 0) + for (i = 0; i < priv->ndevices; i++) { - goto errout; - } - - ret = CLASS_BIND(priv->dev2, dev); - if (ret < 0) - { - goto errout; + ret = CLASS_BIND(priv->device[i].dev, dev); + if (ret < 0) + { + goto errout; + } } /* Report if we are selfpowered */ @@ -363,11 +354,15 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver, if (priv != NULL) { + int i; + /* Unbind the constituent class drivers */ flags = enter_critical_section(); - CLASS_UNBIND(priv->dev1, dev); - CLASS_UNBIND(priv->dev2, dev); + for (i = 0; i < priv->ndevices; i++) + { + CLASS_UNBIND(priv->device[i].dev, dev); + } /* Free the pre-allocated control request */ @@ -377,6 +372,7 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver, composite_freereq(dev->ep0, priv->ctrlreq); priv->ctrlreq = NULL; } + leave_critical_section(flags); } } @@ -423,6 +419,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, return -ENODEV; } #endif + ctrlreq = priv->ctrlreq; /* Extract the little-endian 16-bit values to host order */ @@ -472,10 +469,10 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, case USB_DESC_TYPE_CONFIG: { #ifdef CONFIG_USBDEV_DUALSPEED - ret = composite_mkcfgdesc(ctrlreq->buf, dev->speed, + ret = composite_mkcfgdesc(priv, ctrlreq->buf, dev->speed, ctrl->value[1]); #else - ret = composite_mkcfgdesc(ctrlreq->buf); + ret = composite_mkcfgdesc(priv, ctrlreq->buf); #endif } break; @@ -491,18 +488,21 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, { ret = composite_mkstrdesc(strid, buf); } -#if DEV1_NSTRIDS > 0 - else if (strid <= DEV1_STRIDBASE + DEV1_NSTRIDS) + else { - ret = DEV1_MKSTRDESC(strid, buf); + int i; + + for (i = 0; i < priv->ndevices; i++) + { + if (strid >= priv->device[i].compdesc.devdesc.strbase && + strid < priv->device[i].compdesc.devdesc.strbase + + priv->device[i].compdesc.devdesc.nstrings) + { + ret = priv->device[i].compdesc.mkstrdesc(strid - priv->device[i].compdesc.devdesc.strbase, buf); + break; + } + } } -#endif -#if DEV2_NSTRIDS > 0 - else if (strid <= DEV2_STRIDBASE + DEV2_NSTRIDS) - { - ret = DEV2_MKSTRDESC(strid, buf); - } -#endif } break; @@ -519,19 +519,17 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, { if (ctrl->type == 0) { + int i; + /* Save the configuration and inform the constituent classes */ - ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen); - dispatched = true; - - if (ret >= 0) + for (i = 0; i < priv->ndevices; i++) { - ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen); - if (ret >= 0) - { - priv->config = value; - } + ret = CLASS_SETUP(priv->device[i].dev, dev, ctrl, dataout, outlen); } + + dispatched = true; + priv->config = value; } } break; @@ -635,6 +633,7 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver, { FAR struct composite_dev_s *priv; irqstate_t flags; + int i; usbtrace(TRACE_CLASSDISCONNECT, 0); @@ -664,8 +663,12 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver, flags = enter_critical_section(); priv->config = COMPOSITE_CONFIGIDNONE; - CLASS_DISCONNECT(priv->dev1, dev); - CLASS_DISCONNECT(priv->dev2, dev); + + for (i = 0; i < priv->ndevices; i++) + { + CLASS_DISCONNECT(priv->device[i].dev, dev); + } + leave_critical_section(flags); /* Perform the soft connect function so that we will we can be @@ -688,6 +691,7 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver, { FAR struct composite_dev_s *priv; irqstate_t flags; + int i; usbtrace(TRACE_CLASSSUSPEND, 0); @@ -714,8 +718,12 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver, /* Forward the suspend event to the constituent devices */ flags = enter_critical_section(); - CLASS_SUSPEND(priv->dev1, priv->usbdev); - CLASS_SUSPEND(priv->dev2, priv->usbdev); + + for (i = 0; i < priv->ndevices; i++) + { + CLASS_SUSPEND(priv->device[i].dev, priv->usbdev); + } + leave_critical_section(flags); } @@ -732,6 +740,7 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver, { FAR struct composite_dev_s *priv = NULL; irqstate_t flags; + int i; #ifdef CONFIG_DEBUG_FEATURES if (!dev) @@ -756,8 +765,12 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver, /* Forward the resume event to the constituent devices */ flags = enter_critical_section(); - CLASS_RESUME(priv->dev1, priv->usbdev); - CLASS_RESUME(priv->dev2, priv->usbdev); + + for (i = 0; i < priv->ndevices; i++) + { + CLASS_RESUME(priv->device[i].dev, priv->usbdev); + } + leave_critical_section(flags); } @@ -786,16 +799,20 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver, * ****************************************************************************/ -FAR void *composite_initialize(void) +FAR void *composite_initialize(uint8_t ndevices, + FAR struct composite_devdesc_s *pdevices) { FAR struct composite_alloc_s *alloc; FAR struct composite_dev_s *priv; FAR struct composite_driver_s *drvr; int ret; + int i; /* Allocate the structures needed */ - alloc = (FAR struct composite_alloc_s *)kmm_malloc(sizeof(struct composite_alloc_s)); + alloc = (FAR struct composite_alloc_s *) + kmm_malloc(sizeof(struct composite_alloc_s)); + if (!alloc) { usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCDEVSTRUCT), 0); @@ -811,21 +828,31 @@ FAR void *composite_initialize(void) memset(priv, 0, sizeof(struct composite_dev_s)); - /* Get the constitueat class driver objects */ + priv->cfgdescsize = USB_SIZEOF_CFGDESC; + priv->ninterfaces = 0; - ret = DEV1_CLASSOBJECT(&priv->dev1); - if (ret < 0) + /* Get the constituent class driver objects */ + + for (i = 0; i < ndevices; i++) { - usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret); - goto errout_with_alloc; + memcpy(&priv->device[i].compdesc, &pdevices[i], + sizeof(struct composite_devdesc_s)); + + ret = priv->device[i].compdesc.board_classobject(priv->device[i].compdesc.minor, + &priv->device[i].compdesc.devdesc, + &priv->device[i].dev); + if (ret < 0) + { + usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), + (uint16_t)-ret); + goto errout_with_alloc; + } + + priv->cfgdescsize += priv->device[i].compdesc.cfgdescsize; + priv->ninterfaces += priv->device[i].compdesc.devdesc.ninterfaces; } - ret = DEV2_CLASSOBJECT(&priv->dev2); - if (ret < 0) - { - usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret); - goto errout_with_alloc; - } + priv->ndevices = ndevices; /* Initialize the USB class driver structure */ @@ -875,6 +902,7 @@ void composite_uninitialize(FAR void *handle) { FAR struct composite_alloc_s *alloc = (FAR struct composite_alloc_s *)handle; FAR struct composite_dev_s *priv; + int i; DEBUGASSERT(alloc != NULL); @@ -882,8 +910,10 @@ void composite_uninitialize(FAR void *handle) priv = &alloc->dev; - DEV1_UNINITIALIZE(priv->dev1); - DEV2_UNINITIALIZE(priv->dev2); + for (i = 0; i < priv->ndevices; i++) + { + priv->device[i].compdesc.board_uninitialize(priv->device[i].dev); + } /* Then unregister and destroy the composite class */ @@ -894,8 +924,10 @@ void composite_uninitialize(FAR void *handle) /* Second phase uninitialization: Clean up all memory resources */ - DEV1_UNINITIALIZE(priv->dev1); - DEV2_UNINITIALIZE(priv->dev2); + for (i = 0; i < priv->ndevices; i++) + { + priv->device[i].compdesc.board_uninitialize(priv->device[i].dev); + } /* Then free the composite driver state structure itself */ diff --git a/drivers/usbdev/composite.h b/drivers/usbdev/composite.h index f1adb4337c..718d520b6a 100644 --- a/drivers/usbdev/composite.h +++ b/drivers/usbdev/composite.h @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/composite.h * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #ifdef CONFIG_USBDEV_COMPOSITE @@ -115,127 +116,12 @@ # define COMPOSITE_REMOTEWAKEUP (0) #endif -/* Constituent devices ******************************************************/ - -#undef DEV1_IS_CDCACM -#undef DEV1_IS_USBMSC - -#undef DEV2_IS_CDCACM -#undef DEV2_IS_USBMSC - -/* Pick the first device in the composite. At present, this may only be - * the CDC serial device or the mass storage device. - */ - -#if defined(CONFIG_CDCACM_COMPOSITE) -# define DEV1_IS_CDCACM 1 -# define DEV1_MKCFGDESC cdcacm_mkcfgdesc -# define DEV1_MKSTRDESC cdcacm_mkstrdesc -# define DEV1_CLASSOBJECT board_cdcclassobject -# define DEV1_UNINITIALIZE board_cdcuninitialize -# define DEV1_NCONFIGS CDCACM_NCONFIGS -# define DEV1_CONFIGID CDCACM_CONFIGID -# define DEV1_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE -# define DEV1_NINTERFACES CDCACM_NINTERFACES -# define DEV1_STRIDBASE CONFIG_CDCACM_STRBASE -# define DEV1_NSTRIDS CDCACM_NSTRIDS -# define DEV1_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC -#elif defined(CONFIG_USBMSC_COMPOSITE) -# define DEV1_IS_USBMSC 1 -# define DEV1_MKCFGDESC usbmsc_mkcfgdesc -# define DEV1_MKSTRDESC usbmsc_mkstrdesc -# define DEV1_CLASSOBJECT board_mscclassobject -# define DEV1_UNINITIALIZE board_mscuninitialize -# define DEV1_NCONFIGS USBMSC_NCONFIGS -# define DEV1_CONFIGID USBMSC_CONFIGID -# define DEV1_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE -# define DEV1_NINTERFACES USBMSC_NINTERFACES -# define DEV1_STRIDBASE CONFIG_USBMSC_IFNOBASE -# define DEV1_NSTRIDS USBMSC_NSTRIDS -# define DEV1_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC -#else -# error "No members of the composite defined" -#endif - -/* Pick the second device in the composite. At present, this may only be - * the CDC serial device or the mass storage device. - */ - -#if defined(CONFIG_CDCACM_COMPOSITE) && !defined(DEV1_IS_CDCACM) -# define DEV2_IS_CDCACM 1 -# define DEV2_MKCFGDESC cdcacm_mkcfgdesc -# define DEV2_MKSTRDESC cdcacm_mkstrdesc -# define DEV2_CLASSOBJECT board_cdcclassobject -# define DEV2_UNINITIALIZE board_cdcuninitialize -# define DEV2_NCONFIGS CDCACM_NCONFIGS -# define DEV2_CONFIGID CDCACM_CONFIGID -# define DEV2_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE -# define DEV2_NINTERFACES CDCACM_NINTERFACES -# define DEV2_STRIDBASE CONFIG_CDCACM_STRBASE -# define DEV2_NSTRIDS CDCACM_NSTRIDS -# define DEV2_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC -#elif defined(CONFIG_USBMSC_COMPOSITE) && !defined(DEV1_IS_USBMSC) -# define DEV2_IS_USBMSC 1 -# define DEV2_MKCFGDESC usbmsc_mkcfgdesc -# define DEV2_MKSTRDESC usbmsc_mkstrdesc -# define DEV2_UNINITIALIZE board_mscuninitialize -# define DEV2_CLASSOBJECT board_mscclassobject -# define DEV2_NCONFIGS USBMSC_NCONFIGS -# define DEV2_CONFIGID USBMSC_CONFIGID -# define DEV2_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE -# define DEV2_NINTERFACES USBMSC_NINTERFACES -# define DEV2_STRIDBASE CONFIG_USBMSC_STRBASE -# define DEV2_NSTRIDS USBMSC_NSTRIDS -# define DEV2_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC -#else -# error "Insufficient members of the composite defined" -#endif - -/* Verify interface configuration */ - -#if DEV1_FIRSTINTERFACE != 0 -# warning "The first interface number should be zero" -#endif - -#if (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES) != DEV2_FIRSTINTERFACE -# warning "Interface numbers are not contiguous" -#endif - -/* Check if an IAD is needed */ - -#ifdef CONFIG_COMPOSITE_IAD -# if DEV1_NINTERFACES == 1 && DEV2_NINTERFACES == 1 -# warning "CONFIG_COMPOSITE_IAD not needed" -# endif -#endif - -#if !defined(CONFIG_COMPOSITE_IAD) && DEV1_NINTERFACES > 1 && DEV2_NINTERFACES > 1 -# warning "CONFIG_COMPOSITE_IAD may be needed" -#endif - -/* Total size of the configuration descriptor: */ - -#define COMPOSITE_CFGDESCSIZE (USB_SIZEOF_CFGDESC + DEV1_CFGDESCSIZE + DEV2_CFGDESCSIZE) - -/* The total number of interfaces */ - -#define COMPOSITE_NINTERFACES (DEV1_NINTERFACES + DEV2_NINTERFACES) - -/* Composite configuration ID value */ - -#if DEV1_NCONFIGS != 1 || DEV1_CONFIGID != 1 -# error "DEV1: Only a single configuration is supported" -#endif - -#if DEV2_NCONFIGS != 1 || DEV2_CONFIGID != 1 -# error "DEV2: Only a single configuration is supported" -#endif +#define NUM_DEVICES_TO_HANDLE (4) /* Descriptors **************************************************************/ /* These settings are not modifiable via the NuttX configuration */ #define COMPOSITE_CONFIGIDNONE (0) /* Config ID = 0 means to return to address mode */ -#define COMPOSITE_NCONFIGS (1) /* The number of configurations supported */ #define COMPOSITE_CONFIGID (1) /* The only supported configuration ID */ /* String language */ @@ -248,17 +134,6 @@ #define COMPOSITE_PRODUCTSTRID (2) #define COMPOSITE_SERIALSTRID (3) #define COMPOSITE_CONFIGSTRID (4) -#define COMPOSITE_NSTRIDS (4) - -/* Verify string configuration */ - -#if COMPOSITE_NSTRIDS != DEV1_STRIDBASE -# warning "The DEV1 string base should be COMPOSITE_NSTRIDS" -#endif - -#if (DEV1_STRIDBASE + DEV1_NSTRIDS) != DEV2_STRIDBASE -# warning "String IDs are not contiguous" -#endif /* Everpresent MIN/MAX macros ***********************************************/ @@ -274,6 +149,34 @@ * Public Types ****************************************************************************/ +struct composite_devobj_s +{ + /* Device description given by the user code in the dynamic + * configuration. + */ + + struct composite_devdesc_s compdesc; + + /* Pointer to device class */ + + FAR struct usbdevclass_driver_s *dev; +}; + + +/* This structure describes the internal state of the driver */ + +struct composite_dev_s +{ + FAR struct usbdev_s *usbdev; /* usbdev driver pointer */ + uint8_t config; /* Configuration number */ + FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */ + uint8_t ndevices; /* num devices in this composite device */ + int cfgdescsize; /* Total size of the configuration descriptor: */ + int ninterfaces; /* The total number of interfaces in this composite device */ + + struct composite_devobj_s device[NUM_DEVICES_TO_HANDLE]; /* Device class object */ +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -317,9 +220,10 @@ FAR const struct usb_devdesc_s *composite_getdevdesc(void); ****************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED -int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type); +int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, uint8_t *buf, + uint8_t speed, uint8_t type); #else -int16_t composite_mkcfgdesc(uint8_t *buf); +int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, uint8_t *buf); #endif /**************************************************************************** diff --git a/drivers/usbdev/composite_desc.c b/drivers/usbdev/composite_desc.c index 2cc94e07f1..361bb33baa 100644 --- a/drivers/usbdev/composite_desc.c +++ b/drivers/usbdev/composite_desc.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/composite_desc.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -61,12 +61,6 @@ * Private Types ****************************************************************************/ -#ifdef CONFIG_USBDEV_DUALSPEED -typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf, uint8_t speed, uint8_t type); -#else -typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf); -#endif - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -74,6 +68,7 @@ typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf); /**************************************************************************** * Private Data ****************************************************************************/ + /* Device Descriptor */ static const struct usb_devdesc_s g_devdesc = @@ -84,7 +79,7 @@ static const struct usb_devdesc_s g_devdesc = LSBYTE(0x0200), MSBYTE(0x0200) }, -#ifdef CONFIG_COMPOSITE_IAD +#ifndef CONFIG_COMPOSITE_IAD USB_CLASS_MISC, /* classid */ 2, /* subclass */ 1, /* protocol */ @@ -112,25 +107,6 @@ static const struct usb_devdesc_s g_devdesc = COMPOSITE_NCONFIGS /* nconfigs */ }; -/* Configuration descriptor for the composite device */ - -static const struct usb_cfgdesc_s g_cfgdesc = -{ - USB_SIZEOF_CFGDESC, /* len */ - USB_DESC_TYPE_CONFIG, /* type */ - { - LSBYTE(COMPOSITE_CFGDESCSIZE), /* LS totallen */ - MSBYTE(COMPOSITE_CFGDESCSIZE) /* MS totallen */ - }, - COMPOSITE_NINTERFACES, /* ninterfaces */ - COMPOSITE_CONFIGID, /* cfgvalue */ - COMPOSITE_CONFIGSTRID, /* icfg */ - USB_CONFIG_ATTR_ONE | /* attr */ - COMPOSITE_SELFPOWERED | - COMPOSITE_REMOTEWAKEUP, - (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */ -}; - #ifdef CONFIG_USBDEV_DUALSPEED static const struct usb_qualdesc_s g_qualdesc = { @@ -243,35 +219,52 @@ FAR const struct usb_devdesc_s *composite_getdevdesc(void) ****************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED -int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) +int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, FAR uint8_t *buf, + uint8_t speed, uint8_t type) #else -int16_t composite_mkcfgdesc(uint8_t *buf) +int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, FAR uint8_t *buf) #endif { + FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf; int16_t len; int16_t total; + int i; - /* Configuration descriptor -- Copy the canned configuration descriptor. */ + /* Configuration descriptor for the composite device */ + /* Fill in the values directly into the buf */ + + cfgdesc->len = USB_SIZEOF_CFGDESC; /* Descriptor length */ + cfgdesc->type = USB_DESC_TYPE_CONFIG; /* Descriptor type */ + cfgdesc->totallen[0] = LSBYTE(priv->cfgdescsize); /* Lower Byte of Total length */ + cfgdesc->totallen[1] = MSBYTE(priv->cfgdescsize); /* High Byte of Total length */ + cfgdesc->ninterfaces = priv->ninterfaces; /* Number of interfaces */ + cfgdesc->cfgvalue = COMPOSITE_CONFIGID; /* Configuration value */ + cfgdesc->icfg = COMPOSITE_CONFIGSTRID; /* Configuration */ + cfgdesc->attr = USB_CONFIG_ATTR_ONE | /* Attributes */ + COMPOSITE_SELFPOWERED | + COMPOSITE_REMOTEWAKEUP; + cfgdesc->mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */ + + /* increment the size and buf to point right behind the information filled in */ - memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC); total = USB_SIZEOF_CFGDESC; - buf += USB_SIZEOF_CFGDESC; + buf += USB_SIZEOF_CFGDESC; - /* Copy DEV1/DEV2 interface descriptors */ + /* Copy all contained interface descriptors into the buffer too */ + for (i = 0; i < priv->numDevices; i++) + { #ifdef CONFIG_USBDEV_DUALSPEED - len = DEV1_MKCFGDESC(buf, speed, type); - total += len; - buf += len; - total += DEV2_MKCFGDESC(buf, speed, type); + len = priv->device[i].comp_devdesc.mkconfdesc(buf, &priv->device[i].comp_devdesc.usb_dev_desc, speed, type); + total += len; + buf += len; #else - len = DEV1_MKCFGDESC(buf); - total += len; - buf += len; - total += DEV2_MKCFGDESC(buf); + len = priv->device[i].comp_devdesc.mkconfdesc(buf, &priv->device[i].comp_devdesc.usb_dev_desc); + total += len; + buf += len; #endif + } - DEBUGASSERT(total == COMPOSITE_CFGDESCSIZE); return total; } diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index b3eb1d1c9a..78facb457c 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/usbmsc.c * - * Copyright (C) 2008-2012, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2012, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Mass storage class device. Bulk-only with SCSI subclass. @@ -307,7 +307,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, /* Pre-allocate the IN bulk endpoint */ - priv->epbulkin = DEV_ALLOCEP(dev, USBMSC_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK); + priv->epbulkin = DEV_ALLOCEP(dev, USBMSC_MKEPBULKIN(&priv->usb_dev_desc), + true, USB_EP_ATTR_XFER_BULK); if (!priv->epbulkin) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINALLOCFAIL), 0); @@ -319,7 +320,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, /* Pre-allocate the OUT bulk endpoint */ - priv->epbulkout = DEV_ALLOCEP(dev, USBMSC_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK); + priv->epbulkout = DEV_ALLOCEP(dev, USBMSC_MKEPBULKOUT(&priv->usb_dev_desc), + false, USB_EP_ATTR_XFER_BULK); if (!priv->epbulkout) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTALLOCFAIL), 0); @@ -334,7 +336,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++) { reqcontainer = &priv->rdreqs[i]; - reqcontainer->req = usbmsc_allocreq(priv->epbulkout, CONFIG_USBMSC_BULKOUTREQLEN); + reqcontainer->req = usbmsc_allocreq(priv->epbulkout, + CONFIG_USBMSC_BULKOUTREQLEN); if (reqcontainer->req == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDALLOCREQ), @@ -342,6 +345,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENOMEM; goto errout; } + reqcontainer->req->priv = reqcontainer; reqcontainer->req->callback = usbmsc_rdcomplete; } @@ -359,6 +363,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENOMEM; goto errout; } + reqcontainer->req->priv = reqcontainer; reqcontainer->req->callback = usbmsc_wrcomplete; @@ -929,10 +934,8 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) { FAR struct usbmsc_req_s *privreq; FAR struct usbdev_req_s *req; -#ifdef CONFIG_USBDEV_DUALSPEED - FAR const struct usb_epdesc_s *epdesc; - bool hispeed = (priv->usbdev->speed == USB_SPEED_HIGH); -#endif + struct usb_epdesc_s epdesc; + bool hispeed = false; int i; int ret = 0; @@ -952,6 +955,10 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) return OK; } +#ifdef CONFIG_USBDEV_DUALSPEED + hispeed = (priv->usbdev->speed == USB_SPEED_HIGH); +#endif + /* Discard the previous configuration data */ usbmsc_resetconfig(priv); @@ -974,13 +981,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) /* Configure the IN bulk endpoint */ -#ifdef CONFIG_USBDEV_DUALSPEED - epdesc = USBMSC_EPBULKINDESC(hispeed); - ret = EP_CONFIGURE(priv->epbulkin, epdesc, false); -#else - ret = EP_CONFIGURE(priv->epbulkin, - usbmsc_getepdesc(USBMSC_EPFSBULKIN), false); -#endif + usbmsc_copy_epdesc(USBMSC_EPBULKIN, &epdesc, &priv->usb_dev_desc, + hispeed); + ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0); @@ -991,13 +994,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) /* Configure the OUT bulk endpoint */ -#ifdef CONFIG_USBDEV_DUALSPEED - epdesc = USBMSC_EPBULKOUTDESC(hispeed); - ret = EP_CONFIGURE(priv->epbulkout, epdesc, true); -#else - ret = EP_CONFIGURE(priv->epbulkout, - usbmsc_getepdesc(USBMSC_EPFSBULKOUT), true); -#endif + usbmsc_copy_epdesc(USBMSC_EPBULKOUT, &epdesc, &priv->usb_dev_desc, + hispeed); + ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0); @@ -1015,6 +1014,7 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) req->len = CONFIG_USBMSC_BULKOUTREQLEN; req->priv = privreq; req->callback = usbmsc_rdcomplete; + ret = EP_SUBMIT(priv->epbulkout, req); if (ret < 0) { @@ -1719,7 +1719,7 @@ errout_with_lock: ****************************************************************************/ #ifdef CONFIG_USBMSC_COMPOSITE -int usbmsc_classobject(FAR void *handle, +int usbmsc_classobject(FAR void *handle, FAR struct usbdev_description_s *usb_dev_desc, FAR struct usbdevclass_driver_s **classdev) { FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle; @@ -1860,3 +1860,51 @@ void usbmsc_uninitialize(FAR void *handle) kmm_free(priv); #endif } + +/**************************************************************************** + * Name: usbmsc_get_composite_devdesc + * + * Description: + * Helper function to fill in some constants into the composite + * configuration struct. + * + * Input Parameters: + * dev - Pointer to the configuration struct we should fill + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE) +void usbmsc_get_composite_devdesc(FAR struct composite_devdesc_s *dev) +{ + /* The callback functions for the CDC/ACM class */ + + dev->mkconfdesc = usbmsc_mkcfgdesc; + dev->mkstrdesc = usbmsc_mkstrdesc; + dev->board_classobject = 0; + dev->board_uninitialize = 0; + + dev->nconfigs = USBMSC_NCONFIGS; /* Number of configurations supported */ + dev->configid = USBMSC_CONFIGID; /* The only supported configuration ID */ + dev->cfgdescsize = SIZEOF_USBMSC_CFGDESC; /* The size of the config descriptor */ + dev->minor = 0; /* The minor interface number */ + + /* Interfaces */ + + dev->usb_dev_desc.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces in the configuration */ + dev->usb_dev_desc.ifnobase = 0; /* Offset to Interface-IDs */ + + /* Strings */ + + dev->usb_dev_desc.nstrings = USBMSC_NSTRIDS; /* Number of Strings */ + dev->usb_dev_desc.strbase = 0; /* Offset to String Numbers */ + + /* Endpoints */ + + dev->usb_dev_desc.nendpoints = USBMSC_NENDPOINTS; + dev->usb_dev_desc.epno[USBMSC_EP_BULKIN_IDX] = 0; + dev->usb_dev_desc.epno[USBMSC_EP_BULKOUT_IDX] = 0; +} +#endif \ No newline at end of file diff --git a/drivers/usbdev/usbmsc.h b/drivers/usbdev/usbmsc.h index 2da7b762f2..59dd5174dc 100644 --- a/drivers/usbdev/usbmsc.h +++ b/drivers/usbdev/usbmsc.h @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/usbmsc.h * - * Copyright (C) 2008-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2013, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Mass storage class device. Bulk-only with SCSI subclass. @@ -98,14 +98,18 @@ /* Logical endpoint numbers / max packet sizes */ -#ifndef CONFIG_USBMSC_EPBULKOUT -# warning "EPBULKOUT not defined in the configuration" -# define CONFIG_USBMSC_EPBULKOUT 2 +#ifndef CONFIG_USBMSC_COMPOSITE +# ifndef CONFIG_USBMSC_EPBULKOUT +# warning "EPBULKOUT not defined in the configuration" +# define CONFIG_USBMSC_EPBULKOUT 2 +# endif #endif -#ifndef CONFIG_USBMSC_EPBULKIN -# warning "EPBULKIN not defined in the configuration" -# define CONFIG_USBMSC_EPBULKIN 3 +#ifndef CONFIG_USBMSC_COMPOSITE +# ifndef CONFIG_USBMSC_EPBULKIN +# warning "EPBULKIN not defined in the configuration" +# define CONFIG_USBMSC_EPBULKIN 3 +# endif #endif /* Packet and request buffer sizes */ @@ -293,27 +297,19 @@ #define USBMSC_LASTSTRID USBMSC_INTERFACESTRID #define USBMSC_NSTRIDS (USBMSC_LASTSTRID - CONFIG_USBMSC_STRBASE) -#define USBMSC_NCONFIGS (1) /* Number of configurations supported */ - /* Configuration Descriptor */ -#define USBMSC_NINTERFACES (1) /* Number of interfaces in the configuration */ #define USBMSC_INTERFACEID (CONFIG_USBMSC_IFNOBASE+0) #define USBMSC_ALTINTERFACEID (0) #define USBMSC_CONFIGIDNONE (0) /* Config ID means to return to address mode */ -#define USBMSC_CONFIGID (1) /* The only supported configuration ID */ - -/* Interface description */ - -#define USBMSC_NENDPOINTS (2) /* Number of endpoints in the interface */ /* Endpoint configuration */ -#define USBMSC_EPOUTBULK_ADDR (CONFIG_USBMSC_EPBULKOUT) +#define USBMSC_MKEPBULKOUT(devDesc) ((devDesc)->epno[USBMSC_EP_BULKOUT_IDX]) #define USBMSC_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK) -#define USBMSC_EPINBULK_ADDR (USB_DIR_IN|CONFIG_USBMSC_EPBULKIN) +#define USBMSC_MKEPBULKIN(devDesc) (USB_DIR_IN | (devDesc)->epno[USBMSC_EP_BULKIN_IDX]) #define USBMSC_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK) #define USBMSC_HSBULKMAXPACKET (512) @@ -323,38 +319,10 @@ #define USBMSC_FSBULKMXPKTSHIFT (6) #define USBMSC_FSBULKMXPKTMASK (0x0000003f) -/* Macros for dual speed vs. full speed only operation */ - -#ifdef CONFIG_USBDEV_DUALSPEED -# define USBMSC_EPBULKINDESC(hs) \ - usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKIN : USBMSC_EPFSBULKIN) -# define USBMSC_EPBULKOUTDESC(hs) \ - usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKOUT : USBMSC_EPFSBULKOUT) -# define USBMSC_BULKMAXPACKET(hs) \ - ((hs) ? USBMSC_HSBULKMAXPACKET : USBMSC_FSBULKMAXPACKET) -# define USBMSC_BULKMXPKTSHIFT(d) \ - (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTSHIFT : USBMSC_FSBULKMXPKTSHIFT) -# define USBMSC_BULKMXPKTMASK(d) \ - (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTMASK : USBMSC_FSBULKMXPKTMASK) -#else -# define USBMSC_EPBULKINDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKIN) -# define USBMSC_EPBULKOUTDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKOUT) -# define USBMSC_BULKMAXPACKET(hs) USBMSC_FSBULKMAXPACKET -# define USBMSC_BULKMXPKTSHIFT(d) USBMSC_FSBULKMXPKTSHIFT -# define USBMSC_BULKMXPKTMASK(d) USBMSC_FSBULKMXPKTMASK -#endif - /* Configuration descriptor size */ #ifndef CONFIG_USBMSC_COMPOSITE -/* Number of individual descriptors in the configuration descriptor: - * (1) Configuration descriptor + (1) interface descriptor + (2) interface - * descriptors. - */ - -# define USBMSC_CFGGROUP_SIZE (4) - /* The size of the config descriptor: (9 + 9 + 2*7) = 32 */ # define SIZEOF_USBMSC_CFGDESC \ @@ -362,12 +330,6 @@ #else -/* Number of individual descriptors in the configuration descriptor: - * (1) interface descriptor + (2) interface descriptors. - */ - -# define USBMSC_CFGGROUP_SIZE (3) - /* The size of the config descriptor: (9 + 2*7) = 23 */ # define SIZEOF_USBMSC_CFGDESC \ @@ -398,13 +360,8 @@ enum usbmsc_epdesc_e { - USBMSC_EPFSBULKOUT = 0, /* Full speed bulk OUT endpoint descriptor */ - USBMSC_EPFSBULKIN /* Full speed bulk IN endpoint descriptor */ -#ifdef CONFIG_USBDEV_DUALSPEED - , - USBMSC_EPHSBULKOUT, /* High speed bulk OUT endpoint descriptor */ - USBMSC_EPHSBULKIN /* High speed bulk IN endpoint descriptor */ -#endif + USBMSC_EPBULKOUT = 0, /* Bulk OUT endpoint descriptor */ + USBMSC_EPBULKIN /* Bulk IN endpoint descriptor */ }; /* Container to support a list of requests */ @@ -487,6 +444,8 @@ struct usbmsc_dev_s struct sq_queue_s wrreqlist; /* List of empty write request containers */ struct sq_queue_s rdreqlist; /* List of filled read request containers */ + struct usbdev_description_s devdesc; + /* Pre-allocated write request containers. The write requests will * be linked in a free list (wrreqlist), and used to send requests to * EPBULKIN; Read requests will be queued in the EBULKOUT. @@ -603,16 +562,19 @@ int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc); FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void); #endif -/************************************************************************************ - * Name: usbmsc_getepdesc +/**************************************************************************** + * Name: usbmsc_copy_epdesc * * Description: - * Return a pointer to the raw endpoint descriptor (used for configuring endpoints) + * Copies the requested Endpoint Description into the buffer given. + * Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ). * - ************************************************************************************/ + ****************************************************************************/ -struct usb_epdesc_s; -FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid); +int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, + FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_description_s *devdesc, + bool hispeed); /************************************************************************************ * Name: usbmsc_mkcfgdesc @@ -623,9 +585,10 @@ FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid); ************************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED -int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type); +int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc, + uint8_t speed, uint8_t type); #else -int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf); +int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc); #endif /************************************************************************************ @@ -725,4 +688,4 @@ void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed); } #endif -#endif /* #define __DRIVERS_USBDEV_USBMSC_H */ +#endif /* __DRIVERS_USBDEV_USBMSC_H */ diff --git a/drivers/usbdev/usbmsc_desc.c b/drivers/usbdev/usbmsc_desc.c index 1a97da8224..cdb1041e77 100644 --- a/drivers/usbdev/usbmsc_desc.c +++ b/drivers/usbdev/usbmsc_desc.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/usbmsc_desc.c * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -54,6 +54,27 @@ * Pre-processor Definitions ****************************************************************************/ +/* This little hack makes the compiler producing an error if the (constant) + * condition is not true. + * + * e.g. + * COMPILE_TIME_ASSERTION( sizeof(uint8_t) == 1 ); + * + * when not true, the output is something like + * + * test.c:28:2: error: size of unnamed array is negative + * COMPILE_TIME_ASSERTION( sizeof(uint8_t) != 1 ); + * ^ + * + * else the compiler produces the (empty) statement + * + * ((void)sizeof(char[1])) + * + * which is optimized out. + */ + +#define COMPILE_TIME_ASSERTION(condition) ((void)sizeof(char[1 - 2*!(condition)])) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -92,79 +113,13 @@ static const struct usb_devdesc_s g_devdesc = LSBYTE(CONFIG_USBMSC_VERSIONNO), MSBYTE(CONFIG_USBMSC_VERSIONNO) }, - USBMSC_MANUFACTURERSTRID, /* imfgr */ - USBMSC_PRODUCTSTRID, /* iproduct */ - USBMSC_SERIALSTRID, /* serno */ - USBMSC_NCONFIGS /* nconfigs */ + USBMSC_MANUFACTURERSTRID, /* imfgr */ + USBMSC_PRODUCTSTRID, /* iproduct */ + USBMSC_SERIALSTRID, /* serno */ + USBMSC_NCONFIGS /* nconfigs */ }; #endif -/* Configuration descriptor If the USB mass storage device is configured as part - * of a composite device, then the configuration descriptor will be provided by the - * composite device logic. - */ - -#ifndef CONFIG_USBMSC_COMPOSITE -static const struct usb_cfgdesc_s g_cfgdesc = -{ - USB_SIZEOF_CFGDESC, /* len */ - USB_DESC_TYPE_CONFIG, /* type */ - { /* totallen */ - LSBYTE(SIZEOF_USBMSC_CFGDESC), - MSBYTE(SIZEOF_USBMSC_CFGDESC) - }, - USBMSC_NINTERFACES, /* ninterfaces */ - USBMSC_CONFIGID, /* cfgvalue */ - USBMSC_CONFIGSTRID, /* icfg */ - USB_CONFIG_ATTR_ONE | /* attr */ - USBMSC_SELFPOWERED | - USBMSC_REMOTEWAKEUP, - (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */ -}; -#endif - -/* Single interface descriptor */ - -static const struct usb_ifdesc_s g_ifdesc = -{ - USB_SIZEOF_IFDESC, /* len */ - USB_DESC_TYPE_INTERFACE, /* type */ - USBMSC_INTERFACEID, /* ifno */ - USBMSC_ALTINTERFACEID, /* alt */ - USBMSC_NENDPOINTS, /* neps */ - USB_CLASS_MASS_STORAGE, /* classid */ - USBMSC_SUBCLASS_SCSI, /* subclass */ - USBMSC_PROTO_BULKONLY, /* protocol */ - USBMSC_INTERFACESTRID /* iif */ -}; - -/* Endpoint descriptors */ - -static const struct usb_epdesc_s g_fsepbulkoutdesc = -{ - USB_SIZEOF_EPDESC, /* len */ - USB_DESC_TYPE_ENDPOINT, /* type */ - USBMSC_EPOUTBULK_ADDR, /* addr */ - USBMSC_EPOUTBULK_ATTR, /* attr */ - { /* maxpacket */ - LSBYTE(USBMSC_FSBULKMAXPACKET), - MSBYTE(USBMSC_FSBULKMAXPACKET) - }, - 0 /* interval */ -}; - -static const struct usb_epdesc_s g_fsepbulkindesc = -{ - USB_SIZEOF_EPDESC, /* len */ - USB_DESC_TYPE_ENDPOINT, /* type */ - USBMSC_EPINBULK_ADDR, /* addr */ - USBMSC_EPINBULK_ATTR, /* attr */ - { /* maxpacket */ - LSBYTE(USBMSC_FSBULKMAXPACKET), - MSBYTE(USBMSC_FSBULKMAXPACKET) - }, - 0 /* interval */ -}; #ifdef CONFIG_USBDEV_DUALSPEED #ifndef CONFIG_USBMSC_COMPOSITE @@ -184,32 +139,6 @@ static const struct usb_qualdesc_s g_qualdesc = 0, /* reserved */ }; #endif - -static const struct usb_epdesc_s g_hsepbulkoutdesc = -{ - USB_SIZEOF_EPDESC, /* len */ - USB_DESC_TYPE_ENDPOINT, /* type */ - USBMSC_EPOUTBULK_ADDR, /* addr */ - USBMSC_EPOUTBULK_ATTR, /* attr */ - { /* maxpacket */ - LSBYTE(USBMSC_HSBULKMAXPACKET), - MSBYTE(USBMSC_HSBULKMAXPACKET) - }, - 0 /* interval */ -}; - -static const struct usb_epdesc_s g_hsepbulkindesc = -{ - USB_SIZEOF_EPDESC, /* len */ - USB_DESC_TYPE_ENDPOINT, /* type */ - USBMSC_EPINBULK_ADDR, /* addr */ - USBMSC_EPINBULK_ATTR, /* attr */ - { /* maxpacket */ - LSBYTE(USBMSC_HSBULKMAXPACKET), - MSBYTE(USBMSC_HSBULKMAXPACKET) - }, - 0 /* interval */ -}; #endif /**************************************************************************** @@ -304,7 +233,7 @@ int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc) } /**************************************************************************** - * Name: usbmsc_getepdesc + * Name: usbmsc_getdevdesc * * Description: * Return a pointer to the raw device descriptor @@ -319,35 +248,90 @@ FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void) #endif /**************************************************************************** - * Name: usbmsc_getepdesc + * Name: usbmsc_copy_epdesc * * Description: - * Return a pointer to the raw endpoint descriptor (used for configuring - * endpoints) + * Copies the requested Endpoint Description into the buffer given. + * Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ). * ****************************************************************************/ -FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid) +int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid, + FAR struct usb_epdesc_s *epdesc, + FAR struct usbdev_description_s *devdesc, + bool hispeed) { - switch (epid) - { - case USBMSC_EPFSBULKOUT: /* Full speed bulk OUT endpoint descriptor */ - return &g_fsepbulkoutdesc; +#ifndef CONFIG_USBDEV_DUALSPEED + /* unused */ - case USBMSC_EPFSBULKIN: /* Full speed bulk IN endpoint descriptor */ - return &g_fsepbulkindesc; - -#ifdef CONFIG_USBDEV_DUALSPEED - case USBMSC_EPHSBULKOUT: /* High speed bulk OUT endpoint descriptor */ - return &g_hsepbulkoutdesc; - - case USBMSC_EPHSBULKIN: /* High speed bulk IN endpoint descriptor */ - return &g_hsepbulkindesc; + (void)hispeed; #endif - default: - return NULL; + + switch (epid) + { + case USBMSC_EPBULKOUT: /* Bulk OUT endpoint */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = USBMSC_MKEPBULKOUT(devdesc); /* Endpoint address */ + epdesc->attr = USBMSC_EPOUTBULK_ATTR; /* Endpoint attributes */ + +#ifdef CONFIG_USBDEV_DUALSPEED + if (hispeed) + { + /* Maximum packet size (high speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(USBMSC_HSBULKMAXPACKET); + epdesc->mxpacketsize[1] = MSBYTE(USBMSC_HSBULKMAXPACKET); + } + else +#endif + { + /* Maximum packet size (full speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(USBMSC_FSBULKMAXPACKET); + epdesc->mxpacketsize[1] = MSBYTE(USBMSC_FSBULKMAXPACKET); + } + + epdesc->interval = 0; /* Interval */ + } + break; + + case USBMSC_EPBULKIN: /* Bulk IN endpoint */ + { + epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */ + epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */ + epdesc->addr = USBMSC_MKEPBULKIN(devdesc); /* Endpoint address */ + epdesc->attr = USBMSC_EPINBULK_ATTR; /* Endpoint attributes */ + +#ifdef CONFIG_USBDEV_DUALSPEED + if (hispeed) + { + /* Maximum packet size (high speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(USBMSC_HSBULKMAXPACKET); + epdesc->mxpacketsize[1] = MSBYTE(USBMSC_HSBULKMAXPACKET); + } + else +#endif + { + /* Maximum packet size (full speed) */ + + epdesc->mxpacketsize[0] = LSBYTE(USBMSC_FSBULKMAXPACKET); + epdesc->mxpacketsize[1] = MSBYTE(USBMSC_FSBULKMAXPACKET); + } + + epdesc->interval = 0; /* Interval */ + } + break; + + default: + return 0; } -}; + + COMPILE_TIME_ASSERTION(sizeof(struct usb_epdesc_s) == USB_SIZEOF_EPDESC); + return sizeof(struct usb_epdesc_s); +} /**************************************************************************** * Name: usbmsc_mkcfgdesc @@ -358,53 +342,108 @@ FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid) ****************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED -int16_t usbmsc_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) +int16_t usbmsc_mkcfgdesc(uint8_t *buf, + FAR struct usbdev_description_s *devdesc, + uint8_t speed, uint8_t type) #else -int16_t usbmsc_mkcfgdesc(uint8_t *buf) +int16_t usbmsc_mkcfgdesc(uint8_t *buf, + FAR struct usbdev_description_s *devdesc) #endif { + int length = 0; + bool hispeed = false; + #ifdef CONFIG_USBDEV_DUALSPEED - FAR const struct usb_epdesc_s *epdesc; - bool hispeed; + hispeed = (speed == USB_SPEED_HIGH); + + /* Check for switches between high and full speed */ + + if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG) + { + hispeed = !hispeed; + } #endif + /* Fill in all descriptors directly to the buf */ + /* Configuration descriptor. If the USB mass storage device is * configured as part of a composite device, then the configuration * descriptor will be provided by the composite device logic. */ #ifndef CONFIG_USBMSC_COMPOSITE - memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC); - buf += USB_SIZEOF_CFGDESC; + { + /* Configuration descriptor If the USB mass storage device is configured as part + * of a composite device, then the configuration descriptor will be provided by the + * composite device logic. + */ + + FAR struct usb_cfgdesc_s *dest = (FAR struct usb_cfgdesc_s *)buf; + + dest->len = USB_SIZEOF_CFGDESC; /* Descriptor length */ + dest->type = USB_DESC_TYPE_CONFIG; /* Descriptor type */ + dest->totallen[0] = LSBYTE(SIZEOF_USBMSC_CFGDESC); /* LS Total length */ + dest->totallen[1] = MSBYTE(SIZEOF_USBMSC_CFGDESC); /* MS Total length */ + dest->ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces */ + dest->cfgvalue = USBMSC_CONFIGID; /* Configuration value */ + dest->icfg = USBMSC_CONFIGSTRID; /* Configuration */ + dest->attr = USB_CONFIG_ATTR_ONE | /* Attributes */ + USBMSC_SELFPOWERED | + USBMSC_REMOTEWAKEUP; + dest->mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */ + + COMPILE_TIME_ASSERTION(sizeof(struct usb_cfgdesc_s) == USB_SIZEOF_CFGDESC); + + buf += sizeof(struct usb_cfgdesc_s); + length += sizeof(struct usb_cfgdesc_s); + } #endif /* Copy the canned interface descriptor */ - memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC); - buf += USB_SIZEOF_IFDESC; + { + /* Single interface descriptor */ + + FAR struct usb_ifdesc_s * dest = (struct usb_ifdesc_s *)buf; + + dest->len = USB_SIZEOF_IFDESC; /* Descriptor length */ + dest->type = USB_DESC_TYPE_INTERFACE; /* Descriptor type */ + dest->ifno = devdesc->ifnobase; /* Interface number */ + dest->alt = USBMSC_ALTINTERFACEID; /* Alternate setting */ + dest->neps = USBMSC_NENDPOINTS; /* Number of endpoints */ + dest->classid = USB_CLASS_MASS_STORAGE; /* Interface class */ + dest->subclass = USBMSC_SUBCLASS_SCSI; /* Interface sub-class */ + dest->protocol = USBMSC_PROTO_BULKONLY; /* Interface protocol */ + dest->iif = devdesc->strbase + USBMSC_INTERFACESTRID; /* iInterface */ + + COMPILE_TIME_ASSERTION(sizeof(struct usb_ifdesc_s) == USB_SIZEOF_IFDESC); + + buf += sizeof(struct usb_ifdesc_s); + length += sizeof(struct usb_ifdesc_s); + } /* Make the two endpoint configurations */ -#ifdef CONFIG_USBDEV_DUALSPEED - /* Check for switches between high and full speed */ + /* Bulk IN endpoint descriptor */ - hispeed = (speed == USB_SPEED_HIGH); - if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG) - { - hispeed = !hispeed; - } + { + int len = usbmsc_copy_epdesc(USBMSC_EPBULKIN, (FAR struct usb_epdesc_s *)buf, + devdesc, hispeed); - epdesc = USBMSC_EPBULKINDESC(hispeed); - memcpy(buf, epdesc, USB_SIZEOF_EPDESC); - buf += USB_SIZEOF_EPDESC; + buf += len; + length += len; + } - epdesc = USBMSC_EPBULKOUTDESC(hispeed); - memcpy(buf, epdesc, USB_SIZEOF_EPDESC); -#else - memcpy(buf, &g_fsepbulkoutdesc, USB_SIZEOF_EPDESC); - buf += USB_SIZEOF_EPDESC; - memcpy(buf, &g_fsepbulkindesc, USB_SIZEOF_EPDESC); -#endif + /* Bulk OUT endpoint descriptor */ + + { + int len = usbmsc_copy_epdesc(USBMSC_EPBULKOUT, + (FAR struct usb_epdesc_s *)buf, devdesc, + hispeed); + + buf += len; + length += len; + } return SIZEOF_USBMSC_CFGDESC; } @@ -423,4 +462,3 @@ FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void) return &g_qualdesc; } #endif - diff --git a/include/nuttx/usb/cdc.h b/include/nuttx/usb/cdc.h index d9f0f9e9a8..73a14ac1b9 100644 --- a/include/nuttx/usb/cdc.h +++ b/include/nuttx/usb/cdc.h @@ -1,7 +1,7 @@ /******************************************************************************************** * include/nuttx/usb/cdc.h * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: "Universal Serial Bus Class Definitions for Communication @@ -73,7 +73,7 @@ /* Table 17: Communication Interface Class Control Protocol Codes */ #define CDC_PROTO_NONE 0x00 /* No class specific protocol required */ -#define CDC_PROTO_ATM 0x01 /* Common AT commands (also known as Hayes compatible”) */ +#define CDC_PROTO_ATM 0x01 /* Common AT commands (also known as Hayes compatible) */ /* 0x02-0xfe Reserved (future use) */ #define CDC_PROTO_VENDOR 0xff /* Vendor-specific */ @@ -242,12 +242,12 @@ * (Optional) */ #define ECM_SET_MCAST_FILTERS 0x40 /* As applications are loaded and unloaded on the host, - * the networking transport will instruct the device’s MAC - * driver to change settings of the Networking device’s + * the networking transport will instruct the device's MAC + * driver to change settings of the Networking device's * multicast filters. (Optional) */ #define ECM_SET_PM_PAT_FILTER 0x41 /* Some hosts are able to conserve energy and stay quiet - * in a “sleeping” state while not being used. USB + * in a "sleeping" state while not being used. USB * Networking devices may provide special pattern filtering * hardware that enables it to wake up the attached host * on demand when something is attempting to contact the @@ -588,20 +588,20 @@ struct cdc_funcdesc_s /* Table 26: Class-Specific Descriptor Header Format */ -struct cdc_hdr_funcdesc_s +begin_packed_struct struct cdc_hdr_funcdesc_s { uint8_t size; /* bFunctionLength, Size of this descriptor */ uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */ uint8_t subtype; /* bDescriptorSubType, CDC_DSUBTYPE_HDR as defined in Table 25 */ - uint8_t cdc[2]; /* bcdCDC, USB Class Definitions for Communication Devices Specification release - * number in binary-coded decimal. + uint8_t cdc[2]; /* bcdCDC, USB Class Definitions for Communication Devices Specification + * release number in binary-coded decimal. */ -}; +} end_packed_struct; #define SIZEOF_HDR_FUNCDESC 5 /* Table 27: Call Management Functional Descriptor */ -struct cdc_callmgmt_funcdesc_s +begin_packed_struct struct cdc_callmgmt_funcdesc_s { uint8_t size; /* bFunctionLength, Size of this descriptor */ uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */ @@ -610,18 +610,18 @@ struct cdc_callmgmt_funcdesc_s uint8_t ifno; /* bDataInterface, Interface number of Data Class interface * optionally used for call management */ -}; +} end_packed_struct; #define SIZEOF_CALLMGMT_FUNCDESC 5 /* Table 28: Abstract Control Management Functional Descriptor */ -struct cdc_acm_funcdesc_s +begin_packed_struct struct cdc_acm_funcdesc_s { uint8_t size; /* bFunctionLength, Size of this descriptor */ uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */ uint8_t subtype; /* bDescriptorSubType, CDC_DSUBTYPE_ACM as defined in Table 25 */ uint8_t caps; /* bmCapabilities: Bit encoded */ -}; +} end_packed_struct; #define SIZEOF_ACM_FUNCDESC 4 /* Table 29: Direct Line Management Functional Descriptor */ @@ -673,7 +673,7 @@ struct cdc_tcmc_funcdesc_s /* Table 33: Union Interface Functional Descriptor */ -struct cdc_union_funcdesc_s +begin_packed_struct struct cdc_union_funcdesc_s { uint8_t size; /* bFunctionLength, Size of this descriptor */ uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */ @@ -685,7 +685,7 @@ struct cdc_union_funcdesc_s uint8_t slave[1]; /* bSlaveInterfaceN: Interface number of N slave or associated * interface in the union */ -}; +} end_packed_struct; #define SIZEOF_UNION_FUNCDESC(n) ((n)+4) /* Table 34: Country Selection Functional Descriptor */ @@ -788,7 +788,7 @@ struct cdc_capi_funcdesc_s }; #define SIZEOF_CAPI_FUNCDESC 4 -/* Table 41: Ethernet Networking Functional Descriptor*/ +/* Table 41: Ethernet Networking Functional Descriptor */ struct cdc_ecm_funcdesc_s { @@ -833,7 +833,7 @@ struct cdc_atm_funcdesc_s * capable of supporting */ }; -#define SIZEOF_CALLMGMT_FUNCDESC 12 +#define SIZEOF_ATM_FUNCDESC 12 /* Descriptor Data Structures ***************************************************************/ /* Table 50: Line Coding Structure */ diff --git a/include/nuttx/usb/cdcacm.h b/include/nuttx/usb/cdcacm.h index 8ae1e7f3f7..f734d654b2 100644 --- a/include/nuttx/usb/cdcacm.h +++ b/include/nuttx/usb/cdcacm.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/usb/cdcacm.h * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ /**************************************************************************** * Preprocessor definitions ****************************************************************************/ + /* Configuration ************************************************************/ /* CONFIG_CDCACM * Enable compilation of the USB serial driver @@ -96,6 +97,22 @@ * Size of the serial receive/transmit buffers. Default 256. */ +/* Informations needed in usbdev_description_s */ + +#define CDCACM_NUM_EPS (3) + +#define CDCACM_EP_INTIN_IDX (0) +#define CDCACM_EP_BULKIN_IDX (1) +#define CDCACM_EP_BULKOUT_IDX (2) + +#define CDCACM_NCONFIGS (1) /* Number of configurations supported */ + +/* Configuration descriptor values */ + +#define CDCACM_CONFIGID (1) /* The only supported configuration ID */ + +#define CDCACM_NINTERFACES (2) /* Number of interfaces in the configuration */ + /* EP0 max packet size */ #ifndef CONFIG_CDCACM_EP0MAXPACKET @@ -106,8 +123,10 @@ * notification interrupt endpoint. */ -#ifndef CONFIG_CDCACM_EPINTIN -# define CONFIG_CDCACM_EPINTIN 1 +#ifndef CONFIG_CDCACM_COMPOSITE +# ifndef CONFIG_CDCACM_EPINTIN +# define CONFIG_CDCACM_EPINTIN 1 +# endif #endif #ifndef CONFIG_CDCACM_EPINTIN_FSSIZE @@ -127,8 +146,10 @@ * size will be followed by a NULL packet. */ -#ifndef CONFIG_CDCACM_EPBULKIN -# define CONFIG_CDCACM_EPBULKIN 2 +#ifndef CONFIG_CDCACM_COMPOSITE +# ifndef CONFIG_CDCACM_EPBULKIN +# define CONFIG_CDCACM_EPBULKIN 2 +# endif #endif #ifndef CONFIG_CDCACM_EPBULKIN_FSSIZE @@ -155,8 +176,10 @@ * maxpacket size. */ -#ifndef CONFIG_CDCACM_EPBULKOUT -# define CONFIG_CDCACM_EPBULKOUT 3 +#ifndef CONFIG_CDCACM_COMPOSITE +# ifndef CONFIG_CDCACM_EPBULKOUT +# define CONFIG_CDCACM_EPBULKOUT 3 +# endif #endif #ifndef CONFIG_CDCACM_EPBULKOUT_FSSIZE @@ -326,7 +349,9 @@ typedef FAR void (*cdcacm_callback_t)(enum cdcacm_event_e event); #if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE) struct usbdevclass_driver_s; -int board_cdcclassobject(FAR struct usbdevclass_driver_s **classdev); +struct usbdev_description_s; +int board_cdcclassobject(int minor, FAR struct usbdev_description_s *devdesc, + FAR struct usbdevclass_driver_s **classdev); #endif /**************************************************************************** @@ -370,7 +395,9 @@ void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev); ****************************************************************************/ #if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE) -int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev); +struct usbdev_description_s; +int cdcacm_classobject(int minor, struct usbdev_description_s *devdesc, + FAR struct usbdevclass_driver_s **classdev); #endif /**************************************************************************** @@ -425,6 +452,26 @@ void cdcacm_uninitialize(FAR struct usbdevclass_driver_s *classdev); void cdcacm_uninitialize(FAR void *handle); #endif +/**************************************************************************** + * Name: cdcacm_get_composite_devdesc + * + * Description: + * Helper function to fill in some constants into the composite + * configuration struct. + * + * Input Parameters: + * dev - Pointer to the configuration struct we should fill + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE) +struct composite_devdesc_s; +void cdcacm_get_composite_devdesc(struct composite_devdesc_s *dev); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/usb/composite.h b/include/nuttx/usb/composite.h index 722f9c4667..72281e826d 100644 --- a/include/nuttx/usb/composite.h +++ b/include/nuttx/usb/composite.h @@ -1,7 +1,7 @@ /************************************************************************************ * include/nuttx/usb/composite.h * - * Copyright (C) 2008-2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2011, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,12 +41,14 @@ ****************************************************************************/ #include +#include #ifdef CONFIG_USBDEV_COMPOSITE /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* Configuration ************************************************************/ /* CONFIG_USBDEV_COMPOSITE * Enables USB composite device support @@ -70,6 +72,11 @@ * Interface version number. */ +#define COMPOSITE_NSTRIDS (5) /* The numer of String-IDs to + * reserve for the composite device */ +#define COMPOSITE_NCONFIGS (1) /* The number of configurations + * supported */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -113,7 +120,7 @@ extern "C" * ****************************************************************************/ -FAR void *composite_initialize(void); +FAR void *composite_initialize(uint8_t numDevices, struct composite_devdesc_s * pDevices); /**************************************************************************** * Name: composite_uninitialize @@ -135,30 +142,6 @@ FAR void *composite_initialize(void); void composite_uninitialize(FAR void *handle); -/**************************************************************************** - * Name: composite_initialize - * - * Description: - * Register USB composite device as configured. This function will call - * board-specific implementations in order to obtain the class objects for - * each of the members of the composite (see board_mscclassobject(), - * board_cdcclassobjec(), ...) - * - * Input Parameter: - * None - * - * Returned Value: - * A non-NULL "handle" is returned on success. This handle may be used - * later with composite_uninitialize() in order to removed the composite - * device. This handle is the (untyped) internal representation of the - * the class driver instance. - * - * NULL is returned on any failure. - * - ****************************************************************************/ - -FAR void *composite_initialize(void); - /**************************************************************************** * Name: composite_ep0submit * diff --git a/include/nuttx/usb/usb.h b/include/nuttx/usb/usb.h index 5195c114b4..65f51bde4b 100644 --- a/include/nuttx/usb/usb.h +++ b/include/nuttx/usb/usb.h @@ -306,7 +306,7 @@ struct usb_devdesc_s /* Configuration descriptor */ -struct usb_cfgdesc_s +begin_packed_struct struct usb_cfgdesc_s { uint8_t len; /* Descriptor length */ uint8_t type; /* Descriptor type */ @@ -316,7 +316,7 @@ struct usb_cfgdesc_s uint8_t icfg; /* Configuration */ uint8_t attr; /* Attributes */ uint8_t mxpower; /* Max power (mA/2) */ -}; +} end_packed_struct; #define USB_SIZEOF_CFGDESC 9 struct usb_otherspeedconfigdesc_s @@ -343,7 +343,7 @@ struct usb_strdesc_s /* Interface descriptor */ -struct usb_ifdesc_s +begin_packed_struct struct usb_ifdesc_s { uint8_t len; /* Descriptor length */ uint8_t type; /* Descriptor type */ @@ -354,12 +354,12 @@ struct usb_ifdesc_s uint8_t subclass; /* Interface sub-class */ uint8_t protocol; /* Interface protocol */ uint8_t iif; /* iInterface */ -}; +} end_packed_struct; #define USB_SIZEOF_IFDESC 9 /* Endpoint descriptor */ -struct usb_epdesc_s +begin_packed_struct struct usb_epdesc_s { uint8_t len; /* Descriptor length */ uint8_t type; /* Descriptor type */ @@ -367,7 +367,7 @@ struct usb_epdesc_s uint8_t attr; /* Endpoint attributes */ uint8_t mxpacketsize[2]; /* Maximum packet size */ uint8_t interval; /* Interval */ -}; +} end_packed_struct; #define USB_SIZEOF_EPDESC 7 struct usb_audioepdesc_s @@ -404,7 +404,7 @@ struct usb_qualdesc_s * interfaces. */ -struct usb_iaddesc_s +begin_packed_struct struct usb_iaddesc_s { uint8_t len; /* Descriptor length */ uint8_t type; /* Descriptor type */ @@ -414,7 +414,7 @@ struct usb_iaddesc_s uint8_t subclass; /* Sub-class code */ uint8_t protocol; /* Protocol code */ uint8_t ifunction; /* Index to string identifying the function */ -}; +} end_packed_struct; #define USB_SIZEOF_IADDESC 8 /************************************************************************************