platform: msm_shared: G-Link refactoring for secure processor

Refactor for secure processor.

P4 Changelist: 8487467

Change-Id: Ie5bd8a06769e5a81702e5816702dfc5940dcac6f
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index ab13442..01b18be 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -31,12 +31,13 @@
                         INCLUDE FILES
 ===========================================================================*/
 #include <glink.h>
-#include <glink_rpm.h>
 #include <glink_os_utils.h>
 #include <glink_internal.h>
 #include <glink_vector.h>
-#include <smem_list.h>
-#include <smem_type.h>
+
+#ifdef FEATURE_TRACER_PACKET
+#include "glink_tracer.h"
+#endif
 
 #define GLINK_NOT_INITIALIZED 0
 #define GLINK_INITIALIZED     1
@@ -44,313 +45,9 @@
 /*===========================================================================
                         GLOBAL DATA DECLARATIONS
 ===========================================================================*/
-int glink_core_status = GLINK_NOT_INITIALIZED;
-
-os_cs_type *glink_transport_q_cs[GLINK_NUM_HOSTS];
-os_cs_type *glink_mem_log_cs;
-
-glink_mem_log_entry_type glink_mem_log_arr[GLINK_MEM_LOG_SIZE];
-uint32 glink_mem_log_idx = 0;
-
-/* Keep a list of registered transport for each edge allowed for this host */
-smem_list_type glink_registered_transports[GLINK_NUM_HOSTS];
-
-smem_list_type glink_link_notif_list;
-
-/* List of supported hosts */
-const char* glink_hosts_supported[]   = { "apss",
-                                          "mpss",
-                                          "lpass",
-                                          "dsps",
-                                          "wcnss",
-                                          "tz",
-                                          "rpm",
-                                        };
-
-/* Forward function declarations */
-void glinki_free_intents(glink_channel_ctx_type *open_ch_ctx);
-
 /*===========================================================================
                     LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
-/*===========================================================================
-  FUNCTION      glinki_add_ch_to_xport
-===========================================================================*/
-/**
- * Add remote/local channel context to xport open channel queue
- *
- * @param[in]    if_ptr            Pointer to xport if on which channel is to
- *                                 be opened
- * @param[in]    req_if_ptr        Pointer to xport if on which channel
- *                                 actually wants to open
- * @param[in]    ch_ctx            channel context
- * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
- * @param[in]    local_open        flag to determine if channel is opened
- *                                 locally or remotely
- * @param[in]    prio              negotiated xport priority
- *                                 (used to send priority via remote_open_ack to
- *                                  remote side)
- *
- * @return       pointer to glink_transport_if_type struct
- *
- * @sideeffects  NONE
- */
-/*=========================================================================*/
-glink_err_type glinki_add_ch_to_xport
-(
-  glink_transport_if_type  *if_ptr,
-  glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type  **allocated_ch_ctx,
-  unsigned int              local_open,
-  glink_xport_priority      migrated_ch_prio
-)
-{
-  glink_err_type             status;
-  glink_channel_ctx_type     *open_ch_ctx;
-  glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
-
-  /* See if channel already exists in open_list */
-  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-
-  for( open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-       open_ch_ctx;
-       open_ch_ctx = smem_list_next(open_ch_ctx) )
-  {
-    if( 0 != glink_os_string_compare( open_ch_ctx->name, ch_ctx->name ) ||
-        open_ch_ctx->tag_ch_for_close )
-    {
-      continue;
-    }
-    
-    /* grab lock to avoid race condition for channel state change */
-    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
-
-    if( local_open )
-    {
-      /* LOCAL OPEN REQUEST */
-      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
-
-      glink_os_cs_init( &ch_ctx->tx_cs );
-      glink_os_cs_init(&ch_ctx->qos_cs);
-      glink_os_cs_init( &ch_ctx->ch_state_cs );
-
-      ch_ctx->rcid        = open_ch_ctx->rcid;
-      ch_ctx->lcid        = open_ch_ctx->lcid;
-      ch_ctx->pintents    = open_ch_ctx->pintents;
-      ch_ctx->if_ptr      = open_ch_ctx->if_ptr;
-
-      if (ch_ctx->pintents != NULL)
-      {
-        ch_ctx->pintents->ch_ctx = ch_ctx;
-      }
-
-      ch_ctx->remote_state = open_ch_ctx->remote_state;
-      ch_ctx->local_state  = GLINK_LOCAL_CH_OPENING;
-
-      /* release lock before context switch otherwise it is causing
-       * deadlock */
-      smem_list_delete( &xport_ctx->open_list, open_ch_ctx );
-      smem_list_append( &xport_ctx->open_list, ch_ctx );
-
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
-      glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-      glink_os_free( open_ch_ctx );
-      *allocated_ch_ctx = ch_ctx;
-      /* Send open cmd to transport */
-      status = if_ptr->tx_cmd_ch_open( if_ptr,
-                                       ch_ctx->lcid,
-                                       ch_ctx->name,
-                                       migrated_ch_prio );
-    }
-    else
-    {
-      /* REMOTE OPEN REQUEST */
-
-      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET ||
-          open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLEANUP)
-      {
-        /* During SSR previous channel ctx needs to be destroyed 
-        * new remote/local open request will create new context */
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-        continue;
-      }
-
-      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED );
-
-      open_ch_ctx->rcid = ch_ctx->rcid;
-      *allocated_ch_ctx = open_ch_ctx;
-      status = xport_ctx->channel_init(open_ch_ctx);
-
-      if( status == GLINK_STATUS_SUCCESS )
-      {
-        open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
-      }
-
-      /* release lock before context switch otherwise it is causing deadlock */
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
-      glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-
-      if ( status == GLINK_STATUS_SUCCESS )
-      {
-        /* Send ACK to transport */
-        if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
-                                           open_ch_ctx->rcid,
-                                           migrated_ch_prio );
-
-        /* Inform the client */
-        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED )
-        {
-          open_ch_ctx->notify_state( open_ch_ctx,
-                                     open_ch_ctx->priv,
-                                     GLINK_CONNECTED );
-        }
-      }
-
-      glink_os_free(ch_ctx);
-    } /* end If - else (local_open) */
-
-    return status;
-  } /* end for */
-
-  ASSERT( open_ch_ctx == NULL );
-
-  /* check if a new channel can be added */
-  if ((uint32)smem_list_count(&if_ptr->glink_core_priv->open_list) >= xport_ctx->max_lcid)
-  {
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
-    glink_os_free(ch_ctx);
-    return GLINK_STATUS_OUT_OF_RESOURCES;
-  }
-  
-  /* Channel not in the list - it was not previously opened */
-  ch_ctx->if_ptr = if_ptr;
-  *allocated_ch_ctx = ch_ctx;
-
-  /* Set channel state */
-  if (local_open)
-  {
-    /* This is a local open */
-    ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
-  }
-  else
-  {
-    ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
-  }
-
-  glink_os_cs_init(&ch_ctx->tx_cs);
-  glink_os_cs_init(&ch_ctx->qos_cs);
-  glink_os_cs_init(&ch_ctx->ch_state_cs);
-
-  /* make sure next LCID is not used in currently open channels */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-
-  while (open_ch_ctx)
-  {
-    if (open_ch_ctx->lcid == xport_ctx->free_lcid)
-    {
-  xport_ctx->free_lcid++;
-      
-      if (xport_ctx->free_lcid >= xport_ctx->max_lcid)
-      {
-        xport_ctx->free_lcid = 1;
-      }
-
-      open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-      continue;
-    }
-
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }
-
-  ch_ctx->lcid = xport_ctx->free_lcid;
-
-  /* Append the channel to the transport interface's open_list */
-  smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
-
-  /* release lock before context switch otherwise it is causing deadlock */
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-  /* Send the OPEN command to transport */
-  if ( local_open )
-  {
-    status = if_ptr->tx_cmd_ch_open( if_ptr, ch_ctx->lcid,
-                                     ch_ctx->name,
-                                     migrated_ch_prio );
-  }
-  else
-  {
-    /* initialize channel resources */
-    status = xport_ctx->channel_init(ch_ctx);
-
-    /* ACK the transport for remote open */
-    if (status == GLINK_STATUS_SUCCESS)
-    {
-      if_ptr->tx_cmd_ch_remote_open_ack( if_ptr, ch_ctx->rcid,
-                                         migrated_ch_prio );
-    }
-  }
-
-  if (status != GLINK_STATUS_SUCCESS)
-  {
-    /* Remove the channel from the transport interface's open_list */
-    xport_ctx->free_lcid--;
-    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-    smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-    /* free the ch_ctx structure and return */
-    xport_ctx->channel_cleanup(ch_ctx);
-    glink_os_free(ch_ctx);
-  }
-
-  return status;
-}
-
-/*===========================================================================
-  FUNCTION      glink_is_channel_fully_opened
-===========================================================================*/
-/**
- * Check whether this channel is fully opened or not (local & remote)
- * This also checks transport status
- *
- * @param[in]  handle        glink channel handle
- * @param[in]  xport_ctx     glink transport core private
- *
- * @return     TRUE,  if channel is fully opened
- *             FASLE, otherwise
- *
- * @sideeffects  NONE
- */
-/*=========================================================================*/
-static boolean glink_is_channel_fully_opened
-(
-  glink_handle_type          handle,
-  glink_core_xport_ctx_type *xport_ctx
-)
-{
-  boolean ch_fully_opened = TRUE;
-
-  glink_os_cs_acquire( &handle->ch_state_cs );
-
-  if( handle->local_state != GLINK_LOCAL_CH_OPENED ||
-      handle->remote_state != GLINK_REMOTE_CH_OPENED )
-  {
-    ch_fully_opened = FALSE;
-  }
-
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-  if( xport_ctx->status != GLINK_XPORT_LINK_UP )
-  {
-    ch_fully_opened = FALSE;
-  }
-
-  glink_os_cs_release( &xport_ctx->status_cs );
-  glink_os_cs_release( &handle->ch_state_cs );
-
-  return ch_fully_opened;
-}
 
 /** Default implementation of optional callbacks */
 static void glink_default_notify_rx_sigs
@@ -361,591 +58,16 @@
   uint32             curr
 )
 {
+  (void)handle;
+  (void)priv;
+  (void)prev;
+  (void)curr;
   return;
 }
 
-static void glinki_call_link_notifier
-(
-  glink_link_notif_data_type *link_notif_data,
-  glink_core_xport_ctx_type  *xport_ctx,
-  glink_link_state_type      state
-)
-{
-  glink_link_info_type link_info;
-
-  ASSERT(xport_ctx);
-  ASSERT(link_notif_data);
-
-  link_info.xport = xport_ctx->xport;
-  link_info.remote_ss = xport_ctx->remote_ss;
-  link_info.link_state = state;
-  link_notif_data->link_notifier(&link_info, link_notif_data->priv);
-}
-
-uint32 glinki_find_remote_host
-(
-  const char *remote_ss
-)
-{
-  uint32 remote_host;
-  ASSERT(remote_ss);
-
-  for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++)
-  {
-    if( 0 == glink_os_string_compare( glink_hosts_supported[remote_host],
-                                      remote_ss ) )
-    {
-      /* Match found, break out of loop */
-      break;
-    }
-  }
-  return remote_host;
-}
-
-static void glinki_check_xport_and_notify
-(
-  glink_link_notif_data_type *link_notif_data,
-  glink_core_xport_ctx_type  *xport_ctx,
-  glink_link_state_type      state
-)
-{
-  ASSERT(xport_ctx);
-  ASSERT(link_notif_data);
-
-  if( link_notif_data->xport == NULL ||
-      0 == glink_os_string_compare( xport_ctx->xport, link_notif_data->xport ) )
-  {
-    /* xport not specified, or it is specified and matches the current xport */
-    /* Invoke registered callback */
-    glinki_call_link_notifier(link_notif_data, xport_ctx, state);
-  }
-}
-
-static void glinki_scan_xports_and_notify
-(
-  glink_link_notif_data_type *link_notif_data
-)
-{
-  unsigned int remote_host;
-  glink_transport_if_type *if_ptr;
-  glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(link_notif_data);
-
-  /* Find matching subsystem */
-  for(remote_host = 0;
-      remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-      remote_host++)
-  {
-    if ( link_notif_data->remote_ss != NULL &&
-         0 != glink_os_string_compare( glink_hosts_supported[remote_host],
-                                       link_notif_data->remote_ss ) )
-    {
-      /* client is not interested in this remote SS */
-      continue;
-    }
-
-    /* Find the xport and give link UP notification */
-    for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-         if_ptr != NULL;
-         if_ptr = smem_list_next(if_ptr))
-    {
-      xport_ctx = if_ptr->glink_core_priv;
-
-      if (xport_ctx->status == GLINK_XPORT_LINK_UP)
-      {
-        /* Invoke registered callback */
-        glinki_check_xport_and_notify( link_notif_data, xport_ctx,
-                                       GLINK_LINK_STATE_UP );
-      }
-    }
-  } /* end for remote_host */
-} /* glinki_scan_xports_and_notify */
-
-void glinki_scan_notif_list_and_notify
-(
-  glink_transport_if_type *if_ptr,
-  glink_link_state_type state
-)
-{
-  glink_link_notif_data_type *link_notif_data;
-  glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
-
-  for (link_notif_data = smem_list_first(&glink_link_notif_list);
-       link_notif_data != NULL;
-       link_notif_data = smem_list_next(link_notif_data))
-  {
-    if( link_notif_data->remote_ss == NULL ||
-        0 == glink_os_string_compare( xport_ctx->remote_ss,
-                                      link_notif_data->remote_ss ) )
-    {
-      glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-    }
-  }
-} /* glinki_scan_notif_list_and_notify */
-
-void glinki_scan_channels_and_notify_discon
-(
-  glink_transport_if_type *if_ptr
-)
-{
-  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
-  glink_core_xport_ctx_type  *xport_ctx;
-  glink_remote_state_type     remote_state;
-
-  ASSERT(if_ptr != NULL);
-
-  xport_ctx = if_ptr->glink_core_priv;
-
-  /* Find channel in the open_list */
-  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while( open_ch_ctx )
-  {
-    glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-    open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
-    glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-
-    dummy_open_ch_ctx = smem_list_next( open_ch_ctx );
-
-    switch( open_ch_ctx->local_state )
-    {
-      case GLINK_LOCAL_CH_OPENED:
-      case GLINK_LOCAL_CH_OPENING:
-        /* local channel has called open at the moment. */
-        open_ch_ctx->notify_state( open_ch_ctx,
-                                   open_ch_ctx->priv,
-                                   GLINK_REMOTE_DISCONNECTED );
-        break;
-
-      case GLINK_LOCAL_CH_CLOSING:
-        /* Case when local client already closed channel
-         * but has not received ack yet */
-        if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( if_ptr,
-                                                        open_ch_ctx->lcid );
-        break;
-
-      case GLINK_LOCAL_CH_CLOSED:
-        /* Channel fully closed - local, remote */
-        glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
-        xport_ctx->channel_cleanup(open_ch_ctx);
-        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
-        remote_state = open_ch_ctx->remote_state;
-        glink_os_cs_release(&open_ch_ctx->ch_state_cs);
-
-        if (remote_state != GLINK_REMOTE_CH_CLEANUP)
-        {
-        glink_os_free(open_ch_ctx);
-        }
-        break;
-
-      default:
-        /* invalid local channel state */
-        ASSERT(0);
-    }
-
-    open_ch_ctx = dummy_open_ch_ctx;
-
-  } /* end while */
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-}
-
-void glink_ssr(const char* remote_ss)
-{
-  unsigned int remote_host;
-  glink_transport_if_type *if_ptr;
-
-  remote_host = glinki_find_remote_host(remote_ss);
-
-  /* Scan through the registered interfaces with the crashing ss
-     and let the clients know about the crash via LINK_DOWN
-     notification followed by REMOTE_DISCONNECT */
-  if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-
-  while(if_ptr != NULL)
-  {
-    /* xport is down. change the xport state */
-    glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
-    if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
-
-    /* Let the xport know about ssr */
-    if_ptr->ssr( if_ptr );
-
-    /* Invoke LINK_DOWN notification for any registered notifiers */
-    glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
-
-    /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
-    glinki_scan_channels_and_notify_discon(if_ptr);
-
-    glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
-
-    if_ptr = smem_list_next(if_ptr);
-  }
-}
-
-
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
-/*===========================================================================
-FUNCTION      glink_init
-
-DESCRIPTION   Initializes the GLink core library.
-
-ARGUMENTS     None
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_init(void)
-{
-  uint32 i;
-
-  glink_mem_log_cs = glink_os_cs_create();
-
-  /* Create/Initalize crtitical sections */
-  for(i= 0; i < sizeof(glink_registered_transports)/sizeof(smem_list_type);
-      i++)
-  {
-    glink_transport_q_cs[i] = glink_os_cs_create();
-    ASSERT( glink_transport_q_cs[i] != NULL );
-    smem_list_init(&glink_registered_transports[i]);
-  }
-  
-  glink_core_status = GLINK_INITIALIZED;
-}
-
-/*===========================================================================
-FUNCTION      glink_core_register_transport
-
-DESCRIPTION   Transport calls this API to register its interface with GLINK
-              Core
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            *cfg      Pointer to transport configuration structure.
-
-RETURN VALUE  Standard GLINK error codes.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_err_type glink_core_register_transport
-(
-  glink_transport_if_type       *if_ptr,
-  glink_core_transport_cfg_type *cfg
-)
-{
-  unsigned int remote_host = 0;
-  glink_core_xport_ctx_type *xport_ctx;
-  /* Param validation */
-  if(if_ptr == NULL || cfg == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  if(cfg->name == NULL       ||
-     cfg->remote_ss == NULL  ||
-     cfg->version == NULL    ||
-     cfg->version_count == 0 ||
-     cfg->max_cid == 0)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-
-  if(if_ptr->tx_cmd_version == NULL             ||
-     if_ptr->tx_cmd_version_ack == NULL         ||
-     if_ptr->set_version == NULL                ||
-     if_ptr->tx_cmd_ch_open == NULL             ||
-     if_ptr->tx_cmd_ch_close == NULL            ||
-     if_ptr->tx_cmd_ch_remote_open_ack == NULL  ||
-     if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
-     if_ptr->ssr  == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-        cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;;
-  }
-
-  remote_host = glinki_find_remote_host(cfg->remote_ss);
-
-  if(remote_host == GLINK_NUM_HOSTS ) {
-    /* Unknown transport name trying to register with GLink */
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-           cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
-
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  /* Set the glink_core_if_ptr to point to the default interface */
-  if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
-
-  /* Allocate/fill out the GLink private context data */
-  {
-     xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
-    if(xport_ctx == NULL) {
-      /* Free previously allocated memory */
-      glink_os_free(if_ptr->glink_core_if_ptr);
-
-      GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-          cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
-
-      return GLINK_STATUS_OUT_OF_RESOURCES;
-    }
-
-    xport_ctx->xport = cfg->name;
-    xport_ctx->remote_ss = cfg->remote_ss;
-    xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
-    xport_ctx->max_lcid = cfg->max_cid; /* Max channel ID supported by transport */
-    xport_ctx->version_array = cfg->version;
-    xport_ctx->version_indx = cfg->version_count - 1;
-
-    glink_os_cs_init(&xport_ctx->channel_q_cs);
-    glink_os_cs_init(&xport_ctx->liid_cs);
-    glink_os_cs_init(&xport_ctx->status_cs);
-
-    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-    smem_list_init(&xport_ctx->open_list);
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-    /* Set the glink_core_if_ptr to point to the allocated structure */
-    if_ptr->glink_core_priv = xport_ctx;
-    xport_ctx->status = GLINK_XPORT_REGISTERED;
-  }
-
-  /* Push the transport interface into appropriate queue */
-  glink_os_cs_acquire( glink_transport_q_cs[remote_host] );
-  smem_list_append(&glink_registered_transports[remote_host], if_ptr);
-  glink_os_cs_release( glink_transport_q_cs[remote_host] );
-
-  GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * Regsiters a client specified callback to be invoked when the specified
- * transport (link) is up/down.
- *
- * @param[in]    link_id  Pointer to the configuration structure for the
- *                        xport(link) to be monitored. See glink.h
- * @param[in]    priv     Callback data returned to client when callback
- *                        is invoked.
- *
- * @return       Standard GLink error codes
- *
- * @sideeffects  Puts the callback in a queue which gets scanned when a
- *               transport(link) comes up OR an SSR happnes.
- */
-glink_err_type glink_register_link_state_cb
-(
-  glink_link_id_type *link_id,
-  void*              priv
-)
-{
-  glink_link_notif_data_type* link_notif_data;
-  unsigned int remote_host;
-
-  /* Input validation */
-  ASSERT(link_id != NULL);
-
-  /* Make sure client provided us with the correct version of the input
-   * structure */
-  if(link_id->version != GLINK_LINK_ID_VER || link_id->link_notifier == NULL) {
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  /* Save the callback on the notification list */
-  if((link_notif_data = glink_os_malloc(sizeof(glink_link_notif_data_type)))
-       == NULL) {
-    return GLINK_STATUS_OUT_OF_RESOURCES;
-  }
-
-  /* Check for remote_ss validity */
-  if(link_id->remote_ss != NULL) {
-    remote_host = glinki_find_remote_host(link_id->remote_ss);
-
-    if(remote_host == sizeof(glink_hosts_supported)/sizeof(char *)) {
-      glink_os_free(link_notif_data);
-      return GLINK_STATUS_INVALID_PARAM;
-    }
-  }
-
-  link_notif_data->xport = link_id->xport;
-  link_notif_data->remote_ss = link_id->remote_ss;
-  link_notif_data->link_notifier = link_id->link_notifier;
-  link_notif_data->priv = priv; /* private client data */
-
-  /* Append the request to the list for link UP/DOWN notifications */
-  smem_list_append(&glink_link_notif_list, link_notif_data);
-
-  link_id->handle = (glink_link_handle_type)link_notif_data;
-
-  /* Scan the list of available transport to see if this link is already up */
-  glinki_scan_xports_and_notify(link_notif_data);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * Degsiter the link UP/DOWN notification callback associated with the
- * provided handle.
- *
- * @param[in]    handle  Callback handler returned by
- *                       glink_register_link_state_cb
- *
- * @return       Standard GLink error codes
- *
- * @sideeffects  Removes the callback in a queue which gets scanned when a
- *               transport(link) comes up OR an SSR happnes.
- */
-glink_err_type glink_deregister_link_state_cb
-(
-  glink_link_handle_type handle
-)
-{
-  /* check if glink handle is NULL and return appropriate
-     return code  */
-  if(handle == NULL)
-  {
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  smem_list_delete(&glink_link_notif_list,
-                   (glink_link_notif_data_type*)handle);
-
-  glink_os_free(handle);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * This function gives best available transport for give edge
- *
- * @param[in]    remote_host  Index into glink_registered_transports array of
- *                            registered transports list per edge
- *
- * @return       pointer to glink_transport_if_type
- *
- * @sideeffects  NONE
- */
-glink_transport_if_type* glink_get_best_xport
-(
-  unsigned int remote_host
-)
-{
-  glink_transport_if_type   *if_ptr    = NULL, *best_if_ptr = NULL;
-  glink_xport_priority       priority  = GLINK_MIN_PRIORITY;
-  glink_core_xport_ctx_type *xport_ctx = NULL;
-
-  glink_os_cs_acquire( glink_transport_q_cs[remote_host] );
-  
-  best_if_ptr = if_ptr = smem_list_first(
-                          &glink_registered_transports[remote_host]);
-
-  while(if_ptr != NULL)
-  {
-    xport_ctx = if_ptr->glink_core_priv;
-    /* check if priority of current transport is higher than
-     * current highest priority (0 = highest priority)
-     */
-    if( xport_ctx->status == GLINK_XPORT_LINK_UP &&
-        if_ptr->glink_priority < priority )
-    {
-      best_if_ptr = if_ptr;
-      priority    = if_ptr->glink_priority;
-    }
-    if_ptr = smem_list_next(if_ptr);
-  } /* end while() */
-
-  glink_os_cs_release( glink_transport_q_cs[remote_host] );
-  
-  return best_if_ptr;
-}
-
-/*===========================================================================
-  FUNCTION      glinki_find_requested_xport
-===========================================================================*/
-/** 
- * Find requested or best transport depending on client's request
- *
- * @param[in]    xport_name         name of transport
- * @param[in]    remote_host        remote host ID
- * @param[in]    open_ch_option     option client gave when called glink_open
- * @param[out]   suggested_priority best xport priority glink suggests
- *
- * @return       pointer to glink_transport_if_type struct
- *
- * @sideeffects  NONE
- */
-/*=========================================================================*/
-glink_transport_if_type *glinki_find_requested_xport
-(
-  const char           *xport_name,
-  uint32                remote_host,
-  uint32                open_ch_option,
-  glink_xport_priority *suggested_priority
-)
-{
-  glink_transport_if_type *if_ptr;
-  glink_transport_if_type *xport_found = NULL;
-  
-  *suggested_priority = GLINK_INVALID_PRIORITY;
-
-  if( !xport_name )
-  {
-    xport_found = glink_get_best_xport( remote_host );
-    if( xport_found )
-    {
-      *suggested_priority = xport_found->glink_priority;
-    }
-
-    return xport_found;
-  }
-  
-  glink_os_cs_acquire( glink_transport_q_cs[remote_host] );
-  
-  /* Check to see if requested transport is available */
-  for( if_ptr = smem_list_first( &glink_registered_transports[remote_host] );
-       if_ptr != NULL;
-       if_ptr = smem_list_next( if_ptr ) )
-  {
-    glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
-    
-    if( xport_ctx->status != GLINK_XPORT_LINK_UP ||
-        ( 0 != glink_os_string_compare( xport_name, xport_ctx->xport ) ) )
-    {
-      continue;
-    }
-
-    xport_found = if_ptr;
-    
-    if( ( open_ch_option & GLINK_OPT_INITIAL_XPORT ) != 0 )
-    {
-      if_ptr = glink_get_best_xport( remote_host );
-      *suggested_priority = if_ptr->glink_priority;
-    }
-    else
-    {
-      /* Client is not willing to migrate to better transport */
-      *suggested_priority = xport_found->glink_priority;
-    }
-    
-    break;
-  }
-
-  glink_os_cs_release( glink_transport_q_cs[remote_host] );
-  
-  return xport_found; 
-}
-
 
 /**
  * Opens a logical GLink based on the specified config params
@@ -973,14 +95,8 @@
   glink_err_type           status;
 
   /* Param validation */
-  if(cfg_ptr == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  if(cfg_ptr->remote_ss == NULL             ||
+  if(cfg_ptr == NULL            ||
+     cfg_ptr->remote_ss == NULL ||
      cfg_ptr->name == NULL                  ||
      cfg_ptr->notify_state == NULL)
   {
@@ -992,7 +108,8 @@
   /* Evaluate the equivalent edge name->enum for future use */
   remote_host = glinki_find_remote_host(cfg_ptr->remote_ss);
 
-  if(remote_host == GLINK_NUM_HOSTS ) {
+  if (remote_host == GLINK_NUM_HOSTS)
+  {
     /* Unknown transport name trying to register with GLink */
     GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, cfg_ptr->name, "",
         cfg_ptr->remote_ss, GLINK_STATUS_INVALID_PARAM);
@@ -1022,13 +139,14 @@
   ch_ctx->notify_rx_abort = cfg_ptr->notify_rx_abort;
   ch_ctx->notify_tx_abort = cfg_ptr->notify_tx_abort;
 
-  if (ch_ctx->notify_rx_sigs == NULL) {
+  if (ch_ctx->notify_rx_sigs == NULL)
+  {
     /* set default callback */
     ch_ctx->notify_rx_sigs = glink_default_notify_rx_sigs;
   }
 
   if_ptr = glinki_find_requested_xport( cfg_ptr->transport, 
-                                        remote_host,
+                                       cfg_ptr->remote_ss,
                                         cfg_ptr->options,
                                         &suggested_priority );
 
@@ -1093,6 +211,14 @@
     return GLINK_STATUS_INVALID_PARAM;
   }
 
+  if (!glinki_xport_linkup(handle->if_ptr))
+  {
+    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+      xport_ctx->remote_ss, handle->local_state);
+
+    return GLINK_STATUS_FAILURE;
+  }
+  
   /* get xport context after NULL check */
   xport_ctx = handle->if_ptr->glink_core_priv;
 
@@ -1100,8 +226,8 @@
   glink_os_cs_acquire( &handle->ch_state_cs );
 
   /* Check to see if closed called again for same channel */
-  if ( handle->local_state == GLINK_LOCAL_CH_CLOSING ||
-       handle->local_state == GLINK_LOCAL_CH_CLOSED )
+  if (handle->local_state != GLINK_LOCAL_CH_OPENED &&
+      handle->local_state != GLINK_LOCAL_CH_OPENING)
   {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
       xport_ctx->remote_ss, handle->local_state);
@@ -1113,13 +239,9 @@
 
   handle->local_state = GLINK_LOCAL_CH_CLOSING;
 
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-
-  if( GLINK_XPORT_LINK_UP != xport_ctx->status ||
-      handle->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+  if (handle->remote_state == GLINK_REMOTE_CH_SSR_RESET)
   {
     /* SSR happened on remote-SS. Fake close_ack from here */
-    glink_os_cs_release( &xport_ctx->status_cs );
     glink_os_cs_release( &handle->ch_state_cs );
 
     handle->if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( handle->if_ptr,
@@ -1129,7 +251,6 @@
   }
   else
   {
-    glink_os_cs_release( &xport_ctx->status_cs );
     glink_os_cs_release( &handle->ch_state_cs );
 
     status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
@@ -1214,7 +335,8 @@
 
   /* Input validation */
   if(handle == NULL || iovec == NULL || size == 0 ||
-     (vprovider == NULL && pprovider == NULL)) {
+     (vprovider == NULL && pprovider == NULL))
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
@@ -1222,7 +344,7 @@
 
   xport_ctx = handle->if_ptr->glink_core_priv;
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
     GLINK_LOG_EVENT( GLINK_EVENT_CH_TX,
                      handle->name,
@@ -1263,6 +385,13 @@
     pctx->iovec = iovec;
   }
 
+#ifdef FEATURE_TRACER_PACKET
+  pctx->tracer_pkt = options & GLINK_TX_TRACER_PKT ? TRUE : FALSE;
+  if( pctx->tracer_pkt )
+  {
+    glink_tracer_packet_log_pctx_pkt( pctx, GLINK_CORE_TX );
+  }
+#endif
 
   status = xport_ctx->channel_submit_pkt(handle, pctx, req_intent);
 
@@ -1295,22 +424,26 @@
 {
   glink_err_type         status;
   glink_rx_intent_type   *lc_intent;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+  glink_core_xport_ctx_type *xport_ctx; 
   size_t tmp;
 
   /* Input validation */
-  if(handle == NULL || size == 0) {
+  if(handle == NULL || size == 0)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
 
+  xport_ctx = handle->if_ptr->glink_core_priv;
+  
   /* short circuit for intentless mode */
-  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
+  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS)
+  {
     return GLINK_STATUS_FAILURE;
   }
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
     GLINK_LOG_EVENT( GLINK_EVENT_CH_Q_RX_INTENT,
                      handle->name,
@@ -1323,47 +456,49 @@
 
   /* Allocate an intent structure */
   lc_intent = glink_os_calloc(sizeof(glink_rx_intent_type));
-  if(lc_intent == NULL) {
+  if(lc_intent == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
         xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
     return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
-  glink_os_cs_acquire(&handle->if_ptr->glink_core_priv->liid_cs);
-
   /* Call transport API to allocate rx intent buffer */
   status = handle->if_ptr->allocate_rx_intent(handle->if_ptr, size, lc_intent);
-  if(status != GLINK_STATUS_SUCCESS) {
+  if(status != GLINK_STATUS_SUCCESS)
+  {
     glink_os_free(lc_intent);
-    glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
     GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
         xport_ctx->remote_ss, status);
     return status;
   }
 
   if (handle->notify_rxv == NULL &&
-     (lc_intent->vprovider(lc_intent->iovec, 0, &tmp) == NULL || tmp < size)) {
+     (lc_intent->vprovider(lc_intent->iovec, 0, &tmp) == NULL || tmp < size))
+  {
     /* Allocate bounce buffer for non-vectored Rx */
     lc_intent->data = glink_os_malloc(size);
 
-    if(lc_intent->data == NULL) {
+    if(lc_intent->data == NULL)
+    {
       handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
       glink_os_free(lc_intent);
-      glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
       GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name,
         xport_ctx->xport, xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
       return GLINK_STATUS_OUT_OF_RESOURCES;
     }
   }
 
+  glink_os_cs_acquire(&handle->if_ptr->glink_core_priv->liid_cs);
+  
   /* push the intent on local queue. Do this before calling tx cmd
      as transport may try to read data into the newly queued rx_buffer */
   lc_intent->iid = handle->if_ptr->glink_core_priv->liid;
   lc_intent->size = size;
   lc_intent->pkt_priv = pkt_priv;
-  glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-  smem_list_append(&handle->pintents->local_intent_q, lc_intent);
-  glink_os_cs_release(&handle->pintents->intent_q_cs);
+  glinki_enqueue_item(&handle->pintents->local_intent_q,
+                      lc_intent,
+                      &handle->pintents->intent_q_cs);
 
   /* Call transport API to queue rx intent */
   /* Increment the local intent ID counter associated with this channel */
@@ -1371,11 +506,12 @@
 
   status = handle->if_ptr->tx_cmd_local_rx_intent(handle->if_ptr,
               handle->lcid, size, lc_intent->iid);
-  if(status != GLINK_STATUS_SUCCESS) {
+  if(status != GLINK_STATUS_SUCCESS)
+  {
     /* Failure */
-    glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-    smem_list_delete(&handle->pintents->local_intent_q, lc_intent);
-    glink_os_cs_release(&handle->pintents->intent_q_cs);
+    glinki_dequeue_item(&handle->pintents->local_intent_q,
+                        lc_intent,
+                        &handle->pintents->intent_q_cs);
 
     handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
     glink_os_free(lc_intent->data);
@@ -1414,18 +550,20 @@
   glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
 
   /* Input validation */
-  if(handle == NULL || ptr == NULL) {
+  if(handle == NULL || ptr == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
 
   /* short circuit for intentless mode */
-  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
+  if (xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS)
+  {
     return GLINK_STATUS_SUCCESS;
   }
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
     GLINK_LOG_EVENT( GLINK_EVENT_CH_RX_DONE,
                      handle->name,
@@ -1438,19 +576,21 @@
 
   /* Free the intent */
   lc_intent = smem_list_first(&handle->pintents->local_intent_client_q);
-  while(lc_intent != NULL) {
+  while(lc_intent != NULL)
+  {
     size_t tmp;
 
     if(lc_intent->iovec == ptr || (handle->notify_rxv == NULL &&
        (lc_intent->data == ptr ||
-       ptr == lc_intent->vprovider(lc_intent->iovec, 0, &tmp)))) {
+       ptr == lc_intent->vprovider(lc_intent->iovec, 0, &tmp))))
+    {
 
       uint32 iid;
 
       /* Found intent, delete it */
-      glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-      smem_list_delete(&handle->pintents->local_intent_client_q, lc_intent);
-      glink_os_cs_release(&handle->pintents->intent_q_cs);
+      glinki_dequeue_item(&handle->pintents->local_intent_client_q,
+                          lc_intent,
+                          &handle->pintents->intent_q_cs);
 
       iid = lc_intent->iid;
 
@@ -1458,15 +598,17 @@
       {
         lc_intent->used = 0;
 
-        glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-        smem_list_append(&handle->pintents->local_intent_q, lc_intent);
-        glink_os_cs_release(&handle->pintents->intent_q_cs);
+        glinki_enqueue_item(&handle->pintents->local_intent_q,
+                            lc_intent,
+                            &handle->pintents->intent_q_cs);
+        
       }
       else
       {
         /* Free the intent */
         handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
-        if(lc_intent->data) {
+        if(lc_intent->data)
+        {
           /* Free the bounce buffer if we had allocated one */
           glink_os_free(lc_intent->data);
         }
@@ -1476,8 +618,10 @@
       /* Note that the actual buffer, lc_intent->data, was allocated by the
       * transport and should be freed by the xport. We should not touch it */
       /* Let the xport know we are done with the buffer */
-      handle->if_ptr->tx_cmd_local_rx_done(handle->if_ptr, handle->lcid,
-                                           iid, reuse);
+      handle->if_ptr->tx_cmd_local_rx_done(handle->if_ptr,
+                                           handle->lcid,
+                                           iid,
+                                           reuse);
 
       GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
           xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
@@ -1514,7 +658,8 @@
   glink_err_type status;
 
   /* Input validation */
-  if(handle == NULL) {
+  if(handle == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
@@ -1522,7 +667,7 @@
 
   xport_ctx = handle->if_ptr->glink_core_priv;
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
     GLINK_LOG_EVENT( GLINK_EVENT_CH_SIG_SET,
                      handle->name,
@@ -1533,9 +678,11 @@
     return GLINK_STATUS_FAILURE;
   }
 
-  status = handle->if_ptr->tx_cmd_set_sigs(handle->if_ptr, handle->lcid,
+  status = handle->if_ptr->tx_cmd_set_sigs(handle->if_ptr,
+                                           handle->lcid,
                                            sig_value);
-  if(GLINK_STATUS_SUCCESS == status) {
+  if(GLINK_STATUS_SUCCESS == status)
+  {
     /* Update local copy of local control signal state */
     handle->local_sigs = sig_value;
   }
@@ -1561,7 +708,8 @@
 )
 {
   /* Input validation */
-  if(handle == NULL || sig_value == NULL) {
+  if(handle == NULL || sig_value == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_L_GET, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
@@ -1590,7 +738,8 @@
 )
 {
   /* Input validation */
-  if(handle == NULL || sig_value == NULL) {
+  if(handle == NULL || sig_value == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_R_GET, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
@@ -1601,6 +750,100 @@
   return GLINK_STATUS_SUCCESS;
 }
 
+/** 
+ * Regsiters a client specified callback to be invoked when the specified
+ * transport (link) is up/down.
+ *
+ * @param[in]    link_id  Pointer to the configuration structure for the
+ *                        xport(link) to be monitored. See glink.h
+ * @param[in]    priv     Callback data returned to client when callback
+ *                        is invoked.
+ *
+ * @return       Standard GLink error codes
+ *
+ * @sideeffects  Puts the callback in a queue which gets scanned when a 
+ *               transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_register_link_state_cb
+(
+  glink_link_id_type *link_id,
+  void*              priv
+)
+{
+  glink_link_notif_data_type* link_notif_data;
+  unsigned int remote_host;
+
+  /* Input validation */
+  if (link_id == NULL ||
+      link_id->version != GLINK_LINK_ID_VER ||
+      link_id->link_notifier == NULL)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  /* Check for remote_ss validity */
+  if (link_id->remote_ss != NULL)
+  {
+    remote_host = glinki_find_remote_host(link_id->remote_ss);
+    if (remote_host == GLINK_NUM_HOSTS)
+    {
+      return GLINK_STATUS_INVALID_PARAM;
+    }
+  }
+  
+  /* Save the callback on the notification list */
+  if((link_notif_data = glink_os_calloc(sizeof(glink_link_notif_data_type)))
+       == NULL)
+  {
+    return GLINK_STATUS_OUT_OF_RESOURCES;
+  }
+
+  link_notif_data->xport = link_id->xport;
+  link_notif_data->remote_ss = link_id->remote_ss;
+  link_notif_data->link_notifier = link_id->link_notifier;
+  link_notif_data->priv = priv; /* private client data */
+
+  /* Append the request to the list for link UP/DOWN notifications */
+  glinki_register_link_notif_data(link_notif_data);
+  link_id->handle = (glink_link_handle_type)link_notif_data;
+  
+  /* Scan the list of available transport to see if this link is already up */
+  glinki_scan_xports_and_notify(link_notif_data);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
+/** 
+ * Degsiter the link UP/DOWN notification callback associated with the
+ * provided handle.
+ *
+ * @param[in]    handle  Callback handler returned by 
+ *                       glink_register_link_state_cb
+ *
+ * @return       Standard GLink error codes
+ *
+ * @sideeffects  Removes the callback in a queue which gets scanned when a 
+ *               transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_deregister_link_state_cb
+(
+  glink_link_handle_type handle
+)
+{
+  /* check if glink handle is NULL and return appropriate
+     return code  */
+  if(handle == NULL) 
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  glinki_deregister_link_notif_data((glink_link_notif_data_type *)handle);
+  
+  glink_os_free(handle);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
 /*================= RESTRICTED API ==========================*/
 
 /**
@@ -1619,7 +862,10 @@
   glink_handle_type handle
 )
 {
-  ASSERT(handle);
+  if (!handle)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
 
   if(handle->if_ptr->poll) {
     return handle->if_ptr->poll(handle->if_ptr);
@@ -1648,7 +894,10 @@
   void              *platform_struct
 )
 {
-  ASSERT(handle);
+  if (!handle)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
 
   if(handle->if_ptr->mask_rx_irq) {
     return handle->if_ptr->mask_rx_irq(handle->if_ptr, mask);
@@ -1675,20 +924,3 @@
   return handle->if_ptr->wait_link_down(handle->if_ptr) ?
          GLINK_STATUS_SUCCESS : GLINK_STATUS_FAILURE;
 }
-
-/* ============ Internal Logging API ================ */
-void glink_mem_log
-(
-  const char *func,
-  uint32 line,
-  glink_log_event_type type,
-  const char *msg,
-  const char *xport,
-  const char *remote_ss,
-  uint32 param
-)
-{
-#ifdef DEBUG_GLINK
-  dprintf(INFO, "%s:%u, event:%d, msg:%s, xport:%s, remote_ss:%s, param:%u\n", func, line, type, msg, xport, remote_ss, param);
-#endif
-}
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 3a71422..fd68071 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -34,20 +34,12 @@
 #include "glink_os_utils.h"
 #include "glink.h"
 #include "glink_internal.h"
-#include "smem_list.h"
 
 #define FEATURE_CH_MIGRATION_FREE
 
 /*===========================================================================
                         GLOBAL FUNCTION DECLARATIONS
-==========================================================================*/
-extern void glinki_scan_notif_list_and_notify
-(
-  glink_transport_if_type *if_ptr,
-  glink_link_state_type state
-);
-
-
+===========================================================================*/
 /*===========================================================================
                      LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -86,16 +78,11 @@
    * Only go through process once in case they are negotiated
    * in ver_req before receiving ver_ack */
 
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-
-  if( xport_ctx->status == GLINK_XPORT_LINK_UP )
+  if (glinki_xport_linkup(if_ptr))
   {
-    glink_os_cs_release( &xport_ctx->status_cs );
     return;
   }
 
-  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
-
   /* setup core based on transport capabilities*/
   xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
                                                        version,
@@ -105,7 +92,7 @@
   /* transport is ready to open channels */
   glink_os_cs_acquire( &xport_ctx->status_cs );
   if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
-  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+  glink_os_cs_release(&xport_ctx->status_cs);
 
   /* Scan the notification list to check is we have to let any registered
    * clients know that link came online */
@@ -149,6 +136,35 @@
 }
 
 /*===========================================================================
+  FUNCTION      glink_get_current_version
+===========================================================================*/
+/**
+
+  Get current version/feature. This is necessarily highest version.
+
+  @param[in]     xport_ctx    transport context
+  
+  @return        pointer to version/feature if available.
+                 NULL otherwise.
+  
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
+static const glink_core_version_type *glink_get_current_version
+(
+  glink_core_xport_ctx_type *xport_ctx
+)
+{
+  const glink_core_version_type *ver
+    = &xport_ctx->version_array[xport_ctx->version_indx];
+  
+  ASSERT(ver);
+  
+  return ver;
+}
+
+/*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 /*===========================================================================
@@ -171,14 +187,12 @@
   glink_transport_if_type *if_ptr
 )
 {
-  const glink_core_version_type *version_array;
   glink_core_xport_ctx_type *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
+  const glink_core_version_type *version_array;
 
   xport_ctx = if_ptr->glink_core_priv;
 
-  version_array = xport_ctx->version_array;
+  version_array = glink_get_current_version(xport_ctx);
 
   /* Update the transport state */
   glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
@@ -186,12 +200,12 @@
   glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
   /* Start the negtiation */
-  if_ptr->tx_cmd_version(if_ptr, version_array->version,
+  if_ptr->tx_cmd_version(if_ptr,
+                         version_array->version,
       version_array->features);
 
   GLINK_LOG_EVENT(GLINK_EVENT_LINK_UP, NULL, xport_ctx->xport,
       xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
 }
 
 /*===========================================================================
@@ -222,40 +236,28 @@
   uint32 negotiated_features;
   glink_core_xport_ctx_type *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
+  ver = glink_get_current_version(xport_ctx);
+  
   /* The version to use must be a subset of supported version and features
    * on this host and remote host */
-  ver = &xport_ctx->version_array[xport_ctx->version_indx];
-  ASSERT(ver);
-
   if (version == ver->version)
   {
     /* Call the transport's negotiation function */
     negotiated_features = ver->negotiate_features(if_ptr, ver, features);
 
+    if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
+    
     /* If negotiated features match the provided features, version nogetiation
      * is complete */
     if(negotiated_features == features)
     {
-      /* send version ack before allowing to open channels */
-      if_ptr->tx_cmd_version_ack(if_ptr, version, features);
-
       glink_process_negotiation_complete( if_ptr, version, features );
-      return;
-    }
-    else
-    {
-      if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
     }
   }
   else
   {
-    /* Next time use older version */
-    ver = &xport_ctx->version_array[xport_ctx->version_indx];
-
     /* Versions don't match, return ACK with the feature set that we support */
     if_ptr->tx_cmd_version_ack(if_ptr, ver->version, ver->features);
   }
@@ -289,38 +291,33 @@
   uint32 negotiated_features;
   glink_core_xport_ctx_type *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Check to see if version returned by remote end is supported by
    * this host. Remote side would have acked only when the version/features
    * sent by this host did not match the remote */
-
-  ver = &xport_ctx->version_array[xport_ctx->version_indx];
-  ASSERT(ver);
+  ver = glink_get_current_version(xport_ctx);
 
   if (ver->version == version)
   {
     /* Call the transport's negotiation function */
     negotiated_features = ver->negotiate_features(if_ptr, ver, features);
 
-    if(negotiated_features != features)
+    if(negotiated_features == features)
+    {
+      glink_process_negotiation_complete( if_ptr, version, features );
+    }
+    else
     {
       /* Continue negotiating */
       if_ptr->tx_cmd_version(if_ptr, version, negotiated_features);
     }
-    else
-    {
-      glink_process_negotiation_complete( if_ptr, version, features );
-    }
   }
   else
   {
-    while (ver->version > version)
+    while (ver->version > version && xport_ctx->version_indx > 0)
     {
       /* Next time use older version */
-      ASSERT(xport_ctx->version_indx > 0);
       xport_ctx->version_indx--;
       ver = &xport_ctx->version_array[xport_ctx->version_indx];
     }
@@ -356,13 +353,12 @@
   glink_xport_priority    priority
 )
 {
+  (void)priority;
+  
   glink_channel_ctx_type     *remote_ch_ctx  = NULL;
   glink_channel_ctx_type     *allocated_ch_ctx;
   glink_err_type              status;
 
-  ASSERT( if_ptr != NULL );
-  ASSERT( name != NULL );
-
   /* Allocate and initialize channel info structure */
   remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
   if(remote_ch_ctx == NULL)
@@ -418,22 +414,20 @@
   glink_xport_priority     migrated_ch_prio
 )
 {
+  (void)migrated_ch_prio;
+  
   glink_channel_ctx_type     *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
+  glink_remote_state_type    remote_state;
 
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Move to closed state. Implies we clean up the channel from the
    * open list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->lcid == lcid)
-    {
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
+  
 			glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
 
 			if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
@@ -447,73 +441,54 @@
 
 			open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
 
-			if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+  remote_state = open_ch_ctx->remote_state;
+  glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+  
+  if (remote_state == GLINK_REMOTE_CH_OPENED)
 			{
 			/* remote channel is open on same xport as current xport.
 			 * change channel state to GLINK_CH_STATE_OPEN and notify client */
-				glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-				glink_os_cs_release( &xport_ctx->channel_q_cs );
 				open_ch_ctx->notify_state( open_ch_ctx,
 																	 open_ch_ctx->priv,
 																	 GLINK_CONNECTED );
 			}
-			else
-			{
-				glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-				glink_os_cs_release( &xport_ctx->channel_q_cs );
-			}
 
       GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, lcid);
-      
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-  /* We are here in case we could not find the channel in the open list. */
-  ASSERT(0);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_close_ack
-
-DESCRIPTION   This function is invoked by the transport in response to
-              glink_transport_if_type:: tx_cmd_ch_close
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            lcid      Local Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * This function is invoked by the transport in response to 
+ * glink_transport_if_type:: tx_cmd_ch_close
+ *
+ * @param[in]    if_ptr            Pointer to interface instance; must be unique
+ *                                 for each edge
+ * @param[in]    lcid              Local Channel ID
+ *
+ * @return       None
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_close_ack
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  lcid     /* Local channel ID */
+  glink_transport_if_type *if_ptr,
+  uint32                   lcid
 )
 {
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
-  /* Move to closed state. Implies we clean up the channel from the
-   * open list */
-
-  /* Find channel in the open_list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&xport_ctx->open_list);
-  while( open_ch_ctx )
-  {
-    if( open_ch_ctx->lcid == lcid )
-    {
-      /* Found channel */
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
+  
       glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
 
       GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
@@ -541,59 +516,43 @@
       {
         glink_os_free( open_ch_ctx );
       }
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-  /* We are here in case we could not find the channel in the open list. */
-  ASSERT(0);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_remote_close
-
-DESCRIPTION   Remote channel close request; will result in sending
-              glink_transport_if_type:: tx_cmd_ch_remote_close_ack
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * Remote channel close request; will result in sending 
+ * glink_transport_if_type:: tx_cmd_ch_remote_close_ack
+ *
+ * @param[in]    if_ptr            Pointer to interface instance; must be unique
+ *                                 for each edge
+ * @param[in]    rcid              Remote Channel ID
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_remote_close
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  rcid     /* Remote channel ID */
+  glink_transport_if_type *if_ptr,
+  uint32                   rcid
 )
 {
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
+  glink_remote_state_type    remote_state;
 
   xport_ctx = if_ptr->glink_core_priv;
 
-  /* Find channel in the open_list */
   glink_os_cs_acquire( &xport_ctx->channel_q_cs );
 
-  open_ch_ctx = smem_list_first( &if_ptr->glink_core_priv->open_list );
-  while(open_ch_ctx != NULL)
-  {
-    if( open_ch_ctx->rcid == rcid )
-    {
-      glink_remote_state_type remote_state;
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
 
       GLINK_LOG_EVENT( GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
                        xport_ctx->xport, xport_ctx->remote_ss, rcid);
-      /* Found channel, transition to appropriate state based on current state
-       * grab lock to perform channel state related operations */
+  
       glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
 
       ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
@@ -625,71 +584,55 @@
       else
       {
         /* Inform the client */
-        open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
+    open_ch_ctx->notify_state(open_ch_ctx,
+                              open_ch_ctx->priv,
                                    GLINK_REMOTE_DISCONNECTED);
       }
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  glink_os_cs_release( &xport_ctx->channel_q_cs );
-  ASSERT(0);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_put_pkt_ctx
-
-DESCRIPTION   Transport invokes this call to receive a packet fragment (must
-              have previously received an rx_cmd_rx_data packet)
-
-ARGUMENTS   *if_ptr      Pointer to interface instance; must be unique
-                         for each edge
-
-            rcid         Remote Channel ID
-
-            *intent_ptr  Pointer to the intent fragment
-
-            complete     True if pkt is complete
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * Transport invokes this call to receive a packet fragment (must 
+ * have previously received an rx_cmd_rx_data packet)
+ *
+ * @param[in]    if_ptr       Pointer to interface instance; must be unique
+ *                            for each edge
+ * @param[in]    rcid         Remote Channel ID
+ * @param[in]    intent_ptr   Pointer to the intent fragment
+ * @param[in]    complete     True if pkt is complete
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
 void glink_rx_put_pkt_ctx
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  rcid,    /* Remote channel ID */
-  glink_rx_intent_type    *intent_ptr, /* Fragment ptr */
-  boolean                 complete     /* True if pkt is complete */
+  glink_transport_if_type *if_ptr,
+  uint32                   rcid,
+  glink_rx_intent_type    *intent_ptr,
+  boolean                  complete
 )
 {
+  (void)complete;
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
-  ASSERT(if_ptr != NULL && intent_ptr != NULL);
+  ASSERT(intent_ptr);
 
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->rcid == rcid) {
-      /* Found channel */
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+  
       GLINK_LOG_EVENT(GLINK_EVENT_CH_PUT_PKT_CTX, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, intent_ptr->iid);
 
       xport_ctx->channel_receive_pkt(open_ch_ctx, intent_ptr);
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  /* We end up here if we don't find the channel */
-  ASSERT(0);
 }
 
 /*===========================================================================
@@ -716,42 +659,27 @@
   uint32                  remote_sigs /* Remote control signals */
 )
 {
+  glink_core_xport_ctx_type *xport_ctx;
   glink_channel_ctx_type *open_ch_ctx;
   uint32 prev_sigs;
 
-  ASSERT(if_ptr != NULL);
-
-  /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->rcid == rcid ) {
-      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+  xport_ctx = if_ptr->glink_core_priv;
       
-      if( open_ch_ctx->tag_ch_for_close )
-      {
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-        return;
-      }
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
       
-      if( open_ch_ctx->local_state != GLINK_LOCAL_CH_OPENED &&
-          open_ch_ctx->remote_state != GLINK_REMOTE_CH_OPENED )
+  if (!glinki_channel_fully_opened(open_ch_ctx))
       {
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
         ASSERT(0);
-        return;
       }
-      glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+  
       /* Found channel, let client know of new remote signal state */
       prev_sigs = open_ch_ctx->remote_sigs;
       open_ch_ctx->remote_sigs = remote_sigs;
-      open_ch_ctx->notify_rx_sigs(open_ch_ctx, open_ch_ctx->priv,
-                                  prev_sigs, remote_sigs);
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
+  open_ch_ctx->notify_rx_sigs(open_ch_ctx,
+                              open_ch_ctx->priv,
+                              prev_sigs,
+                              remote_sigs);
   }
 
-  /* We end up here if we don't find the channel */
-  ASSERT(0);
-}
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
index acb1d2a..7282655 100644
--- a/platform/msm_shared/glink/glink_core_intentless_xport.c
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -172,6 +172,7 @@
   boolean req_intent
 )
 {
+  (void)req_intent;
   glink_transport_if_type *if_ptr = open_ch_ctx->if_ptr;
   glink_err_type status = if_ptr->tx(if_ptr, open_ch_ctx->lcid, pctx);
 
diff --git a/platform/msm_shared/glink/glink_core_internal.c b/platform/msm_shared/glink/glink_core_internal.c
new file mode 100644
index 0000000..790ef29
--- /dev/null
+++ b/platform/msm_shared/glink/glink_core_internal.c
@@ -0,0 +1,1458 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/*===========================================================================
+                        INCLUDE FILES
+===========================================================================*/
+#include <glink_internal.h>
+
+#ifdef FEATURE_TRACER_PACKET
+#include "glink_tracer.h"
+#endif
+
+/*===========================================================================
+  MACRO DEFINITION
+===========================================================================*/
+/*===========================================================================
+  GLOBAL DATA DECLARATIONS
+===========================================================================*/
+static os_cs_type glink_transport_q_cs[GLINK_NUM_HOSTS];
+
+/* Keep a list of registered transport for each edge allowed for this host */
+static smem_list_type glink_registered_transports[GLINK_NUM_HOSTS];
+
+/* List of supported hosts */
+const char* glink_hosts_supported[] = { "apss",
+                                        "mpss",
+                                        "lpass",
+                                        "dsps",
+                                        "wcnss",
+                                        "tz",
+                                        "rpm",
+                                      };
+
+static os_cs_type glink_mem_log_cs;
+
+static smem_list_type  glink_link_notif_list;
+static os_cs_type      glink_link_notif_list_cs;
+
+/*===========================================================================
+  GLOBAL FUNCTION DECLARATION
+===========================================================================*/
+/*===========================================================================
+  LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+  FUNCTION      glinki_scan_channels_and_notify_discon
+===========================================================================*/
+/** 
+ * Close all the channels belong to this transport
+ * This is helper function for glink_ssr
+ *
+ * @param[in]    if_ptr  pointer to transport interface
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+static void glinki_scan_channels_and_notify_discon
+(
+  glink_transport_if_type *if_ptr
+)
+{
+  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
+  glink_core_xport_ctx_type  *xport_ctx;
+  glink_remote_state_type     remote_state;
+  
+  xport_ctx = if_ptr->glink_core_priv;
+
+  /* Find channel in the open_list */
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+  while(open_ch_ctx)
+  {
+    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
+    open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
+    glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+    
+    dummy_open_ch_ctx = smem_list_next(open_ch_ctx);
+    
+    switch (open_ch_ctx->local_state)
+    {
+      case GLINK_LOCAL_CH_OPENED:
+      case GLINK_LOCAL_CH_OPENING:
+        /* local channel has called open at the moment. */
+        open_ch_ctx->notify_state(open_ch_ctx, 
+                                  open_ch_ctx->priv, 
+                                  GLINK_REMOTE_DISCONNECTED);
+        break;
+        
+      case GLINK_LOCAL_CH_CLOSING:
+        /* Case when local client already closed channel 
+         * but has not received ack yet */
+        if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack(if_ptr, 
+                                                       open_ch_ctx->lcid);
+        break;
+        
+      case GLINK_LOCAL_CH_CLOSED:
+        /* Channel fully closed - local, remote */
+        glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
+        xport_ctx->channel_cleanup(open_ch_ctx);
+        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+        remote_state = open_ch_ctx->remote_state;
+        glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+
+        if (remote_state != GLINK_REMOTE_CH_CLEANUP)
+        {
+          glink_os_free(open_ch_ctx);
+        }
+        break;
+        
+      default:
+        /* invalid local channel state */
+        ASSERT(0);
+    }
+    
+    open_ch_ctx = dummy_open_ch_ctx;
+    
+  } /* end while */
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xport_priority_comp
+===========================================================================*/
+/** 
+ * Helper function for glinki_get_xport_from_prio. This will be provided to
+ * glinki_xports_find function.
+ * Return true if given transport has same priority
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * @param[in]    cond1      unused
+ * @param[in]    priority   glink transport priority to find
+ *
+ * @return       TRUE   if if_ptr priority matches
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static boolean glinki_xport_priority_comp
+(
+  glink_transport_if_type *if_ptr,
+  void                    *cond1,
+  uint32                   priority,
+  void                   **out
+)
+{
+  (void)cond1;
+  (void)out;
+
+  return if_ptr->glink_priority == (glink_xport_priority)priority;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_client_requested_xport_check
+===========================================================================*/
+/**
+ * check whether this is client requested xport or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * @param[in]    xport_name transport name to find
+ * @param[in]    cond2      unused
+ * @param[in]    out        unused
+ * 
+ * @return       TRUE   if transport name
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static boolean glinki_client_requested_xport_check
+(
+  glink_transport_if_type *if_ptr,
+  void                    *xport_name,
+  uint32                   cond2,
+  void                   **out
+)
+{
+  (void)cond2;
+  (void)out;
+  
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return FALSE;
+  }
+  
+  return 0 == glink_os_string_compare(if_ptr->glink_core_priv->xport,
+                                      (const char *)xport_name);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_update_best_xport
+===========================================================================*/
+/** 
+ * Check whether given transport (if_ptr) has higher priority than
+ * priority user wants to check and update if it is true.
+ *
+ * @param[in]    if_ptr          transport interface pointer
+ * @param[in]    priority_param  xport priority to compare
+ * @param[in]    param2          unused
+ * @param[out]   best_xport      pointer to result xport
+ * 
+ * @return       FALSE  all the time since this needs to iterate all transports
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_update_best_xport
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *priority_param,
+  uint32                    param2,
+  void                    **best_xport
+)
+{
+  (void)param2;
+  glink_xport_priority *priority;
+  
+  ASSERT(best_xport && priority_param);
+  
+  priority = (glink_xport_priority*)priority_param;
+  
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return;
+  }
+  
+  /* Given xport is best one if comparing xport doesn't exist */ 
+  if (if_ptr->glink_priority < *priority)
+  {
+    *best_xport = (void*)if_ptr;
+    *priority = if_ptr->glink_priority;
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_notify_xport_ssr
+===========================================================================*/
+/** 
+ * Notify this xport of ssr event and do ssr clean up
+ *
+ * @param[in]    if_ptr         transport interface pointer
+ * @param[in]    priority       priority to check
+ * @param[in]    cond2          unused
+ * @param[out]   updated_xport  pointer to result xport
+ * 
+ * @return       FALSE  all the time since this needs to iterate all transports
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_notify_xport_ssr
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *param1,
+  uint32                    param2,
+  void                    **out
+)
+{
+  (void)param1;
+  (void)param2;
+  (void)out;
+  /* xport is down. change the xport state */
+  glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
+  if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
+  
+  /* Let the xport know about ssr */
+  if_ptr->ssr( if_ptr );
+  
+  /* Invoke LINK_DOWN notification for any registered notifiers */
+  glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
+  
+  /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
+  glinki_scan_channels_and_notify_discon(if_ptr);
+  
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_check_xport_and_notify
+===========================================================================*/
+/** 
+ * Notify this xport for link state change if applicable
+ *
+ * @param[in]  if_ptr                 transport interface pointer
+ * @param[in]  link_notif_data_param  parameter for link notif data
+ * @param[in]  state                  link state to notify
+ * @param[out] out                    unused
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_check_xport_and_notify
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *link_notif_data_param,
+  uint32                    state,
+  void                    **out
+)
+{
+  (void)out;
+  
+  glink_core_xport_ctx_type  *xport_ctx;
+  glink_link_notif_data_type *link_notif_data;
+  glink_link_info_type        link_info;
+  
+  ASSERT(link_notif_data_param && if_ptr->glink_core_priv);
+  
+  link_notif_data = (glink_link_notif_data_type *)link_notif_data_param;
+  xport_ctx = if_ptr->glink_core_priv;
+  
+  if (link_notif_data->xport == NULL ||
+      0 == glink_os_string_compare(xport_ctx->xport, link_notif_data->xport))
+  {
+    /* xport not specified, or it is specified and matches the current xport */
+    /* Invoke registered callback */
+    link_info.xport = xport_ctx->xport;
+    link_info.remote_ss = xport_ctx->remote_ss;
+    link_info.link_state = (glink_link_state_type)state;
+    
+    link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_check_xport_link_up_and_notify
+===========================================================================*/
+/** 
+ * Notify this xport for link state change if applicable
+ *
+ * @param[in]  if_ptr                 transport interface pointer
+ * @param[in]  link_notif_data_param  parameter for link notif data
+ * @param[in]  state                  link state to notify
+ * @param[out] out                    unused. but just passed as parameter
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_check_xport_link_up_and_notify
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *link_notif_data_param,
+  uint32                    state,
+  void                    **out
+)
+{
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return;
+  }
+  
+  glinki_check_xport_and_notify(if_ptr, link_notif_data_param, state, out);
+}
+
+/*===========================================================================
+  EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION      glink_init
+
+DESCRIPTION   Initializes the GLink core library.
+
+ARGUMENTS     None
+
+RETURN VALUE  None
+
+SIDE EFFECTS  None
+===========================================================================*/
+void glink_init(void)
+{
+  uint32 i;
+  boolean cs_created = FALSE;
+
+  OS_LOG_INIT();
+  
+  smem_list_init(&glink_link_notif_list);
+  cs_created = glink_os_cs_init(&glink_link_notif_list_cs);
+  ASSERT(cs_created);
+  
+  cs_created = glink_os_cs_init(&glink_mem_log_cs);
+  ASSERT(cs_created);
+
+  
+  /* Create/Initalize crtitical sections */
+  for (i = 0; i < GLINK_NUM_HOSTS; ++i)
+  {
+    cs_created = glink_os_cs_init(&glink_transport_q_cs[i]);
+    ASSERT(cs_created);
+    smem_list_init(&glink_registered_transports[i]);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_add_ch_to_xport
+===========================================================================*/
+/** 
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in]    if_ptr            Pointer to xport if on which channel is to
+ *                                 be opened
+ * @param[in]    req_if_ptr        Pointer to xport if on which channel 
+ *                                 actually wants to open
+ * @param[in]    ch_ctx            channel context
+ * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
+ * @param[in]    local_open        flag to determine if channel is opened 
+ *                                 locally or remotely
+ * @param[in]    migrated_ch_prio  negotiated xport priority
+ *                                 (used to send priority via remote_open_ack to 
+ *                                  remote side)
+ *
+ * @return       G-Link standard error type
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_err_type glinki_add_ch_to_xport
+(
+  glink_transport_if_type  *if_ptr,
+  glink_channel_ctx_type   *ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
+  unsigned int              local_open,
+  glink_xport_priority      migrated_ch_prio
+)
+{
+  glink_err_type              status;
+  glink_channel_ctx_type     *open_ch_ctx;
+  glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
+
+  if (!ch_ctx->name)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+  
+  /* See if channel already exists in open_list */
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_name(xport_ctx, ch_ctx->name);
+  
+  if (!open_ch_ctx)
+  {
+    /* check if a new channel can be added */
+    if ((uint32)smem_list_count(&xport_ctx->open_list) >= xport_ctx->max_lcid)
+    {
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
+      glink_os_free(ch_ctx);
+      return GLINK_STATUS_OUT_OF_RESOURCES;
+    }
+    
+    /* Channel not in the list - it was not previously opened */
+    ch_ctx->if_ptr = if_ptr;
+    *allocated_ch_ctx = ch_ctx;
+
+    /* Set channel state */
+    if (local_open)
+    {
+      /* This is a local open */
+      ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
+    }
+    else
+    {
+      ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+    }
+
+    glink_os_cs_init(&ch_ctx->tx_cs);
+    glink_os_cs_init(&ch_ctx->qos_cs);
+    glink_os_cs_init(&ch_ctx->ch_state_cs);
+
+    /* make sure next LCID is not used in currently open channels */
+    open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+
+    while (open_ch_ctx)
+    {
+      if (open_ch_ctx->lcid == xport_ctx->free_lcid)
+      {
+        xport_ctx->free_lcid++;
+        
+        if (xport_ctx->free_lcid >= xport_ctx->max_lcid)
+        {
+          xport_ctx->free_lcid = 1;
+        }
+
+        open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+        continue;
+      }
+
+      open_ch_ctx = smem_list_next(open_ch_ctx);
+    }
+
+    ch_ctx->lcid = xport_ctx->free_lcid;
+
+    /* Append the channel to the transport interface's open_list */
+    smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+
+    /* release lock before context switch otherwise it is causing deadlock */
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    
+    /* Send the OPEN command to transport */
+    if (local_open)
+    {
+      status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
+                                      ch_ctx->name,
+                                      migrated_ch_prio);
+    }
+    else
+    {
+      /* initialize channel resources */
+      status = xport_ctx->channel_init(ch_ctx);
+
+      if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, ch_ctx->rcid, migrated_ch_prio);
+    }
+
+    if (status != GLINK_STATUS_SUCCESS)
+    {
+      /* Remove the channel from the transport interface's open_list */
+      xport_ctx->free_lcid--;
+      glinki_dequeue_item(&if_ptr->glink_core_priv->open_list,
+                          ch_ctx,
+                          &xport_ctx->channel_q_cs);
+      
+      /* free the ch_ctx structure and return */
+      xport_ctx->channel_cleanup(ch_ctx);
+      glink_os_free(ch_ctx);
+    }
+
+    return status;
+  }
+  
+  /* grab lock to avoid race condition for channel state change */
+  glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
+  
+  if (local_open)
+  {
+    /* LOCAL OPEN REQUEST */
+    if (open_ch_ctx->local_state != GLINK_LOCAL_CH_CLOSED)
+    {
+      glink_os_free(ch_ctx);
+      return GLINK_STATUS_FAILURE;
+    }
+    
+    glink_os_cs_init(&ch_ctx->tx_cs);
+    glink_os_cs_init(&ch_ctx->qos_cs);
+    glink_os_cs_init(&ch_ctx->ch_state_cs);
+    
+    ch_ctx->rcid     = open_ch_ctx->rcid;
+    ch_ctx->lcid     = open_ch_ctx->lcid;
+    ch_ctx->pintents = open_ch_ctx->pintents;
+    ch_ctx->if_ptr   = open_ch_ctx->if_ptr;
+
+    if (ch_ctx->pintents != NULL)
+    {
+      ch_ctx->pintents->ch_ctx = ch_ctx;
+    }
+
+    ch_ctx->remote_state = open_ch_ctx->remote_state;
+    ch_ctx->local_state  = GLINK_LOCAL_CH_OPENING;
+    
+    /* release lock before context switch otherwise it is causing
+     * deadlock */
+    smem_list_delete(&xport_ctx->open_list, open_ch_ctx);
+    smem_list_append(&xport_ctx->open_list, ch_ctx);
+
+    glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+    glink_os_free(open_ch_ctx);
+    *allocated_ch_ctx = ch_ctx;
+    
+    /* Send open cmd to transport */
+    status = if_ptr->tx_cmd_ch_open(if_ptr, 
+                                    ch_ctx->lcid,
+                                    ch_ctx->name,
+                                    migrated_ch_prio);
+  }
+  else
+  { 
+    /* REMOTE OPEN REQUEST */
+    ASSERT(open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED);
+    
+    open_ch_ctx->rcid = ch_ctx->rcid;
+    *allocated_ch_ctx = open_ch_ctx;
+    status = xport_ctx->channel_init(open_ch_ctx);
+
+    if (status == GLINK_STATUS_SUCCESS)
+    {
+      open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+    }
+    
+    /* release lock before context switch otherwise it is causing deadlock */
+    glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    
+    /* Send ACK to transport */
+    if_ptr->tx_cmd_ch_remote_open_ack(if_ptr,
+                                      open_ch_ctx->rcid,
+                                      migrated_ch_prio);
+    
+    if (status == GLINK_STATUS_SUCCESS)
+    {
+      /* Inform the client */
+      if (open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED)
+      {
+        open_ch_ctx->notify_state(open_ch_ctx, 
+                                  open_ch_ctx->priv, 
+                                  GLINK_CONNECTED);
+      }
+    }
+
+    glink_os_free(ch_ctx);
+  } /* end If - else (local_open) */
+  
+  return status;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_channel_fully_opened
+===========================================================================*/
+/** 
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in]  handle        glink channel handle
+ *
+ * @return     TRUE,  if channel is fully opened
+ *             FASLE, otherwise
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_channel_fully_opened
+(
+  glink_handle_type          handle
+)
+{
+  boolean ch_fully_opened = TRUE;
+
+  if (!glinki_xport_linkup(handle->if_ptr))
+  {
+    return FALSE;
+  }
+  
+  glink_os_cs_acquire( &handle->ch_state_cs );
+  
+  if (handle->local_state != GLINK_LOCAL_CH_OPENED ||
+      handle->remote_state != GLINK_REMOTE_CH_OPENED)
+  {
+    ch_fully_opened = FALSE;
+  }
+
+  glink_os_cs_release( &handle->ch_state_cs );
+  
+  return ch_fully_opened;
+}
+
+/*===========================================================================
+FUNCTION      glink_core_register_transport
+
+DESCRIPTION   Transport calls this API to register its interface with GLINK 
+              Core
+
+ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
+                      for each edge
+                         
+            *cfg      Pointer to transport configuration structure.
+
+RETURN VALUE  Standard GLINK error codes.
+
+SIDE EFFECTS  None
+===========================================================================*/
+glink_err_type glink_core_register_transport
+(
+  glink_transport_if_type       *if_ptr,
+  glink_core_transport_cfg_type *cfg
+)
+{
+  unsigned int remote_host = 0;
+  glink_core_xport_ctx_type *xport_ctx;
+
+  /* Param validation */
+  if (if_ptr == NULL          ||
+      cfg == NULL             ||
+      cfg->name == NULL       ||
+      cfg->remote_ss == NULL  ||
+      cfg->version == NULL    ||
+      cfg->version_count == 0 ||
+      cfg->max_cid == 0)
+  {
+    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "", 
+        GLINK_STATUS_INVALID_PARAM);    
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  if(if_ptr->tx_cmd_version == NULL             ||
+     if_ptr->tx_cmd_version_ack == NULL         ||
+     if_ptr->set_version == NULL                ||
+     if_ptr->tx_cmd_ch_open == NULL             ||
+     if_ptr->tx_cmd_ch_close == NULL            ||
+     if_ptr->tx_cmd_ch_remote_open_ack == NULL  ||
+     if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
+     if_ptr->ssr  == NULL)
+  {
+    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name, 
+        cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);    
+    return GLINK_STATUS_INVALID_PARAM;;
+  }
+
+  remote_host = glinki_find_remote_host(cfg->remote_ss);
+
+  if(remote_host == GLINK_NUM_HOSTS )
+  {
+    /* Unknown transport name trying to register with GLink */
+    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name, 
+           cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
+    
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  /* Set the glink_core_if_ptr to point to the default interface */
+  if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
+
+  /* Allocate/fill out the GLink private context data */
+  {
+     xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
+    if(xport_ctx == NULL)
+    {
+      GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name, 
+          cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+    
+      return GLINK_STATUS_OUT_OF_RESOURCES;
+    }
+
+    xport_ctx->xport = cfg->name;
+    xport_ctx->remote_ss = cfg->remote_ss;
+    xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
+    xport_ctx->max_lcid = cfg->max_cid; /* Max channel ID supported by transport */
+    xport_ctx->version_array = cfg->version;
+    xport_ctx->version_indx = cfg->version_count - 1;
+
+    glink_os_cs_init(&xport_ctx->channel_q_cs);
+    glink_os_cs_init(&xport_ctx->liid_cs);
+    glink_os_cs_init(&xport_ctx->status_cs);
+
+    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+    smem_list_init(&xport_ctx->open_list);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+    /* Set the glink_core_if_ptr to point to the allocated structure */
+    if_ptr->glink_core_priv = xport_ctx;
+    xport_ctx->status = GLINK_XPORT_REGISTERED;
+  }
+  
+  /* Push the transport interface into appropriate queue */
+  glinki_enqueue_item(&glink_registered_transports[remote_host],
+                      if_ptr,
+                      &glink_transport_q_cs[remote_host]);
+
+  GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT,
+                  NULL,
+                  xport_ctx->xport,
+                  xport_ctx->remote_ss,
+                  GLINK_STATUS_SUCCESS);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_register_link_notif_data
+===========================================================================*/
+/** 
+ * Register link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_register_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  glinki_enqueue_item(&glink_link_notif_list,
+                      (void *)link_notif_data,
+                      &glink_link_notif_list_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_deregister_link_notif_data
+===========================================================================*/
+/** 
+ * Deregister link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_deregister_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  glinki_dequeue_item(&glink_link_notif_list,
+                      (void *)link_notif_data,
+                      &glink_link_notif_list_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_scan_xports_and_notify
+===========================================================================*/
+/** 
+ * Scan xports and notify link up state event
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_xports_and_notify
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  unsigned int          remote_host;
+  glink_link_state_type link_state = GLINK_LINK_STATE_UP;
+  
+  ASSERT(link_notif_data);
+  
+  /* Find matching subsystem */
+  for (remote_host = 0; remote_host < GLINK_NUM_HOSTS; ++remote_host)
+  {
+    if (link_notif_data->remote_ss != NULL &&
+        0 != glink_os_string_compare(glink_hosts_supported[remote_host],
+                                     link_notif_data->remote_ss))
+    {
+      /* client is not interested in this remote SS */
+      continue;
+    }
+    
+    glinki_xports_for_each(glink_hosts_supported[remote_host],
+                           glinki_check_xport_link_up_and_notify,
+                           link_notif_data,
+                           link_state,
+                           NULL);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_scan_notif_list_and_notify
+===========================================================================*/
+/** 
+ * Scan registered link notification list and notify of xport link state change
+ *
+ * @param[in]  if_ptr  pointer to xport interface
+ * @param[in]  state   link state to notify
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_notif_list_and_notify
+(
+  glink_transport_if_type *if_ptr,
+  glink_link_state_type    state
+)
+{
+  glink_link_notif_data_type *link_notif_data;
+
+  glink_os_cs_acquire(&glink_link_notif_list_cs);
+  
+  for (link_notif_data = smem_list_first(&glink_link_notif_list);
+       link_notif_data != NULL;
+       link_notif_data = smem_list_next(link_notif_data))
+  {
+    if( link_notif_data->remote_ss == NULL || 
+        0 == glink_os_string_compare( if_ptr->glink_core_priv->remote_ss,
+                                      link_notif_data->remote_ss ) ) 
+    {
+      glinki_check_xport_and_notify(if_ptr,
+                                    link_notif_data,
+                                    (uint32)state,
+                                    NULL);
+    }
+  }
+  
+  glink_os_cs_release(&glink_link_notif_list_cs);
+} /* glinki_scan_notif_list_and_notify */
+
+/*===========================================================================
+  FUNCTION      glinki_ssr
+===========================================================================*/
+/** 
+ * Notify all the xports of ssr event in this edge
+ *
+ * @param[in]    remote_ss name of remote subsystem
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glink_ssr(const char* remote_ss)
+{
+  glinki_xports_for_each(remote_ss,
+                         glinki_notify_xport_ssr,
+                         NULL,
+                         0,
+                         NULL);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xport_linkup
+===========================================================================*/
+/** 
+ * Check whether this transport is in linkup state or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * 
+ * @return       TRUE   if this xport is in link up state
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_xport_linkup
+(
+  glink_transport_if_type *if_ptr
+)
+{
+  return if_ptr->glink_core_priv->status == GLINK_XPORT_LINK_UP;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xports_for_each
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and perform client's function for each
+ * transport
+ *
+ * @param[in]    remote_ss    name of remote subsystem, NULL string not accepted
+ * @param[in]    client_ex_fn client function to perform on each xport
+ * @param[in]    param1       first parameter to use in client_ex_fn
+ * @param[in]    param2       second parameter to use in client_ex_fn
+ * @param[out]   out          value to return in case client wants
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_xports_for_each
+(
+  const char         *remote_ss,
+  glink_client_ex_fn  client_ex_fn,
+  void               *param1,
+  uint32              param2,
+  void              **out
+)
+{
+  glink_transport_if_type *if_iter_ptr;
+  
+  uint32 remote_host = glinki_find_remote_host(remote_ss);
+  
+  ASSERT(remote_host < GLINK_NUM_HOSTS);
+  
+  glink_os_cs_acquire(&glink_transport_q_cs[remote_host]);
+  
+  for(if_iter_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+      if_iter_ptr != NULL;
+      if_iter_ptr = smem_list_next(if_iter_ptr))
+  {
+    client_ex_fn(if_iter_ptr, param1, param2, out);
+  }
+  
+  glink_os_cs_release(&glink_transport_q_cs[remote_host]);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xports_find
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and finds transport that satisfy
+ * client's condition
+ *
+ * @param[in]    remote_ss      name of remote subsystem, NULL string not accepted
+ * @param[in]    client_cond_fn client function to check if this transport is 
+ *                              what client is looking for
+ * @param[in]    cond1          first condition to use in client_ex_fn
+ * @param[in]    cond2          second condition to use in client_ex_fn
+ * @param[out]   out            value to return in case client wants
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL if there isn't any xport matches client's search condition
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_xports_find
+(
+  const char           *remote_ss,
+  glink_client_cond_fn  client_cond_fn,
+  void                 *cond1,
+  uint32                cond2,
+  void                **out
+)
+{
+  glink_transport_if_type *if_iter_ptr;
+  
+  uint32 remote_host = glinki_find_remote_host(remote_ss);
+  
+  ASSERT(remote_host < GLINK_NUM_HOSTS);
+  
+  glink_os_cs_acquire(&glink_transport_q_cs[remote_host]);
+  
+  for (if_iter_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+       if_iter_ptr != NULL;
+       if_iter_ptr = smem_list_next(if_iter_ptr))
+  {
+    if(client_cond_fn(if_iter_ptr, cond1, cond2, out))
+    {
+      break;
+    }
+  }
+  
+  glink_os_cs_release(&glink_transport_q_cs[remote_host]);
+  
+  return if_iter_ptr;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_lcid
+===========================================================================*/
+/** 
+ * Find channel context by lcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    lcid       local channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_lcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     lcid
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  
+  for (open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+       open_ch_ctx;
+       open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    if (open_ch_ctx->lcid == lcid)
+    {
+      return open_ch_ctx;
+    }
+  }
+  
+  ASSERT(0);
+  return NULL;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_rcid
+===========================================================================*/
+/** 
+ * Find channel context by rcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    rcid       remote channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_rcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     rcid
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  
+  for (open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+       open_ch_ctx;
+       open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    if (open_ch_ctx->rcid == rcid)
+    {
+      return open_ch_ctx;
+    }
+  }
+  
+  ASSERT(0);
+  return NULL;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_name
+===========================================================================*/
+/** 
+ * Find channel context by channel name
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    ch_name    channel name
+ *
+ * @return       pointer to glink channel context
+ *               NULL if channel doesn't exist
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_name
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  const char                *ch_name
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  
+  for(open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+      open_ch_ctx;
+      open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
+    
+    if (0 == glink_os_string_compare(open_ch_ctx->name, ch_name) &&
+        !open_ch_ctx->tag_ch_for_close &&
+        open_ch_ctx->remote_state != GLINK_REMOTE_CH_SSR_RESET &&
+        open_ch_ctx->remote_state != GLINK_REMOTE_CH_CLEANUP)
+    {
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+      break;
+    }
+    
+    glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+  }
+  
+  return open_ch_ctx;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_remote_host
+===========================================================================*/
+/** 
+ * return remote subsystem ID based on remote subsystem name
+ *
+ * @param[in]    remote_ss  remote subsystem name
+ *
+ * @return       remote subsystem ID
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+uint32 glinki_find_remote_host
+(
+  const char *remote_ss
+)
+{
+  uint32 remote_host;
+
+  for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++) 
+  {
+    if( 0 == glink_os_string_compare(glink_hosts_supported[remote_host],
+                                     remote_ss))
+    {
+      /* Match found, break out of loop */
+      break;
+    }
+  }
+  
+  return remote_host;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_best_xport
+===========================================================================*/
+/** 
+ * This function gives best available transport for give edge
+ *
+ * @param[in]    remote_host  Index into glink_registered_transports array of
+ *                            registered transports list per edge
+ * 
+ * @return       pointer to glink_transport_if_type
+ *               Null, if transport not found
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_best_xport
+(
+  const char *remote_ss
+)
+{
+  glink_transport_if_type *best_if_ptr = NULL;
+  glink_xport_priority priority = GLINK_MIN_PRIORITY;
+  
+  glinki_xports_for_each(remote_ss,
+                         glinki_update_best_xport,
+                         (void *)&priority,
+                         0,
+                         (void **)&best_if_ptr);
+  
+  return best_if_ptr;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_requested_xport
+===========================================================================*/
+/** 
+ * Find requested or best transport depending on client's request
+ *
+ * @param[in]    xport_name         name of transport
+ * @param[in]    remote_ss          remote subsystem name
+ * @param[in]    open_ch_option     option client gave when called glink_open
+ * @param[out]   suggested_priority best xport priority glink suggests
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_requested_xport
+(
+  const char           *xport_name,
+  const char           *remote_ss,
+  uint32                open_ch_option,
+  glink_xport_priority *suggested_priority
+)
+{
+  glink_transport_if_type *best_xport = glinki_find_best_xport(remote_ss);
+  glink_transport_if_type *xport_found = NULL;
+  
+  *suggested_priority = GLINK_INVALID_PRIORITY;
+
+  if (!xport_name)
+  {
+    if (best_xport)
+    {
+      *suggested_priority = best_xport->glink_priority;
+    }
+    
+    return best_xport;
+  }
+  
+  xport_found = glinki_xports_find(remote_ss,
+                                   glinki_client_requested_xport_check,
+                                   (void *)xport_name,
+                                   0,
+                                   NULL);
+  
+  if (!xport_found)
+  {
+    return NULL;
+  }
+  
+  if ((open_ch_option & GLINK_OPT_INITIAL_XPORT) != 0)
+  {
+    *suggested_priority = best_xport->glink_priority;
+  }
+  else
+  {
+    /* Client is not willing to migrate to better transport */
+    *suggested_priority = xport_found->glink_priority;
+  }
+  
+  return xport_found;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_xport_by_priority
+===========================================================================*/
+/** 
+ * This function returns glink_transport_if pointer based on transport priority
+ *
+ * @param[in]    prio        glink xport prio
+ * @param[in]    remote_ss   remote subsytem name
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL, if it's not registered or transport not found with
+ *                     the priority
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_xport_by_priority
+(
+  glink_xport_priority  prio,
+  const char           *remote_ss
+)
+{
+  return glinki_xports_find(remote_ss,
+                            glinki_xport_priority_comp,
+                            NULL,
+                            (uint32)prio,
+                            NULL);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_enqueue_item
+===========================================================================*/
+/** 
+ * Enqueue item to smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to enqueue
+ * @param[in]    item       item to queue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_enqueue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+)
+{
+  glink_os_cs_acquire(cs);
+  smem_list_append(smem_list_ptr, item);
+  glink_os_cs_release(cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_dequeue_item
+===========================================================================*/
+/** 
+ *  Dequeue item from smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to dequeue from 
+ * @param[in]    item       item to dequeue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_dequeue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+)
+{
+  glink_os_cs_acquire(cs);
+  smem_list_delete(smem_list_ptr, item);
+  glink_os_cs_release(cs);
+}
+
+/* ============ Internal Logging API ================ */
+void glink_mem_log
+(
+  const char *func,
+  uint32 line,
+  glink_log_event_type type,
+  const char *msg,
+  const char *xport,
+  const char *remote_ss,
+  uint32 param
+)
+{
+#ifdef DEBUG_GLINK
+  dprintf(INFO, "%s:%u, event:%d, msg:%s, xport:%s, remote_ss:%s, param:%u\n", func, line, type, msg, xport, remote_ss, param);
+#endif
+}
+
+
+#ifdef FEATURE_TRACER_PACKET
+/*===========================================================================
+FUNCTION      glink_tracer_packet_log_pctx_pkt
+===========================================================================*/
+/** 
+ * Log tracer packet event. Tracer packet is included in glink_core_tx_pkt
+ * and needs to use vprovider to extract it
+ * 
+ * @param[in]  pctx     pointer to glink_core_tx_pkt_type
+ * @param[in]  event_id event_id
+ * 
+ * @return         None
+ *
+ * @sideeffects    None
+ */
+/*=========================================================================*/
+void glink_tracer_packet_log_pctx_pkt
+(
+  glink_core_tx_pkt_type  *pctx,
+  uint32                   event_id
+)
+{
+  tracer_pkt_result_type  tracer_pkt_log_result;
+  void                   *tracer_pkt_data;
+  size_t                  tracer_pkt_size;
+  
+  tracer_pkt_data = pctx->vprovider(pctx->iovec, 0, &tracer_pkt_size);
+  
+  if (tracer_pkt_size != pctx->size)
+  {
+    GLINK_LOG_EVENT(GLINK_EVENT_TXV_INVALID_BUFFER,
+                    NULL, "", "", 
+                    tracer_pkt_size);
+  }
+
+  tracer_pkt_log_result = tracer_packet_log_event(tracer_pkt_data, event_id);
+  if (tracer_pkt_log_result != TRACER_PKT_STATUS_SUCCESS)
+  {
+    GLINK_LOG_EVENT(GLINK_EVENT_TRACER_PKT_FAILURE,
+                    NULL, "", "", 
+                    tracer_pkt_log_result);
+  }
+}
+#endif
diff --git a/platform/msm_shared/glink/glink_vector.c b/platform/msm_shared/glink/glink_vector.c
index 31f0883..4ca2692 100644
--- a/platform/msm_shared/glink/glink_vector.c
+++ b/platform/msm_shared/glink/glink_vector.c
@@ -109,12 +109,6 @@
     return NULL;
   }
 
-  if (!iovec_l->vlist)
-  {
-    // create vlist and map virtual from physical addresses
-    ASSERT(0);
-  }
-
   if (!iovec_l->vlast || iovec_l->vlast->start_offset > offset)
   {
        iovec_l->vlast = iovec_l->vlist;
@@ -167,12 +161,6 @@
     return NULL;
   }
 
-  if (!iovec_l->plist)
-  {
-    // create plist and get physical addresses from virtual
-    ASSERT(0); // not implemented
-  }
-
   if (!iovec_l->plast || iovec_l->plast->start_offset > offset)
   {
        iovec_l->plast = iovec_l->plist;
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index d78fe34..e350b8f 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -100,6 +100,7 @@
   GLINK_EVENT_CH_QOS_CANCEL,
   GLINK_EVENT_CH_QOS_START,
   GLINK_EVENT_CH_QOS_STOP,
+  GLINK_EVENT_INVALID_REMOTE_SS
 }glink_log_event_type;
 
 typedef struct _glink_channel_intents_type {
@@ -291,17 +292,35 @@
   void                      *priv;         /* Notification priv ptr */
 } glink_link_notif_data_type;
 
+
+/* Function pointer used to iterate glink registered transports
+ * glink_client_cond_fn is used to find specifc transport client wants
+ * glink_client_ex_fn will execute client's operation on specific/all transports
+ * depends on client's choice */
+typedef boolean (*glink_client_cond_fn)
+(
+  glink_transport_if_type *if_ptr,
+  void                    *cond1,   /* First condition to compare */
+  uint32                   cond2,   /* Second condition to compare */
+  void                   **out      /* Client private return value */
+);
+
+typedef void (*glink_client_ex_fn)
+(
+  glink_transport_if_type *if_ptr,
+  void                    *param1,   /* First parameter */
+  uint32                   param2,   /* Second parameter */
+  void                   **out      /* Client private return value */
+);
+
 /*===========================================================================
                               GLOBAL DATA DECLARATIONS
 ===========================================================================*/
-extern os_cs_type *glink_transport_q_cs[GLINK_NUM_HOSTS];
 extern const char *glink_hosts_supported[GLINK_NUM_HOSTS];
-extern smem_list_type glink_registered_transports[];
 
 /*===========================================================================
                     LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
-
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -620,6 +639,22 @@
 void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr);
 
 /*===========================================================================
+  FUNCTION      glink_core_setup_intent_xport
+===========================================================================*/
+/**
+
+  Initializes internal core functions based on the transport capabilities.
+
+  @param[in]  if_ptr   The Pointer to the interface instance.
+
+  @return     None.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+void glink_core_setup_intent_xport(glink_transport_if_type *if_ptr);
+
+/*===========================================================================
   FUNCTION      glink_core_qos_get_priority
 ===========================================================================*/
 /**
@@ -637,6 +672,26 @@
 uint32 glink_core_qos_get_priority(glink_transport_if_type *if_ptr, uint32 req_rate);
 
 /*===========================================================================
+  FUNCTION      glinki_channel_fully_opened
+===========================================================================*/
+/** 
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in]  handle        glink channel handle
+ *
+ * @return     TRUE,  if channel is fully opened
+ *             FASLE, otherwise
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_channel_fully_opened
+(
+  glink_handle_type          handle
+);
+
+/*===========================================================================
   FUNCTION      glink_core_qos_cancel
 ===========================================================================*/
 /**
@@ -652,4 +707,365 @@
 /*=========================================================================*/
 void glink_core_qos_cancel(glink_channel_ctx_type *open_ch_ctx);
 
+/*===========================================================================
+  FUNCTION      glinki_register_link_notif_data
+===========================================================================*/
+/** 
+ * Register link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_register_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_deregister_link_notif_data
+===========================================================================*/
+/** 
+ * Deregister link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_deregister_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_scan_xports_and_notify
+===========================================================================*/
+/** 
+ * Scan xports and notify link up state event
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_xports_and_notify
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_scan_notif_list_and_notify
+===========================================================================*/
+/** 
+ * Scan registered link notification list and notify of xport link state change
+ *
+ * @param[in]  if_ptr  pointer to xport interface
+ * @param[in]  state   link state to notify
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_notif_list_and_notify
+(
+  glink_transport_if_type *if_ptr,
+  glink_link_state_type state
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xport_linkup
+===========================================================================*/
+/** 
+ * Check whether this transport is in linkup state or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * 
+ * @return       TRUE   if this xport is in link up state
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_xport_linkup
+(
+  glink_transport_if_type *if_ptr
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xports_for_each
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and perform client's function for each
+ * transport
+ *
+ * @param[in]    remote_ss    name of remote subsystem, NULL string not accepted
+ * @param[in]    client_ex_fn client function to perform when desired xport is 
+ *                            found
+ * @param[in]    cond1        first condition to use in client_ex_fn
+ * @param[in]    cond2        second condition to use in client_ex_fn
+ * @param[out]   out          value to return in case client wants
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_xports_for_each
+(
+  const char         *remote_ss,
+  glink_client_ex_fn  client_ex_fn,
+  void               *param1,
+  uint32              param2,
+  void              **out
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xports_find
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and finds transport that satisfy
+ * client's condition
+ *
+ * @param[in]    remote_ss      name of remote subsystem, NULL string not accepted
+ * @param[in]    client_cond_fn client function to check if this transport is 
+ *                              what client is looking for
+ * @param[in]    cond1          first condition to use in client_ex_fn
+ * @param[in]    cond2          second condition to use in client_ex_fn
+ * @param[out]   out            value to return in case client wants
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL if there isn't any xport matches client's search condition
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_xports_find
+(
+  const char           *remote_ss,
+  glink_client_cond_fn  client_cond_fn,
+  void                 *cond1,
+  uint32                cond2,
+  void                **out
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_lcid
+===========================================================================*/
+/** 
+ * Find channel context by lcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    lcid       local channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_lcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     lcid
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_rcid
+===========================================================================*/
+/** 
+ * Find channel context by rcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    rcid       remote channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_rcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     rcid
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_name
+===========================================================================*/
+/** 
+ * Find channel context by channel name
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    ch_name    channel name
+ *
+ * @return       pointer to glink channel context
+ *               NULL if channel doesn't exist
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_name
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  const char                *ch_name
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_remote_host
+===========================================================================*/
+/** 
+ * return remote subsystem ID based on remote subsystem name
+ *
+ * @param[in]    remote_ss  remote subsystem name
+ *
+ * @return       remote subsystem ID
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+uint32 glinki_find_remote_host
+(
+  const char *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glink_get_best_xport
+===========================================================================*/
+/** 
+ * This function gives best available transport for give edge
+ *
+ * @param[in]    remote_ss  Name of remote subsystem
+ * 
+ * @return       pointer to glink_transport_if_type
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_best_xport
+(
+  const char *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_requested_xport
+===========================================================================*/
+/** 
+ * Find requested or best transport depending on client's request
+ *
+ * @param[in]    xport_name         name of transport
+ * @param[in]    remote_ss          remote subsystem name
+ * @param[in]    open_ch_option     option client gave when called glink_open
+ * @param[out]   suggested_priority best xport priority glink suggests
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_requested_xport
+(
+  const char           *xport_name,
+  const char           *remote_ss,
+  uint32                open_ch_option,
+  glink_xport_priority *suggested_priority
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_xport_by_priority
+===========================================================================*/
+/** 
+ * This function returns glink_transport_if pointer based on transport priority
+ *
+ * @param[in]    prio        glink xport prio
+ * @param[in]    remote_ss   remote subsytem name
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_xport_by_priority
+(
+  glink_xport_priority  prio,
+  const char           *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glinki_enqueue_item
+===========================================================================*/
+/** 
+ *  Enqueue item to smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to enqueue
+ * @param[in]    item       item to enqueue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_enqueue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+);
+
+/*===========================================================================
+  FUNCTION      glinki_dequeue_item
+===========================================================================*/
+/** 
+ *  Dequeue item from smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to dequeue from 
+ * @param[in]    item       item to dequeue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_dequeue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+);
+
+#ifdef FEATURE_TRACER_PACKET
+/*===========================================================================
+FUNCTION      glink_tracer_packet_log_pctx_pkt
+===========================================================================*/
+/** 
+ * Log tracer packet event. Tracer packet is included in glink_core_tx_pkt
+ * and needs to use vprovider to extract it
+ * 
+ * @param[in]  pctx     pointer to glink_core_tx_pkt_type
+ * @param[in]  event_id event_id
+ * 
+ * @return         None
+ *
+ * @sideeffects    None
+ */
+/*=========================================================================*/
+void glink_tracer_packet_log_pctx_pkt
+(
+  glink_core_tx_pkt_type  *pctx,
+  uint32                   event_id
+);
+#endif
+
 #endif /* GLINK_INTERNAL_H */
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index eb7107d..bffa003 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -55,6 +55,7 @@
 		$(LOCAL_DIR)/rpm-ipc.o \
 		$(LOCAL_DIR)/glink/glink_api.o \
 		$(LOCAL_DIR)/glink/glink_core_if.o \
+		$(LOCAL_DIR)/glink/glink_core_internal.o \
 		$(LOCAL_DIR)/glink/glink_rpmcore_setup.o \
 		$(LOCAL_DIR)/glink/glink_core_intentless_xport.o \
 		$(LOCAL_DIR)/glink/glink_os_utils_dal.o \