diff options
author | Srinu Jella <sjella@codeaurora.org> | 2015-09-21 19:29:50 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:22:19 -0600 |
commit | 13f3c2e0b68a4d4f15330dbcac78aafae4c07aac (patch) | |
tree | 9eed93f7180dd00f2a27a8f37348305ada0b6896 | |
parent | 30245df6d0e2e06aa797d38339d59078b6635dc8 (diff) | |
download | android_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.mk | 4 | ||||
-rw-r--r-- | hci/include/hci_hal.h | 6 | ||||
-rw-r--r-- | hci/src/hci_hal_h4.c | 10 | ||||
-rw-r--r-- | hci/src/hci_hal_mct.c | 33 | ||||
-rw-r--r-- | hci/src/hci_layer.c | 26 |
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; |