From 44567307937694e5bfc62b50f3b83176bec8f9c5 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Mon, 30 Sep 2024 12:53:20 +0200 Subject: [PATCH 1/2] drivers: udc_kinetis: reset control endpoint busy flags Reset control endpoint busy flags if configured and enabled, otherwise it could mark the wrong buffer as busy after endpoint disable/enable. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_kinetis.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/udc/udc_kinetis.c b/drivers/usb/udc/udc_kinetis.c index 5a93d4a8b3a59..c471fb15ebda6 100644 --- a/drivers/usb/udc/udc_kinetis.c +++ b/drivers/usb/udc/udc_kinetis.c @@ -882,6 +882,8 @@ static int usbfsotg_ep_enable(const struct device *dev, if (cfg->addr == USB_CONTROL_EP_OUT) { struct net_buf *buf; + priv->busy[0] = false; + priv->busy[1] = false; buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, USBFSOTG_EP0_SIZE); usbfsotg_bd_set_ctrl(bd_even, buf->size, buf->data, false); priv->out_buf[0] = buf; From 8b49063afdaae6b6f4cabd9c171b344423e98b1a Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 23 Oct 2024 11:23:23 +0200 Subject: [PATCH 2/2] drivers: udc_nrf: fix enqueue of control IN transfer with length 0 If the direction of the last setup packet is not to the device but to the host, then the transfer is not a status stage and should be queued. This is not checked and prevents a zero length control IN transfer to the host, e.g. used by the DFU class to indicate the end of the upload process. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_nrf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index c024d2a6a1847..2d1eb17d47231 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -487,7 +487,7 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt) } } -static void udc_nrf_fake_status_in(const struct device *dev) +static bool udc_nrf_fake_status_in(const struct device *dev) { struct udc_nrf_evt evt = { .type = UDC_NRF_EVT_STATUS_IN, @@ -497,7 +497,10 @@ static void udc_nrf_fake_status_in(const struct device *dev) if (nrf_usbd_common_last_setup_dir_get() == USB_CONTROL_EP_OUT) { /* Let controller perform status IN stage */ k_msgq_put(&drv_msgq, &evt, K_NO_WAIT); + return true; } + + return false; } static int udc_nrf_ep_enqueue(const struct device *dev, @@ -512,8 +515,9 @@ static int udc_nrf_ep_enqueue(const struct device *dev, udc_buf_put(cfg, buf); if (cfg->addr == USB_CONTROL_EP_IN && buf->len == 0) { - udc_nrf_fake_status_in(dev); - return 0; + if (udc_nrf_fake_status_in(dev)) { + return 0; + } } k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);