Bluetooth: Controller: Add common ULL ticker stop with mark function
The same code block for marking an object with ull_disable_mark, stopping the ticker and then unmarking the object appeared multiple places; often with a regression bug where instead of unmarking it in case of error, it would be "remarked". This commit fixes the bug, and moves the functionality to a common function. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
071db25f66
commit
6b72bed967
7 changed files with 74 additions and 102 deletions
|
@ -1230,6 +1230,54 @@ void *ull_disable_mark_get(void)
|
|||
return mark_get(mark_disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops a specified ticker using the ull_disable_(un)mark functions.
|
||||
*
|
||||
* @param ticker_handle The handle of the ticker.
|
||||
* @param param The object to mark.
|
||||
* @param lll_disable Optional object when calling @ref ull_disable
|
||||
*
|
||||
* @return 0 if success, else ERRNO.
|
||||
*/
|
||||
int ull_ticker_stop_with_mark(uint8_t ticker_handle, void *param,
|
||||
void *lll_disable)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
uint32_t ret;
|
||||
void *mark;
|
||||
|
||||
mark = ull_disable_mark(param);
|
||||
if (mark != param) {
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
ticker_handle, ull_ticker_status_give,
|
||||
(void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret) {
|
||||
mark = ull_disable_unmark(param);
|
||||
if (mark != param) {
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
ret = ull_disable(lll_disable);
|
||||
if (ret) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
mark = ull_disable_unmark(param);
|
||||
if (mark != param) {
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
void *ull_update_mark(void *param)
|
||||
{
|
||||
|
|
|
@ -866,34 +866,18 @@ uint32_t ull_adv_aux_start(struct ll_adv_aux_set *aux, uint32_t ticks_anchor,
|
|||
|
||||
uint8_t ull_adv_aux_stop(struct ll_adv_aux_set *aux)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
uint8_t aux_handle;
|
||||
void *mark;
|
||||
uint32_t ret;
|
||||
|
||||
mark = ull_disable_mark(aux);
|
||||
LL_ASSERT(mark == aux);
|
||||
int err;
|
||||
|
||||
aux_handle = aux_handle_get(aux);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
TICKER_ID_ADV_AUX_BASE + aux_handle,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret) {
|
||||
mark = ull_disable_mark(aux);
|
||||
LL_ASSERT(mark == aux);
|
||||
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_ADV_AUX_BASE + aux_handle,
|
||||
aux, &aux->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
ret = ull_disable(&aux->lll);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
mark = ull_disable_unmark(aux);
|
||||
LL_ASSERT(mark == aux);
|
||||
|
||||
aux->is_started = 0U;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -535,34 +535,18 @@ static inline uint16_t sync_handle_get(struct ll_adv_sync_set *sync)
|
|||
|
||||
static uint8_t sync_stop(struct ll_adv_sync_set *sync)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
uint8_t sync_handle;
|
||||
void *mark;
|
||||
uint32_t ret;
|
||||
|
||||
mark = ull_disable_mark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
int err;
|
||||
|
||||
sync_handle = sync_handle_get(sync);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
TICKER_ID_ADV_SYNC_BASE + sync_handle,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret) {
|
||||
mark = ull_disable_mark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_ADV_SYNC_BASE + sync_handle,
|
||||
sync, &sync->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
ret = ull_disable(&sync->lll);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
mark = ull_disable_unmark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1675,30 +1675,16 @@ static void ticker_op_stop_cb(uint32_t status, void *param)
|
|||
|
||||
static inline void disable(uint16_t handle)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
struct ll_conn *conn;
|
||||
void *mark;
|
||||
uint32_t ret;
|
||||
int err;
|
||||
|
||||
conn = ll_conn_get(handle);
|
||||
|
||||
mark = ull_disable_mark(conn);
|
||||
LL_ASSERT(mark == conn);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
TICKER_ID_CONN_BASE + handle,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (!ret) {
|
||||
ret = ull_disable(&conn->lll);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_CONN_BASE + handle,
|
||||
conn, &conn->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
|
||||
conn->lll.link_tx_free = NULL;
|
||||
|
||||
mark = ull_disable_unmark(conn);
|
||||
LL_ASSERT(mark == conn);
|
||||
}
|
||||
|
||||
static void conn_cleanup(struct ll_conn *conn, uint8_t reason)
|
||||
|
|
|
@ -43,6 +43,8 @@ uint32_t ull_ticker_status_take(uint32_t ret, uint32_t volatile *ret_cb);
|
|||
void *ull_disable_mark(void *param);
|
||||
void *ull_disable_unmark(void *param);
|
||||
void *ull_disable_mark_get(void);
|
||||
int ull_ticker_stop_with_mark(uint8_t ticker_handle, void *param,
|
||||
void *lll_disable);
|
||||
void *ull_update_mark(void *param);
|
||||
void *ull_update_unmark(void *param);
|
||||
void *ull_update_mark_get(void);
|
||||
|
|
|
@ -448,31 +448,15 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan)
|
|||
|
||||
uint8_t ull_scan_disable(uint8_t handle, struct ll_scan_set *scan)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
void *mark;
|
||||
uint32_t ret;
|
||||
|
||||
mark = ull_disable_mark(scan);
|
||||
LL_ASSERT(mark == scan);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
TICKER_ID_SCAN_BASE + handle,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret) {
|
||||
mark = ull_disable_unmark(scan);
|
||||
LL_ASSERT(mark == scan);
|
||||
int err;
|
||||
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_BASE + handle,
|
||||
scan, &scan->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
ret = ull_disable(&scan->lll);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
mark = ull_disable_unmark(scan);
|
||||
LL_ASSERT(mark == scan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -235,36 +235,20 @@ uint8_t ll_sync_terminate(uint16_t handle)
|
|||
{
|
||||
memq_link_t *link_sync_lost;
|
||||
struct ll_sync_set *sync;
|
||||
uint32_t volatile ret_cb;
|
||||
uint32_t ret;
|
||||
void *mark;
|
||||
int err;
|
||||
|
||||
sync = is_enabled_get(handle);
|
||||
if (!sync) {
|
||||
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
||||
}
|
||||
|
||||
mark = ull_disable_mark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
TICKER_ID_SCAN_SYNC_BASE + handle,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret) {
|
||||
mark = ull_disable_mark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_SYNC_BASE + handle,
|
||||
sync, &sync->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
ret = ull_disable(&sync->lll);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
mark = ull_disable_unmark(sync);
|
||||
LL_ASSERT(mark == sync);
|
||||
|
||||
link_sync_lost = sync->node_rx_lost.hdr.link;
|
||||
ll_rx_link_release(link_sync_lost);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue