diff --git a/subsys/usb/device_next/class/usbd_cdc_acm.c b/subsys/usb/device_next/class/usbd_cdc_acm.c index eb0abb803cee3d1..2cb2208035a3918 100644 --- a/subsys/usb/device_next/class/usbd_cdc_acm.c +++ b/subsys/usb/device_next/class/usbd_cdc_acm.c @@ -48,6 +48,7 @@ UDC_BUF_POOL_DEFINE(cdc_acm_ep_pool, #define CDC_ACM_IRQ_TX_ENABLED 3 #define CDC_ACM_RX_FIFO_BUSY 4 #define CDC_ACM_LOCK 5 +#define CDC_ACM_TX_EP_BUSY 6 static struct k_work_q cdc_acm_work_q; static K_KERNEL_STACK_DEFINE(cdc_acm_stack, @@ -216,6 +217,9 @@ static int usbd_cdc_acm_request(struct usbd_class_data *const c_data, if (bi->ep == cdc_acm_get_bulk_out(c_data)) { atomic_clear_bit(&data->state, CDC_ACM_RX_FIFO_BUSY); } + else if (bi->ep == cdc_acm_get_bulk_in(c_data)) { + atomic_clear_bit(&data->state, CDC_ACM_TX_EP_BUSY); + } goto ep_request_error; } @@ -236,6 +240,7 @@ static int usbd_cdc_acm_request(struct usbd_class_data *const c_data, if (bi->ep == cdc_acm_get_bulk_in(c_data)) { /* TX transfer completion */ + atomic_clear_bit(&data->state, CDC_ACM_TX_EP_BUSY); if (data->cb) { cdc_acm_work_submit(&data->irq_cb_work); } @@ -540,6 +545,11 @@ static void cdc_acm_tx_fifo_handler(struct k_work *work) return; } + if (atomic_test_and_set_bit(&data->state, CDC_ACM_TX_EP_BUSY)) { + cdc_acm_work_submit(&data->tx_fifo_work); + goto tx_fifo_handler_exit; + } + buf = cdc_acm_buf_alloc(cdc_acm_get_bulk_in(c_data)); if (buf == NULL) { cdc_acm_work_submit(&data->tx_fifo_work);