Major restructuring of CLASS<->driver interface to better support composite USB devices

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4339 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-01-26 17:42:44 +00:00
parent e10dc26580
commit 3b9f7e1b4c
6 changed files with 296 additions and 138 deletions
+55 -22
View File
@@ -63,6 +63,10 @@
#include "cdcacm.h"
#ifdef CONFIG_USBMSC_COMPOSITE
# include "composite.h"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -172,14 +176,17 @@ static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep,
/* USB class device ********************************************************/
static int cdcacm_bind(FAR struct usbdev_s *dev,
FAR struct usbdevclass_driver_s *driver);
static void cdcacm_unbind(FAR struct usbdev_s *dev);
static int cdcacm_setup(FAR struct usbdev_s *dev,
const struct usb_ctrlreq_s *ctrl);
static void cdcacm_disconnect(FAR struct usbdev_s *dev);
static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl);
static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
/* UART Operationt **********************************************************/
/* UART Operations **********************************************************/
static int cdcuart_setup(FAR struct uart_dev_s *dev);
static void cdcuart_shutdown(FAR struct uart_dev_s *dev);
@@ -732,7 +739,7 @@ errout:
****************************************************************************/
static void cdcacm_ep0incomplete(FAR struct usbdev_ep_s *ep,
FAR struct usbdev_req_s *req)
FAR struct usbdev_req_s *req)
{
if (req->result || req->xfrd != req->len)
{
@@ -878,9 +885,10 @@ static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep,
*
****************************************************************************/
static int cdcacm_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s *driver)
static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct cdcacm_dev_s *priv = ((struct cdcacm_driver_s*)driver)->dev;
FAR struct cdcacm_dev_s *priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
FAR struct cdcacm_req_s *reqcontainer;
irqstate_t flags;
uint16_t reqlen;
@@ -892,7 +900,16 @@ static int cdcacm_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s
/* 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 (Unless we are part of
* a composite device and, in that case, the composite device owns
* EP0).
*/
#ifndef CONFIG_USBMSC_COMPOSITE
dev->ep0->priv = priv;
#endif
/* Preallocate control request */
@@ -1010,7 +1027,7 @@ static int cdcacm_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s
return OK;
errout:
cdcacm_unbind(dev);
cdcacm_unbind(driver, dev);
return ret;
}
@@ -1022,7 +1039,8 @@ errout:
*
****************************************************************************/
static void cdcacm_unbind(FAR struct usbdev_s *dev)
static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct cdcacm_dev_s *priv;
FAR struct cdcacm_req_s *reqcontainer;
@@ -1032,7 +1050,7 @@ static void cdcacm_unbind(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSUNBIND, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
return;
@@ -1041,7 +1059,7 @@ static void cdcacm_unbind(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct cdcacm_dev_s *)dev->ep0->priv;
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@@ -1146,7 +1164,9 @@ static void cdcacm_unbind(FAR struct usbdev_s *dev)
*
****************************************************************************/
static int cdcacm_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ctrl)
static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
{
FAR struct cdcacm_dev_s *priv;
FAR struct usbdev_req_s *ctrlreq;
@@ -1156,7 +1176,7 @@ static int cdcacm_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ct
int ret = -EOPNOTSUPP;
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0 || !ctrl)
if (!driver || !dev || !ctrl)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
return -EIO;
@@ -1166,7 +1186,7 @@ static int cdcacm_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ct
/* Extract reference to private data */
usbtrace(TRACE_CLASSSETUP, ctrl->req);
priv = (FAR struct cdcacm_dev_s *)dev->ep0->priv;
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv || !priv->ctrlreq)
@@ -1465,9 +1485,21 @@ static int cdcacm_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ct
if (ret >= 0)
{
/* Configure the response */
ctrlreq->len = MIN(len, ret);
ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
ret = EP_SUBMIT(dev->ep0, ctrlreq);
/* Send the response -- either directly to the USB controller or
* indirectly in the case where this class is a member of a composite
* device.
*/
#ifndef CONFIG_CDCACM_COMPOSITE
ret = EP_SUBMIT(dev->ep0, ctrlreq);
#else
ret = composite_ep0submit(driver, dev, ctrlreq);
#endif
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ), (uint16_t)-ret);
@@ -1488,7 +1520,8 @@ static int cdcacm_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ct
*
****************************************************************************/
static void cdcacm_disconnect(FAR struct usbdev_s *dev)
static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct cdcacm_dev_s *priv;
irqstate_t flags;
@@ -1496,7 +1529,7 @@ static void cdcacm_disconnect(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSDISCONNECT, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev || !dev->ep0)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
return;
@@ -1505,7 +1538,7 @@ static void cdcacm_disconnect(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct cdcacm_dev_s *)dev->ep0->priv;
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@@ -2092,7 +2125,7 @@ void cdcacm_uninitialize(FAR struct usbdevclass_driver_s *classdev)
if (priv->usbdev)
{
cdcacm_unbind(Fpriv->usbdev);
cdcacm_unbind(classdev, priv->usbdev);
}
/* Unregister the driver (unless we are a part of a composite device */