Part II of the same big commit
This commit is contained in:
parent
dcc9b07715
commit
7e6f481581
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 */
|
||||
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -46,6 +46,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/usb/usb.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/usbdev_trace.h>
|
||||
|
||||
#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
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 */
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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
|
||||
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 */
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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)
|
||||
}
|
||||
|
@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,12 +41,14 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
|
||||
#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
|
||||
*
|
||||
|
@ -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
|
||||
|
||||
/************************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user