Merge "app: aboot: support RLE24 compressed logo image"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index b4c10db..90b2b67 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -169,6 +169,7 @@
 static int auth_kernel_img = 0;
 
 static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}};
+static bool is_allow_unlock = 0;
 
 struct atag_ptbl_entry
 {
@@ -755,6 +756,22 @@
 		auth_kernel_img = 1;
 	}
 
+#ifdef MDTP_SUPPORT
+	{
+		/* Verify MDTP lock.
+		 * For boot & recovery partitions, use aboot's verification result.
+		 */
+		mdtp_ext_partition_verification_t ext_partition;
+		ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
+		ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
+		ext_partition.page_size = 0; /* Not needed since already validated */
+		ext_partition.image_addr = 0; /* Not needed since already validated */
+		ext_partition.image_size = 0; /* Not needed since already validated */
+		ext_partition.sig_avail = FALSE; /* Not needed since already validated */
+		mdtp_fwlock_verify_lock(&ext_partition);
+	}
+#endif /* MDTP_SUPPORT */
+
 #if USE_PCOM_SECBOOT
 	set_tamper_flag(device.is_tampered);
 #endif
@@ -836,7 +853,6 @@
 
 void boot_verifier_init()
 {
-
 	uint32_t boot_state;
 	/* Check if device unlock */
 	if(device.is_unlocked)
@@ -1026,6 +1042,23 @@
 		#ifdef TZ_SAVE_KERNEL_HASH
 		aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
 		#endif /* TZ_SAVE_KERNEL_HASH */
+
+#ifdef MDTP_SUPPORT
+		{
+			/* Verify MDTP lock.
+			 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
+			 * since verification was skipped in aboot. The signature is not part of the loaded image.
+			 */
+			mdtp_ext_partition_verification_t ext_partition;
+			ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
+			ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
+			ext_partition.page_size = page_size;
+			ext_partition.image_addr = (uint32)image_addr;
+			ext_partition.image_size = imagesize_actual;
+			ext_partition.sig_avail = FALSE;
+			mdtp_fwlock_verify_lock(&ext_partition);
+		}
+#endif /* MDTP_SUPPORT */
 	}
 
 	/*
@@ -1535,6 +1568,77 @@
 	}
 }
 
+static int read_allow_oem_unlock(device_info *dev)
+{
+	const char *ptn_name = "frp";
+	unsigned offset;
+	int index;
+	unsigned long long ptn;
+	unsigned long long ptn_size;
+	unsigned blocksize = mmc_get_device_blocksize();
+	char buf[blocksize];
+
+	index = partition_get_index(ptn_name);
+	if (index == INVALID_PTN)
+	{
+		dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+		return -1;
+	}
+
+	ptn = partition_get_offset(index);
+	ptn_size = partition_get_size(index);
+	offset = ptn_size - blocksize;
+
+	if (mmc_read(ptn + offset, (void *)buf, sizeof(buf)))
+	{
+		dprintf(CRITICAL, "Reading MMC failed\n");
+		return -1;
+	}
+
+	/*is_allow_unlock is a bool value stored at the LSB of last byte*/
+	is_allow_unlock = buf[blocksize-1] & 0x01;
+	return 0;
+}
+
+static int write_allow_oem_unlock(bool allow_unlock)
+{
+	const char *ptn_name = "frp";
+	unsigned offset;
+
+	int index;
+	unsigned long long ptn;
+	unsigned long long ptn_size;
+	unsigned blocksize = mmc_get_device_blocksize();
+	char buf[blocksize];
+
+	index = partition_get_index(ptn_name);
+	if (index == INVALID_PTN)
+	{
+		dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+		return -1;
+	}
+
+	ptn = partition_get_offset(index);
+	ptn_size = partition_get_size(index);
+	offset = ptn_size - blocksize;
+
+	if (mmc_read(ptn + offset, (void *)buf, sizeof(buf)))
+	{
+		dprintf(CRITICAL, "Reading MMC failed\n");
+		return -1;
+	}
+
+	/*is_allow_unlock is a bool value stored at the LSB of last byte*/
+	buf[blocksize-1] = allow_unlock;
+	if (mmc_write(ptn + offset, blocksize, buf))
+	{
+		dprintf(CRITICAL, "Writing MMC failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 void read_device_info_flash(device_info *dev)
 {
 	struct device_info *info = (void*) info_buf;
@@ -1749,13 +1853,6 @@
 	unsigned int kernel_size = 0;
 	unsigned int scratch_offset = 0;
 
-
-#ifdef MDTP_SUPPORT
-	/* Go through Firmware Lock verification before continue with boot process */
-	mdtp_fwlock_verify_lock();
-	display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
 #if VERIFIED_BOOT
 	if(!device.is_unlocked)
 	{
@@ -1807,6 +1904,24 @@
 		 */
 		verify_signed_bootimg((uint32_t)data, (image_actual - sig_actual));
 
+#ifdef MDTP_SUPPORT
+	else
+	{
+		/* Verify MDTP lock before continue with boot process.
+		 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
+		 * since verification was skipped in aboot. The signarue is already part of the loaded image.
+		 */
+		mdtp_ext_partition_verification_t ext_partition;
+		ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
+		ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
+		ext_partition.page_size = page_size;
+		ext_partition.image_addr = (uint32_t)data;
+		ext_partition.image_size = image_actual - sig_actual;
+		ext_partition.sig_avail = TRUE;
+		mdtp_fwlock_verify_lock(&ext_partition);
+	}
+#endif /* MDTP_SUPPORT */
+
 	/*
 	 * Check if the kernel image is a gzip package. If yes, need to decompress it.
 	 * If not, continue booting.
@@ -2016,12 +2131,13 @@
 	int index = INVALID_PTN;
 	char *token = NULL;
 	char *pname = NULL;
+	char *sp;
 	uint8_t lun = 0;
 	bool lun_set = false;
 
-	token = strtok((char *)arg, ":");
+	token = strtok_r((char *)arg, ":", &sp);
 	pname = token;
-	token = strtok(NULL, ":");
+	token = strtok_r(NULL, ":", &sp);
 	if(token)
 	{
 		lun = atoi(token);
@@ -2421,7 +2537,7 @@
 #endif /* SSD_ENABLE */
 
 #if VERIFIED_BOOT
-	if(!device.is_unlocked && !device.is_verified)
+	if(!device.is_unlocked)
 	{
 		fastboot_fail("device is locked. Cannot flash images");
 		return;
@@ -2536,12 +2652,6 @@
 	fastboot_okay("");
 	fastboot_stop();
 
-#ifdef MDTP_SUPPORT
-	/* Go through Firmware Lock verification before continue with boot process */
-	mdtp_fwlock_verify_lock();
-	display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
 	if (target_is_emmc_boot())
 	{
 		boot_linux_from_mmc();
@@ -2594,12 +2704,34 @@
 
 void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
 {
-	/* TODO: Wipe user data */
+	if(!is_allow_unlock) {
+		fastboot_fail("oem unlock is not allowed");
+		return;
+	}
+
+	display_fbcon_message("Oem Unlock requested");
+	fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
+}
+
+void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
+{
 	if(!device.is_unlocked || device.is_verified)
 	{
+		if(!is_allow_unlock) {
+			fastboot_fail("oem unlock is not allowed");
+			return;
+		}
+
 		device.is_unlocked = 1;
 		device.is_verified = 0;
 		write_device_info(&device);
+
+		struct recovery_message msg;
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+
+		fastboot_okay("");
+		reboot_device(RECOVERY_MODE);
 	}
 	fastboot_okay("");
 }
@@ -2883,6 +3015,7 @@
 											{"reboot", cmd_reboot},
 											{"reboot-bootloader", cmd_reboot_bootloader},
 											{"oem unlock", cmd_oem_unlock},
+											{"oem unlock-go", cmd_oem_unlock_go},
 											{"oem lock", cmd_oem_lock},
 											{"oem verified", cmd_oem_verified},
 											{"oem device-info", cmd_oem_devinfo},
@@ -2949,6 +3082,7 @@
 	ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
 
 	read_device_info(&device);
+	read_allow_oem_unlock(&device);
 
 	/* Display splash screen if enabled */
 #if DISPLAY_SPLASH_SCREEN
@@ -3019,12 +3153,6 @@
 normal_boot:
 	if (!boot_into_fastboot)
 	{
-#ifdef MDTP_SUPPORT
-			/* Go through Firmware Lock verification before continue with boot process */
-			mdtp_fwlock_verify_lock();
-			display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
 		if (target_is_emmc_boot())
 		{
 			if(emmc_recovery_init())
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 5c5782a..2ecccce 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -38,11 +38,14 @@
 #include <string.h>
 #include <rand.h>
 #include <stdlib.h>
+#include <boot_verifier.h>
+#include <image_verify.h>
 #include "scm.h"
 #include "mdtp.h"
 
-#define DIP_ENCRYPT 0
-#define DIP_DECRYPT 1
+#define DIP_ENCRYPT              (0)
+#define DIP_DECRYPT              (1)
+#define MAX_CIPHER_DIP_SCM_CALLS (3)
 
 #define MDTP_MAJOR_VERSION (0)
 #define MDTP_MINOR_VERSION (2)
@@ -50,15 +53,15 @@
 /** Extract major version number from complete version. */
 #define MDTP_GET_MAJOR_VERSION(version) ((version) >> 16)
 
-static int is_mdtp_activated = -1;
-
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
+static void mdtp_tzbsp_disallow_cipher_DIP(void);
 
 uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
+static int is_mdtp_activated = -1;
 
-int scm_random(uint32_t * rbuf, uint32_t  r_len);
 int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+int scm_random(uint32_t * rbuf, uint32_t  r_len);
 
 /********************************************************************************/
 
@@ -175,7 +178,7 @@
 	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
-	unsigned char *buf = (unsigned char *)target_get_scratch_address();
+	unsigned char *buf = (unsigned char *)target_get_scratch_address() + MDTP_SCRATCH_OFFSET;
 	uint32_t block_size = mmc_get_device_blocksize();
 	uint64_t actual_partition_size = ROUNDUP(size, block_size);
 
@@ -225,7 +228,7 @@
 	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
-	unsigned char *buf = (unsigned char *)target_get_scratch_address();
+	unsigned char *buf = (unsigned char *)target_get_scratch_address() + MDTP_SCRATCH_OFFSET;
 	uint32_t bytes_to_read;
 	uint32_t block_num = 0;
 	uint32_t total_num_blocks = ((size - 1) / MDTP_FWLOCK_BLOCK_SIZE) + 1;
@@ -377,18 +380,18 @@
 }
 
 /* Display the recovery UI to allow the user to enter the PIN and continue boot */
-static void display_recovery_ui(DIP_t *dip)
+static void display_recovery_ui(mdtp_cfg_t *mdtp_cfg)
 {
 	uint32_t pin_length = 0;
 	char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
 	uint32_t i;
 	char pin_mismatch = 0;
 
-	if (dip->mdtp_cfg.enable_local_pin_authentication)
+	if (mdtp_cfg->enable_local_pin_authentication)
 	{
 		dprintf(SPEW, "mdtp: display_recovery_ui: Local deactivation enabled\n");
 
-		pin_length = strlen(dip->mdtp_cfg.mdtp_pin.mdtp_pin);
+		pin_length = strlen(mdtp_cfg->mdtp_pin.mdtp_pin);
 
 		if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
 		{
@@ -411,7 +414,7 @@
 			// Go over the entire PIN in any case, to prevent side-channel attacks
 			for (i=0; i<pin_length; i++)
 			{
-				pin_mismatch |= dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
+				pin_mismatch |= mdtp_cfg->mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
 			}
 
 			if (0 == pin_mismatch)
@@ -439,11 +442,110 @@
 	}
 }
 
+/* Verify the boot or recovery partitions using boot_verifier. */
+static int verify_ext_partition(mdtp_ext_partition_verification_t *ext_partition)
+{
+	int ret = 0;
+	bool restore_to_orange = false;
+	unsigned long long ptn = 0;
+	int index = INVALID_PTN;
+
+	/* If image was already verified in aboot, return its status */
+	if (ext_partition->integrity_state == MDTP_PARTITION_STATE_INVALID)
+	{
+		dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verified externally and failed.\n",
+				ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+		return -1;
+	}
+	else if (ext_partition->integrity_state == MDTP_PARTITION_STATE_VALID)
+	{
+		dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verified externally succesfully.\n",
+				ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+		return 0;
+	}
+
+	/* If image was not verified in aboot, verify it ourselves using boot_verifier. */
+
+	/* 1) Initialize keystore. We don't care about return value which is Verified Boot's state machine state. */
+	boot_verify_keystore_init();
+
+	/* 2) If boot_verifier is ORANGE, it will prevent verifying an image. So
+	 *    temporarly change boot_verifier state to BOOT_INIT.
+	 */
+	if (boot_verify_get_state() == ORANGE)
+		restore_to_orange = true;
+	boot_verify_send_event(BOOT_INIT);
+
+	switch (ext_partition->partition)
+	{
+	case MDTP_PARTITION_BOOT:
+	case MDTP_PARTITION_RECOVERY:
+
+		/* 3) Signature may or may not be at the end of the image. Read the signature if needed. */
+		if (!ext_partition->sig_avail)
+		{
+			if (check_aboot_addr_range_overlap((uint32_t)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
+			{
+				dprintf(CRITICAL, "ERROR: Signature read buffer address overlaps with aboot addresses.\n");
+				return -1;
+			}
+
+			index = partition_get_index(ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+			ptn = partition_get_offset(index);
+			if(ptn == 0) {
+				dprintf(CRITICAL, "ERROR: partition %s not found\n",
+					ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+				return -1;
+			}
+
+			if(mmc_read(ptn + ext_partition->image_size, (void *)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
+			{
+				dprintf(CRITICAL, "ERROR: Cannot read %s image signature\n",
+					ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+				return -1;
+			}
+		}
+
+		/* 4) Verify the image using its signature. */
+		ret = boot_verify_image((unsigned char *)ext_partition->image_addr,
+								ext_partition->image_size,
+								ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+		break;
+
+	default:
+		/* Only boot and recovery are legal here */
+		dprintf(CRITICAL, "ERROR: wrong partition %d\n", ext_partition->partition);
+		return -1;
+	}
+
+	if (ret)
+	{
+		dprintf(INFO, "mdtp: verify_ext_partition: image %s verified succesfully in MDTP.\n",
+				ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+	}
+	else
+	{
+		dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verification failed in MDTP.\n",
+				ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
+	}
+
+	/* 5) Restore the right boot_verifier state upon exit. */
+	if (restore_to_orange)
+	{
+		boot_verify_send_event(DEV_UNLOCK);
+	}
+
+	return ret ? 0 : -1;
+}
+
 /* Verify all protected partitinons according to the DIP */
-static void verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
+static void verify_all_partitions(DIP_t *dip,
+								 mdtp_ext_partition_verification_t *ext_partition,
+								 verify_result_t *verify_result)
 {
 	int i;
-	bool verify_failure = FALSE;
+	int verify_failure = 0;
+	int ext_partition_verify_failure = 0;
 	uint32_t total_num_blocks;
 
 	ASSERT(dip != NULL);
@@ -487,7 +589,9 @@
 			}
 		}
 
-		if (verify_failure)
+		ext_partition_verify_failure = verify_ext_partition(ext_partition);
+
+		if (verify_failure || ext_partition_verify_failure)
 		{
 			dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
 			return;
@@ -501,7 +605,7 @@
 }
 
 /* Verify the DIP and all protected partitions */
-static void validate_DIP_and_firmware()
+static void validate_DIP_and_firmware(mdtp_ext_partition_verification_t *ext_partition)
 {
 	int ret;
 	DIP_t *enc_dip;
@@ -509,6 +613,7 @@
 	uint32_t verified = 0;
 	verify_result_t verify_result;
 	uint32_t block_size = mmc_get_device_blocksize();
+	mdtp_cfg_t mdtp_cfg;
 
 	enc_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
 	if (enc_dip == NULL)
@@ -548,12 +653,15 @@
 		display_error_msg(); /* This will never return */
 	}
 
-	/* Verify the integrity of the partitions which are protectedm, according to the content of the DIP */
-	verify_all_partitions(dec_dip, &verify_result);
+	/* Verify the integrity of the partitions which are protected, according to the content of the DIP */
+	verify_all_partitions(dec_dip, ext_partition, &verify_result);
+
+	mdtp_cfg = dec_dip->mdtp_cfg;
 
 	/* Clear decrypted DIP since we don't need it anymore */
 	memset(dec_dip, 0, sizeof(DIP_t));
 
+
 	if (verify_result == VERIFY_OK)
 	{
 		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
@@ -564,9 +672,11 @@
 	} else /* VERIFY_FAILED */
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
-		display_recovery_ui(dec_dip);
+		display_recovery_ui(&mdtp_cfg);
 	}
 
+	memset(&mdtp_cfg, 0, sizeof(mdtp_cfg));
+
 	free(enc_dip);
 	free(dec_dip);
 
@@ -575,10 +685,13 @@
 
 /********************************************************************************/
 
-/** Entry point of the MDTP Firmware Lock: If needed, verify the DIP
- *  and all protected partitions **/
-
-void mdtp_fwlock_verify_lock()
+/** Entry point of the MDTP Firmware Lock.
+ *  If needed, verify the DIP and all protected partitions.
+ *  Allow passing information about partition verified using an external method
+ *  (either boot or recovery). For boot and recovery, either use aboot's
+ *  verification result, or use boot_verifier APIs to verify internally.
+ **/
+void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
 {
 	int ret;
 	bool enabled;
@@ -586,18 +699,34 @@
 	/* sets the default value of this global to be MDTP not activated */
 	is_mdtp_activated = 0;
 
-	ret = mdtp_fuse_get_enabled(&enabled);
-	if(ret)
-	{
-		dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
-		display_error_msg(); /* This will never return */
-	}
+	do {
+		if (ext_partition == NULL)
+		{
+			dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, external partition is NULL\n");
+			display_error_msg(); /* This will never return */
+			break;
+		}
 
-	/* Continue with Firmware Lock verification only if enabled by eFuse */
-	if (enabled)
+		ret = mdtp_fuse_get_enabled(&enabled);
+		if(ret)
+		{
+			dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
+			display_error_msg(); /* This will never return */
+		}
+
+		/* Continue with Firmware Lock verification only if enabled by eFuse */
+		if (enabled)
+		{
+			/* This function will handle firmware verification failure via UI */
+			validate_DIP_and_firmware(ext_partition);
+		}
+	} while (0);
+
+	/* Disallow CIPHER_DIP SCM call from this point, unless we are in recovery */
+	/* The recovery image will disallow CIPHER_DIP SCM call by itself. */
+	if (ext_partition->partition != MDTP_PARTITION_RECOVERY)
 	{
-		/* This function will handle firmware verification failure via UI */
-		validate_DIP_and_firmware();
+		mdtp_tzbsp_disallow_cipher_DIP();
 	}
 }
 /********************************************************************************/
@@ -654,6 +783,7 @@
 	return 0;
 }
 
+/* Encrypt a given DIP and calculate its integrity information */
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
 {
 	SHA256_CTX sha256_ctx;
@@ -677,3 +807,25 @@
 
 	return 0;
 }
+
+/* Disallow the CIPHER_DIP SCM call */
+static void mdtp_tzbsp_disallow_cipher_DIP(void)
+{
+	DIP_t *dip;
+	int i;
+
+	dip = malloc(sizeof(DIP_t));
+	if (dip == NULL)
+	{
+		dprintf(CRITICAL, "mdtp: mdtp_tzbsp_disallow_cipher_DIP: ERROR, cannot allocate DIP\n");
+		return;
+	}
+
+	/* Disallow the CIPHER_DIP SCM by calling it MAX_CIPHER_DIP_SCM_CALLS times */
+	for (i=0; i<MAX_CIPHER_DIP_SCM_CALLS; i++)
+	{
+		mdtp_tzbsp_enc_hash_DIP(dip, dip);
+	}
+
+	free(dip);
+}
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 0f30b54..c29dcc2 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -45,6 +45,13 @@
 #define MDTP_FWLOCK_BLOCK_SIZE          (1024*1024*16)
 #define MDTP_FWLOCK_MAX_FILES           (100)
 #define MDTP_FWLOCK_MAX_FILE_NAME_LEN   (100)
+#define MDTP_SCRATCH_OFFSET 0x8000000
+
+#ifdef MDTP_SUPPORT
+#ifndef VERIFIED_BOOT
+#error MDTP feature requires VERIFIED_BOOT feature
+#endif
+#endif
 
 #pragma pack(push, mdtp, 1)
 
@@ -102,22 +109,35 @@
 } DIP_t;
 
 #pragma pack(pop, mdtp)
+
+typedef enum {
+	MDTP_PARTITION_BOOT = 0,
+	MDTP_PARTITION_RECOVERY,
+	MDTP_PARTITION_NUM,
+} mdtp_ext_partition_t;
+
+typedef enum {
+	MDTP_PARTITION_STATE_UNSET = 0,
+	MDTP_PARTITION_STATE_VALID,
+	MDTP_PARTITION_STATE_INVALID,
+	MDTP_PARTITION_STATE_SIZE,
+} mdtp_ext_partition_state_t;
+
+typedef struct mdtp_ext_partition {
+	mdtp_ext_partition_t partition;
+	mdtp_ext_partition_state_t integrity_state;
+	uint32_t page_size;
+	uint32_t image_addr;
+	uint32_t image_size;
+	bool sig_avail;
+} mdtp_ext_partition_verification_t;
+
 typedef enum {
 	VERIFY_SKIPPED = 0,
 	VERIFY_OK,
 	VERIFY_FAILED,
 } verify_result_t;
 
-
-/**
- * mdtp_fwlock_verify_lock
- *
- * Start Firmware Lock verification process.
- *
- * @return - None.
- */
-void mdtp_fwlock_verify_lock();
-
 /**
  * mdtp_fuse_get_enabled
  *
@@ -175,4 +195,15 @@
  */
 int mdtp_activated(bool * activated);
 
+
+// External functions
+
+/** Entry point of the MDTP Firmware Lock.
+ *  If needed, verify the DIP and all protected partitions.
+ *  Allow passing information about partition verified using an external method
+ *  (either boot or recovery). For boot and recovery, either use aboot's
+ *  verification result, or use boot_verifier APIs to verify internally.
+ **/
+void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition);
+
 #endif
diff --git a/dev/gcdb/display/include/panel_otm1906c_1080p_cmd.h b/dev/gcdb/display/include/panel_otm1906c_1080p_cmd.h
new file mode 100644
index 0000000..8f3e92c
--- /dev/null
+++ b/dev/gcdb/display/include/panel_otm1906c_1080p_cmd.h
@@ -0,0 +1,1786 @@
+/* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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.
+ */
+
+#ifndef _PANEL_OTM1906C_1080P_CMD_H_
+#define _PANEL_OTM1906C_1080P_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config otm1906c_1080p_cmd_panel_data = {
+	"qcom,mdss_dsi_otm1906c_1080p_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, NULL
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution otm1906c_1080p_cmd_panel_res = {
+	1080, 1920, 45, 45, 8, 0, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info otm1906c_1080p_cmd_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char otm1906c_1080p_cmd_on_cmd0[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd1[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xFF, 0x19, 0x06, 0x01,
+};
+
+static char otm1906c_1080p_cmd_on_cmd2[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd3[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xFF, 0x19, 0x06, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd4[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd5[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xC1, 0x00, 0xC0, 0x10,
+};
+
+static char otm1906c_1080p_cmd_on_cmd6[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x91, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd7[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xC5, 0x14, 0x28, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd8[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x95, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd9[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC5, 0x11, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd10[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x81, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd11[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xa5, 0x01, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd12[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xa5, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd13[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xc5, 0x11, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd14[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd15[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0xF5, 0x09, 0x16, 0x09,
+	0x16, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd16[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA7, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd17[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x1A, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd18[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x9D, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd19[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x1A, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd20[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA5, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd21[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd22[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x8D, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd23[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x17, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd24[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE3, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd25[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x11, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd26[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xED, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd27[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd28[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE5, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd29[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd30[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x81, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd31[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd32[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x83, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd33[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd34[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE1, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd35[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xF5, 0x16, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd36[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd37[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x81, 0x80, 0x81,
+	0x81, 0x81, 0x82, 0x83,
+	0x83, 0x84, 0x83, 0x85,
+	0x86, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd38[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd39[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x00, 0x00, 0x80,
+	0x81, 0x82, 0x83, 0x83,
+	0x83, 0x84, 0x84, 0x86,
+	0x88, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd40[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd41[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x00, 0x01, 0x02,
+	0x02, 0x03, 0x04, 0x05,
+	0x06, 0x08, 0x06, 0x2e,
+	0x56, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd42[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd43[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x00, 0x80, 0x80,
+	0x81, 0x82, 0x83, 0x83,
+	0x84, 0x85, 0x84, 0x8b,
+	0x91, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd44[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd45[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x82, 0x83, 0x83,
+	0x85, 0x87, 0x89, 0x8b,
+	0x8f, 0x90, 0x91, 0x95,
+	0x99, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd46[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd47[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xD8, 0x02, 0x02, 0x02,
+	0x03, 0x04, 0x05, 0x06,
+	0x08, 0x0a, 0x0b, 0x18,
+	0x24, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd48[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd49[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0xD7, 0x82, 0x80, 0xC0,
+	0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd50[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd51[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x84, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd52[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd53[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xD9, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd54[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x01, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd55[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xD9, 0xac, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd56[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd57[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xC1, 0x55, 0x55, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd58[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x94, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd59[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC5, 0x88, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd60[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA4, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd61[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC5, 0x88, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd62[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC1, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd63[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC5, 0xF5, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd64[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB3, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd65[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC0, 0x88, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd66[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB4, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd67[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC0, 0x50, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd68[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd69[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xD8, 0x23, 0x23, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd70[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd71[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC4, 0x81, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd72[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd73[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB3, 0x33, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd74[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA6, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd75[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB3, 0x20, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd76[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd77[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xB4, 0x1C, 0x19, 0x3F,
+	0x01, 0x64, 0x5C, 0x01,
+	0xA0, 0x5F, 0xA0, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd78[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd79[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB4, 0x64, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd80[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd81[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xC0, 0x00, 0x70, 0x00,
+	0x0A, 0x0A, 0x00, 0x70,
+	0x0A, 0x0A, 0x00, 0x70,
+	0x00, 0x0A, 0x0A, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd82[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd83[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0xC0, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x04, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd84[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd85[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC0, 0x00, 0x00, 0x02,
+	0x00, 0x04, 0x15, 0x04,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd86[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd87[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC0, 0x00, 0x00, 0x02,
+	0x00, 0x04, 0x15, 0x04,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd88[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd89[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xC2, 0x83, 0x01, 0x00,
+	0x00, 0x82, 0x01, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd90[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd91[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xC2, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd92[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd93[] = {
+	0x0E, 0x00, 0x29, 0xC0,
+	0xC2, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd94[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd95[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC2, 0x82, 0x02, 0x00,
+	0x00, 0x88, 0x81, 0x02,
+	0x00, 0x00, 0x88, 0x00,
+	0x02, 0x00, 0x00, 0x88,
+};
+
+static char otm1906c_1080p_cmd_on_cmd96[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd97[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC2, 0x01, 0x02, 0x00,
+	0x00, 0x88, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd98[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd99[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC2, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x33,
+	0x33, 0x33, 0x33, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd100[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd101[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC3, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd102[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd103[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xC3, 0x83, 0x01, 0x00,
+	0x00, 0x82, 0x01, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd104[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd105[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xC3, 0x00, 0x00, 0x00,
+	0x00, 0x82, 0x02, 0x00,
+	0x00, 0x88, 0x81, 0x02,
+	0x00, 0x00, 0x88, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd106[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd107[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC3, 0x00, 0x02, 0x00,
+	0x00, 0x88, 0x01, 0x02,
+	0x00, 0x00, 0x88, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd108[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd109[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xC3, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd110[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd111[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xC3, 0x33, 0x33, 0x33,
+	0x33, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd112[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd113[] = {
+	0x0C, 0x00, 0x29, 0xC0,
+	0xCB, 0x00, 0x00, 0x00,
+	0x00, 0x30, 0x00, 0x03,
+	0x00, 0x00, 0x00, 0x70,
+};
+
+static char otm1906c_1080p_cmd_on_cmd114[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd115[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCB, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd116[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd117[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCB, 0x00, 0x00, 0x00,
+	0xBF, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFF, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd118[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd119[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xCB, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x77,
+	0x77, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd120[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd121[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCB, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01,
+};
+
+static char otm1906c_1080p_cmd_on_cmd122[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd123[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCB, 0x01, 0x01, 0x01,
+	0xF3, 0x01, 0x01, 0x01,
+	0x01, 0x00, 0xF3, 0x00,
+	0x00, 0x01, 0x00, 0x01,
+};
+
+static char otm1906c_1080p_cmd_on_cmd124[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd125[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xCB, 0x00, 0x01, 0x00,
+	0x01, 0x00, 0x01, 0x00,
+	0x01, 0x00, 0x00, 0x77,
+	0x07, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd126[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd127[] = {
+	0x0C, 0x00, 0x29, 0xC0,
+	0xCB, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0x03,
+	0x33, 0x03, 0x00, 0x70,
+};
+
+static char otm1906c_1080p_cmd_on_cmd128[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd129[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xCC, 0x08, 0x09, 0x18,
+	0x19, 0x0C, 0x0D, 0x0E,
+	0x0F, 0x07, 0x07, 0x07,
+	0x07, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd130[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd131[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xCC, 0x09, 0x08, 0x19,
+	0x18, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x07, 0x07, 0x07,
+	0x07, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd132[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd133[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCC, 0x14, 0x15, 0x16,
+	0x17, 0x1C, 0x1D, 0x1E,
+	0x1F, 0x01, 0x04, 0x20,
+	0x07, 0x07, 0x07, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd134[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd135[] = {
+	0x0A, 0x00, 0x29, 0xC0,
+	0xCC, 0x01, 0x02, 0x03,
+	0x04, 0x05, 0x06, 0x07,
+	0x07, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd136[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd137[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCD, 0x1A, 0x01, 0x11,
+	0x12, 0x1A, 0x05, 0x18,
+	0x07, 0x1A, 0x1A, 0x23,
+	0x23, 0x23, 0x1F, 0x1E,
+};
+
+static char otm1906c_1080p_cmd_on_cmd138[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd139[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xCD, 0x1D, 0x23, 0x23,
+};
+
+static char otm1906c_1080p_cmd_on_cmd140[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd141[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCD, 0x1A, 0x02, 0x11,
+	0x12, 0x1A, 0x06, 0x18,
+	0x08, 0x1A, 0x1A, 0x23,
+	0x23, 0x23, 0x1F, 0x1E,
+};
+
+static char otm1906c_1080p_cmd_on_cmd142[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd143[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xCD, 0x1D, 0x23, 0x23,
+};
+
+static char otm1906c_1080p_cmd_on_cmd144[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd145[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA4, 0xAF, 0x00, 0x20,
+	0x04, 0x00, 0x17, 0x15,
+	0x03, 0x60, 0x00, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd146[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd147[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xA4, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd148[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd149[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xA7, 0xFF, 0x0F, 0x1E,
+	0x00, 0x20, 0x00, 0x01,
+	0x98, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd150[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd151[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA7, 0x1D, 0x20, 0x3d,
+	0x00, 0x00, 0xBE, 0x80,
+	0xBE, 0x05, 0xF0, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd152[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd153[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xA7, 0x30, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd154[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd155[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xA7, 0x00, 0x1E, 0x1E,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd156[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd157[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xA7, 0xFF, 0x3A, 0x49,
+	0x00, 0x1E, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd158[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd159[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA7, 0xFF, 0xFF, 0x1c,
+	0x00, 0x01, 0x7C, 0x81,
+	0x7C, 0x0B, 0xE0, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd160[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd161[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xA7, 0x30, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd162[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd163[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xA7, 0x00, 0x3C, 0x3C,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd164[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd165[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA7, 0xFF, 0xFF, 0x1D,
+	0x00, 0x01, 0x7C, 0x81,
+	0x7C, 0x0B, 0xE0, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd166[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd167[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xA9, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd168[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd169[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA9, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd170[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd171[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xA9, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd172[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd173[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xA9, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd174[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd175[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xA9, 0xFF, 0x3A, 0x49,
+	0x00, 0x1E, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x77, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd176[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd177[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xA9, 0xFF, 0xFF, 0x1D,
+	0x00, 0x01, 0x7C, 0x81,
+	0x7C, 0x0B, 0xE0, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd178[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd179[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xA9, 0x30, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd180[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd181[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xA9, 0x00, 0x3C, 0x3C,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd182[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd183[] = {
+	0x09, 0x00, 0x29, 0xC0,
+	0xA4, 0x05, 0xF0, 0x0B,
+	0xE0, 0x00, 0x00, 0x0B,
+	0xE0, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd184[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd185[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xAB, 0x05, 0x14, 0x00,
+	0x00, 0xFF, 0x6A, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd186[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd187[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xAB, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x00, 0x00,
+	0x00, 0x01, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd188[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd189[] = {
+	0x0d, 0x00, 0x29, 0xC0,
+	0xAB, 0x00, 0x00, 0x68,
+	0x0A, 0x00, 0x00, 0x44,
+	0x04, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd190[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x93, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd191[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB3, 0x01, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd192[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd193[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd194[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x87, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd195[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x33,
+	0x00, 0x33, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd196[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd197[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd198[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x90, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd199[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x00,
+	0xF0, 0x00, 0x00, 0x00,
+	0x00, 0xFC, 0x00, 0xFC,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd200[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xA0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd201[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x40,
+	0x40, 0x40, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd202[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xB0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd203[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCE, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01,
+	0x01, 0xF1, 0x01, 0xF1,
+	0x01, 0x01, 0x01, 0x01,
+};
+
+static char otm1906c_1080p_cmd_on_cmd204[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd205[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xCE, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01,
+};
+
+static char otm1906c_1080p_cmd_on_cmd206[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xD0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd207[] = {
+	0x10, 0x00, 0x29, 0xC0,
+	0xCE, 0x04, 0x04, 0x04,
+	0x04, 0x04, 0x04, 0x04,
+	0x04, 0xF7, 0x04, 0xF7,
+	0x04, 0x04, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd208[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xE0, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd209[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xCE, 0x00, 0x00, 0x15,
+	0x15, 0x15, 0x04, 0x04,
+};
+
+static char otm1906c_1080p_cmd_on_cmd210[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0xF4, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd211[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xCE, 0x25, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd212[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd213[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE1, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd214[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd215[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE2, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd216[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd217[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE3, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd218[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd219[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE4, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd220[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd221[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE5, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd222[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd223[] = {
+	0x19, 0x00, 0x29, 0xC0,
+	0xE6, 0x00, 0x07, 0x0d,
+	0x17, 0x21, 0x28, 0x35,
+	0x48, 0x54, 0x65, 0x6f,
+	0x76, 0x85, 0x7f, 0x77,
+	0x67, 0x53, 0x40, 0x33,
+	0x2a, 0x20, 0x12, 0x04,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd224[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd225[] = {
+	0x22, 0x00, 0x29, 0xC0,
+	0xEC, 0x40, 0x44, 0x43,
+	0x44, 0x44, 0x34, 0x44,
+	0x44, 0x44, 0x34, 0x44,
+	0x44, 0x44, 0x43, 0x44,
+	0x44, 0x34, 0x44, 0x44,
+	0x44, 0x43, 0x44, 0x44,
+	0x34, 0x44, 0x44, 0x44,
+	0x43, 0x44, 0x44, 0x44,
+	0x43, 0x04, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd226[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd227[] = {
+	0x22, 0x00, 0x29, 0xC0,
+	0xED, 0x40, 0x44, 0x43,
+	0x44, 0x44, 0x34, 0x44,
+	0x44, 0x44, 0x43, 0x44,
+	0x44, 0x34, 0x44, 0x44,
+	0x44, 0x43, 0x44, 0x44,
+	0x34, 0x44, 0x44, 0x44,
+	0x43, 0x44, 0x44, 0x34,
+	0x44, 0x44, 0x44, 0x34,
+	0x44, 0x04, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd228[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd229[] = {
+	0x22, 0x00, 0x29, 0xC0,
+	0xEE, 0x40, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x44, 0x44, 0x44,
+	0x44, 0x04, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd230[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd231[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xFB, 0x01, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd232[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x80, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd233[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xFF, 0x00, 0x00, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd234[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd235[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xFF, 0x00, 0x00, 0x00,
+};
+
+static char otm1906c_1080p_cmd_on_cmd236[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd237[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x11, 0x00, 0xFF, 0xFF,
+};
+
+static char otm1906c_1080p_cmd_on_cmd238[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0x29, 0x00, 0xFF, 0xFF,
+};
+
+static struct mipi_dsi_cmd otm1906c_1080p_cmd_on_command[] = {
+	{0x8, otm1906c_1080p_cmd_on_cmd0, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd1, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd2, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd3, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd4, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd5, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd6, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd7, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd8, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd9, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd10, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd11, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd12, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd13, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd14, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd15, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd16, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd17, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd18, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd19, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd20, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd21, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd22, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd23, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd24, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd25, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd26, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd27, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd28, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd29, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd30, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd31, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd32, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd33, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd34, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd35, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd36, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd37, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd38, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd39, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd40, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd41, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd42, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd43, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd44, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd45, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd46, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd47, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd48, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd49, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd50, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd51, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd52, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd53, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd54, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd55, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd56, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd57, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd58, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd59, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd60, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd61, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd62, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd63, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd64, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd65, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd66, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd67, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd68, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd69, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd70, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd71, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd72, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd73, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd74, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd75, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd76, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd77, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd78, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd79, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd80, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd81, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd82, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd83, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd84, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd85, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd86, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd87, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd88, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd89, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd90, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd91, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd92, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd93, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd94, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd95, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd96, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd97, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd98, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd99, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd100, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd101, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd102, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd103, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd104, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd105, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd106, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd107, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd108, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd109, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd110, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd111, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd112, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd113, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd114, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd115, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd116, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd117, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd118, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd119, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd120, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd121, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd122, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd123, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd124, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd125, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd126, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd127, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd128, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd129, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd130, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd131, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd132, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd133, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd134, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd135, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd136, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd137, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd138, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd139, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd140, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd141, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd142, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd143, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd144, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd145, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd146, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd147, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd148, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd149, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd150, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd151, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd152, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd153, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd154, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd155, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd156, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd157, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd158, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd159, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd160, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd161, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd162, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd163, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd164, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd165, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd166, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd167, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd168, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd169, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd170, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd171, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd172, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd173, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd174, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd175, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd176, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd177, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd178, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd179, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd180, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd181, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd182, 0x00},
+	{0x10, otm1906c_1080p_cmd_on_cmd183, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd184, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd185, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd186, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd187, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd188, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd189, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd190, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd191, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd192, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd193, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd194, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd195, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd196, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd197, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd198, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd199, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd200, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd201, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd202, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd203, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd204, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd205, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd206, 0x00},
+	{0x14, otm1906c_1080p_cmd_on_cmd207, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd208, 0x00},
+	{0xc, otm1906c_1080p_cmd_on_cmd209, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd210, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd211, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd212, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd213, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd214, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd215, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd216, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd217, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd218, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd219, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd220, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd221, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd222, 0x00},
+	{0x20, otm1906c_1080p_cmd_on_cmd223, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd224, 0x00},
+	{0x28, otm1906c_1080p_cmd_on_cmd225, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd226, 0x00},
+	{0x28, otm1906c_1080p_cmd_on_cmd227, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd228, 0x00},
+	{0x28, otm1906c_1080p_cmd_on_cmd229, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd230, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd231, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd232, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd233, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd234, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd235, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd236, 0x00},
+	{0x8, otm1906c_1080p_cmd_on_cmd237, 0x78},
+	{0x8, otm1906c_1080p_cmd_on_cmd238, 0x78}
+};
+
+#define OTM1906C_1080P_CMD_ON_COMMAND 239
+
+
+static char otm1906c_1080p_cmdoff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char otm1906c_1080p_cmdoff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd otm1906c_1080p_cmd_off_command[] = {
+	{0x4, otm1906c_1080p_cmdoff_cmd0, 0x32},
+	{0x4, otm1906c_1080p_cmdoff_cmd1, 0x78}
+};
+
+#define OTM1906C_1080P_CMD_OFF_COMMAND 2
+
+
+static struct command_state otm1906c_1080p_cmd_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info otm1906c_1080p_cmd_command_panel = {
+	1, 1, 1, 0, 0, 0x2c, 0, 0, 0, 1, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info otm1906c_1080p_cmd_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration otm1906c_1080p_cmd_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t otm1906c_1080p_cmd_timings[] = {
+	0x6E, 0x3F, 0x36, 0x00, 0x5A, 0x4F, 0x38, 0x41, 0x54, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing otm1906c_1080p_cmd_timing_info = {
+	0, 4, 0x1E, 0x30
+};
+
+static struct panel_reset_sequence otm1906c_1080p_cmd_panel_reset_seq = {
+{ 1, 0, 1, }, { 200, 200, 200, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight otm1906c_1080p_cmd_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#define OTM1906C_1080P_CMD_SIGNATURE 0xFFFF
+
+#endif /*_PANEL_OTM1906C_1080P_CMD_H_*/
diff --git a/include/platform.h b/include/platform.h
index a513843..3cb7f2f 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -49,6 +49,7 @@
 void display_init(void);
 void display_shutdown(void);
 void display_image_on_screen(void);
+void display_fbcon_message(char *str);
 
 unsigned board_machtype(void);
 unsigned board_platform_id(void);
diff --git a/include/string.h b/include/string.h
index 593ecf2..1d987c3 100644
--- a/include/string.h
+++ b/include/string.h
@@ -53,6 +53,7 @@
 size_t      strcspn(const char *s, const char *) __PURE;
 char       *strstr(char const *, char const *) __PURE;
 char       *strtok(char *, char const *);
+char       *strtok_r(char *s, const char *delim, char **last);
 int         strcoll(const char *s1, const char *s2) __PURE;
 size_t      strxfrm(char *dest, const char *src, size_t n) __PURE;
 char       *strdup(const char *str) __MALLOC;
diff --git a/lib/libc/string/strtok.c b/lib/libc/string/strtok.c
index b7c4585..4e963a0 100644
--- a/lib/libc/string/strtok.c
+++ b/lib/libc/string/strtok.c
@@ -1,51 +1,86 @@
-/* 
-** Copyright 2001, Travis Geiselbrecht. All rights reserved.
-** Distributed under the terms of the NewOS License.
-*/
 /*
- * Copyright (c) 2008 Travis Geiselbrecht
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
  *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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 <string.h>
-#include <sys/types.h>
 
-static char *___strtok = NULL;
+#include <string.h>
 
 char *
-strtok(char *s, char const *ct)
+strtok(char *s, const char *delim)
 {
-	char *sbegin, *send;
+	static char *last;
 
-	sbegin  = s ? s : ___strtok;
-	if (!sbegin) {
-		return NULL;
+	return strtok_r(s, delim, &last);
+}
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+	char *spanp;
+	int c, sc;
+	char *tok;
+
+
+	if (s == NULL && (s = *last) == NULL)
+		return (NULL);
+
+	/*
+	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+	 */
+cont:
+	c = *s++;
+	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+		if (c == sc)
+			goto cont;
 	}
-	sbegin += strspn(sbegin,ct);
-	if (*sbegin == '\0') {
-		___strtok = NULL;
-		return( NULL );
+
+	if (c == 0) {		/* no non-delimiter characters */
+		*last = NULL;
+		return (NULL);
 	}
-	send = strpbrk( sbegin, ct);
-	if (send && *send != '\0')
-		*send++ = '\0';
-	___strtok = send;
-	return (sbegin);
+	tok = s - 1;
+
+	/*
+	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+	 * Note that delim must have one NUL; we stop if we see that, too.
+	 */
+	for (;;) {
+		c = *s++;
+		spanp = (char *)delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = 0;
+				*last = s;
+				return (tok);
+			}
+		} while (sc != 0);
+	}
+	/* NOTREACHED */
 }
diff --git a/lib/openssl/crypto/err/err.c b/lib/openssl/crypto/err/err.c
index bd0d402..0a0a45d 100644
--- a/lib/openssl/crypto/err/err.c
+++ b/lib/openssl/crypto/err/err.c
@@ -603,7 +603,7 @@
 			char *src = strerror(i);
 			if (src != NULL)
 				{
-				strncpy(*dest, src, sizeof *dest);
+				strlcpy(*dest, src, sizeof *dest);
 				(*dest)[sizeof *dest - 1] = '\0';
 				str->string = *dest;
 				}
diff --git a/lib/openssl/crypto/evp/evp_key.c b/lib/openssl/crypto/evp/evp_key.c
index 7a3dd35..322fa89 100644
--- a/lib/openssl/crypto/evp/evp_key.c
+++ b/lib/openssl/crypto/evp/evp_key.c
@@ -72,7 +72,7 @@
 		prompt_string[0]='\0';
 	else
 		{
-		strncpy(prompt_string,prompt,79);
+		strlcpy(prompt_string,prompt,79);
 		prompt_string[79]='\0';
 		}
 	}
diff --git a/platform/msm_shared/boot_device.c b/platform/msm_shared/boot_device.c
index ac29dac..f74bdd1 100644
--- a/platform/msm_shared/boot_device.c
+++ b/platform/msm_shared/boot_device.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -76,14 +76,14 @@
 	{
 #if !USE_MDM_BOOT_CFG
 		case BOOT_DEFAULT:
-			sprintf(buf, "%x.sdhci", ((struct mmc_device *)dev)->host.base);
+			snprintf(buf, ((sizeof((struct mmc_device *)dev)->host.base)*2) + 7,"%x.sdhci", ((struct mmc_device *)dev)->host.base);
 			break;
 		case BOOT_UFS:
-			sprintf(buf, "%x.ufshc", ((struct ufs_dev *)dev)->base);
+			snprintf(buf, ((sizeof((struct ufs_dev *)dev)->base)*2) + 7, "%x.ufshc", ((struct ufs_dev *)dev)->base);
 			break;
 #endif
 		case BOOT_EMMC:
-			sprintf(buf, "%x.sdhci", ((struct mmc_device *)dev)->host.base);
+			snprintf(buf, ((sizeof((struct mmc_device *)dev)->host.base)*2) + 7,"%x.sdhci", ((struct mmc_device *)dev)->host.base);
 			break;
 		default:
 			dprintf(CRITICAL,"ERROR: Unexpected boot_device val=%x",val);
diff --git a/platform/msm_shared/debug.c b/platform/msm_shared/debug.c
index 45d1c32..b8c3266 100644
--- a/platform/msm_shared/debug.c
+++ b/platform/msm_shared/debug.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-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
@@ -43,6 +43,7 @@
 #include <vibrator.h>
 #endif
 
+
 static void write_dcc(char c)
 {
 	uint32_t timeout = 10;
@@ -96,6 +97,15 @@
 }
 #endif /* WITH_DEBUG_LOG_BUF */
 
+void display_fbcon_message(char *str)
+{
+#if ENABLE_FBCON_LOGGING
+	while(*str != 0) {
+		fbcon_putc(*str++);
+	}
+#endif
+}
+
 void _dputc(char c)
 {
 #if WITH_DEBUG_LOG_BUF
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index 24f777d..fe5fd92 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -43,7 +43,7 @@
 #define GLINK_INITIALIZED     1
 
 /*===========================================================================
-                              GLOBAL DATA DECLARATIONS
+                        GLOBAL DATA DECLARATIONS
 ===========================================================================*/
 int glink_core_status = GLINK_NOT_INITIALIZED;
 
@@ -74,174 +74,249 @@
 /*===========================================================================
                     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_transport_if_type  *req_if_ptr,
   glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type   **allocated_ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
   unsigned int              local_open,
-  boolean                      migration_state,
   glink_xport_priority      migrated_ch_prio
 )
 {
-  glink_err_type             status = 0;
+  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);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
+
+  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 (strcmp(open_ch_ctx->name, ch_ctx->name) == 0)
+    if( 0 != glink_os_string_compare( open_ch_ctx->name, ch_ctx->name ) )
     {
-      /* We've found a channel name is already in the list of open channel */
-      /* increase reference open count for channel */
-      *allocated_ch_ctx = open_ch_ctx;
-      open_ch_ctx->ref_count++;
+      continue;
+    }
+    /* grab lock to avoid race condition for channel state change */
+    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
 
-      /* Case A: Channel was opened before on the same host */
-      if((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) && local_open) {
-
-        open_ch_ctx->req_if_ptr = req_if_ptr;
-
-        /* Copy local open ctx params */
-        open_ch_ctx->notify_rx = ch_ctx->notify_rx;
-        open_ch_ctx->notify_rxv = ch_ctx->notify_rxv;
-        open_ch_ctx->notify_tx_done = ch_ctx->notify_tx_done;
-        open_ch_ctx->notify_state = ch_ctx->notify_state;
-        open_ch_ctx->notify_rx_intent_req = ch_ctx->notify_rx_intent_req;
-        open_ch_ctx->notify_rx_intent = ch_ctx->notify_rx_intent;
-        open_ch_ctx->notify_rx_sigs = ch_ctx->notify_rx_sigs;
-        open_ch_ctx->priv = ch_ctx->priv;
-        open_ch_ctx->ch_open_options = ch_ctx->ch_open_options;
-
-        /* release lock before context switch otherwise it is causing
-         * deadlock */
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        /* Send open cmd to transport */
-        status = if_ptr->tx_cmd_ch_open(if_ptr,
-                      open_ch_ctx->lcid, open_ch_ctx->name,
-                      open_ch_ctx->req_if_ptr->glink_priority);
-      }
-      else if ((open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN) &&
-               (!local_open))
-      {
-        /* Case B: Channel was opened on this end and we got a remote open */
-        open_ch_ctx->rcid = ch_ctx->rcid;
-
-        status = xport_ctx->channel_init(open_ch_ctx);
-
-        /* release lock before context switch otherwise it is causing deadlock */
-        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);
-        }
-      } else if ((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE)
-                  && (local_open)) {
-        /* Allocate new channel context */
-        break; /* code would break out of loop and create new ch ctx */
-      } else {
-        /* Can't handle this state */
-        ASSERT(0);
-      }
-
-      break;
-    } /* end if match found */
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  if (open_ch_ctx != NULL)
-  {
-    glink_os_free(ch_ctx);
-
-    /* connect channel here if state is local open and remote open request
-     * comes up and channel migration is done; channel will be connected in
-     * remote_open_ack if channel state is remote open and local open
-     * request comes up */
-    if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN &&
-       migration_state == FALSE && status == GLINK_STATUS_SUCCESS)
+    if( local_open )
     {
-      /* Set the channel state to OPEN */
-      open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-      /* Inform the client */
-      open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                GLINK_CONNECTED);
-    }
-  }
-  else
-  {
-    /* Channel not in the list - it was not previously opened */
-    ch_ctx->if_ptr = if_ptr;
-    *allocated_ch_ctx = ch_ctx;
+      /* LOCAL OPEN REQUEST */
+      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
 
-    /* Set channel state */
-    if (local_open) {
-      /* This is a local open */
-      ch_ctx->state      = GLINK_CH_STATE_LOCAL_OPEN;
-      ch_ctx->req_if_ptr = req_if_ptr;
-    }
-    else {
-      ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN;
-    }
+      glink_os_cs_init( &ch_ctx->tx_cs );
+      glink_os_cs_init( &ch_ctx->ch_state_cs );
 
-    glink_os_cs_init(&ch_ctx->tx_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;
+      ch_ctx->req_if_ptr  = req_if_ptr;
 
-    /* Append the channel to the transport interface's open_list */
-    ch_ctx->ref_count++;
-    ch_ctx->lcid = xport_ctx->free_lcid;
-    xport_ctx->free_lcid++;
-    smem_list_append(&if_ptr->glink_core_priv->open_list, 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 */
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
+      /* 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 );
 
-    /* Send the OPEN command to transport */
-    if (local_open)
-    {
-      status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
-                                      ch_ctx->name,
-                                      ch_ctx->req_if_ptr->glink_priority);
+      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,
+                                       ch_ctx->req_if_ptr->glink_priority );
     }
     else
     {
-      /* initialize channel resources */
-      status = xport_ctx->channel_init(ch_ctx);
+      /* REMOTE OPEN REQUEST */
 
-      /* 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( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {/* 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;
       }
-    }
 
-    if (status != GLINK_STATUS_SUCCESS)
-    {
-      /* Remove the channel from the transport interface's open_list */
-      xport_ctx->free_lcid--;
+      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED );
 
-      glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-      smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+      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);
 
-      /* free the ch_ctx structure and return */
-      xport_ctx->channel_cleanup(ch_ctx);
+
+      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 );
+
+  /* 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;
+    ch_ctx->req_if_ptr  = req_if_ptr;
+  }
+  else
+  {
+    ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+  }
+
+  glink_os_cs_init(&ch_ctx->tx_cs);
+  glink_os_cs_init(&ch_ctx->ch_state_cs);
+
+  /* Append the channel to the transport interface's open_list */
+  ch_ctx->lcid = xport_ctx->free_lcid;
+  xport_ctx->free_lcid++;
+  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,
+                                     ch_ctx->req_if_ptr->glink_priority );
+  }
+  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;
 }
 
-/** Default implementation of optional callbacks */
+/*===========================================================================
+  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
 (
   glink_handle_type  handle,
@@ -271,7 +346,7 @@
   link_notif_data->link_notifier(&link_info, link_notif_data->priv);
 }
 
-static uint32 glinki_find_remote_host
+uint32 glinki_find_remote_host
 (
   const char *remote_ss
 )
@@ -279,10 +354,11 @@
   uint32 remote_host;
   ASSERT(remote_ss);
 
-  for(remote_host = 0;
-      remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-      remote_host++) {
-    if( 0 == strcmp(glink_hosts_supported[remote_host], 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;
     }
@@ -297,24 +373,18 @@
   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;
-
-  if(link_notif_data->xport == NULL ||
-     0 == strcmp(xport_ctx->xport, link_notif_data->xport)) {
+  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_notif_data->link_notifier(&link_info, link_notif_data->priv);
+    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
@@ -327,82 +397,33 @@
   ASSERT(link_notif_data);
 
   /* Find matching subsystem */
-  if(link_notif_data->remote_ss) {
-    remote_host = glinki_find_remote_host(link_notif_data->remote_ss);
+  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 */
-    if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-    if(if_ptr == NULL) {
-      /* No registered xports at this time, return without doing anything */
-      return;
-    }
+    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(link_notif_data->xport) {
-      do {
-        xport_ctx = if_ptr->glink_core_priv;
-        if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
-          /* Match found, break out of loop */
-          break;
-        }
-      }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
-      if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
+      if (xport_ctx->status == GLINK_XPORT_LINK_UP)
+      {
         /* Invoke registered callback */
-        glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                  GLINK_LINK_STATE_UP);
+        glinki_check_xport_and_notify( link_notif_data, xport_ctx,
+                                       GLINK_LINK_STATE_UP );
       }
-    } else {
-      /* No xport has been specified, invoke notifier for all registered
-       * xports */
-      do {
-        xport_ctx = if_ptr->glink_core_priv;
-        if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
-          /* Invoke registered callback */
-          glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                    GLINK_LINK_STATE_UP);
-        }
-      }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
     }
-  } else {
-    /* No remote ss is specified, invoke notifier for all remote_ss */
-    for(remote_host = 0;
-        remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-        remote_host++) {
-      /* Find the xport and give link UP notification */
-      if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-      if(if_ptr == NULL) {
-        /* No registered xports at this time, continue with next remote_ss */
-        continue;
-      }
-
-      if(link_notif_data->xport) {
-        do {
-          xport_ctx = if_ptr->glink_core_priv;
-          if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
-            /* Match found, break out of loop */
-            break;
-          }
-        }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
-        if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
-          /* Invoke registered callback */
-          glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                    GLINK_LINK_STATE_UP);
-        }
-      } else {
-        /* No xport has been specified, invoke notifier for all registered
-         * xports */
-        do {
-          xport_ctx = if_ptr->glink_core_priv;
-          if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
-            /* Invoke registered callback */
-            glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                      GLINK_LINK_STATE_UP);
-          }
-        }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-      }
-    } /* end for remote_host */
-  }/* end if else (link_notif_data->remote_ss) */
+  } /* end for remote_host */
 } /* glinki_scan_xports_and_notify */
 
 void glinki_scan_notif_list_and_notify
@@ -414,26 +435,17 @@
   glink_link_notif_data_type *link_notif_data;
   glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
 
-  link_notif_data = smem_list_first(&glink_link_notif_list);
-
-  if(link_notif_data == NULL) {
-    /* list empty */
-    return;
+  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);
+    }
   }
-
-  do {
-      if(link_notif_data->remote_ss &&
-         0 == strcmp(xport_ctx->remote_ss, link_notif_data->remote_ss)) {
-        /* remote_ss specified and matches */
-        glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-      } else if(link_notif_data->remote_ss == NULL) {
-        /* remote_ss not specified, invoke link notif for any remote_ss */
-        if(link_notif_data->xport) {
-          glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-        } /* if else link_notif_data->xport */
-      } /* if else link_notif_data->remote_ss */
-  } while ( (link_notif_data = smem_list_next(link_notif_data)) != NULL);
-
 } /* glinki_scan_notif_list_and_notify */
 
 void glinki_scan_channels_and_notify_discon
@@ -441,7 +453,7 @@
   glink_transport_if_type *if_ptr
 )
 {
-  glink_channel_ctx_type *open_ch_ctx;
+  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
   ASSERT(if_ptr != NULL);
@@ -451,27 +463,46 @@
   /* 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)
+  while( open_ch_ctx )
   {
-    /* Found channel, transition it to appropriate state based
-     * on current state */
-    if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-      open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
+    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 );
 
-      /* Inform the client */
-      open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-          GLINK_REMOTE_DISCONNECTED);
-    } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
-      /* Local side never opened the channel */
-      /* Free channel resources */
-      xport_ctx->channel_cleanup(open_ch_ctx);
+    dummy_open_ch_ctx = smem_list_next( open_ch_ctx );
 
-      smem_list_delete(&if_ptr->glink_core_priv->open_list, 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;
 
-      glink_os_free(open_ch_ctx);
+      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 */
+        xport_ctx->channel_cleanup(open_ch_ctx);
+        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+        glink_os_free(open_ch_ctx);
+        break;
+
+      default:
+        /* invalid local channel state */
+        ASSERT(0);
     }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
+
+    open_ch_ctx = dummy_open_ch_ctx;
+
+  } /* end while */
   glink_os_cs_release(&xport_ctx->channel_q_cs);
 }
 
@@ -487,15 +518,22 @@
      notification followed by REMOTE_DISCONNECT */
   if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
 
-  while(if_ptr != NULL) {
+  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);
 
-    /* Let the xport know about ssr */
-    if_ptr->ssr(if_ptr);
+    glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
     if_ptr = smem_list_next(if_ptr);
   }
@@ -597,32 +635,19 @@
     return GLINK_STATUS_INVALID_PARAM;;
   }
 
+  remote_host = glinki_find_remote_host(cfg->remote_ss);
 
-  /* Allocate/fill out the GLink Core interface structure */
-  {
-    glink_core_if_type *core_if = glink_os_calloc(sizeof(glink_core_if_type));
-    if(core_if == 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;
-    }
-    core_if->link_up = glink_link_up;
-    core_if->rx_cmd_version = glink_rx_cmd_version;
-    core_if->rx_cmd_version_ack = glink_rx_cmd_version_ack;
-    core_if->rx_cmd_ch_remote_open = glink_rx_cmd_ch_remote_open;
-    core_if->rx_cmd_ch_open_ack = glink_rx_cmd_ch_open_ack;
-    core_if->rx_cmd_ch_close_ack = glink_rx_cmd_ch_close_ack;
-    core_if->rx_cmd_ch_remote_close = glink_rx_cmd_ch_remote_close;
-    core_if->ch_state_local_trans = glink_ch_state_local_trans;
-    core_if->rx_put_pkt_ctx = glink_rx_put_pkt_ctx;
-    core_if->rx_cmd_remote_sigs = glink_rx_cmd_remote_sigs;
-    core_if->tx_resume = glink_tx_resume;
-    core_if->set_core_version = glink_set_core_version;
+  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);
 
-    /* Set the glink_core_if_ptr to point to the allocated structure */
-    if_ptr->glink_core_if_ptr = core_if;
+    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));
@@ -636,16 +661,15 @@
       return GLINK_STATUS_OUT_OF_RESOURCES;
     }
 
-    glink_os_string_copy(xport_ctx->xport, cfg->name,
-        sizeof(xport_ctx->xport));
-    glink_os_string_copy(xport_ctx->remote_ss, cfg->remote_ss,
-        sizeof(xport_ctx->xport));
+    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->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);
@@ -657,15 +681,6 @@
   }
 
   /* Push the transport interface into appropriate queue */
-  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, xport_ctx->xport,
-           xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
-
-    return GLINK_STATUS_INVALID_PARAM;
-  }
   glink_os_cs_acquire(glink_transport_q_cs);
   smem_list_append(&glink_registered_transports[remote_host], if_ptr);
   glink_os_cs_release(glink_transport_q_cs);
@@ -732,6 +747,8 @@
   /* 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);
 
@@ -755,7 +772,12 @@
   glink_link_handle_type handle
 )
 {
-  ASSERT(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);
@@ -789,18 +811,17 @@
 
   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)
      */
-    xport_ctx = if_ptr->glink_core_priv;
     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);
+    if_ptr = smem_list_next(if_ptr);
   } /* end while() */
 
   return best_if_ptr;
@@ -924,14 +945,15 @@
                                        ch_ctx,
                                        &allocated_ch_ctx,
                                        TRUE,
-                                       TRUE,
                                        if_ptr->glink_priority );
 
-      if (status == GLINK_STATUS_SUCCESS) {
+      if( status == GLINK_STATUS_SUCCESS )
+      {
         /* Set the handle and return */
         *handle = allocated_ch_ctx;
       }
-      else {
+      else
+      {
         *handle = NULL;
       }
 
@@ -967,37 +989,61 @@
 )
 {
   glink_err_type status;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
-  glink_ch_state_type ch_state;
+  glink_core_xport_ctx_type *xport_ctx = NULL;
 
-  if(handle == NULL) {
+  if(handle == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  ch_state = handle->state;
+  /* get xport context after NULL check */
+  xport_ctx = handle->if_ptr->glink_core_priv;
 
-  /* Check to see if channel is in open/opening state */
-  if (ch_state != GLINK_CH_STATE_OPEN &&
-      ch_state != GLINK_CH_STATE_LOCAL_OPEN &&
-      ch_state != GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE &&
-      ch_state != GLINK_CH_STATE_REMOTE_OPEN)
+  /* grab lock to change/check channel state atomically */
+  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 )
   {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, ch_state);
+      xport_ctx->remote_ss, handle->local_state);
+
+    glink_os_cs_release(&handle->ch_state_cs);
+
     return GLINK_STATUS_FAILURE;
   }
 
-  /* Transition to closing */
-  //handle->state = GLINK_CH_STATE_CLOSING;
+  handle->local_state = GLINK_LOCAL_CH_CLOSING;
 
-  /* Send CLOSE cmd to the transport interface */
-  status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, status);
+  glink_os_cs_acquire( &xport_ctx->status_cs );
+
+  if( GLINK_XPORT_LINK_UP != xport_ctx->status ||
+      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,
+                                                            handle->lcid );
+
+    status = GLINK_STATUS_SUCCESS;
+  }
+  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);
+
+    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+        xport_ctx->remote_ss, status);
+  }
+
   return status;
-
 }
 
 /**
@@ -1066,9 +1112,10 @@
 )
 {
   glink_err_type         status;
-  glink_core_tx_pkt_type pctx;
+  glink_core_tx_pkt_type *pctx;
   boolean                req_intent = options & GLINK_TX_REQ_INTENT;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+
+  glink_core_xport_ctx_type *xport_ctx;
 
   /* Input validation */
   if(handle == NULL || iovec == NULL || size == 0 ||
@@ -1078,42 +1125,51 @@
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN )
+  xport_ctx = handle->if_ptr->glink_core_priv;
+
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  {
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_TX,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
+    return GLINK_STATUS_FAILURE;
+  }
+
+  pctx = glink_os_calloc( sizeof( glink_core_tx_pkt_type ) );
+
+  if (pctx == NULL)
   {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
-    return GLINK_STATUS_FAILURE;
+      xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+    return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
   /* Protect the entire tx operation under a lock as a client may call
      tx in different thread context */
   glink_os_cs_acquire(&handle->tx_cs);
 
-  pctx.pkt_priv = pkt_priv;
-  pctx.size = size;
-  pctx.size_remaining = size;
-  pctx.vprovider = vprovider;
-  pctx.pprovider = pprovider;
+  pctx->pkt_priv = pkt_priv;
+  pctx->size = size;
+  pctx->size_remaining = size;
+  pctx->vprovider = vprovider;
+  pctx->pprovider = pprovider;
 
   if (vprovider == &glink_dummy_tx_vprovider)
   {
-    pctx.data = (void*)iovec;
-    pctx.iovec = &pctx;
+    pctx->data = (void*)iovec;
+    pctx->iovec = pctx;
   }
   else
   {
-    pctx.data = (void*)iovec;
-    pctx.iovec = iovec;
+    pctx->data = (void*)iovec;
+    pctx->iovec = iovec;
   }
 
-  status = xport_ctx->use_rm_intent(handle, &pctx, req_intent);
 
-  /* Call transport API to transmit data */
-  while (pctx.size_remaining != 0 && status == GLINK_STATUS_SUCCESS)
-  {
-    status = handle->if_ptr->tx(handle->if_ptr, handle->lcid, &pctx);
-  }
+  status = xport_ctx->channel_submit_pkt(handle, pctx, req_intent);
 
   GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, handle->name, xport_ctx->xport,
       xport_ctx->remote_ss, status);
@@ -1159,11 +1215,14 @@
     return GLINK_STATUS_FAILURE;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_Q_RX_INTENT,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
@@ -1271,11 +1330,14 @@
     return GLINK_STATUS_SUCCESS;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_RX_DONE,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
@@ -1353,7 +1415,7 @@
   uint32            sig_value
 )
 {
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+  glink_core_xport_ctx_type *xport_ctx;
   glink_err_type status;
 
   /* Input validation */
@@ -1363,11 +1425,16 @@
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  xport_ctx = handle->if_ptr->glink_core_priv;
+
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_SIG_SET,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 3c66369..5e3abd5 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -34,28 +34,26 @@
 #include "glink_os_utils.h"
 #include "glink.h"
 #include "glink_internal.h"
-#include "glink_core_if.h"
 #include "smem_list.h"
 #include "glink_channel_migration.h"
 
-
 #define FEATURE_CH_MIGRATION_FREE
 
-void glinki_scan_notif_list_and_notify
+/*===========================================================================
+                        GLOBAL FUNCTION DECLARATIONS
+==========================================================================*/
+extern void glinki_scan_notif_list_and_notify
 (
   glink_transport_if_type *if_ptr,
   glink_link_state_type state
 );
 
-/*===========================================================================
-                              GLOBAL DATA DECLARATIONS
-===========================================================================*/
 
 /*===========================================================================
                      LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
 /*===========================================================================
-FUNCTION      glink_process_negotiation_complete
+  FUNCTION      glink_process_negotiation_complete
 ===========================================================================*/
 /**
 
@@ -79,20 +77,26 @@
 /*=========================================================================*/
 static void glink_process_negotiation_complete
 (
-  glink_core_xport_ctx_type *xport_ctx,
   glink_transport_if_type   *if_ptr,
   uint32                    version,
   uint32                    features
 )
 {
+  glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
   /* Version/Feautre can be negotiated both in ver_req and ver_ack
    * 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 )
   {
+    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,
@@ -100,38 +104,70 @@
   glink_core_setup(if_ptr);
 
   /* 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);
 
   /* Scan the notification list to check is we have to let any registered
-  * clients know that link came online */
+   * clients know that link came online */
   glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
 }
 
-static void glink_dummy_ch_migration_notification_cb
+
+/*===========================================================================
+  FUNCTION      glink_clean_channel_ctx
+===========================================================================*/
+/**
+
+  This is called when channel is fully closed
+  Clean up the context and redeem channel id if possible
+
+  @param[in]    xport_ctx    transport context
+  @param[in]    channel_ctx  channel context
+
+
+  @return        None
+  @sideeffects   None.
+  @dependencies  This function needs to be called in safe context
+                 which is critical sections locked - channel_q_cs
+*/
+/*=========================================================================*/
+static void glink_clean_channel_ctx
 (
-  glink_handle_type         handle,
-  const void               *priv,
-  glink_channel_event_type event
+  glink_core_xport_ctx_type *xport_ctx,
+  glink_channel_ctx_type    *channel_ctx
 )
 {
+  xport_ctx->channel_cleanup( channel_ctx );
+
+  if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
+  {
+    /* If channel being closed is the last opened channel
+       re-use the lcid of this channel for any new channels */
+    xport_ctx->free_lcid--;
+  }
+
+  smem_list_delete(&xport_ctx->open_list, channel_ctx);
 }
 
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 /*===========================================================================
-FUNCTION      glink_link_up
-
-DESCRIPTION   Indicates that transport is now ready to start negotiation
-              using the v0 configuration
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
+  FUNCTION      glink_link_up
 ===========================================================================*/
+/**
+  Indicates that transport is now ready to start negotiation
+  using the v0 configuration
+
+  @param[in]     if_ptr    Pointer to interface instance; must be unique
+                           for each edge
+
+  @return        None
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
 void glink_link_up
 (
   glink_transport_if_type *if_ptr
@@ -147,7 +183,9 @@
   version_array = xport_ctx->version_array;
 
   /* Update the transport state */
+  glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
   if_ptr->glink_core_priv->status = GLINK_XPORT_NEGOTIATING;
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
   /* Start the negtiation */
   if_ptr->tx_cmd_version(if_ptr, version_array->version,
@@ -207,8 +245,7 @@
       /* send version ack before allowing to open channels */
       if_ptr->tx_cmd_version_ack(if_ptr, version, features);
 
-      glink_process_negotiation_complete( xport_ctx, if_ptr,
-                                          version, features );
+      glink_process_negotiation_complete( if_ptr, version, features );
       return;
     }
     else
@@ -277,8 +314,7 @@
     }
     else
     {
-      glink_process_negotiation_complete( xport_ctx, if_ptr,
-                                          version, features );
+      glink_process_negotiation_complete( if_ptr, version, features );
     }
   }
   else
@@ -323,64 +359,22 @@
   glink_xport_priority    priority
 )
 {
-  glink_channel_ctx_type *remote_ch_ctx;
-  glink_channel_ctx_type  *allocated_ch_ctx;
+  glink_channel_ctx_type     *remote_ch_ctx  = NULL;
+  glink_channel_ctx_type     *allocated_ch_ctx;
+
+  glink_xport_priority        negotiated_xport_priority;
   glink_core_xport_ctx_type  *xport_ctx;
-  glink_err_type status;
-  glink_xport_priority negotiated_prio;
-  boolean migration_state = TRUE;
+  glink_err_type              status;
 
-  ASSERT(if_ptr != NULL);
-  ASSERT(name != NULL);
-
-#ifndef FEATURE_CH_MIGRATION_FREE
-  glink_transport_if_type *present_if_ptr = NULL;
-  boolean channel_exist = FALSE;
-  glink_channel_ctx_type *present_ch_ctx = NULL;
-  /* search if channel with given name exists locally */
-  channel_exist = glinki_local_channel_exists(if_ptr, &present_if_ptr, name, &present_ch_ctx, TRUE);
-
-  /* start channel migration negotiation only if channel exists on local side
-   * for negotiation AND channel is willing to migrate */
-  if(channel_exist &&
-     (present_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
-  {
-    /* channel exists on one of the xports for given remote ss */
-    current_prio =  present_ch_ctx->req_if_ptr->glink_priority;
-    negotiated_prio = glinki_negotiate_ch_migration(priority, current_prio);
-
-    /* if current channel is open in same xport as negotiated xport
-     * local side wont migrate. Set migration flag to FALSE */
-    if(negotiated_prio == present_if_ptr->glink_priority)
-    {
-      migration_state = FALSE;
-    }
-  }
-  else if(channel_exist)
-  {
-    /* channel exists but channel does not want to be moved to another xport.
-       channel is set in stone */
-    negotiated_prio = present_if_ptr->glink_priority;
-    migration_state = FALSE;
-  }
-  else
-  {
-    /* channel does not exist on local side as yet
-     * return negotiated prio as current xport prio on which
-     * remote open request is received */
-    negotiated_prio = if_ptr->glink_priority;
-    migration_state = FALSE;
-  }
-#else
-  negotiated_prio = if_ptr->glink_priority;
-    migration_state = FALSE;
-#endif
+  ASSERT( if_ptr != NULL );
+  ASSERT( name != NULL );
 
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Allocate and initialize channel info structure */
-  remote_ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
-  if(remote_ch_ctx == NULL) {
+  remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
+  if(remote_ch_ctx == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
         xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
     ASSERT(0);
@@ -390,61 +384,113 @@
   glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
   remote_ch_ctx->rcid = rcid;
 
-  status = glinki_add_ch_to_xport(if_ptr, NULL, remote_ch_ctx,
-                                  &allocated_ch_ctx, FALSE,
-                                  migration_state, negotiated_prio);
-  ASSERT(status == GLINK_STATUS_SUCCESS);
+#ifndef FEATURE_CH_MIGRATION_FREE
+  glink_channel_ctx_type     *present_ch_ctx = NULL;
+  glink_transport_if_type    *negotiated_xport;
+  glink_channel_ctx_type     *dummy_ch_ctx;
 
-  GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+  /* search if channel with given name exists locally */
+
+  glink_os_cs_acquire( &xport_ctx->channel_q_cs );
+  present_ch_ctx = glinki_local_channel_exists( if_ptr, name );
+
+  if( !present_ch_ctx )
+  {
+    // channel doesn't exists yet and migration will not happen here
+    status = glinki_add_ch_to_xport( if_ptr,
+                                     if_ptr,
+                                     remote_ch_ctx,
+                                     &allocated_ch_ctx,
+                                     FALSE,
+                                     if_ptr->glink_priority );
+    ASSERT(status == GLINK_STATUS_SUCCESS);
+
+    GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
       xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
 
-#ifndef FEATURE_CH_MIGRATION_FREE
-
-  /* We are done with channel migration negotiation at this stage
-   * Tag all channels with given name on xports other than negotiated
-   * xport for deletion */
-  glinki_tag_ch_for_deletion(if_ptr, name, negotiated_prio);
-
-    if(migration_state == TRUE)
-    {
-      glink_channel_ctx_type *new_ch_ctx;
-
-    /* create a new channel context as current channel will be migrated */
-    new_ch_ctx = (glink_channel_ctx_type *)
-                   glink_os_calloc(sizeof(glink_channel_ctx_type));
-
-    /* Fill in the channel info structure */
-    new_ch_ctx->req_if_ptr =
-             glinki_get_xport_from_prio(negotiated_prio,
-                                          if_ptr->glink_core_priv->remote_ss);
-    glink_os_string_copy(new_ch_ctx->name, present_ch_ctx->name,
-                         sizeof(present_ch_ctx->name));
-    new_ch_ctx->priv = present_ch_ctx->priv;
-    new_ch_ctx->notify_rx = present_ch_ctx->notify_rx;
-    new_ch_ctx->notify_rxv = present_ch_ctx->notify_rxv;
-    new_ch_ctx->notify_tx_done = present_ch_ctx->notify_tx_done;
-    new_ch_ctx->notify_state = present_ch_ctx->notify_state;
-    new_ch_ctx->notify_rx_intent_req = present_ch_ctx->notify_rx_intent_req;
-    new_ch_ctx->notify_rx_intent = present_ch_ctx->notify_rx_intent;
-    new_ch_ctx->notify_rx_sigs = present_ch_ctx->notify_rx_sigs;
-    new_ch_ctx->ch_open_options = present_ch_ctx->ch_open_options;
-
-//      glink_os_cs_init(&new_ch_ctx->intent_q_cs);
-
-    /* close current channel */
-    present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
-    if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
-    /* add new channel context on negotiated xport */
-    glinki_add_ch_to_xport(new_ch_ctx->req_if_ptr,
-                           new_ch_ctx->req_if_ptr,
-                           new_ch_ctx,
-                           &allocated_ch_ctx,
-                           TRUE,
-                           TRUE,
-                           new_ch_ctx->req_if_ptr->glink_priority);
+    glink_os_cs_release( &xport_ctx->channel_q_cs );
+    return;
   }
+
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
+
+  present_ch_ctx->rcid = rcid;
+
+  if( present_ch_ctx->tag_ch_for_close )
+  {
+    // Migration already started.
+    GLINK_LOG_EVENT(GLINK_EVENT_CH_MIGRATION_IN_PROGRESS, name, xport_ctx->xport,
+      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+    return;
+  }
+
+  /* Negotiate the priority for migration if needed */
+  if( priority < present_ch_ctx->req_if_ptr->glink_priority )
+  {
+    negotiated_xport_priority = present_ch_ctx->req_if_ptr->glink_priority;
+  }
+  else
+  {
+    negotiated_xport_priority = priority;
+  }
+
+  negotiated_xport =  glinki_get_xport_from_prio( negotiated_xport_priority,
+                                                  xport_ctx->remote_ss );
+
+  if( if_ptr == negotiated_xport )
+  {
+    /* Current transport is best one. No need to migrate */
+
+    status = glinki_add_ch_to_xport( if_ptr,
+                                     if_ptr,
+                                     remote_ch_ctx,
+                                     &allocated_ch_ctx,
+                                     FALSE,
+                                     negotiated_xport_priority );
+
+    ASSERT(status == GLINK_STATUS_SUCCESS);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_NO_MIGRATION, name, xport_ctx->xport,
+      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+    return;
+  }
+
+  /* Need to migrate to new transport */
+  if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
+                                     rcid,
+                                     negotiated_xport_priority );
+
+  glink_create_dummy_ch_ctx( &dummy_ch_ctx, present_ch_ctx );
+  glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+  glink_init_ch_migrate_candidate( present_ch_ctx );
+
+  status = glinki_add_ch_to_xport( negotiated_xport,
+                                   negotiated_xport,
+                                   present_ch_ctx,
+                                   &allocated_ch_ctx,
+                                   TRUE,
+                                   negotiated_xport_priority );
+
+  ASSERT( status == GLINK_STATUS_SUCCESS );
+
+  glink_os_free( remote_ch_ctx );
+
+#else
+  negotiated_xport_priority = if_ptr->glink_priority;
+
+  status = glinki_add_ch_to_xport( if_ptr,
+                                   NULL,
+                                   remote_ch_ctx,
+                                   &allocated_ch_ctx,
+                                   FALSE,
+                                   negotiated_xport_priority );
+
+  ASSERT(status == GLINK_STATUS_SUCCESS);
 #endif
+
+  GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+    xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
 }
 
 /*===========================================================================
@@ -467,11 +513,11 @@
 void glink_rx_cmd_ch_open_ack
 (
   glink_transport_if_type *if_ptr,
-  uint32                  lcid,
-  glink_xport_priority    migrated_ch_prio
+  uint32                   lcid,
+  glink_xport_priority     migrated_ch_prio
 )
 {
-  glink_channel_ctx_type *open_ch_ctx;
+  glink_channel_ctx_type     *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
   ASSERT(if_ptr != NULL);
@@ -480,121 +526,92 @@
 
   /* 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) {
+    if(open_ch_ctx->lcid == lcid)
+    {
 #ifndef FEATURE_CH_MIGRATION_FREE
-      glink_transport_if_type *present_if_ptr = NULL;
-      glink_channel_ctx_type  *present_ch_ctx = NULL;
-      boolean channel_exist;
-      /* find the channel in all xport list */
-      channel_exist = glinki_local_channel_exists(if_ptr,
-                                                  &present_if_ptr,
-                                                  open_ch_ctx->name,
-                                                  &present_ch_ctx,
-                                                  FALSE);
+      glink_transport_if_type    *negotiated_xport = NULL;
+      negotiated_xport = glinki_get_xport_from_prio( migrated_ch_prio,
+                                                     xport_ctx->remote_ss );
 
-      if(if_ptr->glink_priority == migrated_ch_prio && !channel_exist)
+      if( negotiated_xport != if_ptr &&
+          !open_ch_ctx->tag_ch_for_close &&
+          ( open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT ) )
       {
-        /* only local side has opened the channel. Remote side has not come up yet
-         * which implies negotiation did not take place on remote side */
-        /* DO NOTHING */
-      }
-      else if(if_ptr->glink_priority == migrated_ch_prio)
-      {
-        /* remote channel exists. channel migration negotiation happened
-         * on remote side and negotitated xport is same as current xport */
-        if(present_ch_ctx->ref_count == 1)
-        {
-          /* remote channel is present on different xport than negotiated one.
-           * remote side will migrate its channel to negotiated xport */
-          /* DO NOTHING */
-        }
-        else if(present_ch_ctx->ref_count == 2)
-        {
-          /* remote channel is open on same xport as current xport.
-           * change channel state to GLINK_CH_STATE_OPEN and notify client */
-          open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-          open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                    GLINK_CONNECTED);
-        }
-        else
-        {
-          /* something went wrong in updating ref_count of channel */
-          ASSERT(0);
-        }
+        glink_channel_ctx_type *dummy_ch_ctx;
+        glink_err_type          status;
+
+        glink_create_dummy_ch_ctx( &dummy_ch_ctx, open_ch_ctx );
+        glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+
+        glink_init_ch_migrate_candidate( open_ch_ctx );
+        dummy_ch_ctx = NULL;
+
+        status = glinki_add_ch_to_xport( negotiated_xport,
+                                         negotiated_xport,
+                                         open_ch_ctx,
+                                         &dummy_ch_ctx,
+                                         TRUE,
+                                         negotiated_xport->glink_priority );
+
+        ASSERT( status == GLINK_STATUS_SUCCESS );
       }
       else
       {
+        glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
 
-        /* migrated xport priority <> current xport priority */
-        /* check if remote channel is opened on negotiated xport already */
-          if(migrated_ch_prio == present_if_ptr->glink_priority &&
-             (open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
-          {
-            /* remote channel is already on negotiated xport. remote channel
-             * will not migrate. Local side should migrate */
-
-            glink_channel_ctx_type *new_ch_ctx =
-              (glink_channel_ctx_type *)glink_os_calloc(
-                                       sizeof(glink_channel_ctx_type));
-
-            /* Fill in the channel info structure */
-            glink_os_string_copy(new_ch_ctx->name,
-                                 open_ch_ctx->name,
-                                 sizeof(open_ch_ctx->name));
-            new_ch_ctx->priv = open_ch_ctx->priv;
-            new_ch_ctx->notify_rx = open_ch_ctx->notify_rx;
-            new_ch_ctx->notify_rxv = open_ch_ctx->notify_rxv;
-            new_ch_ctx->notify_tx_done = open_ch_ctx->notify_tx_done;
-            new_ch_ctx->notify_state = open_ch_ctx->notify_state;
-            new_ch_ctx->notify_rx_intent_req =
-                                            open_ch_ctx->notify_rx_intent_req;
-            new_ch_ctx->notify_rx_intent = open_ch_ctx->notify_rx_intent;
-            new_ch_ctx->notify_rx_sigs = open_ch_ctx->notify_rx_sigs;
-            new_ch_ctx->ch_open_options = open_ch_ctx->ch_open_options;
-
-            present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
-            if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
-            /* migrate to negotiated xport */
-            glinki_add_ch_to_xport(present_if_ptr,
-                                   present_if_ptr,
-                                   new_ch_ctx,
-                                   NULL,
-                                   TRUE,
-                                   TRUE,
-                                   present_if_ptr->glink_priority);
-          }
-          else
-          {
-            /* Either our transport is "set in stone"  OR */
-            /* remote side will migrate to negotiated xport and will call
-             * remote open on this side which will cause channel migration
-             * negotiation and this side will ultimately migrate */
-            /* DO NOTHING */
-          }
-        }
-#else
-        if(open_ch_ctx->ref_count == 2)
+        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
         {
-          /* remote channel is open on same xport as current xport.
-           * change channel state to GLINK_CH_STATE_OPEN and notify client */
-          open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-          open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                    GLINK_CONNECTED);
+          /* Local client called glink_close
+           * before local channel is fully opened */
+          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+          glink_os_cs_release( &xport_ctx->channel_q_cs );
+          return;
         }
+
+        open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+
+        if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+        {
+          glink_os_cs_release( &open_ch_ctx->ch_state_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 );
+        }
+      }
+
+#else
+      /* This is same code as above. once core capability code is done copy
+       * issue should be resolved */
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+      open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+      if( open_ch_ctx->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 );
+        open_ch_ctx->notify_state( open_ch_ctx,
+                                   open_ch_ctx->priv,
+                                   GLINK_CONNECTED);
+      }
 #endif
 
       GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, lcid);
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
       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);
 }
@@ -632,55 +649,49 @@
 
   /* 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)
+  open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+  while( open_ch_ctx )
   {
-    if(open_ch_ctx->lcid == lcid) {
+    if( open_ch_ctx->lcid == lcid )
+    {
       /* Found channel */
-      open_ch_ctx->ref_count--;
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+
+
       GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, lcid);
 
-      /* Transition state */
-      if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-        /* this side initiated close procedure */
-        open_ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE;
-      } else if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN ||
-                open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE ||
-                open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
-        /* Other side never opened the port, or closed from its end */
-        /* Clear everything */
-        if(open_ch_ctx->ref_count == 0)
-        {
-          xport_ctx->channel_cleanup(open_ch_ctx);
-          /* re-use channel id if it can be done */
-          if(lcid == (xport_ctx->free_lcid-1)) {
-            /* If channel being closed is the last opened channel
-               re-use the lcid of this channel for any new channels */
-            xport_ctx->free_lcid--;
-          }
-          smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING );
 
-          /* Notify the client */
-          open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
-                                     GLINK_LOCAL_DISCONNECTED);
-          glink_os_free(open_ch_ctx);
-        }
-      } else {
-        /* Unsupported state */
-        ASSERT(0);
+      open_ch_ctx->local_state = GLINK_LOCAL_CH_CLOSED;
+
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {
+        glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
       }
 
+      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_LOCAL_DISCONNECTED );
+
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {
+        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);
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
 }
 
 /*===========================================================================
@@ -712,124 +723,53 @@
   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);
+  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_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
-            xport_ctx->xport, xport_ctx->remote_ss, rcid);
-      /* Found channel, transition it to appropriate state based
-       * on current state */
-      open_ch_ctx->ref_count--;
+    if( open_ch_ctx->rcid == 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);
 
-      if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-         open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE;
+      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
 
+      open_ch_ctx->remote_state = GLINK_REMOTE_CH_CLOSED;
+
+      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+      {
+        /* Local side never opened the channel OR it opened it but closed it */
+        /* Free channel resources */
+        glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
+      }
+
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+      /* Send the remote close ACK back to the other side */
+      if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+
+      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+      {
+        glink_os_free(open_ch_ctx);
+      }
+      else
+      {
         /* Inform the client */
         open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
                                    GLINK_REMOTE_DISCONNECTED);
-
-        /* Send the remote close ACK back to the other side */
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
-        /* Free channel resources */
-        xport_ctx->channel_cleanup(open_ch_ctx);
-
-        GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
-            xport_ctx->xport, xport_ctx->remote_ss, rcid);
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        return;
-      } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN ||
-                 open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE) {
-        /* Local side never opened the channel OR it opened it but closed it */
-        /* Free channel resources */
-        xport_ctx->channel_cleanup(open_ch_ctx);
-
-        /* Send the remote close ACK back to the other side */
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
-        if(open_ch_ctx->ref_count == 0)
-        {
-          /* re-use channel id if it can be done */
-          if (open_ch_ctx->lcid == (xport_ctx->free_lcid - 1)) {
-            /* If channel being closed is the last opened channel
-            re-use the lcid of this channel for any new channels */
-            xport_ctx->free_lcid--;
-          }
-          smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
-          glink_os_free(open_ch_ctx);
-        }
-
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        return;
-      } else {
-        /* SHould not get this callback for a channel in any other state */
-
-        //OS_LOG_ERROR(3, "GLINK_RX_CMD_CH_REMOTE_CLOSE: received close cmd for invalid state"
-        //                "[channel ctx: 0x%x][current channel state: %d]",
-        //                open_ch_ctx, open_ch_ctx->state );
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-        return;
       }
+
+      return;
     }
     open_ch_ctx = smem_list_next(open_ch_ctx);
   }/* end while */
 
-  /* We are here in case we could not find the channel in the open list
-   * or OPEN state. */
-  ASSERT(0);
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-}
-
-/*===========================================================================
-FUNCTION      glink_ch_state_local_trans
-
-DESCRIPTION   Process local state transition
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-)
-{
-  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;
-
-  /* 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) {
-      /* Found channel, transition it to appropriate state */
-      open_ch_ctx->state = new_state;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_STATE_TRANS, open_ch_ctx->name,
-          xport_ctx->xport, xport_ctx->remote_ss, new_state);
-    return;
-  }/* end while */
-
-  /* We are here in case we could not find the channel in the open list
-   * or OPEN state. */
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
   ASSERT(0);
 }
 
@@ -920,7 +860,16 @@
   open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
   while(open_ch_ctx != NULL)
   {
-    if(open_ch_ctx->rcid == rcid) {
+    if(open_ch_ctx->rcid == rcid ) {
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+      if( open_ch_ctx->local_state != GLINK_LOCAL_CH_OPENED &&
+          open_ch_ctx->remote_state != GLINK_REMOTE_CH_OPENED )
+      {
+        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;
@@ -937,29 +886,6 @@
 
 
 /*===========================================================================
-FUNCTION      glink_tx_resume
-
-DESCRIPTION   If transport was full and could not continue a transmit
-              operation, then it will call this function to notify the core
-              that it is ready to resume transmission.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_tx_resume
-(
-  glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-)
-{
-  /* Not sure what to do here */
-}
-
-
-/*===========================================================================
 FUNCTION      glink_set_core_version
 
 DESCRIPTION   Sets the core version used by the transport; called after
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
index 289ef18..98ced24 100644
--- a/platform/msm_shared/glink/glink_core_intentless_xport.c
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -33,6 +33,55 @@
 #include "glink.h"
 #include "glink_internal.h"
 
+glink_core_if_type glink_core_intentless_interface =
+{
+  /** Indicates that transport is now ready to start negotiation using the
+   *  v0 configuration. */
+  glink_link_up,
+  /** Receive transport version for remote-initiated version negotiation */
+  glink_rx_cmd_version,
+  /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
+  glink_rx_cmd_version_ack,
+  /** Sets the core version used by the transport; called after completing
+   *  negotiation.*/
+  glink_set_core_version,
+  /** Receive remote channel open request; expected response is
+   *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
+  glink_rx_cmd_ch_remote_open,
+  /** This function is invoked by the transport in response to
+   *  glink_transport_if_type:: tx_cmd_ch_open */
+  glink_rx_cmd_ch_open_ack,
+  /** This function is invoked by the transport in response to
+   *  glink_transport_if_type:: tx_cmd_ch_close */
+  glink_rx_cmd_ch_close_ack,
+  /** Remote channel close request; will result in sending
+   *  glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
+  glink_rx_cmd_ch_remote_close,
+  /** Transport invokes this call on receiving remote RX intent */
+  NULL,
+  /** Get receive packet context (if successful, should be followed by call to
+      rx_put_pkt_ctx) */
+  NULL,
+  /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
+      packet). */
+  glink_rx_put_pkt_ctx,
+  /** Transport invokes this call to inform GLink that remote side is
+   *   done with previous transmitted packet. */
+  NULL,
+  /** Remote side is requesting an RX intent */
+  NULL,
+  /** ACK to RX Intent Request */
+  NULL,
+  /** Received 32-bit signals value from remote side. It is passed on to
+   *  the client */
+  glink_rx_cmd_remote_sigs,
+  /** If transport was full and could not continue a transmit operation,
+   *  then it will call this function to notify the core that it is ready to
+   *  resume transmission. */
+  NULL
+};
+
+
 /*===========================================================================
 LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -104,10 +153,58 @@
 }
 
 /*===========================================================================
+FUNCTION      glink_channel_submit_pkt
+===========================================================================*/
+/**
+
+  Invokes intentless transport Tx function to transmit a packet
+
+  @param[in]  open_ch_ctx   Channel context.
+  @param[in]  pctx_ctx      Packet context.
+  @param[in]  req_intent    Request intent flag
+
+  @return     Error code.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+static glink_err_type glink_channel_submit_pkt_intentless
+(
+  glink_channel_ctx_type *open_ch_ctx,
+  glink_core_tx_pkt_type *pctx,
+  boolean 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);
+
+  glink_os_free(pctx);
+
+  return status;
+}
+
+/*===========================================================================
 EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 
 /*===========================================================================
+  FUNCTION      glink_core_get_intentless_interface
+===========================================================================*/
+/**
+
+  Provides core interface for the intentless transport.
+
+  @return     Pointer to the core intentless interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_intentless_interface(void)
+{
+  return &glink_core_intentless_interface;
+}
+
+/*===========================================================================
   FUNCTION      glink_core_setup_intentless_xport
 ===========================================================================*/
 /**
@@ -123,9 +220,10 @@
 /*=========================================================================*/
 void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr)
 {
+  if_ptr->glink_core_if_ptr = glink_core_get_intentless_interface();
   if_ptr->glink_core_priv->verify_open_cfg = glink_verify_open_cfg_intentless;
   if_ptr->glink_core_priv->channel_init = (channel_init_fn)glink_core_stub_intentless;
   if_ptr->glink_core_priv->channel_cleanup = (channel_cleanup_fn)glink_core_stub_intentless;
-  if_ptr->glink_core_priv->use_rm_intent = (use_rm_intent_fn)glink_core_stub_intentless;
+  if_ptr->glink_core_priv->channel_submit_pkt = glink_channel_submit_pkt_intentless;
   if_ptr->glink_core_priv->channel_receive_pkt = glink_channel_receive_pkt_intentless;
 }
diff --git a/platform/msm_shared/glink/glink_os_utils_dal.c b/platform/msm_shared/glink/glink_os_utils_dal.c
index 7ad6fb7..311890e 100644
--- a/platform/msm_shared/glink/glink_os_utils_dal.c
+++ b/platform/msm_shared/glink/glink_os_utils_dal.c
@@ -56,6 +56,7 @@
   void                    *param;
 }glink_os_thread_info_type;
 
+static uint32 cs_variable = 1;
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -102,6 +103,23 @@
 }
 
 /*===========================================================================
+FUNCTION      glink_os_cs_create
+===========================================================================*/
+/**
+  Create and initializesa Critical Section
+
+  @return     The critical section.
+*/
+/*=========================================================================*/
+os_cs_type *glink_os_cs_create( void )
+{
+  /* Create the new critical section */
+
+  return ( os_cs_type * )cs_variable;
+}
+
+
+/*===========================================================================
 FUNCTION      glink_os_cs_acquire
 ===========================================================================*/
 /**
@@ -248,15 +266,14 @@
 
   @param[in] s1     String 1
   @param[in] s2     String 2
-  @param[in] size   The maximum number of characters to compare
 
   @return
   0 if strings are identical (up to size characters), non-zero otherwise
 */
 /*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32 size )
+long glink_os_string_compare( const char *s1, const char *s2 )
 {
-  return strncmp( s1, s2, size );
+  return strcmp( s1, s2 );
 }
 
 /*===========================================================================
diff --git a/platform/msm_shared/glink/glink_rpmcore_setup.c b/platform/msm_shared/glink/glink_rpmcore_setup.c
index a206afa..573d68d 100644
--- a/platform/msm_shared/glink/glink_rpmcore_setup.c
+++ b/platform/msm_shared/glink/glink_rpmcore_setup.c
@@ -34,11 +34,30 @@
 #include "glink_internal.h"
 
 
+glink_core_if_type* glink_core_get_intentless_interface(void);
+
 /*===========================================================================
 EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 
 /*===========================================================================
+FUNCTION      glink_core_get_default_interface
+===========================================================================*/
+/**
+
+  Provides default core interface.
+
+  @return     Pointer to the default core interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void)
+{
+  return glink_core_get_intentless_interface();
+}
+
+/*===========================================================================
 FUNCTION      glink_core_setup
 ===========================================================================*/
 /**
diff --git a/platform/msm_shared/glink/xport_rpm.c b/platform/msm_shared/glink/xport_rpm.c
index 05329f9..68a6c80 100644
--- a/platform/msm_shared/glink/xport_rpm.c
+++ b/platform/msm_shared/glink/xport_rpm.c
@@ -135,7 +135,7 @@
   }
 
   last = ctx_ptr->rx_fifo_size - ctx_ptr->pkt_start_ind;
-
+  
   if (offset >= last)
   {
     *size = ctx_ptr->pkt_size - offset;
@@ -235,7 +235,7 @@
     *write_ptr++ = *buffer++;
   }
 
-  return (char*)write_ptr - &ctx_ptr->tx_fifo[0];
+  return (uint32)((char*)write_ptr - &ctx_ptr->tx_fifo[0]);
 }
 
 /*===========================================================================
@@ -271,12 +271,19 @@
 
   glink_os_cs_acquire(ctx_ptr->tx_link_lock);
 
+  /* Transport is in reset */
+  if( ctx_ptr->reset )
+  {
+    glink_os_cs_release(ctx_ptr->tx_link_lock);
+    return GLINK_STATUS_SUCCESS;
+  }
+
   write_ind = ctx_ptr->tx_desc->write_ind;
   read_ind = ctx_ptr->tx_desc->read_ind;
   avail_size = write_ind < read_ind ? read_ind - write_ind :
                ctx_ptr->tx_fifo_size - write_ind + read_ind;
 
-  if (reserve_size + sizeof(uint64_t) > avail_size)
+  if (reserve_size + sizeof(uint64) > avail_size)
   {
     glink_os_cs_release(ctx_ptr->tx_link_lock);
     return GLINK_STATUS_OUT_OF_RESOURCES;
@@ -449,7 +456,7 @@
 
   cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_OPEN_CHANNEL);
   cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
-  cmd[1] =  strlen(name) + 1;
+  cmd[1] =  (uint32)strlen(name) + 1;
 
   return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)name, cmd[1]);
 }
@@ -584,12 +591,12 @@
   cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_TX_DATA);
   cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
   cmd[1] = 0;
-  cmd[2] = pctx->size;
+  cmd[2] = (uint32)pctx->size;
   cmd[3] = 0;
 
   pctx->size_remaining = 0;
 
-  return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, pctx->size);
+  return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, (uint32)pctx->size);
 }
 
 /*===========================================================================
@@ -652,11 +659,11 @@
 }
 
 /*===========================================================================
-FUNCTION      xport_rpm_poll
+FUNCTION      xport_rpm_isr
 ===========================================================================*/
 /**
 
-  Poll of RPM transport.
+  ISR of RPM transport.
 
   @param[in]  ctx_ptr   Pointer to transport context.
 
@@ -667,7 +674,7 @@
   @dependencies None.
 */
 /*=========================================================================*/
-glink_err_type xport_rpm_poll( xport_rpm_ctx_type *ctx_ptr )
+glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
 {
   uint32 write_ind, read_ind;
   boolean stop_processing = FALSE;
@@ -712,7 +719,7 @@
 
         cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
 
-        /* no need to incerment read_ind here since it will be rounded up */
+        /* no need to increment read_ind here since it will be rounded up */
 
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_version(
           (glink_transport_if_type *)ctx_ptr,
@@ -744,56 +751,53 @@
         }
         else
         {
-          char    tmpstr[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
-          uint32  curr = 0;
-          uint32* string_ptr;
-          string_ptr = (uint32 *)&tmpstr[0];
-          while (curr < cmd_arg && curr < sizeof(tmpstr))
+          char  temp_string[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
+          uint32 num_copied_chars = 0;
+          uint32  *string_ptr;
+
+          string_ptr = ( uint32 * )&temp_string[0];
+          while( ( num_copied_chars < cmd_arg ) && ( num_copied_chars < sizeof( temp_string ) ) )
           {
-            CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
-            *(string_ptr++) = MSGRAM_READ32(ctx_ptr, read_ind);
-            curr += sizeof(uint32);
-            read_ind += sizeof(uint32);
+            CHECK_INDEX_WRAP_AROUND( read_ind, ctx_ptr->rx_fifo_size );
+            *( string_ptr++ ) = MSGRAM_READ32( ctx_ptr, read_ind );
+
+            num_copied_chars += sizeof( uint32 );
+            read_ind += sizeof( uint32 );
           }
 
           /* add all the unread stuff */
-          read_ind += cmd_arg - curr;
+          read_ind += cmd_arg - num_copied_chars;
 
           /* make sure the last character is NULL */
-          tmpstr[sizeof(tmpstr) - 1] = 0;
+          temp_string[ sizeof( temp_string ) - 1 ] = 0;
 
           ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
-            (glink_transport_if_type *)ctx_ptr, cid, tmpstr, GLINK_XPORT_RPM);
+            (glink_transport_if_type *)ctx_ptr, cid, temp_string, GLINK_XPORT_RPM);
         }
 
         break;
 
       case XPORT_RPM_CMD_CLOSE_CHANNEL:
 
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_close(
-          //(glink_transport_if_type *)ctx_ptr, XPORT_RPM_GET_CHANNEL_ID(cmd));
           (glink_transport_if_type *)ctx_ptr, cid);
 
-        /* no need to increment read_ind here since it would be rounded up */
-
         break;
 
       case XPORT_RPM_CMD_OPEN_CHANNEL_ACK:
 
-        /* no need to increment read_ind here since it would be rounded up */
-
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
             (glink_transport_if_type *)ctx_ptr, cid, GLINK_XPORT_RPM);
 
         break;
 
       case XPORT_RPM_CMD_CLOSE_CHANNEL_ACK:
-
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
           (glink_transport_if_type *)ctx_ptr, cid);
 
-        /* no need to increment read_ind here since it would be rounded up */
-
         break;
 
       case XPORT_RPM_CMD_TX_DATA:
@@ -843,7 +847,7 @@
 
         cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
 
-        /* no need to incerement read_ind here since it will be rounded up */
+        /* no need to increment read_ind here since it will be rounded up */
 
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_remote_sigs(
           (glink_transport_if_type *)ctx_ptr,
@@ -851,20 +855,28 @@
         break;
 
       default:
-      	dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
-      	ASSERT(0);
+        dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
+        ASSERT(0);
         break;
     }
 
-    read_ind = ROUNDUP64(read_ind);
-
-    if (read_ind >= ctx_ptr->rx_fifo_size)
+    /* Update read index only if transport has not been reset  */
+    if( !ctx_ptr->reset )
     {
-      read_ind -= ctx_ptr->rx_fifo_size;
-    }
+      read_ind = ROUNDUP64(read_ind);
 
-    /* Update the shared read index */
-    ctx_ptr->rx_desc->read_ind = read_ind;
+      if (read_ind >= ctx_ptr->rx_fifo_size)
+      {
+        read_ind -= ctx_ptr->rx_fifo_size;
+      }
+
+      /* Update the shared read index */
+      ctx_ptr->rx_desc->read_ind = read_ind;
+    }
+    else
+    {
+      stop_processing = TRUE;
+    }
   }
 
   glink_os_cs_release(ctx_ptr->rx_link_lock);
@@ -872,51 +884,6 @@
   return GLINK_STATUS_SUCCESS;
 }
 
-#ifdef GLINK_RPM_PROC
-/*===========================================================================
-FUNCTION      xport_rpm_isr
-===========================================================================*/
-/**
-
-  ISR of RPM transport.
-
-  @return     Returns error code.
-
-  @sideeffects  None.
-
-  @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( void )
-{
-  xport_rpm_ctx_type *ctx_ptr  = xport_rpm_get_context();
-
-  return xport_rpm_poll( ctx_ptr );
-}
-#else
-/*===========================================================================
-FUNCTION      xport_rpm_isr
-===========================================================================*/
-/**
-
-  ISR of RPM transport.
-
-  @param[in]  ctx_ptr   Pointer to transport context.
-
-  @return     Returns error code.
-
-  @sideeffects  None.
-
-  @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
-{
-  return xport_rpm_poll( ctx_ptr );
-}
-#endif
-
-
 /*===========================================================================
 FUNCTION      xport_rpm_ssr
 ===========================================================================*/
@@ -935,9 +902,15 @@
 {
   xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
 
+  glink_os_cs_acquire(ctx_ptr->tx_link_lock);
+  glink_os_cs_acquire(ctx_ptr->rx_link_lock);
   ctx_ptr->tx_desc->write_ind = 0;
+  ctx_ptr->tx_desc->read_ind = 0;
+  ctx_ptr->rx_desc->write_ind = 0;
   ctx_ptr->rx_desc->read_ind = 0;
   ctx_ptr->reset = TRUE;
+  glink_os_cs_release(ctx_ptr->rx_link_lock);
+  glink_os_cs_release(ctx_ptr->tx_link_lock);
 
   return GLINK_STATUS_SUCCESS;
 }
@@ -1004,6 +977,25 @@
 }
 
 /*===========================================================================
+FUNCTION      xport_rpm_is_toc_present
+===========================================================================*/
+/**
+
+  Checks RPM MSG RAM for ToC presence.
+
+  @return     TRUE if ToC is detected, FALSE otherwise.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+boolean xport_rpm_is_toc_present(void)
+{
+  uint32 *msg_ram_toc = (uint32*)xport_rpm_msg_ram_toc;
+
+  return msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] == XPORT_RPM_TOC_MAGIC;
+}
+
+/*===========================================================================
 FUNCTION      xport_rpm_init
 ===========================================================================*/
 /**
@@ -1033,8 +1025,9 @@
     return GLINK_STATUS_SUCCESS;
   }
 
-  if (msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] != XPORT_RPM_TOC_MAGIC)
+  if (!xport_rpm_is_toc_present())
   {
+    /* switch to err fatal once RPM side is integrated */
     dprintf(CRITICAL, "%s:%d: RPM Transport Failure: Invalid ToC cookie\n", __func__, __LINE__);
     return GLINK_STATUS_FAILURE;
   }
@@ -1076,14 +1069,12 @@
       if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->tx_fifo_id)
       {
         xport_rpm_ctx[ind].tx_desc = (xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
-        xport_rpm_ctx[ind].tx_desc->write_ind = 0;
         xport_rpm_ctx[ind].tx_fifo = (char*)(xport_rpm_ctx[ind].tx_desc + 1);
         xport_rpm_ctx[ind].tx_fifo_size = entry->fifo_size;
       }
       else if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->rx_fifo_id)
       {
         xport_rpm_ctx[ind].rx_desc =(xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
-        xport_rpm_ctx[ind].rx_desc->read_ind = 0;
         xport_rpm_ctx[ind].rx_fifo = (char*)(xport_rpm_ctx[ind].rx_desc + 1);
         xport_rpm_ctx[ind].rx_fifo_size = entry->fifo_size;
       }
@@ -1096,9 +1087,13 @@
       continue;
     }
 
+    /* Rx read index should be cleared last */
+    xport_rpm_ctx[ind].tx_desc->write_ind = 0;
+    xport_rpm_ctx[ind].rx_desc->read_ind = 0;
+
     /* Initialize context */
-    xport_rpm_ctx[ind].tx_link_lock = NULL;
-    xport_rpm_ctx[ind].rx_link_lock = NULL;
+    xport_rpm_ctx[ind].tx_link_lock = glink_os_cs_create();
+    xport_rpm_ctx[ind].rx_link_lock = glink_os_cs_create();
 
     /* Initialize GLink transport interface */
     xport_rpm_ctx[ind].xport_if.tx_cmd_version = &xport_rpm_tx_cmd_version;
@@ -1112,7 +1107,7 @@
     xport_rpm_ctx[ind].xport_if.tx_cmd_set_sigs = &xport_rpm_tx_cmd_set_sigs;
     xport_rpm_ctx[ind].xport_if.ssr = &xport_rpm_ssr;
     xport_rpm_ctx[ind].xport_if.mask_rx_irq = &xport_rpm_mask_interrupt;
-    xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_poll;
+    xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_isr;
     xport_rpm_ctx[ind].xport_if.wait_link_down = &xport_rpm_wait_link_down;
 
     /* TODO: glink transport priority */
@@ -1125,6 +1120,7 @@
     xport_rpm_cfg.version_count = 1;
     xport_rpm_cfg.max_cid = 0xFF;
     xport_rpm_cfg.max_iid = 0;
+
     if (glink_core_register_transport(&xport_rpm_ctx[ind].xport_if, &xport_rpm_cfg) !=
         GLINK_STATUS_SUCCESS)
     {
@@ -1137,7 +1133,8 @@
                                 (os_isr_cb_fn)xport_rpm_isr,
                                 &xport_rpm_ctx[ind]) )
     {
-       /* ISR registration failed, set index to invalid. */
+       /* ISR registration failed, set index to invalid.
+        * It will never fail */
       xport_rpm_ctx[ind].pcfg = NULL;
       continue;
     }
diff --git a/platform/msm_shared/include/glink.h b/platform/msm_shared/include/glink.h
index fe5b823..b36fba0 100644
--- a/platform/msm_shared/include/glink.h
+++ b/platform/msm_shared/include/glink.h
@@ -102,6 +102,9 @@
                           (link_id).version = GLINK_LINK_ID_VER;
 
 /* GLink tx options */
+/* Flag for no options */
+#define GLINK_TX_NO_OPTIONS      ( 0 )
+
 /* Whether to block and request for remote rx intent in
  * case it is not available for this pkt tx */
 #define GLINK_TX_REQ_INTENT      0x00000001
@@ -111,6 +114,9 @@
  * it is not able to do so */
 #define GLINK_TX_SINGLE_THREADED 0x00000002
 
+/* This option is to turn on tracer packet */
+#define GLINK_TX_TRACER_PKT      0x00000004
+
 /* ======================= glink open cfg options ==================*/
 
 /* Specified transport is just the initial transport and migration is possible
@@ -205,6 +211,17 @@
   size_t            intent_used /* size of the intent used for this packet */
 );
 
+/** Data receive notification callback type*/
+typedef void (*glink_rx_tracer_pkt_notification_cb)
+(
+  glink_handle_type handle,     /* handle for the glink channel */
+  const void        *priv,      /* priv client data passed in glink_open */
+  const void        *pkt_priv,  /* private client data assiciated with the
+                                   rx intent that client queued earlier */
+  const void        *ptr,       /* pointer to the received buffer */
+  size_t            size        /* size of the packet */
+);
+
 /** Vector receive notification callback type*/
 typedef void (*glink_rxv_notification_cb)
 (
@@ -295,54 +312,58 @@
  */
 typedef struct {
   /** string name for the transport to use (Optional)*/
-  const char                    *transport;
+  const char                          *transport;
 
   /** string name for the remote subsystem to which the user wants to
       connect */
-  const char                    *remote_ss;
+  const char                          *remote_ss;
 
   /** string name for the channel */
-  const char                    *name;
+  const char                          *name;
 
   /** bitfield for specifying various options */
-  unsigned                      options;
+  unsigned                            options;
 
   /** Private data for client to maintain context. This data is passed back
       to client in the notification callbacks */
-  const void                    *priv;
+  const void                          *priv;
 
   /** Data receive notification callback. Optional if notify_rxv is provided */
-  glink_rx_notification_cb      notify_rx;
+  glink_rx_notification_cb            notify_rx;
+
+  /** Tracer packet receive notification callback.
+   *  Optional if user doesn't need to use this */
+  glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
 
   /** Vector receive notification callback. Optional if notify_rx is provided */
-  glink_rxv_notification_cb     notify_rxv;
+  glink_rxv_notification_cb           notify_rxv;
 
   /** Data transmit notification callback */
-  glink_tx_notification_cb      notify_tx_done;
+  glink_tx_notification_cb            notify_tx_done;
 
   /** GLink channel state notification callback */
-  glink_state_notification_cb   notify_state;
+  glink_state_notification_cb         notify_state;
 
   /** Intent request from the remote side. Optional */
-  glink_notify_rx_intent_req_cb notify_rx_intent_req;
+  glink_notify_rx_intent_req_cb       notify_rx_intent_req;
 
   /** New intent arrival from the remote side */
-  glink_notify_rx_intent_cb     notify_rx_intent;
+  glink_notify_rx_intent_cb           notify_rx_intent;
 
   /** Control signal change notification - Invoked when remote side
    *  alters its control signals. Optional */
-  glink_notify_rx_sigs_cb       notify_rx_sigs;
+  glink_notify_rx_sigs_cb             notify_rx_sigs;
 
   /** rx_intent abort notification. This callback would be invoked for
    *  every rx_intent that is queued with GLink core at the time the
    *  remote side or local side decides to close the port. Optional */
-  glink_notify_rx_abort_cb      notify_rx_abort;
+  glink_notify_rx_abort_cb            notify_rx_abort;
 
   /** tx abort notification. This callback would be invoked if client
   *   had queued a tx buffer with glink and it had not been transmitted i.e.
   *   tx_done callback has not been called for this buffer and remote side
   *   or local side closed the port. Optional */
-  glink_notify_tx_abort_cb      notify_tx_abort;
+  glink_notify_tx_abort_cb            notify_tx_abort;
 
 }glink_open_config_type;
 
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
index 040bf31..67cd106 100644
--- a/platform/msm_shared/include/glink_core_if.h
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -57,9 +57,6 @@
 ===========================================================================*/
 typedef struct glink_core_version glink_core_version_type;
 
-struct glink_channel_ctx;
-typedef struct glink_channel_ctx glink_channel_ctx_type;
-
 /**
  * Transport status
  */
@@ -81,45 +78,48 @@
   size_t     pkt_sz;     /* Size of the packet */
   uint32     iid;        /* Intent ID */
   void       *iovec;     /* Pointer to the data buffer to be transmitted */
+  boolean    tracer_pkt;  /* Specify if this intent is for tracer packet */
   glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
   glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
 };
-/** GLink channel states*/
-typedef enum {
-  /** GLink channel state during initialization. No resources have been
-   *  allocated for this channel as neither GLink end has actually opened
-   *  the channel */
-  GLINK_CH_STATE_CLOSED,
 
-  /** GLink channel state when the local side has opened the channel. GLink
-   *  core is waiting for the other end of the channel to open */
-  GLINK_CH_STATE_LOCAL_OPEN,
+/** Context of Tx activity for a transport */
+typedef struct glink_tx_xport_ctx_s {
+  os_event_type event;   /* Event to signal Tx thread */
+  os_cs_type tx_q_cs;    /* Lock to protect Tx queue */
+  smem_list_type tx_q;   /* Tx channel queue */
+} glink_tx_xport_ctx_type;
 
-  /** GLink channel state when it is fully open. This implies that both ends
-   *  of the GLink channel are now open. Data transfer can now take place */
-  GLINK_CH_STATE_OPEN,
+/** G-Link Local channel states */
+typedef enum
+{
+  /** Local G-Link channel is fully closed */
+  GLINK_LOCAL_CH_CLOSED,
 
-  /** GLink channel state when remote side has initiated a OPEN operation. */
-  GLINK_CH_STATE_REMOTE_OPEN,
+  /** Local G-Link channel opened channel and waiting for ACK from remote */
+  GLINK_LOCAL_CH_OPENING,
 
-  /** GLink channel state when remote side has initiated a CLOSE operation.
-   *  Data cannot be transmitted/received any further on this channel */
-  GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE,
+  /** Local G-Link channel is fully opened */
+  GLINK_LOCAL_CH_OPENED,
 
-  /** GLink channel state when the local side has initiated a CLOSE. This
-   *  would be followed by a GLINK_STATE_CLOSE state transition after
-   *  the remote side has acknowledged the CLOSE request */
-   GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE,
+  /** Local G-Link channel closed the channel and waiting for ACK from remote */
+  GLINK_LOCAL_CH_CLOSING
 
-  /** GLink channel state would transition to SLEEP if the underlying
-   *  transport supports low power mode and decides to go into sleep
-   *  due to inactivity for some time or any other reason. */
-  GLINK_CH_STATE_SLEEP,
+}glink_local_state_type;
 
-  /** GLink channel state would transition to AWAKE state when underlying
-   *  transport layer has powered up the hardware */
-  GLINK_CH_STATE_AWAKE
-}glink_ch_state_type;
+/** G-Link Remote channel states */
+typedef enum
+{
+  /** Remote G-Link channel is closed */
+  GLINK_REMOTE_CH_CLOSED,
+
+  /** Remote G-Link channel is opened */
+  GLINK_REMOTE_CH_OPENED,
+
+  /* Glink channel state when SSR is received from remote sub-system */
+  GLINK_REMOTE_CH_SSR_RESET
+
+}glink_remote_state_type;
 
 /** Indicates that transport is now ready to start negotiation using the
  *  v0 configuration. */
@@ -187,14 +187,6 @@
   uint32                  rcid     /* Remote channel ID */
 );
 
-/** Process local state transition */
-typedef void (*ch_state_local_trans_fn)
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-);
-
 /** Transport invokes this call on receiving remote RX intent */
 typedef void (*rx_cmd_remote_rx_intent_put_fn)
 (
@@ -246,7 +238,7 @@
 (
   glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
   uint32                  rcid,    /* Remote channel ID */
-  boolean                 granted  /* True if RX Intent will be queued, FALSE
+  boolean                 granted  /* True if RX Intent will be queued, false
                                       if request will not be granted. */
 );
 
@@ -292,8 +284,8 @@
   glink_rx_intent_type *intent_ptr      /* Pointer to the intent context */
 );
 
-/** Use remote intent */
-typedef glink_err_type(*use_rm_intent_fn)
+/** Channel submit pkt */
+typedef glink_err_type(*channel_submit_pkt_fn)
 (
   glink_channel_ctx_type *open_ch_ctx,  /* Pointer to the channel context */
   glink_core_tx_pkt_type *pctx,         /* Pointer to the packet context */
@@ -306,10 +298,10 @@
 struct glink_core_xport_ctx
 {
   /* Transport name */
-  char                          xport[32];
+  const char                    *xport;
 
   /* Remote subsystem name */
-  char                          remote_ss[32];
+  const char                    *remote_ss;
 
   /** Keep track of version array index in use */
   const glink_core_version_type *version_array;
@@ -320,6 +312,10 @@
   /* Keeps track of the current status of the transport */
   glink_transport_status_type   status;
 
+  /* critical section to change/access xport status
+   * automically */
+  os_cs_type                    status_cs;
+
   /* Transport's capabilities */
   uint32                        xport_capabilities;
 
@@ -339,6 +335,9 @@
   /* Critical section to protect access to liid allocation */
   os_cs_type                    liid_cs;
 
+  /* Context of Tx activity for a transport */
+  glink_tx_xport_ctx_type       *tx_ctx;
+
   /* channel open config verification */
   verify_open_cfg_fn            verify_open_cfg;
 
@@ -351,8 +350,8 @@
   /* channel receive pkt */
   channel_receive_pkt_fn        channel_receive_pkt;
 
-  /** Use remote intent */
-  use_rm_intent_fn              use_rm_intent;
+  /* channel submit pkt */
+  channel_submit_pkt_fn         channel_submit_pkt;
 };
 
 /**
@@ -381,26 +380,18 @@
    *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
   rx_cmd_ch_remote_open_fn       rx_cmd_ch_remote_open;
 
-
   /** This function is invoked by the transport in response to
    *  glink_transport_if_type:: tx_cmd_ch_open */
   rx_cmd_ch_open_ack_fn          rx_cmd_ch_open_ack;
 
-
   /** This function is invoked by the transport in response to
    *  glink_transport_if_type:: tx_cmd_ch_close */
   rx_cmd_ch_close_ack_fn         rx_cmd_ch_close_ack;
 
-
   /** Remote channel close request; will result in sending
    *  glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
   rx_cmd_ch_remote_close_fn      rx_cmd_ch_remote_close;
 
-
-  /** Process local state transition */
-  ch_state_local_trans_fn        ch_state_local_trans;
-
-
   /** Transport invokes this call on receiving remote RX intent */
   rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
 
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index 96b0a59..bdd434c 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -45,7 +45,6 @@
 #include "glink_os_utils.h"
 #include "glink_core_if.h"
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -92,10 +91,18 @@
   GLINK_EVENT_CH_SIG_SET,
   GLINK_EVENT_CH_SIG_L_GET,
   GLINK_EVENT_CH_SIG_R_GET,
+  GLINK_EVENT_CH_NO_MIGRATION,
+  GLINK_EVENT_CH_MIGRATION_IN_PROGRESS,
   GLINK_EVENT_XPORT_INTERNAL,
+  GLINK_EVENT_TRACER_PKT_FAILURE,
+  GLINK_EVENT_TXV_INVALID_BUFFER
 }glink_log_event_type;
 
 typedef struct _glink_channel_intents_type {
+
+  /* Link for a channel in Tx queue */
+  struct _glink_channel_intents_type* next;
+
   /* Critical section to protest access to intent queues */
   os_cs_type                    intent_q_cs;
 
@@ -124,81 +131,91 @@
   /* Read intent being gathered */
   glink_rx_intent_type          *cur_read_intent;
 
+  /* Linked list of Tx packets in the order they where submitted by
+   * the channel owner */
+  smem_list_type                tx_pkt_q;
+
 } glink_channel_intents_type;
 
 struct glink_channel_ctx {
   /* Link needed for use with list APIs.  Must be at the head of the struct */
-  smem_list_link_type           link;
+  smem_list_link_type                 link;
 
   /* Channel name */
-  char                          name[GLINK_CH_NAME_LEN];
+  char                                name[GLINK_CH_NAME_LEN];
 
   /* Local channel ID */
-  uint32                        lcid;
+  uint32                              lcid;
 
   /* Remote Channel ID */
-  uint32                        rcid;
+  uint32                              rcid;
 
-  /* Channel state */
-  glink_ch_state_type           state;
+  /* Local Channel state */
+  glink_local_state_type              local_state;
+
+  /* Remote channel state */
+  glink_remote_state_type             remote_state;
+
+  /* Critical section to protect channel states */
+  os_cs_type                          ch_state_cs;
 
   /* Channel local control signal state */
-  uint32                        local_sigs;
+  uint32                              local_sigs;
 
   /* Channel remote control signal state */
-  uint32                        remote_sigs;
+  uint32                              remote_sigs;
 
   /* Critical section to protect tx operations */
-  os_cs_type                    tx_cs;
+  os_cs_type                          tx_cs;
 
   /* channel intent collection */
-  glink_channel_intents_type    *pintents;
+  glink_channel_intents_type          *pintents;
 
   /* Interface pointer with with this channel is registered */
-  glink_transport_if_type       *if_ptr;
+  glink_transport_if_type             *if_ptr;
 
   /** Private data for client to maintain context. This data is passed back
    * to client in the notification callbacks */
-  const void                    *priv;
+  const void                          *priv;
 
   /** Data receive notification callback */
-  glink_rx_notification_cb      notify_rx;
+  glink_rx_notification_cb            notify_rx;
+
+  /** Tracer Packet data receive notification callback */
+  glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
 
   /** Vector receive notification callback */
-  glink_rxv_notification_cb      notify_rxv;
+  glink_rxv_notification_cb           notify_rxv;
 
   /** Data transmit notification callback */
-  glink_tx_notification_cb      notify_tx_done;
+  glink_tx_notification_cb            notify_tx_done;
 
   /** GLink channel state notification callback */
-  glink_state_notification_cb   notify_state;
+  glink_state_notification_cb         notify_state;
 
   /** Intent request from the remote side */
-  glink_notify_rx_intent_req_cb notify_rx_intent_req;
+  glink_notify_rx_intent_req_cb       notify_rx_intent_req;
 
   /** New intent arrival from the remote side */
-  glink_notify_rx_intent_cb     notify_rx_intent;
+  glink_notify_rx_intent_cb           notify_rx_intent;
 
   /** Control signal change notification - Invoked when remote side
    *  alters its control signals */
-  glink_notify_rx_sigs_cb       notify_rx_sigs;
+  glink_notify_rx_sigs_cb             notify_rx_sigs;
 
   /** rx_intent abort notification. This callback would be invoked for
   *  every rx_intent that is queued with GLink core at the time the
   *  remote side or local side decides to close the port. Optional */
-  glink_notify_rx_abort_cb      notify_rx_abort;
+  glink_notify_rx_abort_cb            notify_rx_abort;
 
   /** tx abort notification. This callback would be invoked if client
   *   had queued a tx buffer with glink and it had not been transmitted i.e.
   *   tx_done callback has not been called for this buffer and remote side
   *   or local side closed the port. Optional */
-  glink_notify_tx_abort_cb      notify_tx_abort;
+  glink_notify_tx_abort_cb            notify_tx_abort;
 
   /* glink transport if pointer for preferred channel */
-  glink_transport_if_type       *req_if_ptr;
-
-  /* reference count for no of times channel open/close has been called */
-  uint32                        ref_count;
+  glink_transport_if_type             *req_if_ptr;
 
   /* flag to check if channel is marked for deletion
    * This is workaround to prevent channel migration algorithm from finding channel
@@ -207,10 +224,10 @@
    * This may lead to remote side opening channel on neogitated xport from which local side
    * will get remote open again. In this case channel to be closed will be found for negotiation
    * on initial xport again and channel migration algorithm will be triggered(again)  */
-  boolean                       tag_ch_for_close;
+  boolean                             tag_ch_for_close;
 
   /* save glink open config options */
-  uint32 ch_open_options;
+  uint32                              ch_open_options;
 };
 
 
@@ -235,7 +252,6 @@
   void                      *priv;         /* Notification priv ptr */
 } glink_link_notif_data_type;
 
-
 /*===========================================================================
                               GLOBAL DATA DECLARATIONS
 ===========================================================================*/
@@ -411,27 +427,6 @@
 );
 
 /*===========================================================================
-FUNCTION      glink_ch_state_local_trans
-
-DESCRIPTION   Process local state transition
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-);
-
-/*===========================================================================
 FUNCTION      glink_rx_put_pkt_ctx
 
 DESCRIPTION   Transport invokes this call to receive a packet fragment (must
@@ -483,25 +478,6 @@
 );
 
 /*===========================================================================
-FUNCTION      glink_tx_resume
-
-DESCRIPTION   If transport was full and could not continue a transmit
-              operation, then it will call this function to notify the core
-              that it is ready to resume transmission.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_tx_resume
-(
-  glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-);
-
-/*===========================================================================
 FUNCTION      glink_set_core_version
 
 DESCRIPTION   Sets the core version used by the transport; called after
@@ -534,7 +510,7 @@
 
 ARGUMENTS     *cfg_ptr   - Pointer to channel context
 
-RETURN VALUE  True if fully opened, FALSE otherwise.
+RETURN VALUE  True if fully opened, false otherwise.
 
 SIDE EFFECTS  None
 ===========================================================================*/
@@ -746,41 +722,36 @@
 );
 
 /*===========================================================================
-FUNCTION      glinki_add_ch_to_xport
-
-DESCRIPTION   Add remote/local channel context to xport open channel queue
-
-ARGUMENTS     *if_ptr            - Pointer to xport if on which channel is to
-                                   be opened
-              *req_if_ptr        - Pointer to xport if on which channel
-			                       actually wants to open
-              *ch_ctx            - channel context
-              **allocated_ch_ctx - Pointer to channel context pointer
-              local_open         - flag to determine if channel is opened
-			                       locally or remotely
-              migration state    - flag to identify whether channel migration
-			                       negotiation is done
-                                   TRUE - negotiation is not complete
-                                   FALSE - negotiation is complete.
-								   channel is being opened on same xport as negotiated
-              prio               - negotiated xport priority
-			                       (used to send priority via remote_open_ack to
-								    remote side)
-              *tx_pkt            - Pointer to the packet context to remove
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
+  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_transport_if_type  *req_if_ptr,
   glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type   **allocated_ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
   unsigned int              local_open,
-  boolean                  migration_state,
-  glink_xport_priority     prio
+  glink_xport_priority      prio
 );
 
 void glink_mem_log
@@ -811,6 +782,20 @@
 void glink_core_setup(glink_transport_if_type *if_ptr);
 
 /*===========================================================================
+FUNCTION      glink_core_get_default_interface
+===========================================================================*/
+/**
+
+  Provides default core interface.
+
+  @return     Pointer to the default core interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void);
+
+/*===========================================================================
 FUNCTION      glink_core_setup_full_xport
 ===========================================================================*/
 /**
diff --git a/platform/msm_shared/include/glink_os_utils.h b/platform/msm_shared/include/glink_os_utils.h
index e0a1613..ad8f0d1 100644
--- a/platform/msm_shared/include/glink_os_utils.h
+++ b/platform/msm_shared/include/glink_os_utils.h
@@ -175,13 +175,12 @@
 
   @param[in] s1     String 1
   @param[in] s2     String 2
-  @param[in] size   The maximum number of characters to compare
 
   @return
   0 if strings are identical (up to size characters), non-zero otherwise
 */
 /*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32_t size );
+long glink_os_string_compare( const char *s1, const char *s2 );
 
 /*===========================================================================
   FUNCTION  glink_os_copy_mem
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
index da9e2bd..84056b0 100644
--- a/platform/msm_shared/include/glink_transport_if.h
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -51,9 +51,13 @@
 /* GLink transport capability bit definitions */
 /* Whether transport supports signalling */
 #define GLINK_CAPABILITY_SIG_SUPPORT 0x00000001
+
 /* Intentless mode of operation */
 #define GLINK_CAPABILITY_INTENTLESS  0x00000002
 
+/* Tracer packet support */
+#define GLINK_CAPABILITY_TRACER_PKT  0x00000004
+
 /*===========================================================================
                       TYPE DECLARATIONS
 ===========================================================================*/
@@ -70,6 +74,9 @@
 struct glink_rx_intent;
 typedef struct glink_rx_intent      glink_rx_intent_type;
 
+struct glink_channel_ctx;
+typedef struct glink_channel_ctx glink_channel_ctx_type;
+
 /* Priority of transports registered with glink */
 typedef enum {
   GLINK_XPORT_SMEM = 100,
@@ -81,13 +88,17 @@
 } glink_xport_priority;
 
 /** Glink core -> Xport pkt type definition */
-typedef struct {
+typedef struct glink_core_tx_pkt_s {
+  struct glink_core_tx_pkt_s *next; /* pointer to the next packet in list */
+
   void       *data;      /* Pointer to the data buffer to be transmitted */
   const void *pkt_priv;  /* Per packet private data */
+  uint32     cid;        /* Local channel ID being used to transmit data */
   uint32     iid;        /* Remote intent ID being used to transmit data */
   size_t     size;       /* Size of data buffer */
   size_t     size_remaining; /* Size left to transmit */
   void       *iovec;      /* Pointer to the data buffer to be transmitted */
+  boolean    tracer_pkt;  /* specify if this intent is for tracer packet */
   glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
   glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
 }glink_core_tx_pkt_type;
@@ -317,7 +328,7 @@
    *  channel */
   tx_fn                              tx;
 
-   /** Send request to the remote to queue more rx intents */
+  /** Send request to the remote to queue more rx intents */
   tx_cmd_rx_intent_req_fn            tx_cmd_rx_intent_req;
 
   /** Send ACK to the remote side's request to queue more rx intents */
diff --git a/platform/msm_shared/include/xport_rpm.h b/platform/msm_shared/include/xport_rpm.h
index 2566172..8282766 100644
--- a/platform/msm_shared/include/xport_rpm.h
+++ b/platform/msm_shared/include/xport_rpm.h
@@ -39,7 +39,7 @@
                         INCLUDE FILES
 ===========================================================================*/
 #include "glink_transport_if.h"
-#include <glink.h>
+
 /*===========================================================================
                       MACRO DECLARATIONS
 ===========================================================================*/
@@ -67,10 +67,6 @@
 
 #define XPORT_RPM_GET_CHANNEL_ID(c)   (((c) >> 16) & 0xFFFF)
 #define XPORT_RPM_SET_CHANNEL_ID(cid) (((cid) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_STR_LEN(c)      (((c) >> 16) & 0xFFFF)
-#define XPORT_RPM_SET_STR_LEN(c)      (((c) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_PRIO(c)         ((c) & 0xFFFF)
-#define XPORT_RPM_SET_PRIO(c)         ((c) & 0xFFFF)
 
 #define XPORT_RPM_GET_VERSION(c) (((c) >> 16) & 0xFFFF)
 #define XPORT_RPM_SET_VERSION(v) (((v) << 16) & 0xFFFF0000)
diff --git a/project/msm8916.mk b/project/msm8916.mk
index 5322f72..5891664 100644
--- a/project/msm8916.mk
+++ b/project/msm8916.mk
@@ -18,6 +18,7 @@
 DEFINES += WITH_DEBUG_LOG_BUF=1
 DEFINES += WITH_DEBUG_UART=1
 #DEFINES += WITH_DEBUG_FBCON=1
+DEFINES += ENABLE_FBCON_LOGGING=1
 DEFINES += DEVICE_TREE=1
 #DEFINES += MMC_BOOT_BAM=1
 DEFINES += CRYPTO_BAM=1
@@ -56,4 +57,4 @@
 DEFINES += PLATFORM_USE_SCM_DLOAD=1
 
 #Enable the external reboot functions
-ENABLE_REBOOT_MODULE := 1
\ No newline at end of file
+ENABLE_REBOOT_MODULE := 1
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 3567f5a..6998aa4 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -455,6 +455,7 @@
 		switch (board_hardware_id()) {
 		case HW_PLATFORM_MTP:
 		case HW_PLATFORM_SURF:
+		case HW_PLATFORM_QRD:
 			splash_screen = 1;
 			break;
 		default:
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index d94d37f..c94d98a 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -44,6 +44,7 @@
 /*---------------------------------------------------------------------------*/
 #include "include/panel_truly_1080p_video.h"
 #include "include/panel_truly_1080p_cmd.h"
+#include "include/panel_otm1906c_1080p_cmd.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -51,6 +52,7 @@
 enum {
 	TRULY_1080P_VIDEO_PANEL,
 	TRULY_1080P_CMD_PANEL,
+	OTM1906C_1080P_CMD_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -150,6 +152,32 @@
 			truly_1080p_cmd_timings, TIMING_SIZE);
 		pinfo->mipi.signature 	= TRULY_1080P_CMD_SIGNATURE;
 		break;
+	case OTM1906C_1080P_CMD_PANEL:
+		panelstruct->paneldata    = &otm1906c_1080p_cmd_panel_data;
+		panelstruct->paneldata->panel_with_enable_gpio = 1;
+		panelstruct->panelres     = &otm1906c_1080p_cmd_panel_res;
+		panelstruct->color        = &otm1906c_1080p_cmd_color;
+		panelstruct->videopanel   = &otm1906c_1080p_cmd_video_panel;
+		panelstruct->commandpanel = &otm1906c_1080p_cmd_command_panel;
+		panelstruct->state        = &otm1906c_1080p_cmd_state;
+		panelstruct->laneconfig   = &otm1906c_1080p_cmd_lane_config;
+		panelstruct->paneltiminginfo
+			= &otm1906c_1080p_cmd_timing_info;
+		panelstruct->panelresetseq
+					 = &otm1906c_1080p_cmd_panel_reset_seq;
+		panelstruct->backlightinfo = &otm1906c_1080p_cmd_backlight;
+		pinfo->mipi.panel_on_cmds
+			= otm1906c_1080p_cmd_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= OTM1906C_1080P_CMD_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= otm1906c_1080p_cmd_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= OTM1906C_1080P_CMD_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			otm1906c_1080p_cmd_timings, TIMING_SIZE);
+		pinfo->mipi.signature = OTM1906C_1080P_CMD_SIGNATURE;
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -197,6 +225,9 @@
 	case HW_PLATFORM_SURF:
 		panel_id = TRULY_1080P_VIDEO_PANEL;
 		break;
+	case HW_PLATFORM_QRD:
+		panel_id = OTM1906C_1080P_CMD_PANEL;
+		break;
 	default:
 		dprintf(CRITICAL, "Display not enabled for %d HW type\n",
 			hw_id);