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
1 change: 1 addition & 0 deletions drivers/usb/udc/udc_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2328,6 +2328,7 @@ static int udc_dwc2_disable(const struct device *dev)
}

config->irq_disable_func(dev);
cancel_hibernation_request(priv);

if (priv->hibernated) {
dwc2_exit_hibernation(dev, false, true);
Expand Down
4 changes: 4 additions & 0 deletions include/zephyr/usb/usbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ struct usbd_context {
const struct device *dev;
/** Notification message recipient callback */
usbd_msg_cb_t msg_cb;
/** slist to keep endpoint events */
sys_slist_t ep_events;
/** Endpoint event list spinlock */
struct k_spinlock ep_event_lock;
/** Middle layer runtime data */
struct usbd_ch9_data ch9_data;
/** slist to manage descriptors like string, BOS */
Expand Down
60 changes: 44 additions & 16 deletions subsys/usb/device_next/usbd_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,53 @@
static int usbd_event_carrier(const struct device *dev,
const struct udc_event *const event)
{
struct usbd_context *const uds_ctx = (void *)udc_get_event_ctx(dev);
k_spinlock_key_t key;

if (event->type == UDC_EVT_EP_REQUEST) {
/*
* Always add completed transfer requests to the list, so they
* do not get lost.
*/
key = k_spin_lock(&uds_ctx->ep_event_lock);
sys_slist_append(&uds_ctx->ep_events, &event->buf->node);
k_spin_unlock(&uds_ctx->ep_event_lock, key);
}

return k_msgq_put(&usbd_msgq, event, K_NO_WAIT);
}

static int event_handler_ep_request(struct usbd_context *const uds_ctx,
const struct udc_event *const event)
static void event_handler_ep_request(struct usbd_context *const uds_ctx)
{
struct udc_buf_info *bi;
k_spinlock_key_t key;
struct net_buf *buf;
sys_snode_t *node;
int ret;

bi = udc_get_buf_info(event->buf);
while (!sys_slist_is_empty(&uds_ctx->ep_events)) {
key = k_spin_lock(&uds_ctx->ep_event_lock);
node = sys_slist_get(&uds_ctx->ep_events);
k_spin_unlock(&uds_ctx->ep_event_lock, key);

if (USB_EP_GET_IDX(bi->ep) == 0) {
ret = usbd_handle_ctrl_xfer(uds_ctx, event->buf, bi->err);
} else {
ret = usbd_class_handle_xfer(uds_ctx, event->buf, bi->err);
}
buf = SYS_SLIST_CONTAINER(node, buf, node);
if (buf == NULL) {
break;
}

if (ret) {
LOG_ERR("unrecoverable error %d, ep 0x%02x, buf %p",
ret, bi->ep, event->buf);
}
bi = udc_get_buf_info(buf);
if (USB_EP_GET_IDX(bi->ep) == 0) {
ret = usbd_handle_ctrl_xfer(uds_ctx, buf, bi->err);
} else {
ret = usbd_class_handle_xfer(uds_ctx, buf, bi->err);
}

return ret;
if (ret) {
LOG_ERR("Unrecoverable error %d, ep 0x%02x, buf %p",
ret, bi->ep, (void *)buf);
usbd_msg_pub_simple(uds_ctx, USBD_MSG_STACK_ERROR, ret);

Check notice on line 81 in subsys/usb/device_next/usbd_core.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/usb/device_next/usbd_core.c:81 - LOG_ERR("Unrecoverable error %d, ep 0x%02x, buf %p", - ret, bi->ep, (void *)buf); + LOG_ERR("Unrecoverable error %d, ep 0x%02x, buf %p", ret, bi->ep, + (void *)buf);
}
}
}

static void usbd_class_bcast_event(struct usbd_context *const uds_ctx,
Expand Down Expand Up @@ -138,6 +162,13 @@
{
int err = 0;

/* Always check if there is a completed transfer request. */
event_handler_ep_request(uds_ctx);
if (event->type == UDC_EVT_EP_REQUEST) {
/* It has already been handled and cannot be another event type. */
return;
}

switch (event->type) {
case UDC_EVT_VBUS_REMOVED:
LOG_DBG("VBUS remove event");
Expand Down Expand Up @@ -167,9 +198,6 @@
err = event_handler_bus_reset(uds_ctx);
usbd_msg_pub_simple(uds_ctx, USBD_MSG_RESET, 0);
break;
case UDC_EVT_EP_REQUEST:
err = event_handler_ep_request(uds_ctx, event);
break;
case UDC_EVT_ERROR:
LOG_ERR("UDC error event");
usbd_msg_pub_simple(uds_ctx, USBD_MSG_UDC_ERROR, event->status);
Expand Down
Loading