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];