summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhimta ram <hram@codeaurora.org>2019-01-21 17:27:07 +0530
committerhimta ram <hram@codeaurora.org>2019-03-27 18:56:43 +0530
commit7edc3c3948b8e3514cac4f343be5aa1e3f8caf4c (patch)
tree858e51220f8969dc14c663b1f12ecb5075d7ee50
parent1f23f3a5108767a0f279f2ce0197a6f4d63440f2 (diff)
downloadandroid_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.cpp9
-rw-r--r--fm_hci/fm_hci.h2
-rw-r--r--helium/radio_helium_hal.c54
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;
}