From 557ec03976f16556e42bb6541aac8eb69d762dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 20 Mar 2025 13:07:39 +0100 Subject: [PATCH 1/2] [nrf fromtree] drivers: usb: udc: Reduce unnecessary ep config lookups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UDC API passes struct udc_ep_config to all functions. Some UDC functions were using endpoint config structure while some were using device and endpoint number. This API inconsistency led to completely unnecessary endpoint structure lookups. Remove unnecessary lookups by using endpoint config structure pointer where it makes sense. Signed-off-by: Tomasz Moń (cherry picked from commit 1cccf28d5e51f8919000a0e68b60834ff59046f4) (cherry picked from commit 511cd38b489beac989202077472bac92078d0900) --- drivers/usb/udc/udc_ambiq.c | 36 ++++++++++--------- drivers/usb/udc/udc_common.c | 41 ++++------------------ drivers/usb/udc/udc_common.h | 28 ++++++--------- drivers/usb/udc/udc_dwc2.c | 52 ++++++++++++++------------- drivers/usb/udc/udc_it82xx2.c | 46 ++++++++++++++---------- drivers/usb/udc/udc_kinetis.c | 36 +++++++++---------- drivers/usb/udc/udc_mcux_ehci.c | 24 +++++++------ drivers/usb/udc/udc_mcux_ip3511.c | 24 +++++++------ drivers/usb/udc/udc_nrf.c | 38 ++++++++++++-------- drivers/usb/udc/udc_numaker.c | 38 +++++++++++++------- drivers/usb/udc/udc_renesas_ra.c | 21 ++++++----- drivers/usb/udc/udc_rpi_pico.c | 30 ++++++++-------- drivers/usb/udc/udc_skeleton.c | 2 +- drivers/usb/udc/udc_smartbond.c | 44 +++++++++++++---------- drivers/usb/udc/udc_stm32.c | 58 +++++++++++++++++-------------- drivers/usb/udc/udc_virtual.c | 10 +++--- 16 files changed, 272 insertions(+), 256 deletions(-) diff --git a/drivers/usb/udc/udc_ambiq.c b/drivers/usb/udc/udc_ambiq.c index f6f342fc21cd..11d26865df1e 100644 --- a/drivers/usb/udc/udc_ambiq.c +++ b/drivers/usb/udc/udc_ambiq.c @@ -96,13 +96,14 @@ static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length) static int udc_ambiq_tx(const struct device *dev, uint8_t ep, struct net_buf *buf) { const struct udc_ambiq_data *priv = udc_get_private(dev); + struct udc_ep_config *cfg = udc_get_ep_cfg(dev, ep); uint32_t status; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(cfg)) { LOG_WRN("ep 0x%02x is busy!", ep); return 0; } - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(cfg, true); /* buf equals NULL is used as indication of ZLP request */ if (buf == NULL) { @@ -112,7 +113,7 @@ static int udc_ambiq_tx(const struct device *dev, uint8_t ep, struct net_buf *bu } if (status != AM_HAL_STATUS_SUCCESS) { - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(cfg, false); LOG_ERR("am_hal_usb_ep_xfer write failed(0x%02x), %d", ep, (int)status); return -EIO; } @@ -123,15 +124,16 @@ static int udc_ambiq_tx(const struct device *dev, uint8_t ep, struct net_buf *bu static int udc_ambiq_rx(const struct device *dev, uint8_t ep, struct net_buf *buf) { struct udc_ambiq_data *priv = udc_get_private(dev); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct udc_ep_config *cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); uint32_t status; uint16_t rx_size = buf->size; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(ep_cfg)) { LOG_WRN("ep 0x%02x is busy!", ep); return 0; } - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); /* Make sure that OUT transaction size triggered doesn't exceed EP's MPS */ if ((ep != USB_CONTROL_EP_OUT) && (cfg->mps < rx_size)) { @@ -140,7 +142,7 @@ static int udc_ambiq_rx(const struct device *dev, uint8_t ep, struct net_buf *bu status = am_hal_usb_ep_xfer(priv->usb_handle, ep, buf->data, rx_size); if (status != AM_HAL_STATUS_SUCCESS) { - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); LOG_ERR("am_hal_usb_ep_xfer read(rx) failed(0x%02x), %d", ep, (int)status); return -EIO; } @@ -223,7 +225,9 @@ static void udc_ambiq_ep_xfer_complete_callback(const struct device *dev, uint8_ if (USB_EP_DIR_IS_IN(ep_addr)) { evt.type = UDC_AMBIQ_EVT_HAL_IN_CMP; } else { - buf = udc_buf_peek(dev, ep_addr); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep_addr); + + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", ep_addr); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -281,12 +285,12 @@ static int udc_ambiq_ep_dequeue(const struct device *dev, struct udc_ep_config * lock_key = irq_lock(); - buf = udc_buf_get_all(dev, ep_cfg->addr); + buf = udc_buf_get_all(ep_cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, ep_cfg->addr, false); + udc_ep_set_busy(ep_cfg, false); am_hal_usb_ep_state_reset(priv->usb_handle, ep_cfg->addr); irq_unlock(lock_key); @@ -320,7 +324,7 @@ static int udc_ambiq_ep_clear_halt(const struct device *dev, struct udc_ep_confi ep_cfg->stat.halted = false; /* Resume queued transfer if any */ - if (udc_buf_peek(dev, ep_cfg->addr)) { + if (udc_buf_peek(ep_cfg)) { struct udc_ambiq_event evt = { .ep = ep_cfg->addr, .type = UDC_AMBIQ_EVT_XFER, @@ -647,14 +651,14 @@ static inline void ambiq_handle_evt_dout(const struct device *dev, struct udc_ep struct net_buf *buf; /* retrieve endpoint buffer */ - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf == NULL) { LOG_ERR("No buffer queued for control ep"); return; } /* Clear endpoint busy status */ - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); /* Handle transfer complete event */ if (cfg->addr == USB_CONTROL_EP_OUT) { @@ -686,9 +690,9 @@ static void ambiq_handle_evt_din(const struct device *dev, struct udc_ep_config bool udc_ambiq_rx_status_in_completed = false; /* Clear endpoint busy status */ - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); /* Check and Handle ZLP flag */ - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (cfg->addr != USB_CONTROL_EP_IN) { if (udc_ep_buf_has_zlp(buf)) { udc_ep_buf_clear_zlp(buf); @@ -699,7 +703,7 @@ static void ambiq_handle_evt_din(const struct device *dev, struct udc_ep_config } /* retrieve endpoint buffer */ - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf == NULL) { LOG_ERR("No buffer queued for control ep"); return; @@ -754,7 +758,7 @@ static void udc_event_xfer(const struct device *dev, struct udc_ep_config *const { struct net_buf *buf; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", cfg->addr); return; diff --git a/drivers/usb/udc/udc_common.c b/drivers/usb/udc/udc_common.c index 9429c404ad60..3718290ce42e 100644 --- a/drivers/usb/udc/udc_common.c +++ b/drivers/usb/udc/udc_common.c @@ -78,22 +78,13 @@ struct udc_ep_config *udc_get_ep_cfg(const struct device *dev, const uint8_t ep) return data->ep_lut[USB_EP_LUT_IDX(ep)]; } -bool udc_ep_is_busy(const struct device *dev, const uint8_t ep) +bool udc_ep_is_busy(const struct udc_ep_config *const ep_cfg) { - struct udc_ep_config *ep_cfg; - - ep_cfg = udc_get_ep_cfg(dev, ep); - __ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep); - return ep_cfg->stat.busy; } -void udc_ep_set_busy(const struct device *dev, const uint8_t ep, const bool busy) +void udc_ep_set_busy(struct udc_ep_config *const ep_cfg, const bool busy) { - struct udc_ep_config *ep_cfg; - - ep_cfg = udc_get_ep_cfg(dev, ep); - __ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep); ep_cfg->stat.busy = busy; } @@ -115,34 +106,21 @@ int udc_register_ep(const struct device *dev, struct udc_ep_config *const cfg) return 0; } -struct net_buf *udc_buf_get(const struct device *dev, const uint8_t ep) +struct net_buf *udc_buf_get(struct udc_ep_config *const ep_cfg) { - struct udc_ep_config *ep_cfg; - - ep_cfg = udc_get_ep_cfg(dev, ep); - if (ep_cfg == NULL) { - return NULL; - } - return k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); } -struct net_buf *udc_buf_get_all(const struct device *dev, const uint8_t ep) +struct net_buf *udc_buf_get_all(struct udc_ep_config *const ep_cfg) { - struct udc_ep_config *ep_cfg; struct net_buf *buf; - ep_cfg = udc_get_ep_cfg(dev, ep); - if (ep_cfg == NULL) { - return NULL; - } - buf = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); if (!buf) { return NULL; } - LOG_DBG("ep 0x%02x dequeue %p", ep, buf); + LOG_DBG("ep 0x%02x dequeue %p", ep_cfg->addr, buf); for (struct net_buf *n = buf; !k_fifo_is_empty(&ep_cfg->fifo); n = n->frags) { n->frags = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); LOG_DBG("|-> %p ", n->frags); @@ -154,15 +132,8 @@ struct net_buf *udc_buf_get_all(const struct device *dev, const uint8_t ep) return buf; } -struct net_buf *udc_buf_peek(const struct device *dev, const uint8_t ep) +struct net_buf *udc_buf_peek(struct udc_ep_config *const ep_cfg) { - struct udc_ep_config *ep_cfg; - - ep_cfg = udc_get_ep_cfg(dev, ep); - if (ep_cfg == NULL) { - return NULL; - } - return k_fifo_peek_head(&ep_cfg->fifo); } diff --git a/drivers/usb/udc/udc_common.h b/drivers/usb/udc/udc_common.h index 19cad23bd39e..8cad6b6dd1c5 100644 --- a/drivers/usb/udc/udc_common.h +++ b/drivers/usb/udc/udc_common.h @@ -61,21 +61,19 @@ struct udc_ep_config *udc_get_ep_cfg(const struct device *dev, /** * @brief Checks if the endpoint is busy * - * @param[in] dev Pointer to device struct of the driver instance - * @param[in] ep Endpoint address + * @param[in] ep_cfg Pointer to endpoint configuration * * @return true if endpoint is busy */ -bool udc_ep_is_busy(const struct device *dev, const uint8_t ep); +bool udc_ep_is_busy(const struct udc_ep_config *const ep_cfg); /** * @brief Helper function to set endpoint busy state * - * @param[in] dev Pointer to device struct of the driver instance - * @param[in] ep Endpoint address + * @param[in] ep_cfg Pointer to endpoint configuration * @param[in] busy Busy state */ -void udc_ep_set_busy(const struct device *dev, const uint8_t ep, +void udc_ep_set_busy(struct udc_ep_config *const ep_cfg, const bool busy); /** @@ -85,13 +83,11 @@ void udc_ep_set_busy(const struct device *dev, const uint8_t ep, * Use it when transfer is finished and request should * be passed to the higher level. * - * @param[in] dev Pointer to device struct of the driver instance - * @param[in] ep Endpoint address + * @param[in] ep_cfg Pointer to endpoint configuration * * @return pointer to UDC request or NULL on error. */ -struct net_buf *udc_buf_get(const struct device *dev, - const uint8_t ep); +struct net_buf *udc_buf_get(struct udc_ep_config *const ep_cfg); /** * @brief Get all UDC request from endpoint FIFO. @@ -100,13 +96,11 @@ struct net_buf *udc_buf_get(const struct device *dev, * This function removes all request from endpoint FIFO and * is typically used to dequeue endpoint FIFO. * - * @param[in] dev Pointer to device struct of the driver instance - * @param[in] ep Endpoint address + * @param[in] ep_cfg Pointer to endpoint configuration * * @return pointer to UDC request or NULL on error. */ -struct net_buf *udc_buf_get_all(const struct device *dev, - const uint8_t ep); +struct net_buf *udc_buf_get_all(struct udc_ep_config *const ep_cfg); /** * @brief Peek request at the head of endpoint FIFO. @@ -114,13 +108,11 @@ struct net_buf *udc_buf_get_all(const struct device *dev, * Return request from the head of endpoint FIFO without removing. * Use it when request buffer is required for a transfer. * - * @param[in] dev Pointer to device struct of the driver instance - * @param[in] ep Endpoint address + * @param[in] ep_cfg Pointer to endpoint configuration * * @return pointer to request or NULL on error. */ -struct net_buf *udc_buf_peek(const struct device *dev, - const uint8_t ep); +struct net_buf *udc_buf_peek(struct udc_ep_config *const ep_cfg); /** * @brief Put request at the tail of endpoint FIFO. diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index feccd3d8662b..2339356d8823 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -417,7 +417,7 @@ static void dwc2_ensure_setup_ready(const struct device *dev) return; } - if (!udc_buf_peek(dev, USB_CONTROL_EP_OUT)) { + if (!udc_buf_peek(udc_get_ep_cfg(dev, USB_CONTROL_EP_IN))) { dwc2_ctrl_feed_dout(dev, 8); } } @@ -762,7 +762,7 @@ static void dwc2_handle_xfer_next(const struct device *dev, { struct net_buf *buf; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { return; } @@ -796,7 +796,7 @@ static void dwc2_handle_xfer_next(const struct device *dev, LOG_ERR("Failed to start write to TX FIFO, ep 0x%02x (err: %d)", cfg->addr, err); - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (udc_submit_ep_event(dev, buf, -ECONNREFUSED)) { LOG_ERR("Failed to submit endpoint event"); }; @@ -805,12 +805,14 @@ static void dwc2_handle_xfer_next(const struct device *dev, } } - udc_ep_set_busy(dev, cfg->addr, true); + udc_ep_set_busy(cfg, true); } static int dwc2_handle_evt_setup(const struct device *dev) { struct udc_dwc2_data *const priv = udc_get_private(dev); + struct udc_ep_config *cfg_out = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct udc_ep_config *cfg_in = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN); struct net_buf *buf; int err; @@ -820,18 +822,18 @@ static int dwc2_handle_evt_setup(const struct device *dev) */ k_event_clear(&priv->xfer_finished, BIT(0) | BIT(16)); - buf = udc_buf_get_all(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get_all(cfg_out); if (buf) { net_buf_unref(buf); } - buf = udc_buf_get_all(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get_all(cfg_in); if (buf) { net_buf_unref(buf); } - udc_ep_set_busy(dev, USB_CONTROL_EP_OUT, false); - udc_ep_set_busy(dev, USB_CONTROL_EP_IN, false); + udc_ep_set_busy(cfg_out, false); + udc_ep_set_busy(cfg_in, false); /* Allocate buffer and copy received SETUP for processing */ buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, 8); @@ -877,13 +879,13 @@ static inline int dwc2_handle_evt_dout(const struct device *dev, struct net_buf *buf; int err = 0; - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf == NULL) { LOG_ERR("No buffer queued for ep 0x%02x", cfg->addr); return -ENODATA; } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); if (cfg->addr == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev)) { @@ -925,7 +927,7 @@ static int dwc2_handle_evt_din(const struct device *dev, { struct net_buf *buf; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", cfg->addr); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -942,8 +944,8 @@ static int dwc2_handle_evt_din(const struct device *dev, return dwc2_tx_fifo_write(dev, cfg, buf); } - buf = udc_buf_get(dev, cfg->addr); - udc_ep_set_busy(dev, cfg->addr, false); + buf = udc_buf_get(cfg); + udc_ep_set_busy(cfg, false); if (cfg->addr == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || @@ -1649,7 +1651,7 @@ static void udc_dwc2_ep_disable(const struct device *dev, dwc2_flush_tx_fifo(dev, usb_dwc2_get_depctl_txfnum(dxepctl)); } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); } /* Deactivated endpoint means that there will be a bus timeout when the host @@ -1723,7 +1725,7 @@ static int udc_dwc2_ep_clear_halt(const struct device *dev, cfg->stat.halted = false; /* Resume queued transfers if any */ - if (udc_buf_peek(dev, cfg->addr)) { + if (udc_buf_peek(cfg)) { uint32_t ep_bit; if (USB_EP_DIR_IS_IN(cfg->addr)) { @@ -1771,12 +1773,12 @@ static int udc_dwc2_ep_dequeue(const struct device *dev, udc_dwc2_ep_disable(dev, cfg, false); - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); LOG_DBG("dequeue ep 0x%02x", cfg->addr); @@ -2235,7 +2237,7 @@ static int udc_dwc2_disable(const struct device *dev) * triggering Soft Reset seems to be enough on shutdown clean up. */ dwc2_core_soft_reset(dev); - buf = udc_buf_get_all(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get_all(udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT)); if (buf) { net_buf_unref(buf); } @@ -2513,7 +2515,7 @@ static inline void dwc2_handle_rxflvl(const struct device *dev) case USB_DWC2_GRXSTSR_PKTSTS_OUT_DATA: ep_cfg = udc_get_ep_cfg(dev, ep); - buf = udc_buf_peek(dev, ep_cfg->addr); + buf = udc_buf_peek(ep_cfg); /* RxFIFO data must be retrieved even when buf is NULL */ dwc2_read_fifo(dev, ep, buf, bcnt); @@ -2539,7 +2541,7 @@ static inline void dwc2_handle_in_xfercompl(const struct device *dev, struct net_buf *buf; ep_cfg = udc_get_ep_cfg(dev, ep_idx | USB_EP_DIR_IN); - buf = udc_buf_peek(dev, ep_cfg->addr); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); return; @@ -2602,7 +2604,7 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev, doeptsiz = sys_read32((mem_addr_t)&base->out_ep[ep_idx].doeptsiz); - buf = udc_buf_peek(dev, ep_cfg->addr); + buf = udc_buf_peek(ep_cfg); if (!buf) { LOG_ERR("No buffer for ep 0x%02x", ep_cfg->addr); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -2771,7 +2773,7 @@ static void dwc2_handle_incompisoin(const struct device *dev) udc_dwc2_ep_disable(dev, cfg, false); - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf) { /* Data is no longer relevant */ udc_submit_ep_event(dev, buf, 0); @@ -2826,7 +2828,7 @@ static void dwc2_handle_incompisoout(const struct device *dev) udc_dwc2_ep_disable(dev, cfg, false); - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf) { udc_submit_ep_event(dev, buf, 0); } @@ -3061,7 +3063,7 @@ static ALWAYS_INLINE void dwc2_thread_handler(void *const arg) ep = pull_next_ep_from_bitmap(&eps); ep_cfg = udc_get_ep_cfg(dev, ep); - if (!udc_ep_is_busy(dev, ep_cfg->addr)) { + if (!udc_ep_is_busy(ep_cfg)) { dwc2_handle_xfer_next(dev, ep_cfg); } else { LOG_DBG("ep 0x%02x busy", ep_cfg->addr); @@ -3091,7 +3093,7 @@ static ALWAYS_INLINE void dwc2_thread_handler(void *const arg) dwc2_handle_evt_dout(dev, ep_cfg); } - if (!udc_ep_is_busy(dev, ep_cfg->addr)) { + if (!udc_ep_is_busy(ep_cfg)) { dwc2_handle_xfer_next(dev, ep_cfg); } else { LOG_DBG("ep 0x%02x busy", ep_cfg->addr); diff --git a/drivers/usb/udc/udc_it82xx2.c b/drivers/usb/udc/udc_it82xx2.c index 0c61b7b17db8..fd00587dd653 100644 --- a/drivers/usb/udc/udc_it82xx2.c +++ b/drivers/usb/udc/udc_it82xx2.c @@ -506,12 +506,12 @@ static int it82xx2_ep_dequeue(const struct device *dev, struct udc_ep_config *co } irq_unlock(lock_key); - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); return 0; } @@ -861,16 +861,17 @@ static int work_handler_xfer_continue(const struct device *dev, uint8_t ep, stru return ret; } -static int work_handler_xfer_next(const struct device *dev, uint8_t ep) +static int work_handler_xfer_next(const struct device *dev, + struct udc_ep_config *ep_cfg) { struct net_buf *buf; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { return -ENODATA; } - return work_handler_xfer_continue(dev, ep, buf); + return work_handler_xfer_continue(dev, ep_cfg->addr, buf); } /* @@ -984,11 +985,12 @@ static inline int work_handler_in(const struct device *dev, uint8_t ep) k_sem_give(&priv->fifo_sem[fifo_idx - 1]); } - buf = udc_buf_peek(dev, ep); + ep_cfg = udc_get_ep_cfg(dev, ep); + + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { return -ENODATA; } - ep_cfg = udc_get_ep_cfg(dev, ep); net_buf_pull(buf, MIN(buf->len, udc_mps_ep_size(ep_cfg))); @@ -1005,12 +1007,12 @@ static inline int work_handler_in(const struct device *dev, uint8_t ep) return 0; } - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { return -ENODATA; } - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); if (ep == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { @@ -1042,10 +1044,13 @@ static inline int work_handler_setup(const struct device *dev, uint8_t ep) int err = 0; if (udc_ctrl_stage_is_status_out(dev)) { + struct udc_ep_config *cfg_out; + /* out -> setup */ - buf = udc_buf_get(dev, USB_CONTROL_EP_OUT); + cfg_out = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get(cfg_out); if (buf) { - udc_ep_set_busy(dev, USB_CONTROL_EP_OUT, false); + udc_ep_set_busy(cfg_out, false); net_buf_unref(buf); } } @@ -1109,7 +1114,8 @@ static inline int work_handler_out(const struct device *dev, uint8_t ep) return 0; } - buf = udc_buf_peek(dev, ep); + ep_cfg = udc_get_ep_cfg(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { return -ENODATA; } @@ -1121,7 +1127,7 @@ static inline int work_handler_out(const struct device *dev, uint8_t ep) if (ep == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev) && len != 0) { LOG_DBG("Handle early setup token"); - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); /* Notify upper layer */ udc_ctrl_submit_status(dev, buf); /* Update to next stage of control transfer */ @@ -1130,7 +1136,6 @@ static inline int work_handler_out(const struct device *dev, uint8_t ep) } } - ep_cfg = udc_get_ep_cfg(dev, ep); if (len > udc_mps_ep_size(ep_cfg)) { LOG_ERR("Failed to handle this packet due to the packet size"); return -ENOBUFS; @@ -1148,12 +1153,12 @@ static inline int work_handler_out(const struct device *dev, uint8_t ep) return err; } - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { return -ENODATA; } - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); if (ep == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev)) { @@ -1179,11 +1184,14 @@ static inline int work_handler_out(const struct device *dev, uint8_t ep) static void xfer_work_handler(const struct device *dev) { while (true) { + struct udc_ep_config *ep_cfg; struct it82xx2_ep_event evt; int err = 0; k_msgq_get(&evt_msgq, &evt, K_FOREVER); + ep_cfg = udc_get_ep_cfg(evt.dev, evt.ep); + switch (evt.event) { case IT82xx2_EVT_SETUP_TOKEN: err = work_handler_setup(evt.dev, evt.ep); @@ -1206,9 +1214,9 @@ static void xfer_work_handler(const struct device *dev) udc_submit_event(evt.dev, UDC_EVT_ERROR, err); } - if (evt.ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(evt.dev, evt.ep)) { - if (work_handler_xfer_next(evt.dev, evt.ep) == 0) { - udc_ep_set_busy(evt.dev, evt.ep, true); + if (evt.ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ep_cfg)) { + if (work_handler_xfer_next(ep_cfg) == 0) { + udc_ep_set_busy(ep_cfg, true); } } } diff --git a/drivers/usb/udc/udc_kinetis.c b/drivers/usb/udc/udc_kinetis.c index 70fae41b4871..19e1f865efa4 100644 --- a/drivers/usb/udc/udc_kinetis.c +++ b/drivers/usb/udc/udc_kinetis.c @@ -221,7 +221,7 @@ static int usbfsotg_xfer_next(const struct device *dev, { struct net_buf *buf; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { return -ENODATA; } @@ -317,7 +317,7 @@ static inline int work_handler_setup(const struct device *dev) struct net_buf *buf; int err; - buf = udc_buf_get(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get(udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT)); if (buf == NULL) { return -ENODATA; } @@ -365,17 +365,17 @@ static inline int work_handler_setup(const struct device *dev) } static inline int work_handler_out(const struct device *dev, - const uint8_t ep) + struct udc_ep_config *ep_cfg) { struct net_buf *buf; int err = 0; - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { return -ENODATA; } - if (ep == USB_CONTROL_EP_OUT) { + if (ep_cfg->addr == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev)) { /* s-in-status finished, next bd is already fed */ LOG_DBG("dout:%p|no feed", buf); @@ -404,16 +404,16 @@ static inline int work_handler_out(const struct device *dev, } static inline int work_handler_in(const struct device *dev, - const uint8_t ep) + struct udc_ep_config *ep_cfg) { struct net_buf *buf; - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { return -ENODATA; } - if (ep == USB_CONTROL_EP_IN) { + if (ep_cfg->addr == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { /* Status stage finished, notify upper layer */ @@ -482,12 +482,12 @@ static void xfer_work_handler(struct k_work *item) err = work_handler_setup(ev->dev); break; case USBFSOTG_EVT_DOUT: - err = work_handler_out(ev->dev, ev->ep); - udc_ep_set_busy(ev->dev, ev->ep, false); + err = work_handler_out(ev->dev, ep_cfg); + udc_ep_set_busy(ep_cfg, false); break; case USBFSOTG_EVT_DIN: - err = work_handler_in(ev->dev, ev->ep); - udc_ep_set_busy(ev->dev, ev->ep, false); + err = work_handler_in(ev->dev, ep_cfg); + udc_ep_set_busy(ep_cfg, false); break; case USBFSOTG_EVT_CLEAR_HALT: err = usbfsotg_ep_clear_halt(ev->dev, ep_cfg); @@ -501,9 +501,9 @@ static void xfer_work_handler(struct k_work *item) } /* Peek next transfer */ - if (ev->ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ev->dev, ev->ep)) { + if (ev->ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ep_cfg)) { if (usbfsotg_xfer_next(ev->dev, ep_cfg) == 0) { - udc_ep_set_busy(ev->dev, ev->ep, true); + udc_ep_set_busy(ep_cfg, true); } } @@ -584,7 +584,7 @@ static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev, priv->busy[odd] = false; priv->out_buf[odd] = NULL; } else { - buf = udc_buf_peek(dev, ep_cfg->addr); + buf = udc_buf_peek(ep_cfg); } if (buf == NULL) { @@ -614,7 +614,7 @@ static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev, ep_cfg->stat.odd = !odd; ep_cfg->stat.data1 = !data1; - buf = udc_buf_peek(dev, ep_cfg->addr); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", ep); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -740,12 +740,12 @@ static int usbfsotg_ep_dequeue(const struct device *dev, irq_unlock(lock_key); cfg->stat.halted = false; - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); return 0; } diff --git a/drivers/usb/udc/udc_mcux_ehci.c b/drivers/usb/udc/udc_mcux_ehci.c index 489540a9d159..fc5f65b76443 100644 --- a/drivers/usb/udc/udc_mcux_ehci.c +++ b/drivers/usb/udc/udc_mcux_ehci.c @@ -112,8 +112,8 @@ static int udc_mcux_ep_feed(const struct device *dev, } udc_mcux_lock(dev); - if (!udc_ep_is_busy(dev, cfg->addr)) { - udc_ep_set_busy(dev, cfg->addr, true); + if (!udc_ep_is_busy(cfg)) { + udc_ep_set_busy(cfg, true); udc_mcux_unlock(dev); if (USB_EP_DIR_IS_OUT(cfg->addr)) { @@ -130,7 +130,7 @@ static int udc_mcux_ep_feed(const struct device *dev, udc_mcux_lock(dev); if (status != kStatus_USB_Success) { - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); } udc_mcux_unlock(dev); } else { @@ -147,7 +147,7 @@ static int udc_mcux_ep_try_feed(const struct device *dev, { struct net_buf *feed_buf; - feed_buf = udc_buf_peek(dev, cfg->addr); + feed_buf = udc_buf_peek(cfg); if (feed_buf) { int ret = udc_mcux_ep_feed(dev, cfg, feed_buf); @@ -322,13 +322,14 @@ static int udc_mcux_handler_non_ctrl_out(const struct device *dev, uint8_t ep, static int udc_mcux_handler_out(const struct device *dev, uint8_t ep, uint8_t *mcux_buf, uint16_t mcux_len) { + struct udc_ep_config *const cfg = udc_get_ep_cfg(dev, ep); int err; struct net_buf *buf; - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(cfg); udc_mcux_lock(dev); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); if (buf == NULL) { @@ -375,10 +376,11 @@ static bool udc_mcux_handler_zlt(const struct device *dev, uint8_t ep, struct ne static int udc_mcux_handler_in(const struct device *dev, uint8_t ep, uint8_t *mcux_buf, uint16_t mcux_len) { + struct udc_ep_config *const cfg = udc_get_ep_cfg(dev, ep); int err; struct net_buf *buf; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(cfg); if (buf == NULL) { udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); return -ENOBUFS; @@ -388,10 +390,10 @@ static int udc_mcux_handler_in(const struct device *dev, uint8_t ep, return 0; } - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(cfg); udc_mcux_lock(dev); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); if (buf == NULL) { @@ -593,13 +595,13 @@ static int udc_mcux_ep_dequeue(const struct device *dev, struct net_buf *buf; cfg->stat.halted = false; - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } udc_mcux_lock(dev); - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); return 0; diff --git a/drivers/usb/udc/udc_mcux_ip3511.c b/drivers/usb/udc/udc_mcux_ip3511.c index f8db1221e074..564f2f9357b9 100644 --- a/drivers/usb/udc/udc_mcux_ip3511.c +++ b/drivers/usb/udc/udc_mcux_ip3511.c @@ -112,8 +112,8 @@ static int udc_mcux_ep_feed(const struct device *dev, } udc_mcux_lock(dev); - if (!udc_ep_is_busy(dev, cfg->addr)) { - udc_ep_set_busy(dev, cfg->addr, true); + if (!udc_ep_is_busy(cfg)) { + udc_ep_set_busy(cfg, true); udc_mcux_unlock(dev); if (USB_EP_DIR_IS_OUT(cfg->addr)) { @@ -130,7 +130,7 @@ static int udc_mcux_ep_feed(const struct device *dev, udc_mcux_lock(dev); if (status != kStatus_USB_Success) { - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); } udc_mcux_unlock(dev); } else { @@ -147,7 +147,7 @@ static int udc_mcux_ep_try_feed(const struct device *dev, { struct net_buf *feed_buf; - feed_buf = udc_buf_peek(dev, cfg->addr); + feed_buf = udc_buf_peek(cfg); if (feed_buf) { int ret = udc_mcux_ep_feed(dev, cfg, feed_buf); @@ -322,13 +322,14 @@ static int udc_mcux_handler_non_ctrl_out(const struct device *dev, uint8_t ep, static int udc_mcux_handler_out(const struct device *dev, uint8_t ep, uint8_t *mcux_buf, uint16_t mcux_len) { + struct udc_ep_config *const cfg = udc_get_ep_cfg(dev, ep); int err; struct net_buf *buf; - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(cfg); udc_mcux_lock(dev); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); if (buf == NULL) { @@ -375,10 +376,11 @@ static bool udc_mcux_handler_zlt(const struct device *dev, uint8_t ep, struct ne static int udc_mcux_handler_in(const struct device *dev, uint8_t ep, uint8_t *mcux_buf, uint16_t mcux_len) { + struct udc_ep_config *const cfg = udc_get_ep_cfg(dev, ep); int err; struct net_buf *buf; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(cfg); if (buf == NULL) { udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); return -ENOBUFS; @@ -388,10 +390,10 @@ static int udc_mcux_handler_in(const struct device *dev, uint8_t ep, return 0; } - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(cfg); udc_mcux_lock(dev); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); if (buf == NULL) { @@ -593,13 +595,13 @@ static int udc_mcux_ep_dequeue(const struct device *dev, struct net_buf *buf; cfg->stat.halted = false; - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } udc_mcux_lock(dev); - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); udc_mcux_unlock(dev); return 0; diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index cafe3fbd19fb..8e43313bd19a 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -96,13 +96,14 @@ static void udc_nrf_clear_control_out(const struct device *dev) static void udc_event_xfer_in_next(const struct device *dev, const uint8_t ep) { + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct net_buf *buf; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(ep_cfg)) { return; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf != NULL) { nrf_usbd_common_transfer_t xfer = { .p_data = {.tx = buf->data}, @@ -118,7 +119,7 @@ static void udc_event_xfer_in_next(const struct device *dev, const uint8_t ep) /* REVISE: remove from endpoint queue? ASSERT? */ udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); } } } @@ -151,9 +152,10 @@ static void udc_event_xfer_ctrl_in(const struct device *dev, static void udc_event_fake_status_in(const struct device *dev) { + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN); struct net_buf *buf; - buf = udc_buf_get(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get(ep_cfg); if (unlikely(buf == NULL)) { LOG_DBG("ep 0x%02x queue is empty", USB_CONTROL_EP_IN); return; @@ -166,19 +168,22 @@ static void udc_event_fake_status_in(const struct device *dev) static void udc_event_xfer_in(const struct device *dev, nrf_usbd_common_evt_t const *const event) { + struct udc_ep_config *ep_cfg; uint8_t ep = event->data.eptransfer.ep; struct net_buf *buf; + ep_cfg = udc_get_ep_cfg(dev, ep); + switch (event->data.eptransfer.status) { case NRF_USBD_COMMON_EP_OK: - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { LOG_ERR("ep 0x%02x queue is empty", ep); __ASSERT_NO_MSG(false); return; } - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); if (ep == USB_CONTROL_EP_IN) { udc_event_xfer_ctrl_in(dev, buf); return; @@ -189,14 +194,14 @@ static void udc_event_xfer_in(const struct device *dev, case NRF_USBD_COMMON_EP_ABORTED: LOG_WRN("aborted IN ep 0x%02x", ep); - buf = udc_buf_get_all(dev, ep); + buf = udc_buf_get_all(ep_cfg); if (buf == NULL) { LOG_DBG("ep 0x%02x queue is empty", ep); return; } - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); udc_submit_ep_event(dev, buf, -ECONNABORTED); break; @@ -226,13 +231,14 @@ static void udc_event_xfer_ctrl_out(const struct device *dev, static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) { + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct net_buf *buf; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(ep_cfg)) { return; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf != NULL) { nrf_usbd_common_transfer_t xfer = { .p_data = {.rx = buf->data}, @@ -247,7 +253,7 @@ static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) /* REVISE: remove from endpoint queue? ASSERT? */ udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); } } else { LOG_DBG("ep 0x%02x waiting, queue is empty", ep); @@ -257,6 +263,7 @@ static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) static void udc_event_xfer_out(const struct device *dev, nrf_usbd_common_evt_t const *const event) { + struct udc_ep_config *ep_cfg; uint8_t ep = event->data.eptransfer.ep; nrf_usbd_common_ep_status_t err_code; struct net_buf *buf; @@ -276,14 +283,15 @@ static void udc_event_xfer_out(const struct device *dev, LOG_ERR("OUT transfer failed %d", err_code); } - buf = udc_buf_get(dev, ep); + ep_cfg = udc_get_ep_cfg(dev, ep); + buf = udc_buf_get(ep_cfg); if (buf == NULL) { LOG_ERR("ep 0x%02x ok, queue is empty", ep); return; } net_buf_add(buf, len); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); if (ep == USB_CONTROL_EP_OUT) { udc_event_xfer_ctrl_out(dev, buf); } else { @@ -616,7 +624,7 @@ static int udc_nrf_ep_dequeue(const struct device *dev, * HAL driver does not generate event for an OUT endpoint * or when IN endpoint is not busy. */ - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } else { @@ -625,7 +633,7 @@ static int udc_nrf_ep_dequeue(const struct device *dev, } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); return 0; } diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 5545132944d2..736ded93fc50 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -505,6 +505,7 @@ static void numaker_usbd_ep_config_dmabuf(struct numaker_usbd_ep *ep_cur, uint32 static void numaker_usbd_ep_abort(struct numaker_usbd_ep *ep_cur) { + struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); @@ -512,7 +513,8 @@ static void numaker_usbd_ep_abort(struct numaker_usbd_ep *ep_cur) ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; if (ep_cur->addr_valid) { - udc_ep_set_busy(dev, ep_cur->addr, false); + ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); + udc_ep_set_busy(ep_cfg, false); } } @@ -589,11 +591,13 @@ static void numaker_usbd_ep_disable(struct numaker_usbd_ep *ep_cur) /* Start EP data transaction */ static void udc_numaker_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) { + struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); if (ep_cur->addr_valid) { - udc_ep_set_busy(dev, ep_cur->addr, true); + ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); + udc_ep_set_busy(ep_cfg, true); } ep_base->MXPLD = len; @@ -762,13 +766,15 @@ static int numaker_usbd_xfer_out(const struct device *dev, uint8_t ep, bool stri { struct net_buf *buf; struct numaker_usbd_ep *ep_cur; + struct udc_ep_config *ep_cfg; if (!USB_EP_DIR_IS_OUT(ep)) { LOG_ERR("Invalid EP address 0x%02x for data out", ep); return -EINVAL; } - if (udc_ep_is_busy(dev, ep)) { + ep_cfg = udc_get_ep_cfg(dev, ep); + if (udc_ep_is_busy(ep_cfg)) { if (strict) { LOG_ERR("EP 0x%02x busy", ep); return -EAGAIN; @@ -777,7 +783,7 @@ static int numaker_usbd_xfer_out(const struct device *dev, uint8_t ep, bool stri return 0; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { if (strict) { LOG_ERR("No buffer queued for EP 0x%02x", ep); @@ -803,6 +809,7 @@ static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool stric { struct net_buf *buf; struct numaker_usbd_ep *ep_cur; + struct udc_ep_config *ep_cfg; uint32_t data_len; if (!USB_EP_DIR_IS_IN(ep)) { @@ -810,7 +817,8 @@ static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool stric return -EINVAL; } - if (udc_ep_is_busy(dev, ep)) { + ep_cfg = udc_get_ep_cfg(dev, ep); + if (udc_ep_is_busy(ep_cfg)) { if (strict) { LOG_ERR("EP 0x%02x busy", ep); return -EAGAIN; @@ -819,7 +827,7 @@ static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool stric return 0; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { if (strict) { LOG_ERR("No buffer queued for EP 0x%02x", ep); @@ -944,6 +952,7 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ int err; uint8_t ep; struct numaker_usbd_ep *ep_cur; + struct udc_ep_config *ep_cfg; struct net_buf *buf; uint8_t *data_ptr; uint32_t data_len; @@ -952,8 +961,9 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_OUT); ep = msg->out.ep; + ep_cfg = udc_get_ep_cfg(ep); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); /* Bind EP H/W context to EP address */ ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep); @@ -962,7 +972,7 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ return -ENODEV; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_ERR("No buffer queued for ep=0x%02x", ep); return -ENODATA; @@ -993,7 +1003,7 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ } /* To submit the peeked buffer */ - udc_buf_get(dev, ep); + udc_buf_get(ep_cfg); if (ep == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev)) { @@ -1037,13 +1047,15 @@ static int numaker_usbd_msg_handle_in(const struct device *dev, struct numaker_u int err; uint8_t ep; struct numaker_usbd_ep *ep_cur; + struct udc_ep_config *ep_cfg; struct net_buf *buf; __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_IN); ep = msg->in.ep; + ep_cfg = udc_get_ep_cfg(dev, ep); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); /* Bind EP H/W context to EP address */ ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep); @@ -1052,7 +1064,7 @@ static int numaker_usbd_msg_handle_in(const struct device *dev, struct numaker_u return -ENODEV; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { /* No DATA IN request */ return 0; @@ -1063,7 +1075,7 @@ static int numaker_usbd_msg_handle_in(const struct device *dev, struct numaker_u } /* To submit the peeked buffer */ - udc_buf_get(dev, ep); + udc_buf_get(ep_cfg); if (ep == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { @@ -1408,7 +1420,7 @@ static int udc_numaker_ep_dequeue(const struct device *dev, struct udc_ep_config numaker_usbd_ep_abort(ep_cur); - buf = udc_buf_get_all(dev, ep_cfg->addr); + buf = udc_buf_get_all(ep_cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } diff --git a/drivers/usb/udc/udc_renesas_ra.c b/drivers/usb/udc/udc_renesas_ra.c index 66f3ae308404..60f32d86b305 100644 --- a/drivers/usb/udc/udc_renesas_ra.c +++ b/drivers/usb/udc/udc_renesas_ra.c @@ -97,13 +97,14 @@ static void udc_renesas_ra_interrupt_handler(void *arg) static void udc_event_xfer_next(const struct device *dev, const uint8_t ep) { struct udc_renesas_ra_data *data = udc_get_private(dev); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct net_buf *buf; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(ep_cfg)) { return; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf != NULL) { int err; @@ -117,7 +118,7 @@ static void udc_event_xfer_next(const struct device *dev, const uint8_t ep) LOG_ERR("ep 0x%02x error", ep); udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); } } } @@ -200,7 +201,7 @@ static void udc_event_status_in(const struct device *dev) struct udc_renesas_ra_data *data = udc_get_private(dev); struct net_buf *buf; - buf = udc_buf_get(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get(udc_get_ep_cfg(dev, USB_CONTROL_EP_IN)); if (unlikely(buf == NULL)) { LOG_DBG("ep 0x%02x queue is empty", USB_CONTROL_EP_IN); return; @@ -234,14 +235,16 @@ static void udc_event_xfer_complete(const struct device *dev, struct udc_renesas { struct net_buf *buf; struct udc_renesas_ra_data *data = udc_get_private(dev); + struct udc_ep_config *ep_cfg; uint8_t ep = evt->hal_evt.xfer_complete.ep_addr; usbd_xfer_result_t result = evt->hal_evt.xfer_complete.result; uint32_t len = evt->hal_evt.xfer_complete.len; - udc_ep_set_busy(dev, ep, false); + ep_cfg = udc_get_ep_cfg(dev, ep); + udc_ep_set_busy(ep_cfg, false); - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { return; } @@ -260,7 +263,7 @@ static void udc_event_xfer_complete(const struct device *dev, struct udc_renesas return; } - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (ep == USB_CONTROL_EP_IN) { udc_event_xfer_ctrl_in(dev, buf); @@ -351,7 +354,7 @@ static int udc_renesas_ra_ep_dequeue(const struct device *dev, struct udc_ep_con lock_key = irq_lock(); - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf != NULL) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } @@ -360,7 +363,7 @@ static int udc_renesas_ra_ep_dequeue(const struct device *dev, struct udc_ep_con return -EIO; } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); irq_unlock(lock_key); diff --git a/drivers/usb/udc/udc_rpi_pico.c b/drivers/usb/udc/udc_rpi_pico.c index 4065f4555b15..763e5a3d8029 100644 --- a/drivers/usb/udc/udc_rpi_pico.c +++ b/drivers/usb/udc/udc_rpi_pico.c @@ -278,14 +278,16 @@ static int rpi_pico_ctrl_feed_dout(const struct device *dev, const size_t length static void drop_control_transfers(const struct device *dev) { + struct udc_ep_config *cfg_out = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct udc_ep_config *cfg_in = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN); struct net_buf *buf; - buf = udc_buf_get_all(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get_all(cfg_out); if (buf != NULL) { net_buf_unref(buf); } - buf = udc_buf_get_all(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get_all(cfg_in); if (buf != NULL) { net_buf_unref(buf); } @@ -337,14 +339,14 @@ static inline int rpi_pico_handle_evt_dout(const struct device *dev, struct net_buf *buf; int err = 0; - buf = udc_buf_get(dev, cfg->addr); + buf = udc_buf_get(cfg); if (buf == NULL) { LOG_ERR("No buffer for OUT ep 0x%02x", cfg->addr); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); return -ENODATA; } - udc_ep_set_busy(dev, cfg->addr, false); + udc_ep_set_busy(cfg, false); if (cfg->addr == USB_CONTROL_EP_OUT) { if (udc_ctrl_stage_is_status_out(dev)) { @@ -373,15 +375,15 @@ static int rpi_pico_handle_evt_din(const struct device *dev, struct net_buf *buf; int err; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", cfg->addr); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); return -ENOBUFS; } - buf = udc_buf_get(dev, cfg->addr); - udc_ep_set_busy(dev, cfg->addr, false); + buf = udc_buf_get(cfg); + udc_ep_set_busy(cfg, false); if (cfg->addr == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || @@ -415,7 +417,7 @@ static void rpi_pico_handle_xfer_next(const struct device *dev, struct net_buf *buf; int err; - buf = udc_buf_peek(dev, cfg->addr); + buf = udc_buf_peek(cfg); if (buf == NULL) { return; } @@ -429,7 +431,7 @@ static void rpi_pico_handle_xfer_next(const struct device *dev, if (err != 0) { udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { - udc_ep_set_busy(dev, cfg->addr, true); + udc_ep_set_busy(cfg, true); } } @@ -460,7 +462,7 @@ static ALWAYS_INLINE void rpi_pico_thread_handler(void *const arg) break; } - if (ep_cfg->addr != USB_CONTROL_EP_OUT && !udc_ep_is_busy(dev, ep_cfg->addr)) { + if (ep_cfg->addr != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ep_cfg)) { rpi_pico_handle_xfer_next(dev, ep_cfg); } } @@ -503,7 +505,7 @@ static void rpi_pico_handle_buff_status_in(const struct device *dev, const uint8 struct net_buf *buf; size_t len; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", ep); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -538,7 +540,7 @@ static void rpi_pico_handle_buff_status_out(const struct device *dev, const uint struct net_buf *buf; size_t len; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_ERR("No buffer for ep 0x%02x", ep); udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS); @@ -739,7 +741,7 @@ static int udc_rpi_pico_ep_dequeue(const struct device *dev, lock_key = irq_lock(); rpi_pico_ep_cancel(dev, cfg->addr); - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } @@ -856,7 +858,7 @@ static int udc_rpi_pico_ep_clear_halt(const struct device *dev, arch_nop(); rpi_pico_bit_clr(buf_ctrl_reg, USB_BUF_CTRL_STALL); - if (udc_buf_peek(dev, cfg->addr)) { + if (udc_buf_peek(cfg)) { k_msgq_put(&drv_msgq, &evt, K_NO_WAIT); } } diff --git a/drivers/usb/udc/udc_skeleton.c b/drivers/usb/udc/udc_skeleton.c index cba2016572ca..86c7cdc75f7e 100644 --- a/drivers/usb/udc/udc_skeleton.c +++ b/drivers/usb/udc/udc_skeleton.c @@ -119,7 +119,7 @@ static int udc_skeleton_ep_dequeue(const struct device *dev, lock_key = irq_lock(); - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } diff --git a/drivers/usb/udc/udc_smartbond.c b/drivers/usb/udc/udc_smartbond.c index dd5a2aa782a5..e413f518d68e 100644 --- a/drivers/usb/udc/udc_smartbond.c +++ b/drivers/usb/udc/udc_smartbond.c @@ -555,14 +555,15 @@ static int udc_smartbond_ep_tx(const struct device *dev, uint8_t ep) { struct usb_smartbond_data *data = dev->data; struct smartbond_ep_state *ep_state = usb_dc_get_ep_in_state(data, USB_EP_GET_IDX(ep)); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct net_buf *buf; - if (udc_ep_is_busy(dev, ep) || + if (udc_ep_is_busy(ep_cfg) || (ep_state->regs->epc_in & USB_USB_EPC1_REG_USB_STALL_Msk) != 0) { return 0; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); LOG_DBG("TX ep 0x%02x len %u", ep, buf ? buf->len : -1); if (buf) { @@ -571,7 +572,7 @@ static int udc_smartbond_ep_tx(const struct device *dev, uint8_t ep) start_tx_packet(data, ep_state); - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); } return 0; @@ -581,13 +582,14 @@ static int udc_smartbond_ep_rx(const struct device *dev, uint8_t ep) { struct usb_smartbond_data *data = dev->data; struct smartbond_ep_state *ep_state = usb_dc_get_ep_out_state(data, USB_EP_GET_IDX(ep)); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep); struct net_buf *buf; - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(ep_cfg)) { return 0; } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf) { LOG_DBG("RX ep 0x%02x len %u", ep, buf->size); @@ -597,7 +599,7 @@ static int udc_smartbond_ep_rx(const struct device *dev, uint8_t ep) start_rx_packet(data, ep_state); - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(ep_cfg, true); } return 0; @@ -648,12 +650,12 @@ static int udc_smartbond_ep_dequeue(const struct device *dev, struct udc_ep_conf udc_smartbond_ep_abort(dev, ep_cfg); - buf = udc_buf_get_all(dev, ep); + buf = udc_buf_get_all(ep_cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); irq_unlock(lock_key); @@ -729,7 +731,7 @@ static int udc_smartbond_ep_set_halt(const struct device *dev, struct udc_ep_con if (ep_cfg->addr == USB_CONTROL_EP_IN) { /* Stall in DATA IN phase, drop status OUT packet */ if (udc_ctrl_stage_is_data_in(dev)) { - buf = udc_buf_get(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get(udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT)); if (buf) { net_buf_unref(buf); } @@ -992,7 +994,7 @@ static void handle_epx_rx_ev(struct usb_smartbond_data *data, uint8_t ep_idx) if (net_buf_tailroom(buf) == 0 || ep_state->last_packet_size < udc_mps_ep_size(ep_cfg) || ep_state->iso) { - buf = udc_buf_get(data->dev, ep_cfg->addr); + buf = udc_buf_get(ep_cfg); if (unlikely(buf == NULL)) { LOG_ERR("ep 0x%02x queue is empty", ep_cfg->addr); break; @@ -1063,8 +1065,8 @@ static void handle_epx_tx_ev(struct usb_smartbond_data *data, struct smartbond_e regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk | USB_USB_TXC1_REG_USB_LAST_Msk; } else { - udc_ep_set_busy(data->dev, ep, false); - buf = udc_buf_get(data->dev, ep); + udc_ep_set_busy(ep_cfg, false); + buf = udc_buf_get(ep_cfg); udc_submit_ep_event(data->dev, buf, 0); udc_smartbond_ep_tx(data->dev, ep); @@ -1164,13 +1166,15 @@ static void handle_ep0_nak(struct usb_smartbond_data *data) static void empty_ep0_queues(const struct device *dev) { + struct udc_ep_config *cfg_out = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct udc_ep_config *cfg_in = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN); struct net_buf *buf; - buf = udc_buf_get_all(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get_all(cfg_out); if (buf) { net_buf_unref(buf); } - buf = udc_buf_get_all(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get_all(cfg_in); if (buf) { net_buf_unref(buf); } @@ -1452,6 +1456,7 @@ static void handle_ep0_rx_work(struct k_work *item) struct usb_smartbond_data *data = CONTAINER_OF(item, struct usb_smartbond_data, ep0_rx_work); const uint8_t ep = USB_CONTROL_EP_OUT; + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(ep); struct net_buf *buf; const struct device *dev = data->dev; unsigned int lock_key; @@ -1462,8 +1467,8 @@ static void handle_ep0_rx_work(struct k_work *item) */ lock_key = irq_lock(); - udc_ep_set_busy(dev, ep, false); - buf = udc_buf_get(dev, ep); + udc_ep_set_busy(ep_cfg, false); + buf = udc_buf_get(ep_cfg); irq_unlock(lock_key); if (unlikely(buf == NULL)) { @@ -1490,9 +1495,10 @@ static void handle_ep0_tx_work(struct k_work *item) struct net_buf *buf; const struct device *dev = data->dev; const uint8_t ep = USB_CONTROL_EP_IN; + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(ep); unsigned int lock_key; - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); __ASSERT(buf == EP0_IN_STATE(data)->buf, "TX work without buffer %p %p", buf, EP0_IN_STATE(data)->buf); @@ -1502,10 +1508,10 @@ static void handle_ep0_tx_work(struct k_work *item) */ lock_key = irq_lock(); - udc_ep_set_busy(dev, ep, false); + udc_ep_set_busy(ep_cfg, false); /* Remove buffer from queue */ - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); irq_unlock(lock_key); diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index d95c6fb0afd5..99136d1ba447 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -194,7 +194,7 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) udc_submit_event(priv->dev, UDC_EVT_SOF, 0); } -static int udc_stm32_tx(const struct device *dev, uint8_t ep, +static int udc_stm32_tx(const struct device *dev, struct udc_ep_config *epcfg, struct net_buf *buf) { struct udc_stm32_data *priv = udc_get_private(dev); @@ -202,31 +202,31 @@ static int udc_stm32_tx(const struct device *dev, uint8_t ep, uint8_t *data; uint32_t len; HAL_StatusTypeDef status; - LOG_DBG("TX ep 0x%02x len %u", ep, buf->len); + LOG_DBG("TX ep 0x%02x len %u", epcfg->addr, buf->len); - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(epcfg)) { return 0; } data = buf->data; len = buf->len; - if (ep == USB_CONTROL_EP_IN) { + if (epcfg->addr == USB_CONTROL_EP_IN) { len = MIN(cfg->ep0_mps, buf->len); } buf->data += len; buf->len -= len; - status = HAL_PCD_EP_Transmit(&priv->pcd, ep, data, len); + status = HAL_PCD_EP_Transmit(&priv->pcd, epcfg->addr, data, len); if (status != HAL_OK) { - LOG_ERR("HAL_PCD_EP_Transmit failed(0x%02x), %d", ep, (int)status); + LOG_ERR("HAL_PCD_EP_Transmit failed(0x%02x), %d", epcfg->addr, (int)status); return -EIO; } - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(epcfg, true); - if (ep == USB_CONTROL_EP_IN && len > 0) { + if (epcfg->addr == USB_CONTROL_EP_IN && len > 0) { /* Wait for an empty package from the host. * This also flushes the TX FIFO to the host. */ @@ -236,25 +236,25 @@ static int udc_stm32_tx(const struct device *dev, uint8_t ep, return 0; } -static int udc_stm32_rx(const struct device *dev, uint8_t ep, +static int udc_stm32_rx(const struct device *dev, struct udc_ep_config *epcfg, struct net_buf *buf) { struct udc_stm32_data *priv = udc_get_private(dev); HAL_StatusTypeDef status; - LOG_DBG("RX ep 0x%02x len %u", ep, buf->size); + LOG_DBG("RX ep 0x%02x len %u", epcfg->addr, buf->size); - if (udc_ep_is_busy(dev, ep)) { + if (udc_ep_is_busy(epcfg)) { return 0; } - status = HAL_PCD_EP_Receive(&priv->pcd, ep, buf->data, buf->size); + status = HAL_PCD_EP_Receive(&priv->pcd, epcfg->addr, buf->data, buf->size); if (status != HAL_OK) { - LOG_ERR("HAL_PCD_EP_Receive failed(0x%02x), %d", ep, (int)status); + LOG_ERR("HAL_PCD_EP_Receive failed(0x%02x), %d", epcfg->addr, (int)status); return -EIO; } - udc_ep_set_busy(dev, ep, true); + udc_ep_set_busy(epcfg, true); return 0; } @@ -264,14 +264,16 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) uint32_t rx_count = HAL_PCD_EP_GetRxCount(hpcd, epnum); struct udc_stm32_data *priv = hpcd2data(hpcd); const struct device *dev = priv->dev; + struct udc_ep_config *epcfg; uint8_t ep = epnum | USB_EP_DIR_OUT; struct net_buf *buf; LOG_DBG("DataOut ep 0x%02x", ep); - udc_ep_set_busy(dev, ep, false); + epcfg = udc_get_ep_cfg(dev, ep); + udc_ep_set_busy(epcfg, false); - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(epcfg); if (unlikely(buf == NULL)) { LOG_ERR("ep 0x%02x queue is empty", ep); return; @@ -294,9 +296,9 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) udc_submit_ep_event(dev, buf, 0); } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(epcfg); if (buf) { - udc_stm32_rx(dev, ep, buf); + udc_stm32_rx(dev, epcfg, buf); } } @@ -304,14 +306,16 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { struct udc_stm32_data *priv = hpcd2data(hpcd); const struct device *dev = priv->dev; + struct udc_ep_config *epcfg; uint8_t ep = epnum | USB_EP_DIR_IN; struct net_buf *buf; LOG_DBG("DataIn ep 0x%02x", ep); - udc_ep_set_busy(dev, ep, false); + epcfg = udc_get_ep_cfg(dev, ep); + udc_ep_set_busy(epcfg, false); - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(epcfg); if (unlikely(buf == NULL)) { return; } @@ -335,7 +339,7 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) return; } - udc_buf_get(dev, ep); + udc_buf_get(epcfg); if (ep == USB_CONTROL_EP_IN) { if (udc_ctrl_stage_is_status_in(dev) || @@ -360,9 +364,9 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) udc_submit_ep_event(dev, buf, 0); - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(epcfg); if (buf) { - udc_stm32_tx(dev, ep, buf); + udc_stm32_tx(dev, epcfg, buf); } } @@ -763,9 +767,9 @@ static int udc_stm32_ep_enqueue(const struct device *dev, lock_key = irq_lock(); if (USB_EP_DIR_IS_IN(epcfg->addr)) { - ret = udc_stm32_tx(dev, epcfg->addr, buf); + ret = udc_stm32_tx(dev, epcfg, buf); } else { - ret = udc_stm32_rx(dev, epcfg->addr, buf); + ret = udc_stm32_rx(dev, epcfg, buf); } irq_unlock(lock_key); @@ -780,12 +784,12 @@ static int udc_stm32_ep_dequeue(const struct device *dev, udc_stm32_ep_flush(dev, epcfg); - buf = udc_buf_get_all(dev, epcfg->addr); + buf = udc_buf_get_all(epcfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } - udc_ep_set_busy(dev, epcfg->addr, false); + udc_ep_set_busy(epcfg, false); return 0; } diff --git a/drivers/usb/udc/udc_virtual.c b/drivers/usb/udc/udc_virtual.c index c729aa08cd75..ae32c9ae2c62 100644 --- a/drivers/usb/udc/udc_virtual.c +++ b/drivers/usb/udc/udc_virtual.c @@ -172,7 +172,7 @@ static int vrt_handle_out(const struct device *dev, return vrt_request_reply(dev, pkt, UVB_REPLY_STALL); } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_DBG("reply NACK ep 0x%02x", ep); return vrt_request_reply(dev, pkt, UVB_REPLY_NACK); @@ -184,7 +184,7 @@ static int vrt_handle_out(const struct device *dev, LOG_DBG("Handle data OUT, %zu | %zu", pkt->length, net_buf_tailroom(buf)); if (net_buf_tailroom(buf) == 0 || pkt->length < udc_mps_ep_size(ep_cfg)) { - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (ep == USB_CONTROL_EP_OUT) { err = vrt_handle_ctrl_out(dev, buf); @@ -239,7 +239,7 @@ static int vrt_handle_in(const struct device *dev, return vrt_request_reply(dev, pkt, UVB_REPLY_STALL); } - buf = udc_buf_peek(dev, ep); + buf = udc_buf_peek(ep_cfg); if (buf == NULL) { LOG_DBG("reply NACK ep 0x%02x", ep); return vrt_request_reply(dev, pkt, UVB_REPLY_NACK); @@ -259,7 +259,7 @@ static int vrt_handle_in(const struct device *dev, } LOG_DBG("Finish data IN %zu | %u", pkt->length, buf->len); - buf = udc_buf_get(dev, ep); + buf = udc_buf_get(ep_cfg); if (ep == USB_CONTROL_EP_IN) { err = isr_handle_ctrl_in(dev, buf); @@ -411,7 +411,7 @@ static int udc_vrt_ep_dequeue(const struct device *dev, lock_key = irq_lock(); /* Draft dequeue implementation */ - buf = udc_buf_get_all(dev, cfg->addr); + buf = udc_buf_get_all(cfg); if (buf) { udc_submit_ep_event(dev, buf, -ECONNABORTED); } From 09a4f4fe8e50892bd26887619431c8a112d2874d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Mon, 7 Apr 2025 10:27:23 +0200 Subject: [PATCH 2/2] [nrf fromlist] drivers: udc_dwc2: Mark endpoint idle on disable while hibernated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When endpoint is disabled while hibernated, the UDC endpoint state has to be reset. Set the busy to false to keep UDC endpoint state in sync with peripheral register state. Upstream PR #: 88236 Fixes: 2be960ad2b33 ("drivers: udc_dwc2: Disable endpoint while hibernated") Signed-off-by: Tomasz Moń (cherry picked from commit 7a28ef1dc00aeeae17034631b79cdc0d52a13c6b) --- drivers/usb/udc/udc_dwc2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 2339356d8823..5920ae10b786 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -1553,6 +1553,7 @@ static void udc_dwc2_ep_disable(const struct device *dev, priv->pending_tx_flush |= BIT(usb_dwc2_get_depctl_txfnum(dxepctl)); } + udc_ep_set_busy(cfg, false); return; }