merge in nyc-mr1-release history after reset to nyc-mr1-dev
diff --git a/msmcobalt/libbt-vendor/include/bt_vendor_qcom.h b/msmcobalt/libbt-vendor/include/bt_vendor_qcom.h
index fae931e..dd956cf 100644
--- a/msmcobalt/libbt-vendor/include/bt_vendor_qcom.h
+++ b/msmcobalt/libbt-vendor/include/bt_vendor_qcom.h
@@ -17,9 +17,8 @@
#ifndef BT_VENDOR_QCOM_H
#define BT_VENDOR_QCOM_H
+#include <stdbool.h>
#include "bt_vendor_lib.h"
-//#include "vnd_buildcfg.h"
-
#ifndef FALSE
#define FALSE 0
@@ -48,7 +47,6 @@
BT_VND_OP_ANT_USERIAL_CLOSE
}ant_serial;
-extern bt_vendor_callbacks_t *bt_vendor_cbacks;
/* HW_NEED_END_WITH_HCI_RESET
code implementation of sending a HCI_RESET command during the epilog
@@ -66,5 +64,26 @@
#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5
#define HCI_EVT_CMD_CMPL_OPCODE 3
+enum {
+ BT_STATUS_SUCCESS = 0,
+ BT_STATUS_FAIL,
+ BT_STATUS_INVAL,
+ BT_STATUS_NOMEM,
+};
+
+struct bt_qcom_struct {
+ int fd[2];
+ int ant_fd;
+ int fm_fd;
+ bt_vendor_callbacks_t *cb;
+ uint8_t bdaddr[6];
+ int soc_type;
+ int rfkill_id;
+ char *rfkill_state;
+ bool enable_extldo;
+};
+extern struct bt_qcom_struct *q;
+extern pthread_mutex_t q_lock;
+
#endif /* BT_VENDOR_QCOM_H */
diff --git a/msmcobalt/libbt-vendor/src/bt_vendor_qcom.c b/msmcobalt/libbt-vendor/src/bt_vendor_qcom.c
index 36b9fee..09583d5 100644
--- a/msmcobalt/libbt-vendor/src/bt_vendor_qcom.c
+++ b/msmcobalt/libbt-vendor/src/bt_vendor_qcom.c
@@ -64,21 +64,8 @@
/******************************************************************************
** Variables
******************************************************************************/
-int pFd[2] = {0,};
-#ifdef ENABLE_ANT
-int ant_fd;
-#endif
-#ifdef FM_OVER_UART
-int fm_fd;
-#endif
-bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
-
-uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-static int btSocType = BT_SOC_DEFAULT;
-static int rfkill_id = -1;
-static char *rfkill_state = NULL;
-bool enable_extldo = FALSE;
+struct bt_qcom_struct *q = NULL;
+pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER;
int userial_clock_operation(int fd, int cmd);
int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
@@ -87,8 +74,6 @@
void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
bool is_download_progress();
-pthread_mutex_t m_lock = PTHREAD_MUTEX_INITIALIZER;
-
static const tUSERIAL_CFG userial_init_cfg =
{
(USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
@@ -96,7 +81,7 @@
};
#if (HW_NEED_END_WITH_HCI_RESET == TRUE)
-void hw_epilog_process(void);
+void __hw_epilog_process(void);
#endif
#ifdef WIFI_BT_STATUS_SYNC
@@ -383,7 +368,10 @@
return init_success;
}
-/** Bluetooth Controller power up or shutdown */
+/*
+ * Bluetooth Controller power up or shutdown, this function is called with
+ * q_lock held and q is non-NULL
+ */
static int bt_powerup(int en )
{
char rfkill_type[64], *enable_ldo_path = NULL;
@@ -420,7 +408,7 @@
#endif
/* Assign rfkill_id and find bluetooth rfkill state path*/
- for(i=0;(rfkill_id == -1) && (rfkill_state == NULL);i++)
+ for(i = 0; (q->rfkill_id == -1) && (q->rfkill_state == NULL); i++)
{
snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
if ((fd = open(rfkill_type, O_RDONLY)) < 0)
@@ -439,17 +427,17 @@
if ((size >= 9) && !memcmp(type, "bluetooth", 9))
{
- asprintf(&rfkill_state, "/sys/class/rfkill/rfkill%d/state", rfkill_id = i);
+ asprintf(&q->rfkill_state, "/sys/class/rfkill/rfkill%d/state", q->rfkill_id = i);
break;
}
}
/* Get rfkill State to control */
- if (rfkill_state != NULL)
+ if (q->rfkill_state != NULL)
{
- if ((fd = open(rfkill_state, O_RDWR)) < 0)
+ if ((fd = open(q->rfkill_state, O_RDWR)) < 0)
{
- ALOGE("open(%s) for write failed: %s (%d)",rfkill_state, strerror(errno), errno);
+ ALOGE("open(%s) for write failed: %s (%d)", q->rfkill_state, strerror(errno), errno);
#ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_release(lock_fd);
bt_semaphore_destroy(lock_fd);
@@ -466,8 +454,7 @@
#endif
goto done;
}
-
- ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", rfkill_id);
+ ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id);
if( (ret < 0 ) || (enable_ldo_path == NULL) )
{
ALOGE("Memory Allocation failure");
@@ -489,7 +476,7 @@
if (ret < 0) {
ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__);
}
- enable_extldo = TRUE;
+ q->enable_extldo = TRUE;
}
if(on == '0'){
@@ -503,7 +490,7 @@
/* Write value to control rfkill */
if(fd >= 0) {
if ((size = write(fd, &on, 1)) < 0) {
- ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno);
+ ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno);
#ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_release(lock_fd);
bt_semaphore_destroy(lock_fd);
@@ -558,84 +545,89 @@
return 0;
}
+static inline void soc_init(int soc_type)
+{
+ switch (soc_type)
+ {
+ case BT_SOC_CHEROKEE:
+ case BT_SOC_ROME:
+ case BT_SOC_AR3K:
+ ALOGI("bt-vendor : Initializing UART transport layer");
+ userial_vendor_init();
+ break;
+ case BT_SOC_DEFAULT:
+ break;
+ default:
+ ALOGE("Unknown soc yype: %d", soc_type);
+ break;
+ }
+}
+
+/* Copy BD Address as little-endian byte order */
+static inline void le2bd(unsigned char *src, unsigned char *dst)
+{
+ int i;
+ for (i = 0; i < 6; i++)
+ dst[i] = src[5-i];
+}
+
+static inline void print_bdaddr(unsigned char *addr)
+{
+ ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1],
+ addr[2], addr[3], addr[4], addr[5]);
+}
+
/*****************************************************************************
**
** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
**
*****************************************************************************/
-static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
+static int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr)
{
- int i, ret;
char address[PROPERTY_VALUE_MAX];
+ struct bt_qcom_struct *temp = NULL;
+ int ret = BT_STATUS_SUCCESS, i;
- ALOGI("bt-vendor : init");
+ ALOGI("++%s", __FUNCTION__);
- if (p_cb == NULL)
- {
- ALOGE("init failed with no user callbacks!");
- return -1;
+ if (!cb || !bdaddr) {
+ ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr);
+ ret = -BT_STATUS_INVAL;
+ goto out;
}
- if ((btSocType = get_bt_soc_type()) < 0) {
- ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
- return -1;
+ temp = (struct bt_qcom_struct *) malloc(sizeof(*q));
+ if (!temp) {
+ ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno);
+ ret = -BT_STATUS_NOMEM;
+ goto out;
}
+ memset(temp, 0, sizeof(*temp));
- switch(btSocType)
- {
- case BT_SOC_ROME:
- case BT_SOC_AR3K:
- case BT_SOC_CHEROKEE:
- ALOGI("bt-vendor : check soc initialized ");
- if (!is_soc_initialized()) {
- ALOGI("bt-vendor : Initializing UART transport layer");
- userial_vendor_init();
- }
- break;
- case BT_SOC_DEFAULT:
- break;
- default:
- ALOGE("Unknown btSocType: 0x%x", btSocType);
- break;
- }
+ temp->rfkill_id = -1;
+ temp->enable_extldo = FALSE;
+ temp->cb = cb;
+ temp->ant_fd = -1;
+ temp->soc_type = get_bt_soc_type();
+ soc_init(temp->soc_type);
+ le2bd(bdaddr, temp->bdaddr);
+ print_bdaddr(temp->bdaddr);
- /* store reference to user callbacks */
- bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
-
- /* Copy BD Address as little-endian byte order */
- if(local_bdaddr)
- for(i=0;i<6;i++)
- vnd_local_bd_addr[i] = *(local_bdaddr + (5-i));
-
- ALOGI("%s: Local BD Address : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", __FUNCTION__,
- vnd_local_bd_addr[0],
- vnd_local_bd_addr[1],
- vnd_local_bd_addr[2],
- vnd_local_bd_addr[3],
- vnd_local_bd_addr[4],
- vnd_local_bd_addr[5]);
-
- /*Update the property here so that It can be fetched at wcnss_filter*/
- snprintf(address, sizeof(address), "%02x:%02x:%02x:%02x:%02x:%02x",
- vnd_local_bd_addr[0],
- vnd_local_bd_addr[1],
- vnd_local_bd_addr[2],
- vnd_local_bd_addr[3],
- vnd_local_bd_addr[4],
- vnd_local_bd_addr[5]);
-
- ret = property_set("wc_transport.stack_bdaddr", address);
- if (ret < 0) {
- ALOGE("%s: Error while updating bd addr property: %d\n", __func__, ret);
- return false;
- }
-
+/* TODO: Move these fields inside bt_qcom context */
#ifdef WIFI_BT_STATUS_SYNC
isInit = 1;
#endif /* WIFI_BT_STATUS_SYNC */
- return 0;
+ /* Everything successful */
+ q = temp;
+ return ret;
+
+out:
+ if (temp)
+ free(temp);
+ ALOGI("--%s ret %d", __FUNCTION__, ret);
+ return ret;
}
#ifdef READ_BT_ADDR_FROM_PROP
@@ -712,7 +704,7 @@
/** Requested operations */
static int op(bt_vendor_opcode_t opcode, void *param)
{
- int retval = 0;
+ int retval = BT_STATUS_SUCCESS;
int nCnt = 0;
int nState = -1;
bool is_ant_req = false;
@@ -729,7 +721,13 @@
#endif
bool skip_init = true;
int opcode_init = opcode;
- ALOGV("bt-vendor : op for %d", opcode);
+ ALOGV("++%s opcode %d", __FUNCTION__, opcode);
+ pthread_mutex_lock(&q_lock);
+ if (!q) {
+ ALOGE("op called with NULL context");
+ retval = -BT_STATUS_INVAL;
+ goto out;
+ }
switch(opcode_init)
{
@@ -745,11 +743,15 @@
#endif
case BT_VND_OP_POWER_CTRL:
{
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
+ }
nState = *(int *) param;
ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s",
(nState == BT_VND_PWR_ON)? "On" : "Off" );
- switch(btSocType)
+ switch(q->soc_type)
{
case BT_SOC_DEFAULT:
if (readTrpState())
@@ -771,47 +773,33 @@
case BT_SOC_AR3K:
case BT_SOC_CHEROKEE:
/* BT Chipset Power Control through Device Tree Node */
- if(!pthread_mutex_lock(&m_lock)) {
- retval = bt_powerup(nState);
- pthread_mutex_unlock(&m_lock);
- }
+ retval = bt_powerup(nState);
default:
break;
}
}
break;
- case BT_VND_OP_FW_CFG:
- {
- // call hciattach to initalize the stack
- if(bt_vendor_cbacks){
- if (btSocType == BT_SOC_ROME) {
- if (is_soc_initialized()) {
- ALOGI("Bluetooth FW and transport layer are initialized");
- bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
- } else {
- ALOGE("bt_vendor_cbacks is null or SoC not initialized");
- ALOGE("Error : hci, smd initialization Error");
- retval = -1;
- }
- } else {
- ALOGI("Bluetooth FW and transport layer are initialized");
- bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
- }
+ case BT_VND_OP_FW_CFG: {
+ /* call hciattach to initalize the stack */
+ if (q->soc_type == BT_SOC_ROME) {
+ if (is_soc_initialized()) {
+ ALOGI("Bluetooth FW and transport layer are initialized");
+ q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
+ } else {
+ ALOGE("bt_vendor_cbacks is null or SoC not initialized");
+ ALOGE("Error : hci, smd initialization Error");
+ retval = -1;
+ }
+ } else {
+ ALOGI("Bluetooth FW and transport layer are initialized");
+ q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
}
- else{
- ALOGE("bt_vendor_cbacks is null");
- ALOGE("Error : hci, smd initialization Error");
- retval = -1;
- }
- }
+ }
break;
case BT_VND_OP_SCO_CFG:
- {
- if (bt_vendor_cbacks)
- bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
- }
+ q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
break;
#ifdef ENABLE_ANT
case BT_VND_OP_ANT_USERIAL_OPEN:
@@ -828,20 +816,24 @@
userial_open:
case BT_VND_OP_USERIAL_OPEN:
{
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
+ }
int (*fd_array)[] = (int (*)[]) param;
int idx, fd = -1, fd_filter = -1;
ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
- switch(btSocType)
+ switch(q->soc_type)
{
case BT_SOC_DEFAULT:
{
- if(bt_hci_init_transport(pFd) != -1){
+ if(bt_hci_init_transport(q->fd) != -1){
int (*fd_array)[] = (int (*) []) param;
- (*fd_array)[CH_CMD] = pFd[0];
- (*fd_array)[CH_EVT] = pFd[0];
- (*fd_array)[CH_ACL_OUT] = pFd[1];
- (*fd_array)[CH_ACL_IN] = pFd[1];
+ (*fd_array)[CH_CMD] = q->fd[0];
+ (*fd_array)[CH_EVT] = q->fd[0];
+ (*fd_array)[CH_ACL_OUT] = q->fd[1];
+ (*fd_array)[CH_ACL_IN] = q->fd[1];
}
else {
retval = -1;
@@ -914,8 +906,12 @@
ignore_boot_prop = TRUE;
break;
}
- if (!validate_tok(tok)) {
- ALOGE("Invalid token in BD address");
+ if (i == 6 && !ignore_boot_prop) {
+ ALOGV("Valid BD address read from prop");
+ memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
+ ignore_boot_prop = FALSE;
+ } else {
+ ALOGE("There are not enough tokens in BD addr");
ignore_boot_prop = TRUE;
break;
}
@@ -938,12 +934,12 @@
}
#endif //READ_BT_ADDR_FROM_PROP
/* Always read BD address from NV file */
- if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr))
+ if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr))
{
/* Since the BD address is configured in boot time We should not be here */
ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
}
- if(rome_soc_init(fd, (char*)vnd_local_bd_addr)<0) {
+ if(rome_soc_init(fd, (char*)q->bdaddr)<0) {
retval = -1;
} else {
ALOGV("rome_soc_init is completed");
@@ -965,7 +961,7 @@
#ifdef ENABLE_ANT
if (is_ant_req) {
ALOGI("%s: connect to ant channel", __func__);
- ant_fd = fd_filter = connect_to_local_socket("ant_sock");
+ q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
}
else
#endif
@@ -1002,7 +998,7 @@
}
}
} else {
- if (btSocType == BT_SOC_ROME)
+ if (q->soc_type == BT_SOC_ROME)
ALOGE("Failed to initialize ROME Controller!!!");
}
@@ -1024,14 +1020,14 @@
#ifdef ENABLE_ANT
if (is_ant_req) {
ALOGI("%s: connect to ant channel", __func__);
- ant_fd = fd_filter = connect_to_local_socket("ant_sock");
+ q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
}
else
#endif
#ifdef FM_OVER_UART
- if (is_fm_req && (btSocType >=BT_SOC_ROME && btSocType < BT_SOC_RESERVED)) {
+ if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) {
ALOGI("%s: connect to fm channel", __func__);
- fm_fd = fd_filter = connect_to_local_socket("fm_sock");
+ q->fm_fd = fd_filter = connect_to_local_socket("fm_sock");
}
else
#endif
@@ -1067,7 +1063,7 @@
}
break;
default:
- ALOGE("Unknown btSocType: 0x%x", btSocType);
+ ALOGE("Unknown soc_type: 0x%x", q->soc_type);
break;
}
} break;
@@ -1075,52 +1071,46 @@
case BT_VND_OP_ANT_USERIAL_CLOSE:
{
ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
- if(!pthread_mutex_lock(&m_lock)) {
- property_set("wc_transport.clean_up","1");
- if (ant_fd != -1) {
- ALOGE("closing ant_fd");
- close(ant_fd);
- ant_fd = -1;
- }
- pthread_mutex_unlock(&m_lock);
+ property_set("wc_transport.clean_up","1");
+ if (q->ant_fd != -1) {
+ ALOGE("closing ant_fd");
+ close(q->ant_fd);
+ q->ant_fd = -1;
}
}
- break;
+ break;
#endif
#ifdef FM_OVER_UART
case BT_VND_OP_FM_USERIAL_CLOSE:
{
ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE");
property_set("wc_transport.clean_up","1");
- if (fm_fd != -1) {
+ if (q->fm_fd != -1) {
ALOGE("closing fm_fd");
- close(fm_fd);
- fm_fd = -1;
+ close(q->fm_fd);
+ q->fm_fd = -1;
}
break;
- }
+ }
#endif
case BT_VND_OP_USERIAL_CLOSE:
{
- ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType);
- switch(btSocType)
+ ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type);
+ switch(q->soc_type)
{
case BT_SOC_DEFAULT:
- bt_hci_deinit_transport(pFd);
+ bt_hci_deinit_transport(q->fd);
break;
case BT_SOC_ROME:
case BT_SOC_AR3K:
case BT_SOC_CHEROKEE:
{
- if(!pthread_mutex_lock(&m_lock)) {
- property_set("wc_transport.clean_up","1");
- userial_vendor_close();
- pthread_mutex_unlock(&m_lock);
- }
+ property_set("wc_transport.clean_up","1");
+ userial_vendor_close();
break;
}
default:
- ALOGE("Unknown btSocType: 0x%x", btSocType);
+ ALOGE("Unknown soc_type: 0x%x", q->soc_type);
break;
}
}
@@ -1128,6 +1118,10 @@
case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
{
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
+ }
uint32_t *timeout_ms = (uint32_t *) param;
*timeout_ms = 1000;
}
@@ -1135,7 +1129,11 @@
break;
case BT_VND_OP_LPM_SET_MODE:
- if(btSocType == BT_SOC_AR3K) {
+ if (q->soc_type == BT_SOC_AR3K) {
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
+ }
uint8_t *mode = (uint8_t *) param;
if (*mode) {
@@ -1144,57 +1142,59 @@
else {
lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
}
- if (bt_vendor_cbacks )
- bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
- }
- else {
- // respond with failure as it's already handled by other mechanism
- if (bt_vendor_cbacks)
- bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
+ q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
+ } else {
+ /* respond with failure as it's handled by other mechanism */
+ q->cb->lpm_cb(BT_VND_OP_RESULT_FAIL);
}
break;
- case BT_VND_OP_LPM_WAKE_SET_STATE:
- {
- switch(btSocType)
- {
- case BT_SOC_CHEROKEE:
- case BT_SOC_ROME:
- {
- uint8_t *state = (uint8_t *) param;
- uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
- BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
-
- if (wake_assert == 0)
- ALOGV("ASSERT: Waking up BT-Device");
- else if (wake_assert == 1)
- ALOGV("DEASSERT: Allowing BT-Device to Sleep");
- }
- break;
- case BT_SOC_AR3K:
- {
- uint8_t *state = (uint8_t *) param;
- uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
- UPIO_ASSERT : UPIO_DEASSERT;
- lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
- }
- case BT_SOC_DEFAULT:
- break;
- default:
- ALOGE("Unknown btSocType: 0x%x", btSocType);
- break;
- }
- }
- break;
- case BT_VND_OP_EPILOG:
- {
-#if (HW_NEED_END_WITH_HCI_RESET == FALSE)
- if (bt_vendor_cbacks)
- {
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ case BT_VND_OP_LPM_WAKE_SET_STATE: {
+ switch(q->soc_type) {
+ case BT_SOC_CHEROKEE:
+ case BT_SOC_ROME: {
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
}
+ uint8_t *state = (uint8_t *) param;
+ uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
+ BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
+
+ if (wake_assert == 0)
+ ALOGV("ASSERT: Waking up BT-Device");
+ else if (wake_assert == 1)
+ ALOGV("DEASSERT: Allowing BT-Device to Sleep");
+
+#ifdef QCOM_BT_SIBS_ENABLE
+ ALOGI("Invoking HCI H4 callback function");
+ q->cb->lpm_set_state_cb(wake_assert);
+#endif
+ }
+ break;
+ case BT_SOC_AR3K: {
+ if (!param) {
+ ALOGE("opcode = %d: param is null", opcode_init);
+ break;
+ }
+ uint8_t *state = (uint8_t *) param;
+ uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
+ UPIO_ASSERT : UPIO_DEASSERT;
+ lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
+ }
+ case BT_SOC_DEFAULT:
+ break;
+ default:
+ ALOGE("Unknown soc_type: 0x%x", q->soc_type);
+ break;
+ }
+ }
+ break;
+ case BT_VND_OP_EPILOG: {
+#if (HW_NEED_END_WITH_HCI_RESET == FALSE)
+ q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
#else
- switch(btSocType)
+ switch(q->soc_type)
{
case BT_SOC_CHEROKEE:
case BT_SOC_ROME:
@@ -1203,20 +1203,16 @@
property_get("wc_transport.hci_filter_status", value, "0");
if(is_soc_initialized()&& (strcmp(value,"1") == 0))
{
- hw_epilog_process();
+ __hw_epilog_process();
}
else
{
- if (bt_vendor_cbacks)
- {
- ALOGE("vendor lib epilog process aborted");
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
- }
+ q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
}
}
break;
default:
- hw_epilog_process();
+ __hw_epilog_process();
break;
}
#endif
@@ -1231,7 +1227,7 @@
break;
}
- switch(btSocType)
+ switch(q->soc_type)
{
case BT_SOC_CHEROKEE:
retval = 3200000;
@@ -1247,41 +1243,55 @@
}
}
+out:
+ pthread_mutex_unlock(&q_lock);
+ ALOGV("--%s", __FUNCTION__);
return retval;
}
-static void ssr_cleanup(int reason) {
- int pwr_state=BT_VND_PWR_OFF;
+static void ssr_cleanup(int reason)
+{
+ int pwr_state = BT_VND_PWR_OFF;
int ret;
unsigned char trig_ssr = 0xEE;
- ALOGI("ssr_cleanup");
+
+ ALOGI("++%s", __FUNCTION__);
+
+ pthread_mutex_lock(&q_lock);
+ if (!q) {
+ ALOGE("ssr_cleanup called with NULL context");
+ pthread_mutex_unlock(&q_lock);
+ return;
+ }
if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
- ALOGE("%s: Failed to set property", __FUNCTION__);
+ ALOGE("Failed to set property");
}
- if ((btSocType = get_bt_soc_type()) < 0) {
- ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
- }
-
- if (btSocType == BT_SOC_ROME || btSocType == BT_SOC_CHEROKEE) {
- //Indicate to filter by sending
- //special byte
+ if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) {
+#ifdef ENABLE_ANT
+ /*Indicate to filter by sending special byte */
if (reason == CMD_TIMEOUT) {
trig_ssr = 0xEE;
ret = write (vnd_userial.fd, &trig_ssr, 1);
- ALOGI("Trig_ssr is being sent to BT socket, retval(%d) :errno: %s", ret, strerror(errno));
+ ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s",
+ ret, strerror(errno));
if (is_debug_force_special_bytes()) {
- //Then we should send special byte to crash SOC in WCNSS_Filter, so we do not
- //need to power off UART here.
+ /*
+ * Then we should send special byte to crash SOC in
+ * WCNSS_Filter, so we do not need to power off UART here.
+ */
+ pthread_mutex_unlock(&q_lock);
return;
}
}
-#ifdef ENABLE_ANT
- /*Close both ANT channel*/
+ /* release lock here as op holds lock anyways */
+ pthread_mutex_unlock(&q_lock);
+
+ /* Close both ANT channel */
op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
#endif
- /*Close both BT channel*/
+ /* Close both BT channel */
op(BT_VND_OP_USERIAL_CLOSE, NULL);
#ifdef FM_OVER_UART
@@ -1298,16 +1308,20 @@
}
/*Generally switching of chip should be enough*/
op(BT_VND_OP_POWER_CTRL, &pwr_state);
+
+ ALOGI("--%s", __FUNCTION__);
}
/** Closes the interface */
-static void cleanup( void )
+static void cleanup(void)
{
ALOGI("cleanup");
- if(!pthread_mutex_lock(&m_lock)) {
- bt_vendor_cbacks = NULL;
- pthread_mutex_unlock(&m_lock);
- }
+
+ pthread_mutex_lock(&q_lock);
+ q->cb = NULL;
+ free(q);
+ q = NULL;
+ pthread_mutex_unlock(&q_lock);
#ifdef WIFI_BT_STATUS_SYNC
isInit = 0;
@@ -1344,12 +1358,12 @@
ALOGV("%s:", __FUNCTION__);
- if ((btSocType = get_bt_soc_type()) < 0) {
+ if ((q->soc_type = get_bt_soc_type()) < 0) {
ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
return -1;
}
- switch(btSocType)
+ switch(q->soc_type)
{
case BT_SOC_ROME:
ALOGI("%s: ROME case", __func__);
@@ -1366,7 +1380,7 @@
case BT_SOC_DEFAULT:
break;
default:
- ALOGE("Unknown btSocType: 0x%x", btSocType);
+ ALOGE("Unknown btSocType: 0x%x", q->soc_type);
break;
}
return retval;
diff --git a/msmcobalt/libbt-vendor/src/hardware.c b/msmcobalt/libbt-vendor/src/hardware.c
index 496ebc1..ff421c2 100644
--- a/msmcobalt/libbt-vendor/src/hardware.c
+++ b/msmcobalt/libbt-vendor/src/hardware.c
@@ -132,26 +132,31 @@
ALOGI("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
- if (bt_vendor_cbacks)
- {
- /* Must free the RX event buffer */
- bt_vendor_cbacks->dealloc(p_evt_buf);
-
- /* Once epilog process is done, must call callback to notify caller */
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ pthread_mutex_lock(&q_lock);
+ if (!q) {
+ ALOGE("hw_epilog_cback called with NULL context");
+ goto out;
}
+ /* Must free the RX event buffer */
+ q->cb->dealloc(p_evt_buf);
+
+ /* Once epilog process is done, must call callback to notify caller */
+ q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+out:
+ pthread_mutex_unlock(&q_lock);
}
/*******************************************************************************
**
** Function hw_epilog_process
**
-** Description Sample implementation of epilog process
+** Description Sample implementation of epilog process. This process is
+** called with q_lock held and q->cb is assumed to be valid.
**
** Returns None
**
*******************************************************************************/
-void hw_epilog_process(void)
+void __hw_epilog_process(void)
{
HC_BT_HDR *p_buf = NULL;
uint8_t *p;
@@ -159,13 +164,8 @@
ALOGI("hw_epilog_process");
/* Sending a HCI_RESET */
- if (bt_vendor_cbacks)
- {
- /* Must allocate command buffer via HC's alloc API */
- p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
- HCI_CMD_PREAMBLE_SIZE);
- }
-
+ /* Must allocate command buffer via HC's alloc API */
+ p_buf = (HC_BT_HDR *) q->cb->alloc(BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE);
if (p_buf)
{
p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
@@ -178,15 +178,12 @@
*p = 0; /* parameter length */
/* Send command via HC's xmit_cb API */
- bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
+ q->cb->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
}
else
{
- if (bt_vendor_cbacks)
- {
- ALOGE("vendor lib epilog process aborted [no buffer]");
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
- }
+ ALOGE("vendor lib epilog process aborted [no buffer]");
+ q->cb->epilog_cb(BT_VND_OP_RESULT_FAIL);
}
}
#endif // (HW_NEED_END_WITH_HCI_RESET == TRUE)
diff --git a/msmcobalt/libbt-vendor/src/hw_rome.c b/msmcobalt/libbt-vendor/src/hw_rome.c
index da1ccb1..56c3b9a 100644
--- a/msmcobalt/libbt-vendor/src/hw_rome.c
+++ b/msmcobalt/libbt-vendor/src/hw_rome.c
@@ -88,7 +88,6 @@
/******************************************************************************
** Extern variables
******************************************************************************/
-extern uint8_t vnd_local_bd_addr[6];
/*****************************************************************************
** Functions
@@ -818,6 +817,7 @@
return err;
}
+/* This function is called with q_lock held and q is non-NULL */
int rome_get_tlv_file(char *file_path)
{
FILE * pFile;
@@ -908,7 +908,7 @@
/* Write BD Address */
if(nvm_ptr->tag_id == TAG_NUM_2){
- memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6);
+ memcpy(nvm_byte_ptr, q->bdaddr, 6);
ALOGI("BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
*nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2),
*(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5));
@@ -1348,7 +1348,7 @@
{
/* Write BD Address */
if(cmds[i][TAG_NUM_OFFSET] == TAG_NUM_2){
- memcpy(&cmds[i][TAG_BDADDR_OFFSET], vnd_local_bd_addr, 6);
+ memcpy(&cmds[i][TAG_BDADDR_OFFSET], q->bdaddr, 6);
ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
cmds[i][TAG_BDADDR_OFFSET ], cmds[i][TAG_BDADDR_OFFSET + 1],
cmds[i][TAG_BDADDR_OFFSET + 2], cmds[i][TAG_BDADDR_OFFSET + 3],
@@ -1781,10 +1781,11 @@
}
+/* This function is called with q_lock held and q is non-NULL */
static int disable_internal_ldo(int fd)
{
int ret = 0;
- if (enable_extldo) {
+ if (q->enable_extldo) {
unsigned char cmd[5] = {0x01, 0x0C, 0xFC, 0x01, 0x32};
unsigned char rsp[HCI_MAX_EVENT_SIZE];