From 50cf84c99adef2210a107b88a48604919774a6ae Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 23 Mar 2023 17:21:25 +0100 Subject: [PATCH] usbdev-composite: ep0 submit should be send only once for the composite class --- drivers/usbdev/cdcacm.c | 2 +- drivers/usbdev/composite.c | 28 +++++++++++++++++++++------- drivers/usbdev/dfu.c | 2 +- drivers/usbdev/rndis.c | 2 +- drivers/usbdev/usbmsc.c | 2 +- include/nuttx/usb/composite.h | 4 +++- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c index e096d3149b..d8997edc74 100644 --- a/drivers/usbdev/cdcacm.c +++ b/drivers/usbdev/cdcacm.c @@ -1982,7 +1982,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, #ifndef CONFIG_CDCACM_COMPOSITE ret = EP_SUBMIT(dev->ep0, ctrlreq); #else - ret = composite_ep0submit(driver, dev, ctrlreq); + ret = composite_ep0submit(driver, dev, ctrlreq, ctrl); #endif if (ret < 0) { diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c index 949766f31a..b300c318f4 100644 --- a/drivers/usbdev/composite.c +++ b/drivers/usbdev/composite.c @@ -658,7 +658,6 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, outlen); } - dispatched = true; priv->config = value; } } @@ -1082,14 +1081,29 @@ void composite_uninitialize(FAR void *handle) int composite_ep0submit(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, - FAR struct usbdev_req_s *ctrlreq) + FAR struct usbdev_req_s *ctrlreq, + FAR const struct usb_ctrlreq_s *ctrl) { - /* 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. - */ + bool ep0submit = true; - return EP_SUBMIT(dev->ep0, ctrlreq); + /* Some EP0 responses must be send only once from the composite class */ + + if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) + { + if (ctrl->req == USB_REQ_SETCONFIGURATION) + { + ep0submit = false; + } + } + + if (ep0submit) + { + return EP_SUBMIT(dev->ep0, ctrlreq); + } + else + { + return 0; + } } #endif /* CONFIG_USBDEV_COMPOSITE */ diff --git a/drivers/usbdev/dfu.c b/drivers/usbdev/dfu.c index 565d900e1b..767e1b9018 100644 --- a/drivers/usbdev/dfu.c +++ b/drivers/usbdev/dfu.c @@ -424,7 +424,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { ctrlreq->len = (len < ret) ? len : ret; ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT; - ret = composite_ep0submit(driver, dev, ctrlreq); + ret = composite_ep0submit(driver, dev, ctrlreq, ctrl); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ), (uint16_t)-ret); diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c index 58d61d2c7d..4e3f205235 100644 --- a/drivers/usbdev/rndis.c +++ b/drivers/usbdev/rndis.c @@ -2586,7 +2586,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, #ifndef CONFIG_RNDIS_COMPOSITE ret = EP_SUBMIT(dev->ep0, ctrlreq); #else - ret = composite_ep0submit(driver, dev, ctrlreq); + ret = composite_ep0submit(driver, dev, ctrlreq, ctrl); #endif if (ret < 0) { diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index 79db6a446f..f3714e1373 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -816,7 +816,7 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver, #ifndef CONFIG_USBMSC_COMPOSITE ret = EP_SUBMIT(dev->ep0, ctrlreq); #else - ret = composite_ep0submit(driver, dev, ctrlreq); + ret = composite_ep0submit(driver, dev, ctrlreq, ctrl); #endif if (ret < 0) { diff --git a/include/nuttx/usb/composite.h b/include/nuttx/usb/composite.h index c0ec379fe1..dcf2552ebb 100644 --- a/include/nuttx/usb/composite.h +++ b/include/nuttx/usb/composite.h @@ -130,10 +130,12 @@ void composite_uninitialize(FAR void *handle); struct usbdevclass_driver_s; struct usbdev_s; struct usbdev_req_s; +struct usb_ctrlreq_s; int composite_ep0submit(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, - FAR struct usbdev_req_s *ctrlreq); + FAR struct usbdev_req_s *ctrlreq, + FAR const struct usb_ctrlreq_s *ctrl); #undef EXTERN #if defined(__cplusplus)