From b3bfb154195109d4eddb2bb14c23f8cf2b122f98 Mon Sep 17 00:00:00 2001 From: Dibyendu Roy Date: Wed, 25 May 2016 14:54:43 +0530 Subject: [PATCH] Bluetooth: Select bluetooth transport dynamically Select bluetooth transport dynamically on the basis of qcom.bluetooth.soc property. This patch removes the use of board configuration option QCOM_BT_USE_SMD_TTY and uses dynamically detected SOC type to choose required transport. Change-Id: Iae1ee900362af95c42bffcc444b56267cbbae92d --- hci/Android.mk | 4 - hci/include/hci_hal.h | 3 - hci/src/hci_hal_h4.c | 4 - hci/src/hci_hal_mct.c | 6 -- hci/src/hci_layer.c | 256 +++++++++++++++++++++++++++++++++----------------- 5 files changed, 170 insertions(+), 103 deletions(-) diff --git a/hci/Android.mk b/hci/Android.mk index c3fa4889a..5e477326d 100644 --- a/hci/Android.mk +++ b/hci/Android.mk @@ -21,10 +21,6 @@ LOCAL_SRC_FILES := \ src/packet_fragmenter.c \ src/vendor.c -ifeq ($(QCOM_BT_USE_SMD_TTY),true) -LOCAL_CFLAGS += -DQCOM_WCN_SSR -endif - LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/include \ $(LOCAL_PATH)/.. \ diff --git a/hci/include/hci_hal.h b/hci/include/hci_hal.h index df6a99fe7..454c8ed35 100644 --- a/hci/include/hci_hal.h +++ b/hci/include/hci_hal.h @@ -76,11 +76,8 @@ typedef struct hci_hal_t { // 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 a83a56a44..78674f1c5 100644 --- a/hci/src/hci_hal_h4.c +++ b/hci/src/hci_hal_h4.c @@ -227,12 +227,10 @@ done:; return transmitted_length; } -#ifdef QCOM_WCN_SSR static bool hal_dev_in_reset() { return false; } -#endif // Internal functions @@ -332,9 +330,7 @@ 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 5e43fb273..240656761 100644 --- a/hci/src/hci_hal_mct.c +++ b/hci/src/hci_hal_mct.c @@ -33,10 +33,8 @@ #define HCI_HAL_SERIAL_BUFFER_SIZE 1026 -#ifdef QCOM_WCN_SSR #include #include -#endif // Our interface and modules we import static const hci_hal_t interface; @@ -169,7 +167,6 @@ static void hal_close() { uart_fds[i] = INVALID_FD; } -#ifdef QCOM_WCN_SSR static bool hal_dev_in_reset() { volatile int serial_bits; @@ -196,7 +193,6 @@ static bool hal_dev_in_reset() } return dev_reset_done; } -#endif static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) { #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE)) @@ -328,9 +324,7 @@ 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 7f7ceded0..08bdd4530 100644 --- a/hci/src/hci_layer.c +++ b/hci/src/hci_layer.c @@ -100,6 +100,16 @@ typedef struct { BT_HDR *command; } waiting_command_t; +typedef enum { + BT_SOC_DEFAULT = 0, + BT_SOC_SMD = BT_SOC_DEFAULT, + BT_SOC_AR3K, + BT_SOC_ROME, + BT_SOC_CHEROKEE, + /* Add chipset type here */ + BT_SOC_RESERVED +} bt_soc_type; + // Using a define here, because it can be stringified for the property lookup #define DEFAULT_STARTUP_TIMEOUT_MS 8000 #define STRING_VALUE_OF(x) #x @@ -107,6 +117,7 @@ typedef struct { static const uint32_t EPILOG_TIMEOUT_MS = 3000; static const uint32_t COMMAND_PENDING_TIMEOUT_MS = 8000; +extern int soc_type; // Our interface static bool interface_created; static hci_t interface; @@ -568,103 +579,176 @@ 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 reset; -#endif uint8_t byte; while (hal->read_data(type, &byte, 1) != 0) { -#ifdef QCOM_WCN_SSR - reset = hal->dev_in_reset(); - if (reset) { - incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)]; - if(!create_hw_reset_evt_packet(incoming)) - break; - else { - //Reset SOC status to trigger hciattach service - if(property_set("bluetooth.status", "off") < 0) { - LOG_ERROR(LOG_TAG, "SSR: Error resetting SOC status\n "); + if (soc_type == BT_SOC_ROME || soc_type == BT_SOC_CHEROKEE) { + reset = hal->dev_in_reset(); + if (reset) { + incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)]; + if(!create_hw_reset_evt_packet(incoming)) + break; + else { + //Reset SOC status to trigger hciattach service + if(property_set("bluetooth.status", "off") < 0) { + LOG_ERROR(LOG_TAG, "SSR: Error resetting SOC status\n "); + } else { + ALOGE("SSR: SOC Status is reset\n "); + } + } } else { - ALOGE("SSR: SOC Status is reset\n "); + switch (incoming->state) { + case BRAND_NEW: + // Initialize and prepare to jump to the preamble reading state + incoming->bytes_remaining = preamble_sizes[PACKET_TYPE_TO_INDEX(type)]; + memset(incoming->preamble, 0, PREAMBLE_BUFFER_SIZE); + incoming->index = 0; + incoming->state = PREAMBLE; + // INTENTIONAL FALLTHROUGH + case PREAMBLE: + incoming->preamble[incoming->index] = byte; + incoming->index++; + incoming->bytes_remaining--; + + if (incoming->bytes_remaining == 0) { + // For event and sco preambles, the last byte we read is the length + incoming->bytes_remaining = (type == DATA_TYPE_ACL) ? RETRIEVE_ACL_LENGTH(incoming->preamble) : byte; + + size_t buffer_size = BT_HDR_SIZE + incoming->index + incoming->bytes_remaining; + + if (buffer_size > MCA_USER_RX_BUF_SIZE) { + LOG_ERROR(LOG_TAG, "%s buffer_size(%zu) exceeded allowed packet size, allocation not possible", __func__, buffer_size); + incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)]; + if(create_hw_reset_evt_packet(incoming)) + break; + else + return; + } + + incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size); + + if (!incoming->buffer) { + LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size); + // Can't read any more of this current packet, so jump out + incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE; + break; + } + + // Initialize the buffer + incoming->buffer->offset = 0; + incoming->buffer->layer_specific = 0; + incoming->buffer->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)]; + memcpy(incoming->buffer->data, incoming->preamble, incoming->index); + + incoming->state = incoming->bytes_remaining > 0 ? BODY : FINISHED; + } + + break; + case BODY: + incoming->buffer->data[incoming->index] = byte; + incoming->index++; + incoming->bytes_remaining--; + + size_t bytes_read = hal->read_data(type, (incoming->buffer->data + incoming->index), incoming->bytes_remaining); + incoming->index += bytes_read; + incoming->bytes_remaining -= bytes_read; + + incoming->state = incoming->bytes_remaining == 0 ? FINISHED : incoming->state; + break; + case IGNORE: + incoming->bytes_remaining--; + if (incoming->bytes_remaining == 0) { + incoming->state = BRAND_NEW; + // Don't forget to let the hal know we finished the packet we were ignoring. + // Otherwise we'll get out of sync with hals that embed extra information + // in the uart stream (like H4). #badnewsbears + hal->packet_finished(type); + return; + } + + break; + case FINISHED: + LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__); + break; + } } - } - } else -#endif - { - switch (incoming->state) { - case BRAND_NEW: - // Initialize and prepare to jump to the preamble reading state - incoming->bytes_remaining = preamble_sizes[PACKET_TYPE_TO_INDEX(type)]; - memset(incoming->preamble, 0, PREAMBLE_BUFFER_SIZE); - incoming->index = 0; - incoming->state = PREAMBLE; - // INTENTIONAL FALLTHROUGH - case PREAMBLE: - incoming->preamble[incoming->index] = byte; - incoming->index++; - incoming->bytes_remaining--; - - if (incoming->bytes_remaining == 0) { - // For event and sco preambles, the last byte we read is the length - incoming->bytes_remaining = (type == DATA_TYPE_ACL) ? RETRIEVE_ACL_LENGTH(incoming->preamble) : byte; - - size_t buffer_size = BT_HDR_SIZE + incoming->index + incoming->bytes_remaining; - - if (buffer_size > MCA_USER_RX_BUF_SIZE) { - LOG_ERROR(LOG_TAG, "%s buffer_size(%zu) exceeded allowed packet size, allocation not possible", __func__, buffer_size); - incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)]; - if(create_hw_reset_evt_packet(incoming)) - break; - else - return; - } - - incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size); - - if (!incoming->buffer) { - LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size); - // Can't read any more of this current packet, so jump out - incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE; + } else { + + switch (incoming->state) { + case BRAND_NEW: + // Initialize and prepare to jump to the preamble reading state + incoming->bytes_remaining = preamble_sizes[PACKET_TYPE_TO_INDEX(type)]; + memset(incoming->preamble, 0, PREAMBLE_BUFFER_SIZE); + incoming->index = 0; + incoming->state = PREAMBLE; + // INTENTIONAL FALLTHROUGH + case PREAMBLE: + incoming->preamble[incoming->index] = byte; + incoming->index++; + incoming->bytes_remaining--; + + if (incoming->bytes_remaining == 0) { + // For event and sco preambles, the last byte we read is the length + incoming->bytes_remaining = (type == DATA_TYPE_ACL) ? RETRIEVE_ACL_LENGTH(incoming->preamble) : byte; + + size_t buffer_size = BT_HDR_SIZE + incoming->index + incoming->bytes_remaining; + + if (buffer_size > MCA_USER_RX_BUF_SIZE) { + LOG_ERROR(LOG_TAG, "%s buffer_size(%zu) exceeded allowed packet size, allocation not possible", __func__, buffer_size); + incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)]; + if(create_hw_reset_evt_packet(incoming)) + break; + else + return; + } + + incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size); + + if (!incoming->buffer) { + LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size); + // Can't read any more of this current packet, so jump out + incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE; + break; + } + + // Initialize the buffer + incoming->buffer->offset = 0; + incoming->buffer->layer_specific = 0; + incoming->buffer->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)]; + memcpy(incoming->buffer->data, incoming->preamble, incoming->index); + + incoming->state = incoming->bytes_remaining > 0 ? BODY : FINISHED; + } + break; - } + case BODY: + incoming->buffer->data[incoming->index] = byte; + incoming->index++; + incoming->bytes_remaining--; - // Initialize the buffer - incoming->buffer->offset = 0; - incoming->buffer->layer_specific = 0; - incoming->buffer->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)]; - memcpy(incoming->buffer->data, incoming->preamble, incoming->index); + size_t bytes_read = hal->read_data(type, (incoming->buffer->data + incoming->index), incoming->bytes_remaining); + incoming->index += bytes_read; + incoming->bytes_remaining -= bytes_read; - incoming->state = incoming->bytes_remaining > 0 ? BODY : FINISHED; - } + incoming->state = incoming->bytes_remaining == 0 ? FINISHED : incoming->state; + break; + case IGNORE: + incoming->bytes_remaining--; + if (incoming->bytes_remaining == 0) { + incoming->state = BRAND_NEW; + // Don't forget to let the hal know we finished the packet we were ignoring. + // Otherwise we'll get out of sync with hals that embed extra information + // in the uart stream (like H4). #badnewsbears + hal->packet_finished(type); + return; + } - break; - case BODY: - incoming->buffer->data[incoming->index] = byte; - incoming->index++; - incoming->bytes_remaining--; - - size_t bytes_read = hal->read_data(type, (incoming->buffer->data + incoming->index), incoming->bytes_remaining); - incoming->index += bytes_read; - incoming->bytes_remaining -= bytes_read; - - incoming->state = incoming->bytes_remaining == 0 ? FINISHED : incoming->state; - break; - case IGNORE: - incoming->bytes_remaining--; - if (incoming->bytes_remaining == 0) { - incoming->state = BRAND_NEW; - // Don't forget to let the hal know we finished the packet we were ignoring. - // Otherwise we'll get out of sync with hals that embed extra information - // in the uart stream (like H4). #badnewsbears - hal->packet_finished(type); - return; + break; + case FINISHED: + LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__); + break; } - - break; - case FINISHED: - LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__); - break; - } } if (incoming->state == FINISHED) { -- 2.11.0