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

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4339 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-01-26 17:42:44 +00:00
parent 930ca11f09
commit 7bf58dba52
6 changed files with 296 additions and 138 deletions

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 */

View File

@ -67,7 +67,7 @@
struct composite_dev_s
{
FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
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 */
@ -107,14 +107,19 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep,
/* USB class device ********************************************************/
static int composite_bind(FAR struct usbdev_s *dev,
FAR struct usbdevclass_driver_s *driver);
static void composite_unbind(FAR struct usbdev_s *dev);
static int composite_setup(FAR struct usbdev_s *dev,
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);
static void composite_disconnect(FAR struct usbdev_s *dev);
static void composite_suspend(FAR struct usbdev_s *dev);
static void composite_resume(FAR struct usbdev_s *dev);
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
@ -150,13 +155,15 @@ const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR;
* Name: composite_ep0incomplete
*
* Description:
* Handle completion of EP0 control operations
* 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);
@ -254,9 +261,10 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep,
*
****************************************************************************/
static int composite_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s *driver)
static int composite_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct composite_dev_s *priv = ((struct composite_driver_s*)driver)->dev;
FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s*)driver)->dev;
int ret;
usbtrace(TRACE_CLASSBIND, 0);
@ -264,9 +272,14 @@ static int composite_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_drive
/* 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 control request */
/* Preallocate one control request */
priv->ctrlreq = composite_allocreq(dev->ep0, COMPOSITE_CFGDESCSIZE);
if (priv->ctrlreq == NULL)
@ -318,7 +331,8 @@ errout:
*
****************************************************************************/
static void composite_unbind(FAR struct usbdev_s *dev)
static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct composite_dev_s *priv;
irqstate_t flags;
@ -326,7 +340,7 @@ static void composite_unbind(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSUNBIND, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev || !dev->ep0)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
return;
@ -335,7 +349,7 @@ static void composite_unbind(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct composite_dev_s *)dev->ep0->priv;
priv = ((FAR struct composite_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -376,7 +390,8 @@ static void composite_unbind(FAR struct usbdev_s *dev)
*
****************************************************************************/
static int composite_setup(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 struct composite_dev_s *priv;
@ -388,7 +403,7 @@ static int composite_setup(FAR struct usbdev_s *dev,
int ret = -EOPNOTSUPP;
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0 || !ctrl)
if (!driver || !dev || !dev->ep0 || !ctrl)
{
usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_SETUPINVALIDARGS), 0);
return -EIO;
@ -398,7 +413,7 @@ static int composite_setup(FAR struct usbdev_s *dev,
/* Extract a reference to private data */
usbtrace(TRACE_CLASSSETUP, ctrl->req);
priv = (FAR struct composite_dev_s *)dev->ep0->priv;
priv = ((FAR struct composite_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -562,9 +577,14 @@ static int composite_setup(FAR struct usbdev_s *dev,
if (ret >= 0 && !dispatched)
{
/* Setup the request */
ctrlreq->len = MIN(len, ret);
ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
ret = EP_SUBMIT(dev->ep0, ctrlreq);
/* 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);
@ -585,7 +605,8 @@ static int composite_setup(FAR struct usbdev_s *dev,
*
****************************************************************************/
static void composite_disconnect(FAR struct usbdev_s *dev)
static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct composite_dev_s *priv;
irqstate_t flags;
@ -593,7 +614,7 @@ static void composite_disconnect(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSDISCONNECT, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
return;
@ -602,7 +623,7 @@ static void composite_disconnect(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct composite_dev_s *)dev->ep0->priv;
priv = ((FAR struct composite_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -637,7 +658,8 @@ static void composite_disconnect(FAR struct usbdev_s *dev)
*
****************************************************************************/
static void composite_suspend(FAR struct usbdev_s *dev)
static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct composite_dev_s *priv;
irqstate_t flags;
@ -645,7 +667,7 @@ static void composite_suspend(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSSUSPEND, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0 || !dev->ep0->priv)
if (!dev)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
return;
@ -654,7 +676,15 @@ static void composite_suspend(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct composite_dev_s *)dev->ep0->priv;
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 */
@ -672,15 +702,14 @@ static void composite_suspend(FAR struct usbdev_s *dev)
*
****************************************************************************/
static void composite_resume(FAR struct usbdev_s *dev)
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;
if (!dev || !dev->ep0 || !dev->ep0->priv)
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!dev)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
return;
@ -689,7 +718,15 @@ static void composite_resume(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct composite_dev_s *)dev->ep0->priv;
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 */
@ -784,4 +821,27 @@ errout_with_alloc:
return ret;
}
/****************************************************************************
* 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 */

View File

@ -253,7 +253,22 @@ extern const char g_compserialstr[];
****************************************************************************/
/****************************************************************************
* Name: usbmsc_mkstrdesc
* 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);
/****************************************************************************
* Name: composite_mkstrdesc
*
* Description:
* Construct a string descriptor

View File

@ -303,7 +303,7 @@ static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv,
/* Request helpers *********************************************************/
static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
uint16_t len);
static void usbclass_freereq(FAR struct usbdev_ep_s *ep,
FAR struct usbdev_req_s *req);
@ -333,22 +333,25 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep,
/* USB class device ********************************************************/
static int usbclass_bind(FAR struct usbdev_s *dev,
FAR struct usbdevclass_driver_s *driver);
static void usbclass_unbind(FAR struct usbdev_s *dev);
static int usbclass_setup(FAR struct usbdev_s *dev,
const struct usb_ctrlreq_s *ctrl);
static void usbclass_disconnect(FAR struct usbdev_s *dev);
static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl);
static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
/* Serial port *************************************************************/
static int pl2303_setup(FAR struct uart_dev_s *dev);
static void pl2303_shutdown(FAR struct uart_dev_s *dev);
static int pl2303_attach(FAR struct uart_dev_s *dev);
static void pl2303_detach(FAR struct uart_dev_s *dev);
static void pl2303_rxint(FAR struct uart_dev_s *dev, bool enable);
static void pl2303_txint(FAR struct uart_dev_s *dev, bool enable);
static bool pl2303_txempty(FAR struct uart_dev_s *dev);
static int usbser_setup(FAR struct uart_dev_s *dev);
static void usbser_shutdown(FAR struct uart_dev_s *dev);
static int usbser_attach(FAR struct uart_dev_s *dev);
static void usbser_detach(FAR struct uart_dev_s *dev);
static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable);
static void usbser_txint(FAR struct uart_dev_s *dev, bool enable);
static bool usbser_txempty(FAR struct uart_dev_s *dev);
/****************************************************************************
* Private Variables
@ -370,18 +373,18 @@ static const struct usbdevclass_driverops_s g_driverops =
static const struct uart_ops_s g_uartops =
{
pl2303_setup, /* setup */
pl2303_shutdown, /* shutdown */
pl2303_attach, /* attach */
pl2303_detach, /* detach */
usbser_setup, /* setup */
usbser_shutdown, /* shutdown */
usbser_attach, /* attach */
usbser_detach, /* detach */
NULL, /* ioctl */
NULL, /* receive */
pl2303_rxint, /* rxinit */
usbser_rxint, /* rxinit */
NULL, /* rxavailable */
NULL, /* send */
pl2303_txint, /* txinit */
usbser_txint, /* txinit */
NULL, /* txready */
pl2303_txempty /* txempty */
usbser_txempty /* txempty */
};
/* USB descriptor templates these will be copied and modified **************/
@ -1265,9 +1268,10 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep,
*
****************************************************************************/
static int usbclass_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s *driver)
static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct pl2303_dev_s *priv = ((struct pl2303_driver_s*)driver)->dev;
FAR struct pl2303_dev_s *priv = ((FAR struct pl2303_driver_s*)driver)->dev;
FAR struct pl2303_req_s *reqcontainer;
irqstate_t flags;
uint16_t reqlen;
@ -1279,6 +1283,13 @@ static int usbclass_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver
/* 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).
*/
dev->ep0->priv = priv;
/* Preallocate control request */
@ -1393,7 +1404,7 @@ static int usbclass_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver
return OK;
errout:
usbclass_unbind(dev);
usbclass_unbind(driver, dev);
return ret;
}
@ -1405,7 +1416,8 @@ errout:
*
****************************************************************************/
static void usbclass_unbind(FAR struct usbdev_s *dev)
static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct pl2303_dev_s *priv;
FAR struct pl2303_req_s *reqcontainer;
@ -1415,7 +1427,7 @@ static void usbclass_unbind(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSUNBIND, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev || !dev->ep0)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
return;
@ -1424,7 +1436,7 @@ static void usbclass_unbind(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct pl2303_dev_s *)dev->ep0->priv;
priv = ((FAR struct pl2303_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -1529,7 +1541,9 @@ static void usbclass_unbind(FAR struct usbdev_s *dev)
*
****************************************************************************/
static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ctrl)
static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
{
FAR struct pl2303_dev_s *priv;
FAR struct usbdev_req_s *ctrlreq;
@ -1539,7 +1553,7 @@ static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *
int ret = -EOPNOTSUPP;
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0 || !ctrl)
if (!driver || !dev || !dev->ep0 || !ctrl)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
return -EIO;
@ -1549,7 +1563,7 @@ static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *
/* Extract reference to private data */
usbtrace(TRACE_CLASSSETUP, ctrl->req);
priv = (FAR struct pl2303_dev_s *)dev->ep0->priv;
priv = ((FAR struct pl2303_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv || !priv->ctrlreq)
@ -1791,7 +1805,8 @@ static int usbclass_setup(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *
*
****************************************************************************/
static void usbclass_disconnect(FAR struct usbdev_s *dev)
static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct pl2303_dev_s *priv;
irqstate_t flags;
@ -1799,7 +1814,7 @@ static void usbclass_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;
@ -1808,7 +1823,7 @@ static void usbclass_disconnect(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct pl2303_dev_s *)dev->ep0->priv;
priv = ((FAR struct pl2303_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -1841,14 +1856,14 @@ static void usbclass_disconnect(FAR struct usbdev_s *dev)
****************************************************************************/
/****************************************************************************
* Name: pl2303_setup
* Name: usbser_setup
*
* Description:
* This method is called the first time that the serial port is opened.
*
****************************************************************************/
static int pl2303_setup(FAR struct uart_dev_s *dev)
static int usbser_setup(FAR struct uart_dev_s *dev)
{
FAR struct pl2303_dev_s *priv;
@ -1880,18 +1895,18 @@ static int pl2303_setup(FAR struct uart_dev_s *dev)
}
/****************************************************************************
* Name: pl2303_shutdown
* Name: usbser_shutdown
*
* Description:
* This method is called when the serial port is closed. This operation
* is very simple for the USB serial backend because the serial driver
* has already assured that the TX data has full drained -- it calls
* pl2303_txempty() until that function returns true before calling this
* usbser_txempty() until that function returns true before calling this
* function.
*
****************************************************************************/
static void pl2303_shutdown(FAR struct uart_dev_s *dev)
static void usbser_shutdown(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_SHUTDOWN, 0);
@ -1906,50 +1921,50 @@ static void pl2303_shutdown(FAR struct uart_dev_s *dev)
}
/****************************************************************************
* Name: pl2303_attach
* Name: usbser_attach
*
* Description:
* Does not apply to the USB serial class device
*
****************************************************************************/
static int pl2303_attach(FAR struct uart_dev_s *dev)
static int usbser_attach(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_ATTACH, 0);
return OK;
}
/****************************************************************************
* Name: pl2303_detach
* Name: usbser_detach
*
* Description:
* Does not apply to the USB serial class device
*
****************************************************************************/
static void pl2303_detach(FAR struct uart_dev_s *dev)
static void usbser_detach(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_DETACH, 0);
}
/****************************************************************************
* Name: pl2303_rxint
* Name: usbser_rxint
*
* Description:
* Called by the serial driver to enable or disable RX interrupts. We, of
* course, have no RX interrupts but must behave consistently. This method
* is called under the conditions:
*
* 1. With enable==true when the port is opened (just after pl2303_setup
* and pl2303_attach are called called)
* 1. With enable==true when the port is opened (just after usbser_setup
* and usbser_attach are called called)
* 2. With enable==false while transferring data from the RX buffer
* 2. With enable==true while waiting for more incoming data
* 3. With enable==false when the port is closed (just before pl2303_detach
* and pl2303_shutdown are called).
* 3. With enable==false when the port is closed (just before usbser_detach
* and usbser_shutdown are called).
*
****************************************************************************/
static void pl2303_rxint(FAR struct uart_dev_s *dev, bool enable)
static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable)
{
FAR struct pl2303_dev_s *priv;
FAR uart_dev_t *serdev;
@ -2029,7 +2044,7 @@ static void pl2303_rxint(FAR struct uart_dev_s *dev, bool enable)
}
/****************************************************************************
* Name: pl2303_txint
* Name: usbser_txint
*
* Description:
* Called by the serial driver to enable or disable TX interrupts. We, of
@ -2042,7 +2057,7 @@ static void pl2303_rxint(FAR struct uart_dev_s *dev, bool enable)
*
****************************************************************************/
static void pl2303_txint(FAR struct uart_dev_s *dev, bool enable)
static void usbser_txint(FAR struct uart_dev_s *dev, bool enable)
{
FAR struct pl2303_dev_s *priv;
@ -2076,7 +2091,7 @@ static void pl2303_txint(FAR struct uart_dev_s *dev, bool enable)
}
/****************************************************************************
* Name: pl2303_txempty
* Name: usbser_txempty
*
* Description:
* Return true when all data has been sent. This is called from the
@ -2087,7 +2102,7 @@ static void pl2303_txint(FAR struct uart_dev_s *dev, bool enable)
*
****************************************************************************/
static bool pl2303_txempty(FAR struct uart_dev_s *dev)
static bool usbser_txempty(FAR struct uart_dev_s *dev)
{
FAR struct pl2303_dev_s *priv = (FAR struct pl2303_dev_s*)dev->priv;

View File

@ -82,6 +82,10 @@
#include "usbmsc.h"
#ifdef CONFIG_USBMSC_COMPOSITE
# include "composite.h"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -121,12 +125,15 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep,
/* Class Driver Operations (most at interrupt level) ************************/
static int usbmsc_bind(FAR struct usbdev_s *dev,
FAR struct usbdevclass_driver_s *driver);
static void usbmsc_unbind(FAR struct usbdev_s *dev);
static int usbmsc_setup(FAR struct usbdev_s *dev,
static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl);
static void usbmsc_disconnect(FAR struct usbdev_s *dev);
static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
/* Initialization/Uninitialization ******************************************/
@ -235,9 +242,10 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
*
****************************************************************************/
static int usbmsc_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s *driver)
static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct usbmsc_dev_s *priv = ((struct usbmsc_driver_s*)driver)->dev;
FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s*)driver)->dev;
FAR struct usbmsc_req_s *reqcontainer;
irqstate_t flags;
int ret = OK;
@ -248,7 +256,16 @@ static int usbmsc_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
/* The configured EP0 size should match the reported EP0 size. We could
* easily adapt to the reported EP0 size, but then we could not use the
@ -351,7 +368,7 @@ static int usbmsc_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s
return OK;
errout:
usbmsc_unbind(dev);
usbmsc_unbind(driver, dev);
return ret;
}
@ -363,7 +380,8 @@ errout:
*
****************************************************************************/
static void usbmsc_unbind(FAR struct usbdev_s *dev)
static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
FAR struct usbmsc_dev_s *priv;
FAR struct usbmsc_req_s *reqcontainer;
@ -373,7 +391,7 @@ static void usbmsc_unbind(FAR struct usbdev_s *dev)
usbtrace(TRACE_CLASSUNBIND, 0);
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0)
if (!driver || !dev || !dev->ep0)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDINVALIDARGS), 0);
return;
@ -382,7 +400,7 @@ static void usbmsc_unbind(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct usbmsc_dev_s *)dev->ep0->priv;
priv = ((FAR struct usbmsc_driver_s*)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)
@ -477,7 +495,8 @@ static void usbmsc_unbind(FAR struct usbdev_s *dev)
*
****************************************************************************/
static int usbmsc_setup(FAR struct usbdev_s *dev,
static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
{
FAR struct usbmsc_dev_s *priv;
@ -488,7 +507,7 @@ static int usbmsc_setup(FAR struct usbdev_s *dev,
int ret = -EOPNOTSUPP;
#ifdef CONFIG_DEBUG
if (!dev || !dev->ep0 || !ctrl)
if (!driver || !dev || !dev->ep0 || !ctrl)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETUPINVALIDARGS), 0);
return -EIO;
@ -498,7 +517,7 @@ static int usbmsc_setup(FAR struct usbdev_s *dev,
/* Extract reference to private data */
usbtrace(TRACE_CLASSSETUP, ctrl->req);
priv = (FAR struct usbmsc_dev_s *)dev->ep0->priv;
priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv || !priv->ctrlreq)
@ -763,9 +782,21 @@ static int usbmsc_setup(FAR struct usbdev_s *dev,
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_USBMSC_COMPOSITE
ret = EP_SUBMIT(dev->ep0, ctrlreq);
#else
ret = composite_ep0submit(driver, dev, ctrlreq);
#endif
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPRESPQ), (uint16_t)-ret);
@ -789,7 +820,8 @@ static int usbmsc_setup(FAR struct usbdev_s *dev,
*
****************************************************************************/
static void usbmsc_disconnect(FAR struct usbdev_s *dev)
static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev)
{
struct usbmsc_dev_s *priv;
irqstate_t flags;
@ -797,7 +829,7 @@ static void usbmsc_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(USBMSC_TRACEERR_DISCONNECTINVALIDARGS), 0);
return;
@ -806,7 +838,7 @@ static void usbmsc_disconnect(FAR struct usbdev_s *dev)
/* Extract reference to private data */
priv = (FAR struct usbmsc_dev_s *)dev->ep0->priv;
priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
#ifdef CONFIG_DEBUG
if (!priv)

View File

@ -1,8 +1,8 @@
/************************************************************************************
* include/nuttx/usb/usbdev.h
*
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* NOTE: This interface was inspired by the Linux gadget interface by
* David Brownell. That work was very helpful in determining a usable
@ -151,29 +151,29 @@
/* Invoked when the driver is bound to a USB device driver. */
#define CLASS_BIND(drvr,dev) (drvr)->ops->bind(dev, drvr)
#define CLASS_BIND(drvr,dev) (drvr)->ops->bind(drvr,dev)
/* Invoked when the driver is unbound from a USB device driver */
#define CLASS_UNBIND(drvr,dev) (drvr)->ops->unbind(dev)
#define CLASS_UNBIND(drvr,dev) (drvr)->ops->unbind(drvr,dev)
/* Invoked after all transfers have been stopped, when the host is disconnected. */
#define CLASS_DISCONNECT(drvr,dev) (drvr)->ops->disconnect(dev)
#define CLASS_DISCONNECT(drvr,dev) (drvr)->ops->disconnect(drvr,dev)
/* Invoked for ep0 control requests */
#define CLASS_SETUP(drvr,dev,ctrl) (drvr)->ops->setup(dev, ctrl)
#define CLASS_SETUP(drvr,dev,ctrl) (drvr)->ops->setup(drvr,dev,ctrl)
/* Invoked on USB suspend. */
#define CLASS_SUSPEND(drvr,dev) \
do { if ((drvr)->ops->suspend) (drvr)->ops->suspend(dev); } while (0)
do { if ((drvr)->ops->suspend) (drvr)->ops->suspend(drvr,dev); } while (0)
/* Invoked on USB resume */
#define CLASS_RESUME(drvr,dev) \
do { if ((drvr)->ops->resume) (drvr)->ops->resume(dev); } while (0)
do { if ((drvr)->ops->resume) (drvr)->ops->resume(drvr,dev); } while (0)
/* Device speeds */
@ -260,7 +260,8 @@ struct usbdev_ops_s
{
/* Allocate and free endpoints */
FAR struct usbdev_ep_s *(*allocep)(FAR struct usbdev_s *dev, uint8_t epphy, bool in, uint8_t eptype);
FAR struct usbdev_ep_s *(*allocep)(FAR struct usbdev_s *dev, uint8_t epphy,
bool in, uint8_t eptype);
void (*freeep)(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep);
/* Get the frame number from the last SOF */
@ -291,12 +292,14 @@ struct usbdev_s
struct usbdevclass_driver_s;
struct usbdevclass_driverops_s
{
int (*bind)(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_s *driver);
void (*unbind)(FAR struct usbdev_s *dev);
int (*setup)(FAR struct usbdev_s *dev, const struct usb_ctrlreq_s *ctrl);
void (*disconnect)(FAR struct usbdev_s *dev);
void (*suspend)(FAR struct usbdev_s *dev);
void (*resume)(FAR struct usbdev_s *dev);
int (*bind)(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev);
void (*unbind)(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev);
int (*setup)(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl);
void (*disconnect)(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
void (*suspend)(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev);
void (*resume)(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev);
};
struct usbdevclass_driver_s