diff options
author | himta ram <hram@codeaurora.org> | 2019-01-21 17:27:07 +0530 |
---|---|---|
committer | himta ram <hram@codeaurora.org> | 2019-03-27 18:56:43 +0530 |
commit | 7edc3c3948b8e3514cac4f343be5aa1e3f8caf4c (patch) | |
tree | 858e51220f8969dc14c663b1f12ecb5075d7ee50 | |
parent | 1f23f3a5108767a0f279f2ce0197a6f4d63440f2 (diff) | |
download | android_hardware_qcom_fm-7edc3c3948b8e3514cac4f343be5aa1e3f8caf4c.tar.gz android_hardware_qcom_fm-7edc3c3948b8e3514cac4f343be5aa1e3f8caf4c.tar.bz2 android_hardware_qcom_fm-7edc3c3948b8e3514cac4f343be5aa1e3f8caf4c.zip |
FM: add synchronization fix across hal init and hal close
-add synchronization fix across hal init and hal close.
-add timeout of 3 sec for FM hci initialize and close to complete.
-killing the FM process when FM hci initialize and close not completed
within 3 sec.
CRs-Fixed: 2424464
Change-Id: I5bdf026ccba7401ede7285967a9bf3aa642798ac
-rw-r--r-- | fm_hci/fm_hci.cpp | 9 | ||||
-rw-r--r-- | fm_hci/fm_hci.h | 2 | ||||
-rw-r--r-- | helium/radio_helium_hal.c | 54 |
3 files changed, 45 insertions, 20 deletions
diff --git a/fm_hci/fm_hci.cpp b/fm_hci/fm_hci.cpp index 76949d2..6a9dba6 100644 --- a/fm_hci/fm_hci.cpp +++ b/fm_hci/fm_hci.cpp @@ -661,7 +661,14 @@ int fm_hci_init(fm_hci_hal_t *hci_hal) __func__, hci.state); if(hci.state == FM_RADIO_ENABLING){ Lock lk(hci.on_mtx); - hci.on_cond.wait(lk); + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + status = + hci.on_cond.wait_until(lk, now + std::chrono::seconds(HCI_TIMEOUT)); + if (status == std::cv_status::timeout) { + ALOGE("hci_initialize failed, kill the fm process"); + kill(getpid(), SIGKILL); + } } } diff --git a/fm_hci/fm_hci.h b/fm_hci/fm_hci.h index 8470519..aa3c2b7 100644 --- a/fm_hci/fm_hci.h +++ b/fm_hci/fm_hci.h @@ -35,7 +35,7 @@ #define FM_CMD_COMPLETE 0x0f #define FM_CMD_STATUS 0x10 #define FM_HW_ERR_EVENT 0x1A - +#define HCI_TIMEOUT 3 struct fm_hci_t { public: fm_power_state_t state; diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c index 79f40a4..019db8c 100644 --- a/helium/radio_helium_hal.c +++ b/helium/radio_helium_hal.c @@ -59,9 +59,12 @@ static uint32_t station_dbg_param_mask_flag; uint64_t flag; static int slimbus_flag = 0; struct fm_hal_t *hal = NULL; +static pthread_mutex_t hal_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t hal_cond = PTHREAD_COND_INITIALIZER; #define LOG_TAG "radio_helium" #define WAIT_TIMEOUT 20000 /* 20*1000us */ +#define HAL_TIMEOUT 3 static void radio_hci_req_complete(char result) { @@ -1099,6 +1102,7 @@ int fm_hci_close_done() ALOGI("fm_hci_close_done"); fm_hal_callbacks_t *ptr = NULL; + pthread_mutex_lock(&hal_lock); if(hal != NULL){ ptr = hal->jni_cb; ALOGI("clearing hal "); @@ -1114,6 +1118,8 @@ int fm_hci_close_done() ptr->disabled_cb(); ptr->thread_evt_cb(1); } + pthread_cond_broadcast(&hal_cond); + pthread_mutex_unlock(&hal_lock); return 0; } @@ -1276,27 +1282,31 @@ int hal_init(fm_hal_callbacks_t *cb) { int ret = -FM_HC_STATUS_FAIL, i; fm_hci_hal_t hci_hal; + struct timespec ts; ALOGD("++%s", __func__); memset(&hci_hal, 0, sizeof(fm_hci_hal_t)); - if (hal) { - ALOGE("%s:HAL is still available from the last session, please wait for sometime", __func__); - for(i=0; i<10; i++) { - if (!hal) { - break; + pthread_mutex_lock(&(hal_lock)); + while (hal) { + ALOGE("%s:HAL is still available wait for last hal session to close", __func__); + if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) == 0) { + ts.tv_sec += HAL_TIMEOUT; + ret = pthread_cond_timedwait(&hal_cond, &hal_lock, + &ts); + if(ret == ETIMEDOUT) { + ALOGE("%s:FM Hci close is stuck kiiling the fm process", __func__); + kill(getpid(), SIGKILL); } else { - usleep(WAIT_TIMEOUT); + ALOGD("%s:last HAL session is closed ", LOG_TAG); } + } else { + ALOGE("%s: clock gettime failed. err = %d(%s)", LOG_TAG, + errno, strerror(errno)); } } - - if (hal) { - ALOGE("%s:Last FM session didnot end properly, please launch again", __func__); - hal = NULL; - return ret; - } + pthread_mutex_unlock(&hal_lock); hal = malloc(sizeof(struct fm_hal_t)); if (!hal) { @@ -1359,9 +1369,11 @@ static int set_fm_ctrl(int cmd, int val) struct hci_fm_def_data_wr_req def_data_wrt; struct hci_fm_def_data_rd_req def_data_rd; + pthread_mutex_lock(&hal_lock); if (!hal) { ALOGE("%s:ALERT: command sent before hal init", __func__); - return -FM_HC_STATUS_FAIL; + ret = -FM_HC_STATUS_FAIL; + goto end; } ALOGD("%s:cmd: %x, val: %d",LOG_TAG, cmd, val); @@ -1946,6 +1958,7 @@ static int set_fm_ctrl(int cmd, int val) end: if (ret < 0) ALOGE("%s:%s: 0x%x cmd failed", LOG_TAG, __func__, cmd); + pthread_mutex_unlock(&hal_lock); return ret; } @@ -1954,31 +1967,33 @@ static int get_fm_ctrl(int cmd, int *val) int ret = 0; struct hci_fm_def_data_rd_req def_data_rd; + pthread_mutex_lock(&hal_lock); if (!hal) { ALOGE("%s:ALERT: command sent before hal_init", __func__); - return -FM_HC_STATUS_FAIL; + ret = -FM_HC_STATUS_FAIL; + goto end; } ALOGE("%s: cmd = 0x%x", __func__, cmd); switch(cmd) { case HCI_FM_HELIUM_FREQ: if (!val) - return -FM_HC_STATUS_NULL_POINTER; + ret = -FM_HC_STATUS_NULL_POINTER; *val = hal->radio->fm_st_rsp.station_rsp.station_freq; break; case HCI_FM_HELIUM_UPPER_BAND: if (!val) - return -FM_HC_STATUS_NULL_POINTER; + ret = -FM_HC_STATUS_NULL_POINTER; *val = hal->radio->recv_conf.band_high_limit; break; case HCI_FM_HELIUM_LOWER_BAND: if (!val) - return -FM_HC_STATUS_NULL_POINTER; + ret = -FM_HC_STATUS_NULL_POINTER; *val = hal->radio->recv_conf.band_low_limit; break; case HCI_FM_HELIUM_AUDIO_MUTE: if (!val) - return -FM_HC_STATUS_NULL_POINTER; + ret = -FM_HC_STATUS_NULL_POINTER; *val = hal->radio->mute_mode.hard_mute; break; case HCI_FM_HELIUM_SINR_SAMPLES: @@ -2122,8 +2137,11 @@ cmd: default: break; } + +end: if (ret < 0) ALOGE("%s:%s: %d cmd failed", LOG_TAG, __func__, cmd); + pthread_mutex_unlock(&hal_lock); return ret; } |