btfmcodec: unblock waiting threads during usecase shutdown

This change notifies waiting thread when usecase shutdown
is triggered and also flush work queues.

Change-Id: If523e806dc23fc256e82c4eac30f7aa79b119f55
This commit is contained in:
Balakrishna Godavarthi
2023-01-27 10:52:49 +05:30
committed by Gerrit - the friendly Code Review server
parent 4a2649332e
commit e7e85692a1
4 changed files with 34 additions and 5 deletions

View File

@@ -94,6 +94,7 @@ static int btfmcodec_dev_release(struct inode *inode, struct file *file)
{
struct btfmcodec_char_device *btfmcodec_dev = cdev_to_btfmchardev(inode->i_cdev);
unsigned long flags;
int idx;
BTFMCODEC_INFO("for %s by %s:%d active_clients[%u]\n",
btfmcodec_dev->dev_name, current->comm,
@@ -110,6 +111,16 @@ static int btfmcodec_dev_release(struct inode *inode, struct file *file)
skb_queue_purge(&btfmcodec_dev->rxq);
}
/* Notify waiting clients that client is closed or killed */
for (idx = 0; idx < BTM_PKT_TYPE_MAX; idx++) {
btfmcodec_dev->status[idx] = BTM_RSP_NOT_RECV_CLIENT_KILLED;
wake_up_interruptible(&btfmcodec_dev->rsp_wait_q[idx]);
}
cancel_work_sync(&btfmcodec_dev->wq_hwep_shutdown);
cancel_work_sync(&btfmcodec_dev->wq_hwep_configure);
cancel_work_sync(&btfmcodec_dev->wq_prepare_bearer);
btfmcodec->states.current_state = IDLE;
btfmcodec->states.next_state = IDLE;
return 0;
@@ -140,8 +151,16 @@ static void btfmcodec_dev_rxwork(struct work_struct *work)
idx = BTM_PKT_TYPE_PREPARE_REQ;
BTFMCODEC_DBG("BTM_BTFMCODEC_PREPARE_AUDIO_BEARER_SWITCH_REQ");
if (len == BTM_PREPARE_AUDIO_BEARER_SWITCH_REQ_LEN) {
/* there are chances where bearer indication is not recevied,
* So inform waiting thread to unblock itself and move to
* previous state.
*/
if (btfmcodec_dev->status[BTM_PKT_TYPE_BEARER_SWITCH_IND] == BTM_WAITING_RSP) {
BTFMCODEC_DBG("Notifying waiting beare indications");
btfmcodec_dev->status[BTM_PKT_TYPE_BEARER_SWITCH_IND] = BTM_FAIL_RESP_RECV;
wake_up_interruptible(&btfmcodec_dev->rsp_wait_q[BTM_PKT_TYPE_BEARER_SWITCH_IND]);
}
btfmcodec_dev->status[idx] = skb->data[0];
BTFMCODEC_INFO("prepare wq_prepare_bearer:%p", btfmcodec_dev->wq_prepare_bearer);
queue_work(btfmcodec_dev->workqueue, &btfmcodec_dev->wq_prepare_bearer);
} else {
BTFMCODEC_ERR("wrong packet format with len:%d", len);

View File

@@ -30,7 +30,8 @@ void btfmcodec_initiate_hwep_shutdown(struct btfmcodec_char_device *btfmcodec_de
if (*status == BTM_RSP_RECV) {
BTFMCODEC_ERR("sucessfully closed hwep");
return;
} else if (*status == BTM_FAIL_RESP_RECV) {
} else if (*status == BTM_FAIL_RESP_RECV ||
*status == BTM_RSP_NOT_RECV_CLIENT_KILLED) {
BTFMCODEC_ERR("Failed to close hwep");
return;
}
@@ -136,6 +137,9 @@ int btfmcodec_wait_for_bearer_ind(struct btfmcodec_char_device *btfmcodec_dev)
} else if (*status == BTM_FAIL_RESP_RECV) {
BTFMCODEC_ERR("Rx BTM_BEARER_SWITCH_IND with failure status");
ret = -1;
} else if (*status == BTM_RSP_NOT_RECV_CLIENT_KILLED) {
BTFMCODEC_ERR("client killed so moving further");
ret = -1;
}
}
@@ -162,7 +166,8 @@ int btfmcodec_initiate_hwep_configuration(struct btfmcodec_char_device *btfmcode
} else {
if (*status == BTM_RSP_RECV) {
ret = 0;
} else if (*status == BTM_FAIL_RESP_RECV) {
} else if (*status == BTM_FAIL_RESP_RECV ||
*status == BTM_RSP_NOT_RECV_CLIENT_KILLED) {
BTFMCODEC_ERR("Failed to close hwep moving back to previous state");
ret = -1;
}

View File

@@ -255,7 +255,8 @@ int btfmcodec_hwep_shutdown(struct btfmcodec_data *btfmcodec, int id)
} else {
if (*status == BTM_RSP_RECV)
ret = 0;
else if (*status == BTM_FAIL_RESP_RECV)
else if (*status == BTM_FAIL_RESP_RECV ||
*status == BTM_RSP_NOT_RECV_CLIENT_KILLED)
ret = -1;
}
} else {
@@ -489,7 +490,8 @@ static int btfmcodec_configure_master(struct btfmcodec_data *btfmcodec, uint8_t
} else {
if (*status == BTM_RSP_RECV)
return 0;
else if (*status == BTM_FAIL_RESP_RECV)
else if (*status == BTM_FAIL_RESP_RECV ||
*status == BTM_RSP_NOT_RECV_CLIENT_KILLED)
return -1;
}

View File

@@ -57,7 +57,10 @@ enum rx_status {
BTM_RSP_RECV,
/* Response recevied with failure status*/
BTM_FAIL_RESP_RECV,
/* Response not recevied, but client killed */
BTM_RSP_NOT_RECV_CLIENT_KILLED,
};
enum btfm_kp_status {
/* KP processed message succesfully */
MSG_SUCCESS = 0,