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 \