aboutsummaryrefslogtreecommitdiff
path: root/nuttx/drivers/usbdev/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/drivers/usbdev/composite.c')
-rw-r--r--nuttx/drivers/usbdev/composite.c933
1 files changed, 0 insertions, 933 deletions
diff --git a/nuttx/drivers/usbdev/composite.c b/nuttx/drivers/usbdev/composite.c
deleted file mode 100644
index 530d64416..000000000
--- a/nuttx/drivers/usbdev/composite.c
+++ /dev/null
@@ -1,933 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/composite.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "composite.h"
-
-#ifdef CONFIG_USBDEV_COMPOSITE
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * 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 */
-
-struct composite_driver_s
-{
- struct usbdevclass_driver_s drvr;
- FAR struct composite_dev_s *dev;
-};
-
-/* This is what is allocated */
-
-struct composite_alloc_s
-{
- struct composite_dev_s dev;
- struct composite_driver_s drvr;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* USB helps ****************************************************************/
-
-static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static int composite_classsetup(FAR struct composite_dev_s *priv,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len);
-static void composite_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* USB class device ********************************************************/
-
-static int composite_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static int composite_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-/* USB class device *********************************************************/
-
-static const struct usbdevclass_driverops_s g_driverops =
-{
- composite_bind, /* bind */
- composite_unbind, /* unbind */
- composite_setup, /* setup */
- composite_disconnect, /* disconnect */
- composite_suspend, /* suspend */
- composite_resume, /* resume */
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-const char g_compvendorstr[] = CONFIG_COMPOSITE_VENDORSTR;
-const char g_compproductstr[] = CONFIG_COMPOSITE_PRODUCTSTR;
-const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR;
-
- /****************************************************************************
- * Private Functions
- ****************************************************************************/
-/****************************************************************************
- * Helpers
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_ep0incomplete
- *
- * Description:
- * Handle completion of the composite driver's EP0 control operations
- *
- ****************************************************************************/
-
-static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- /* Just check the result of the transfer */
-
- if (req->result || req->xfrd != req->len)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT), (uint16_t)-req->result);
- }
-}
-
-/****************************************************************************
- * Name: composite_classsetup
- *
- * Description:
- * Forward a setup command to the appropriate component device
- *
- ****************************************************************************/
-
-static int composite_classsetup(FAR struct composite_dev_s *priv,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- uint16_t index;
- uint8_t interface;
- int ret = -EOPNOTSUPP;
-
- index = GETUINT16(ctrl->index);
- interface = (uint8_t)(index & 0xff);
-
- if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES))
- {
- 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);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_allocreq
- *
- * Description:
- * Allocate a request instance along with its buffer
- *
- ****************************************************************************/
-
-static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len)
-{
- FAR struct usbdev_req_s *req;
-
- req = EP_ALLOCREQ(ep);
- if (req != NULL)
- {
- req->len = len;
- req->buf = EP_ALLOCBUFFER(ep, len);
- if (!req->buf)
- {
- EP_FREEREQ(ep, req);
- req = NULL;
- }
- }
- return req;
-}
-
-/****************************************************************************
- * Name: composite_freereq
- *
- * Description:
- * Free a request instance along with its buffer
- *
- ****************************************************************************/
-
-static void composite_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (ep != NULL && req != NULL)
- {
- if (req->buf != NULL)
- {
- EP_FREEBUFFER(ep, req->buf);
- }
- EP_FREEREQ(ep, req);
- }
-}
-
-/****************************************************************************
- * USB Class Driver Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_bind
- *
- * Description:
- * Invoked when the driver is bound to a USB device driver
- *
- ****************************************************************************/
-
-static int composite_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s*)driver)->dev;
- int ret;
-
- usbtrace(TRACE_CLASSBIND, 0);
-
- /* Bind the structures */
-
- priv->usbdev = dev;
-
- /* Save the reference to our private data structure in EP0 so that it
- * can be recovered in ep0 completion events.
- */
-
- dev->ep0->priv = priv;
-
- /* Preallocate one control request */
-
- priv->ctrlreq = composite_allocreq(dev->ep0, COMPOSITE_CFGDESCSIZE);
- if (priv->ctrlreq == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCCTRLREQ), 0);
- ret = -ENOMEM;
- goto errout;
- }
-
- /* Initialize the pre-allocated control request */
-
- priv->ctrlreq->callback = composite_ep0incomplete;
-
- /* Then bind each of the constituent class drivers */
-
- ret = CLASS_BIND(priv->dev1, dev);
- if (ret < 0)
- {
- goto errout;
- }
-
- ret = CLASS_BIND(priv->dev2, dev);
- if (ret < 0)
- {
- goto errout;
- }
-
- /* Report if we are selfpowered */
-
-#ifdef CONFIG_USBDEV_SELFPOWERED
- DEV_SETSELFPOWERED(dev);
-#endif
-
- /* And pull-up the data line for the soft connect function */
-
- DEV_CONNECT(dev);
- return OK;
-
-errout:
- composite_unbind(driver, dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_unbind
- *
- * Description:
- * Invoked when the driver is unbound from a USB device driver
- *
- ****************************************************************************/
-
-static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSUNBIND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Make sure that we are not already unbound */
-
- if (priv != NULL)
- {
- /* Unbind the constituent class drivers */
-
- flags = irqsave();
- CLASS_UNBIND(priv->dev1, dev);
- CLASS_UNBIND(priv->dev2, dev);
-
- /* Free the pre-allocated control request */
-
- priv->config = COMPOSITE_CONFIGIDNONE;
- if (priv->ctrlreq != NULL)
- {
- composite_freereq(dev->ep0, priv->ctrlreq);
- priv->ctrlreq = NULL;
- }
- irqrestore(flags);
- }
-}
-
-/****************************************************************************
- * Name: composite_setup
- *
- * Description:
- * Invoked for ep0 control requests. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int composite_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- FAR struct composite_dev_s *priv;
- FAR struct usbdev_req_s *ctrlreq;
- uint16_t value;
- uint16_t index;
- uint16_t len;
- bool dispatched = false;
- int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0 || !ctrl)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_SETUPINVALIDARGS), 0);
- return -EIO;
- }
-#endif
-
- /* Extract a reference to private data */
-
- usbtrace(TRACE_CLASSSETUP, ctrl->req);
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_EP0NOTBOUND2), 0);
- return -ENODEV;
- }
-#endif
- ctrlreq = priv->ctrlreq;
-
- /* Extract the little-endian 16-bit values to host order */
-
- value = GETUINT16(ctrl->value);
- index = GETUINT16(ctrl->index);
- len = GETUINT16(ctrl->len);
-
- uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
- ctrl->type, ctrl->req, value, index, len);
-
- if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
- {
- /**********************************************************************
- * Standard Requests
- **********************************************************************/
-
- switch (ctrl->req)
- {
- case USB_REQ_GETDESCRIPTOR:
- {
- /* The value field specifies the descriptor type in the MS byte and the
- * descriptor index in the LS byte (order is little endian)
- */
-
- switch (ctrl->value[1])
- {
- case USB_DESC_TYPE_DEVICE:
- {
- ret = USB_SIZEOF_DEVDESC;
- memcpy(ctrlreq->buf, composite_getdevdesc(), ret);
- }
- break;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- case USB_DESC_TYPE_DEVICEQUALIFIER:
- {
- ret = USB_SIZEOF_QUALDESC;
- memcpy(ctrlreq->buf, composite_getqualdesc(), ret);
- }
- break;
-
- case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-#endif
-
- case USB_DESC_TYPE_CONFIG:
- {
-#ifdef CONFIG_USBDEV_DUALSPEED
- ret = composite_mkcfgdesc(ctrlreq->buf, dev->speed,
- ctrl->value[1]);
-#else
- ret = composite_mkcfgdesc(ctrlreq->buf);
-#endif
- }
- break;
-
- case USB_DESC_TYPE_STRING:
- {
- /* value == string index. Zero is the language ID. */
-
- uint8_t strid = ctrl->value[0];
- FAR struct usb_strdesc_s *buf = (FAR struct usb_strdesc_s *)ctrlreq->buf;
-
- if (strid <= COMPOSITE_NSTRIDS)
- {
- ret = composite_mkstrdesc(strid, buf);
- }
-#if DEV1_NSTRIDS > 0
- else if (strid <= DEV1_STRIDBASE + DEV1_NSTRIDS)
- {
- ret = DEV1_MKSTRDESC(strid, buf);
- }
-#endif
-#if DEV2_NSTRIDS > 0
- else if (strid <= DEV2_STRIDBASE + DEV2_NSTRIDS)
- {
- ret = DEV2_MKSTRDESC(strid, buf);
- }
-#endif
- }
- break;
-
- default:
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_GETUNKNOWNDESC), value);
- }
- break;
- }
- }
- break;
-
- case USB_REQ_SETCONFIGURATION:
- {
- if (ctrl->type == 0)
- {
- /* Save the configuration and inform the constituent classes */
-
- ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
- dispatched = true;
-
- if (ret >= 0)
- {
- ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
- if (ret >= 0)
- {
- priv->config = value;
- }
- }
- }
- }
- break;
-
- case USB_REQ_GETCONFIGURATION:
- {
- if (ctrl->type == USB_DIR_IN)
- {
- ctrlreq->buf[0] = priv->config;
- ret = 1;
- }
- }
- break;
-
- case USB_REQ_SETINTERFACE:
- {
- if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
- priv->config == COMPOSITE_CONFIGID)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
- break;
-
- case USB_REQ_GETINTERFACE:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
- priv->config == COMPOSITE_CONFIGIDNONE)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
- break;
- }
- }
- else
- {
- uint8_t recipient;
-
- /**********************************************************************
- * Non-Standard Class Requests
- **********************************************************************/
-
- /* Class implementations should handle there own interface and endpoint
- * requests.
- */
-
- recipient = ctrl->type & USB_REQ_RECIPIENT_MASK;
- if (recipient == USB_REQ_RECIPIENT_INTERFACE || recipient == USB_REQ_RECIPIENT_ENDPOINT)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
-
-
- /* Respond to the setup command if (1) data was returned, and (2) the request was
- * NOT successfully dispatched to the component class driver. On an error return
- * value (ret < 0), the USB driver will stall EP0.
- */
-
- if (ret >= 0 && !dispatched)
- {
- /* Setup the request */
-
- ctrlreq->len = MIN(len, ret);
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
-
- /* And submit the request to the USB controller driver */
-
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_EPRESPQ), (uint16_t)-ret);
- ctrlreq->result = OK;
- composite_ep0incomplete(dev->ep0, ctrlreq);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_disconnect
- *
- * Description:
- * Invoked after all transfers have been stopped, when the host is
- * disconnected. This function is probably called from the context of an
- * interrupt handler.
- *
- ****************************************************************************/
-
-static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Reset the configuration and inform the constituent class drivers of
- * the disconnection.
- */
-
- flags = irqsave();
- priv->config = COMPOSITE_CONFIGIDNONE;
- CLASS_DISCONNECT(priv->dev1, dev);
- CLASS_DISCONNECT(priv->dev2, dev);
- irqrestore(flags);
-
- /* Perform the soft connect function so that we will we can be
- * re-enumerated.
- */
-
- DEV_CONNECT(dev);
-}
-
-/****************************************************************************
- * Name: composite_suspend
- *
- * Description:
- * Invoked on a USB suspend event.
- *
- ****************************************************************************/
-
-static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSSUSPEND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Forward the suspend event to the constituent devices */
-
- flags = irqsave();
- CLASS_SUSPEND(priv->dev1, priv->usbdev);
- CLASS_SUSPEND(priv->dev2, priv->usbdev);
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: composite_resume
- *
- * Description:
- * Invoked on a USB resume event.
- *
- ****************************************************************************/
-
-static void composite_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv = NULL;
- irqstate_t flags;
-
-#ifdef CONFIG_DEBUG
- if (!dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Forward the resume event to the constituent devices */
-
- flags = irqsave();
- CLASS_RESUME(priv->dev1, priv->usbdev);
- CLASS_RESUME(priv->dev2, priv->usbdev);
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-/****************************************************************************
- * 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)
-{
- FAR struct composite_alloc_s *alloc;
- FAR struct composite_dev_s *priv;
- FAR struct composite_driver_s *drvr;
- int ret;
-
- /* Allocate the structures needed */
-
- alloc = (FAR struct composite_alloc_s*)kmalloc(sizeof(struct composite_alloc_s));
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCDEVSTRUCT), 0);
- return NULL;
- }
-
- /* Convenience pointers into the allocated blob */
-
- priv = &alloc->dev;
- drvr = &alloc->drvr;
-
- /* Initialize the USB composite driver structure */
-
- memset(priv, 0, sizeof(struct composite_dev_s));
-
- /* Get the constitueat class driver objects */
-
- ret = DEV1_CLASSOBJECT(&priv->dev1);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- ret = DEV2_CLASSOBJECT(&priv->dev2);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- /* Initialize the USB class driver structure */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- drvr->drvr.speed = USB_SPEED_HIGH;
-#else
- drvr->drvr.speed = USB_SPEED_FULL;
-#endif
- drvr->drvr.ops = &g_driverops;
- drvr->dev = priv;
-
- /* Register the USB composite class driver */
-
- ret = usbdev_register(&drvr->drvr);
- if (ret)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_DEVREGISTER), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- return (FAR void *)alloc;
-
-errout_with_alloc:
- kfree(alloc);
- return NULL;
-}
-
-/****************************************************************************
- * Name: composite_uninitialize
- *
- * Description:
- * Un-initialize the USB composite driver. The handle is the USB composite
- * class' device object as was returned by composite_initialize(). This
- * function will call board-specific implementations in order to free the
- * class objects for each of the members of the composite (see
- * board_mscuninitialize(), board_cdcuninitialize(), ...)
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to composite_initialize().
- *
- * Returned Value:
- * None
- *
- ***************************************************************************/
-
-void composite_uninitialize(FAR void *handle)
-{
- FAR struct composite_alloc_s *alloc = (FAR struct composite_alloc_s *)handle;
- FAR struct composite_dev_s *priv;
-
- DEBUGASSERT(alloc != NULL);
-
- /* Uninitialize each of the member classes */
-
- priv = &alloc->dev;
- if (priv->dev1)
- {
- DEV1_UNINITIALIZE(priv->dev1);
- priv->dev1 = NULL;
- }
-
- if (priv->dev2)
- {
- DEV1_UNINITIALIZE(priv->dev2);
- priv->dev2 = NULL;
- }
-
- /* Then unregister and destroy the composite class */
-
- usbdev_unregister(&alloc->drvr.drvr);
-
- /* Free any resources used by the composite driver */
- /* None */
-
- /* Then free the composite driver state structure itself */
-
- kfree(priv);
-}
-
-/****************************************************************************
- * Name: composite_ep0submit
- *
- * Description:
- * Members of the composite cannot send on EP0 directly because EP0 is
- * is "owned" by the composite device. Instead, when configured as members
- * of a composite device, those classes should call this method so that
- * the composite device can send on EP0 onbehalf of the class.
- *
- ****************************************************************************/
-
-int composite_ep0submit(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR struct usbdev_req_s *ctrlreq)
-{
- /* This function is not really necessary in the current design. However,
- * keeping this will provide us a little flexibility in the future if
- * it becomes necessary to manage the completion callbacks.
- */
-
- return EP_SUBMIT(dev->ep0, ctrlreq);
-}
-
-#endif /* CONFIG_USBDEV_COMPOSITE */