summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinu Jella <sjella@codeaurora.org>2015-09-21 19:29:50 +0530
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:22:19 -0600
commit13f3c2e0b68a4d4f15330dbcac78aafae4c07aac (patch)
tree9eed93f7180dd00f2a27a8f37348305ada0b6896
parent30245df6d0e2e06aa797d38339d59078b6635dc8 (diff)
downloadandroid_system_bt-13f3c2e0b68a4d4f15330dbcac78aafae4c07aac.tar.gz
android_system_bt-13f3c2e0b68a4d4f15330dbcac78aafae4c07aac.tar.bz2
android_system_bt-13f3c2e0b68a4d4f15330dbcac78aafae4c07aac.zip
Bluetooth: Add support to send h/w error event
- Bluedroid stack needs to be reset whenever H/w chip restarts like Subsytem restart. - Emulates the hardware error event on detecting SSR event from PR controller. CRs-Fixed: 914079 Change-Id: I9248a4e6ad689fc590fd4fd0f7a067cd33bf314f
-rw-r--r--hci/Android.mk4
-rw-r--r--hci/include/hci_hal.h6
-rw-r--r--hci/src/hci_hal_h4.c10
-rw-r--r--hci/src/hci_hal_mct.c33
-rw-r--r--hci/src/hci_layer.c26
5 files changed, 79 insertions, 0 deletions
diff --git a/hci/Android.mk b/hci/Android.mk
index bbaf11781..5dee0966a 100644
--- a/hci/Android.mk
+++ b/hci/Android.mk
@@ -23,6 +23,10 @@ ifeq ($(BLUETOOTH_HCI_USE_MCT),true)
LOCAL_CFLAGS += -DHCI_USE_MCT
endif
+ifeq ($(QCOM_BT_USE_SMD_TTY),true)
+LOCAL_CFLAGS += -DQCOM_WCN_SSR
+endif
+
ifeq ($(TARGET_BUILD_VARIANT), userdebug)
LOCAL_CFLAGS += -DBTSNOOP_DEFAULT=TRUE
endif
diff --git a/hci/include/hci_hal.h b/hci/include/hci_hal.h
index b0b3c67fb..a2f93673a 100644
--- a/hci/include/hci_hal.h
+++ b/hci/include/hci_hal.h
@@ -76,6 +76,12 @@ typedef struct hci_hal_t {
// This is safe in the bluetooth context, because there is always a buffer
// header that prefixes data you're sending.
uint16_t (*transmit_data)(serial_data_type_t type, uint8_t *data, uint16_t length);
+
+#ifdef QCOM_WCN_SSR
+ // to detect the SSR in PR controller
+ bool (*dev_in_reset)(void);
+#endif
+
} hci_hal_t;
// Gets the correct hal implementation, as compiled for.
diff --git a/hci/src/hci_hal_h4.c b/hci/src/hci_hal_h4.c
index 4fc4274f4..a59c6df56 100644
--- a/hci/src/hci_hal_h4.c
+++ b/hci/src/hci_hal_h4.c
@@ -166,6 +166,13 @@ done:;
return transmitted_length;
}
+#ifdef QCOM_WCN_SSR
+static bool hal_dev_in_reset()
+{
+ return false;
+}
+#endif
+
// Internal functions
// See what data is waiting, and notify the upper layer
@@ -197,6 +204,9 @@ static const hci_hal_t interface = {
read_data,
packet_finished,
transmit_data,
+#ifdef QCOM_WCN_SSR
+ hal_dev_in_reset
+#endif
};
const hci_hal_t *hci_hal_h4_get_interface() {
diff --git a/hci/src/hci_hal_mct.c b/hci/src/hci_hal_mct.c
index 9b3707c7f..adc17c3ad 100644
--- a/hci/src/hci_hal_mct.c
+++ b/hci/src/hci_hal_mct.c
@@ -32,6 +32,11 @@
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026
+#ifdef QCOM_WCN_SSR
+#include <termios.h>
+#include <sys/ioctl.h>
+#endif
+
// Our interface and modules we import
static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks;
@@ -125,6 +130,31 @@ static void hal_close() {
uart_fds[i] = INVALID_FD;
}
+#ifdef QCOM_WCN_SSR
+static bool hal_dev_in_reset()
+{
+ volatile int serial_bits;
+ bool dev_reset_done =0;
+ uint8_t retry_count = 0;
+ ioctl(uart_fds[CH_EVT], TIOCMGET, &serial_bits);
+ if (serial_bits & TIOCM_OUT2) {
+ while(serial_bits & TIOCM_OUT1) {
+ LOG_WARN("userial_device in reset \n");
+ sleep(2);
+ retry_count++;
+ ioctl(uart_fds[CH_EVT], TIOCMGET, &serial_bits);
+ if((serial_bits & TIOCM_OUT1))
+ dev_reset_done = 0;
+ else
+ dev_reset_done = 1;
+ if(retry_count == 6)
+ break;
+ }
+ }
+ return dev_reset_done;
+}
+#endif
+
static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size, bool block) {
if (type == DATA_TYPE_ACL) {
return eager_reader_read(acl_stream, buffer, max_size, block);
@@ -196,6 +226,9 @@ static const hci_hal_t interface = {
read_data,
packet_finished,
transmit_data,
+#ifdef QCOM_WCN_SSR
+ hal_dev_in_reset
+#endif
};
const hci_hal_t *hci_hal_mct_get_interface() {
diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c
index 5c5a908fe..fb2bb972e 100644
--- a/hci/src/hci_layer.c
+++ b/hci/src/hci_layer.c
@@ -540,8 +540,33 @@ static void command_timed_out(UNUSED_ATTR void *context) {
static void hal_says_data_ready(serial_data_type_t type) {
packet_receive_data_t *incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type)];
+#ifdef QCOM_WCN_SSR
+ uint8_t dev_ssr_event[3] = { 0x10, 0x01, 0x0A };
+ uint8_t reset;
+#endif
+
uint8_t byte;
while (hal->read_data(type, &byte, 1, false) != 0) {
+#ifdef QCOM_WCN_SSR
+ reset = hal->dev_in_reset();
+ if (reset) {
+ incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)];
+ incoming->buffer = (BT_HDR *)buffer_allocator->alloc(BT_HDR_SIZE + 3);
+ if (incoming->buffer) {
+ LOG_ERROR("sending H/w error event to stack\n ");
+ incoming->buffer->offset = 0;
+ incoming->buffer->layer_specific = 0;
+ incoming->buffer->event = MSG_HC_TO_STACK_HCI_EVT;
+ incoming->index = 3;
+ memcpy(incoming->buffer->data, &dev_ssr_event, 3);
+ incoming->state = FINISHED;
+ } else {
+ LOG_ERROR("error getting buffer for H/W event\n ");
+ break;
+ }
+ } else
+#endif
+ {
switch (incoming->state) {
case BRAND_NEW:
// Initialize and prepare to jump to the preamble reading state
@@ -606,6 +631,7 @@ static void hal_says_data_ready(serial_data_type_t type) {
LOG_ERROR("%s the state machine should not have been left in the finished state.", __func__);
break;
}
+ }
if (incoming->state == FINISHED) {
incoming->buffer->len = incoming->index;