usb: fix usb data race
Clock ISR would callback into the USB driver before it was initialized and ready to deal with events. This caused a fault. Statically initialize the fifo to queue events and process them when the USB device is initialized to avoid the problem. Signed-off-by: Tom Burdick <thomas.burdick@gmail.com>
This commit is contained in:
parent
b6b5fdac32
commit
08d900df4b
1 changed files with 18 additions and 6 deletions
|
@ -266,7 +266,6 @@ struct nrf_usbd_ctx {
|
||||||
bool ready;
|
bool ready;
|
||||||
|
|
||||||
struct k_work usb_work;
|
struct k_work usb_work;
|
||||||
struct k_fifo work_queue;
|
|
||||||
struct k_mutex drv_lock;
|
struct k_mutex drv_lock;
|
||||||
|
|
||||||
struct nrf_usbd_ep_ctx ep_ctx[CFG_EP_CNT];
|
struct nrf_usbd_ep_ctx ep_ctx[CFG_EP_CNT];
|
||||||
|
@ -275,7 +274,13 @@ struct nrf_usbd_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct nrf_usbd_ctx usbd_ctx;
|
K_FIFO_DEFINE(work_queue);
|
||||||
|
|
||||||
|
|
||||||
|
static struct nrf_usbd_ctx usbd_ctx = {
|
||||||
|
.attached = false,
|
||||||
|
.ready = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static inline struct nrf_usbd_ctx *get_usbd_ctx(void)
|
static inline struct nrf_usbd_ctx *get_usbd_ctx(void)
|
||||||
|
@ -392,7 +397,7 @@ static inline void usbd_evt_free(struct usbd_event *ev)
|
||||||
*/
|
*/
|
||||||
static inline void usbd_evt_put(struct usbd_event *ev)
|
static inline void usbd_evt_put(struct usbd_event *ev)
|
||||||
{
|
{
|
||||||
k_fifo_put(&get_usbd_ctx()->work_queue, ev);
|
k_fifo_put(&work_queue, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -400,7 +405,7 @@ static inline void usbd_evt_put(struct usbd_event *ev)
|
||||||
*/
|
*/
|
||||||
static inline struct usbd_event *usbd_evt_get(void)
|
static inline struct usbd_event *usbd_evt_get(void)
|
||||||
{
|
{
|
||||||
return k_fifo_get(&get_usbd_ctx()->work_queue, K_NO_WAIT);
|
return k_fifo_get(&work_queue, K_NO_WAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -498,8 +503,12 @@ void usb_dc_nrfx_power_event_callback(nrf_power_event_t event)
|
||||||
ev->evt_type = USBD_EVT_POWER;
|
ev->evt_type = USBD_EVT_POWER;
|
||||||
ev->evt.pwr_evt.state = new_state;
|
ev->evt.pwr_evt.state = new_state;
|
||||||
|
|
||||||
|
|
||||||
usbd_evt_put(ev);
|
usbd_evt_put(ev);
|
||||||
usbd_work_schedule();
|
|
||||||
|
if (usbd_ctx.attached) {
|
||||||
|
usbd_work_schedule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1233,7 +1242,6 @@ int usb_dc_attach(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
k_work_init(&ctx->usb_work, usbd_work_handler);
|
k_work_init(&ctx->usb_work, usbd_work_handler);
|
||||||
k_fifo_init(&ctx->work_queue);
|
|
||||||
k_mutex_init(&ctx->drv_lock);
|
k_mutex_init(&ctx->drv_lock);
|
||||||
|
|
||||||
IRQ_CONNECT(DT_NORDIC_NRF_USBD_USBD_0_IRQ,
|
IRQ_CONNECT(DT_NORDIC_NRF_USBD_USBD_0_IRQ,
|
||||||
|
@ -1262,6 +1270,10 @@ int usb_dc_attach(void)
|
||||||
ctx->attached = true;
|
ctx->attached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!k_fifo_is_empty(&work_queue)) {
|
||||||
|
usbd_work_schedule();
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue