am 5faa2a52: New call-in/-back functions for Controller to do vendor-specific shutdown

* commit '5faa2a529b07625c341ee8cee4040c87e030f050':
  New call-in/-back functions for Controller to do vendor-specific shutdown
diff --git a/libbt-vendor/include/bt_vendor_qcom.h b/libbt-vendor/include/bt_vendor_qcom.h
index 31a18d3..23e1167 100644
--- a/libbt-vendor/include/bt_vendor_qcom.h
+++ b/libbt-vendor/include/bt_vendor_qcom.h
@@ -20,6 +20,7 @@
 #include "bt_vendor_lib.h"
 #include "vnd_buildcfg.h"
 #include "userial_vendor.h"
+#include "utils.h"
 
 #ifndef FALSE
 #define FALSE  0
@@ -35,6 +36,22 @@
 extern bt_hci_transport_device_type bt_hci_transport_device;
 
 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
+    process. It calls back to the callers after command complete of HCI_RESET
+    is received.
+
+    Default TRUE .
+*/
+#ifndef HW_NEED_END_WITH_HCI_RESET
+#define HW_NEED_END_WITH_HCI_RESET TRUE
+#endif
+
+#define HCI_RESET  0x0C03
+#define HCI_CMD_PREAMBLE_SIZE 3
+#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE   5
+#define HCI_EVT_CMD_CMPL_OPCODE        3
 
 #endif /* BT_VENDOR_BRCM_H */
 
diff --git a/libbt-vendor/src/bt_vendor_qcom.c b/libbt-vendor/src/bt_vendor_qcom.c
index 53d3e13..b4a59b7 100644
--- a/libbt-vendor/src/bt_vendor_qcom.c
+++ b/libbt-vendor/src/bt_vendor_qcom.c
@@ -46,6 +46,11 @@
 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
 uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
+#if (HW_NEED_END_WITH_HCI_RESET == TRUE)
+void hw_epilog_process(void);
+#endif
+
+
 /******************************************************************************
 **  Local type definitions
 ******************************************************************************/
@@ -167,6 +172,18 @@
 
         case BT_VND_OP_LPM_WAKE_SET_STATE:
             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);
+                }
+#else
+                hw_epilog_process();
+#endif
+            }
+            break;
     }
 
     return retval;
diff --git a/libbt-vendor/src/hardware.c b/libbt-vendor/src/hardware.c
index 5675ce3..45a174b 100644
--- a/libbt-vendor/src/hardware.c
+++ b/libbt-vendor/src/hardware.c
@@ -93,3 +93,88 @@
 
     return (i==0)? FALSE:TRUE;
 }
+
+#if (HW_NEED_END_WITH_HCI_RESET == TRUE)
+/*******************************************************************************
+**
+** Function         hw_epilog_cback
+**
+** Description      Callback function for Command Complete Events from HCI
+**                  commands sent in epilog process.
+**
+** Returns          None
+**
+*******************************************************************************/
+void hw_epilog_cback(void *p_mem)
+{
+    HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
+    char        *p_name, *p_tmp;
+    uint8_t     *p, status;
+    uint16_t    opcode;
+
+    status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
+    p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
+    STREAM_TO_UINT16(opcode,p);
+
+    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);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         hw_epilog_process
+**
+** Description      Sample implementation of epilog process
+**
+** Returns          None
+**
+*******************************************************************************/
+void hw_epilog_process(void)
+{
+    HC_BT_HDR  *p_buf = NULL;
+    uint8_t     *p;
+
+    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);
+    }
+
+    if (p_buf)
+    {
+        p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+        p_buf->offset = 0;
+        p_buf->layer_specific = 0;
+        p_buf->len = HCI_CMD_PREAMBLE_SIZE;
+
+        p = (uint8_t *) (p_buf + 1);
+        UINT16_TO_STREAM(p, HCI_RESET);
+        *p = 0; /* parameter length */
+
+        /* Send command via HC's xmit_cb API */
+        bt_vendor_cbacks->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);
+        }
+    }
+}
+#endif // (HW_NEED_END_WITH_HCI_RESET == TRUE)
+
+