1
0
Fork 0
forked from nuttx/nuttx-update

Extend the USB device/class interface: Add parameters to pass the EP0 OUT data that should accompany the OUT SETUP request

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4595 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-04-12 16:30:48 +00:00
parent 333bd7254a
commit a571bad413
15 changed files with 65 additions and 40 deletions

View file

@ -2646,3 +2646,6 @@
* arch/arm/srm/stm32/stm32_otgfsdev.c: A USB OTG FS device-side driver
for the STM32 F4 (and maybe F2 and F1 connectivity line).
* tools/cmpconfig.c: A tool for comparing two configuration files.
* include/nuttx/usb/usbdev.h, drivers/usbdev/*, arch/*/src/*/*usb*.c:
Extend the USB device side interface so that EP0 OUT data can be passed
with OUT SETUP requests.

6
TODO
View file

@ -532,6 +532,12 @@ o USB (drivers/usbdev, drivers/usbhost)
2. But EP0 OUT data could be buffered in a buffer in the driver
data structure. However, there is no method currently
defined in the USB device interface to obtain the EP0 data.
Updates: (1) The USB device-to-class interface as been extended so
that EP0 OUT data can accompany the SETUP request sent to the
class drivers. (2) The logic in the STM32 F4 OTG FS device driver
has been extended to provide this data. Updates are still needed
to other drivers.
Status: Open
Priority: High for class drivers that need EP0 data. For example, the
CDC/ACM serial driver might need the line coding data (that

View file

@ -1,8 +1,8 @@
/*******************************************************************************
* arch/arm/src/dm320/dm320_usbdev.c
*
* Copyright (C) 2008-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2008-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
@ -1144,7 +1144,7 @@ static void dm320_dispatchrequest(struct dm320_usbdev_s *priv,
usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_DISPATCH), 0);
if (priv && priv->driver)
{
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0);
if (ret < 0)
{
/* Stall on failure */

View file

@ -1,8 +1,8 @@
/*******************************************************************************
* arch/arm/src/lpc17xx/lpc17_usbdev.c
*
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2010, 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
@ -1517,7 +1517,7 @@ static void lpc17_dispatchrequest(struct lpc17_usbdev_s *priv,
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0);
if (ret < 0)
{
/* Stall on failure */

View file

@ -1475,7 +1475,7 @@ static void lpc214x_dispatchrequest(struct lpc214x_usbdev_s *priv,
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0);
if (ret < 0)
{
/* Stall on failure */

View file

@ -6,8 +6,8 @@
*
* Part of the NuttX OS and based, in part, on the LPC2148 USB driver:
*
* Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2010-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
@ -980,7 +980,7 @@ static void lpc31_dispatchrequest(struct lpc31_usbdev_s *priv,
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0);
}
if (ret < 0)

View file

@ -1645,7 +1645,7 @@ static int stm32_req_dispatch(struct stm32_usbdev_s *priv,
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0);
}
if (ret < 0)

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32/stm32_usbdev.c
*
* Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.orgr>
*
* References:
@ -1394,7 +1394,7 @@ static void stm32_dispatchrequest(struct stm32_usbdev_s *priv)
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, NULL, 0);
if (ret < 0)
{
/* Stall on failure */

View file

@ -1,8 +1,8 @@
/*******************************************************************************
* arch/arm/src/at90usb/at90usb_usbdev.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2011-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
@ -1080,7 +1080,7 @@ static void avr_dispatchrequest(FAR const struct usb_ctrlreq_s *ctrl)
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(g_usbdev.driver, &g_usbdev.usbdev, ctrl);
ret = CLASS_SETUP(g_usbdev.driver, &g_usbdev.usbdev, ctrl, NULL, 0);
}
if (ret < 0)

View file

@ -1693,7 +1693,7 @@ static void pic32mx_dispatchrequest(struct pic32mx_usbdev_s *priv)
{
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl);
ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, NULL, 0);
if (ret < 0)
{
/* Stall on failure */

View file

@ -184,7 +184,8 @@ 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);
FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
size_t outlen);
static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
@ -1168,7 +1169,8 @@ static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver,
static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
FAR const struct usb_ctrlreq_s *ctrl,
FAR uint8_t *dataout, size_t outlen)
{
FAR struct cdcacm_dev_s *priv;
FAR struct usbdev_req_s *ctrlreq;
@ -1398,14 +1400,19 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
case ACM_SET_LINE_CODING:
{
if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) &&
len == SIZEOF_CDC_LINECODING && index == CDCACM_NOTIFID)
len == SIZEOF_CDC_LINECODING && /* dataout && len == outlen && */
index == CDCACM_NOTIFID)
{
/* Save the new line coding in the private data structure */
/* Save the new line coding in the private data structure. NOTE:
* that this is conditional now because not all device controller
* drivers supported provisioni of EP0 OUT data with the setup
* command.
*/
#warning "There is no mechanism now for the class driver to receive EP0 SETUP OUT data"
#if 0
memcpy(&priv->linecoding, ctrlreq->buf, MIN(len, 7));
#endif
if (dataout && len <= SIZEOF_CDC_LINECODING) /* REVISIT */
{
memcpy(&priv->linecoding, dataout, SIZEOF_CDC_LINECODING);
}
ret = 0;
/* If there is a registered callback to receive line status info, then

View file

@ -99,7 +99,8 @@ 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 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,
@ -113,7 +114,8 @@ 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 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,
@ -180,7 +182,8 @@ static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
static int composite_classsetup(FAR struct composite_dev_s *priv,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
FAR const struct usb_ctrlreq_s *ctrl,
FAR uint8_t *dataout, size_t outlen)
{
uint16_t index;
uint8_t interface;
@ -191,11 +194,11 @@ static int composite_classsetup(FAR struct composite_dev_s *priv,
if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES))
{
ret = CLASS_SETUP(priv->dev1, dev, ctrl);
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);
ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
}
return ret;
@ -392,7 +395,8 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
static int composite_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
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;
@ -549,7 +553,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
priv->config == COMPOSITE_CONFIGID)
{
ret = composite_classsetup(priv, dev, ctrl);
ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
dispatched = true;
}
}
@ -560,7 +564,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
priv->config == COMPOSITE_CONFIGIDNONE)
{
ret = composite_classsetup(priv, dev, ctrl);
ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
dispatched = true;
}
}
@ -586,7 +590,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
recipient = ctrl->type & USB_REQ_RECIPIENT_MASK;
if (recipient == USB_REQ_RECIPIENT_INTERFACE || recipient == USB_REQ_RECIPIENT_ENDPOINT)
{
ret = composite_classsetup(priv, dev, ctrl);
ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
dispatched = true;
}
}

View file

@ -339,7 +339,8 @@ 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);
FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
size_t outlen);
static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
@ -1543,7 +1544,8 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
FAR const struct usb_ctrlreq_s *ctrl,
FAR uint8_t *dataout, size_t outlen)
{
FAR struct pl2303_dev_s *priv;
FAR struct usbdev_req_s *ctrlreq;

View file

@ -132,7 +132,8 @@ 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);
FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
size_t outlen);
static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
@ -501,7 +502,8 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev,
FAR const struct usb_ctrlreq_s *ctrl)
FAR const struct usb_ctrlreq_s *ctrl,
FAR uint8_t *dataout, size_t outlen)
{
FAR struct usbmsc_dev_s *priv;
FAR struct usbdev_req_s *ctrlreq;

View file

@ -168,7 +168,8 @@
/* Invoked for ep0 control requests */
#define CLASS_SETUP(drvr,dev,ctrl) (drvr)->ops->setup(drvr,dev,ctrl)
#define CLASS_SETUP(drvr,dev,ctrl,dataout,outlen) \
(drvr)->ops->setup(drvr,dev,ctrl,dataout,outlen)
/* Invoked on USB suspend. */
@ -300,7 +301,7 @@ struct usbdevclass_driverops_s
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);
FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen);
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);