Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions drivers/usb/udc/udc_ambiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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)) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
41 changes: 6 additions & 35 deletions drivers/usb/udc/udc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
Expand All @@ -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);
}

Expand Down
28 changes: 10 additions & 18 deletions drivers/usb/udc/udc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand All @@ -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.
Expand All @@ -100,27 +96,23 @@ 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.
*
* 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.
Expand Down
Loading