From a571bad413a01a2b745dfa0bf6b4e7cc0c6e0df3 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 12 Apr 2012 16:30:48 +0000 Subject: [PATCH] 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 --- ChangeLog | 3 +++ TODO | 6 ++++++ arch/arm/src/dm320/dm320_usbdev.c | 6 +++--- arch/arm/src/lpc17xx/lpc17_usbdev.c | 6 +++--- arch/arm/src/lpc214x/lpc214x_usbdev.c | 2 +- arch/arm/src/lpc31xx/lpc31_usbdev.c | 6 +++--- arch/arm/src/stm32/stm32_otgfsdev.c | 2 +- arch/arm/src/stm32/stm32_usbdev.c | 4 ++-- arch/avr/src/at90usb/at90usb_usbdev.c | 6 +++--- arch/mips/src/pic32mx/pic32mx-usbdev.c | 2 +- drivers/usbdev/cdcacm.c | 23 +++++++++++++++-------- drivers/usbdev/composite.c | 22 +++++++++++++--------- drivers/usbdev/pl2303.c | 6 ++++-- drivers/usbdev/usbmsc.c | 6 ++++-- include/nuttx/usb/usbdev.h | 5 +++-- 15 files changed, 65 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8adb64da7b..9b82910d59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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. diff --git a/TODO b/TODO index a71bf9183f..7799799558 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/arch/arm/src/dm320/dm320_usbdev.c b/arch/arm/src/dm320/dm320_usbdev.c index 1a3bc0629d..abc89e31d9 100644 --- a/arch/arm/src/dm320/dm320_usbdev.c +++ b/arch/arm/src/dm320/dm320_usbdev.c @@ -1,8 +1,8 @@ /******************************************************************************* * arch/arm/src/dm320/dm320_usbdev.c * - * Copyright (C) 2008-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * 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 */ diff --git a/arch/arm/src/lpc17xx/lpc17_usbdev.c b/arch/arm/src/lpc17xx/lpc17_usbdev.c index 4055a6fc91..4d6be083e0 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbdev.c +++ b/arch/arm/src/lpc17xx/lpc17_usbdev.c @@ -1,8 +1,8 @@ /******************************************************************************* * arch/arm/src/lpc17xx/lpc17_usbdev.c * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * 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 */ diff --git a/arch/arm/src/lpc214x/lpc214x_usbdev.c b/arch/arm/src/lpc214x/lpc214x_usbdev.c index a74ac70385..1d4cd54743 100644 --- a/arch/arm/src/lpc214x/lpc214x_usbdev.c +++ b/arch/arm/src/lpc214x/lpc214x_usbdev.c @@ -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 */ diff --git a/arch/arm/src/lpc31xx/lpc31_usbdev.c b/arch/arm/src/lpc31xx/lpc31_usbdev.c index d6605f0c1b..5584937cc2 100755 --- a/arch/arm/src/lpc31xx/lpc31_usbdev.c +++ b/arch/arm/src/lpc31xx/lpc31_usbdev.c @@ -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 + * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * 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) diff --git a/arch/arm/src/stm32/stm32_otgfsdev.c b/arch/arm/src/stm32/stm32_otgfsdev.c index d3f11977f7..55389327a2 100755 --- a/arch/arm/src/stm32/stm32_otgfsdev.c +++ b/arch/arm/src/stm32/stm32_otgfsdev.c @@ -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) diff --git a/arch/arm/src/stm32/stm32_usbdev.c b/arch/arm/src/stm32/stm32_usbdev.c index 4659114ed5..602de38240 100644 --- a/arch/arm/src/stm32/stm32_usbdev.c +++ b/arch/arm/src/stm32/stm32_usbdev.c @@ -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 * * 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 */ diff --git a/arch/avr/src/at90usb/at90usb_usbdev.c b/arch/avr/src/at90usb/at90usb_usbdev.c index 3022352948..dcda5d6d09 100644 --- a/arch/avr/src/at90usb/at90usb_usbdev.c +++ b/arch/avr/src/at90usb/at90usb_usbdev.c @@ -1,8 +1,8 @@ /******************************************************************************* * arch/arm/src/at90usb/at90usb_usbdev.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * 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) diff --git a/arch/mips/src/pic32mx/pic32mx-usbdev.c b/arch/mips/src/pic32mx/pic32mx-usbdev.c index 3e16680454..dafd35aa03 100644 --- a/arch/mips/src/pic32mx/pic32mx-usbdev.c +++ b/arch/mips/src/pic32mx/pic32mx-usbdev.c @@ -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 */ diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c index b8b7d0653b..2065b54335 100644 --- a/drivers/usbdev/cdcacm.c +++ b/drivers/usbdev/cdcacm.c @@ -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 diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c index aae4f45815..4cad8af864 100644 --- a/drivers/usbdev/composite.c +++ b/drivers/usbdev/composite.c @@ -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; } } diff --git a/drivers/usbdev/pl2303.c b/drivers/usbdev/pl2303.c index 48db77c8a5..a1ba667f53 100644 --- a/drivers/usbdev/pl2303.c +++ b/drivers/usbdev/pl2303.c @@ -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; diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index 3c17bfd661..68b61814a7 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -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; diff --git a/include/nuttx/usb/usbdev.h b/include/nuttx/usb/usbdev.h index b799272d3e..89813cac96 100644 --- a/include/nuttx/usb/usbdev.h +++ b/include/nuttx/usb/usbdev.h @@ -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);