[Feature][T106_eSDK]T106-V2.01.01.02P56U06.AP.15.11_CAP.15.11(SDK4.6)diff_17.02(SDK4.7)

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I9dc02273b59a074828ab3eeaa84306415b153138
diff --git a/upstream/linux-5.10/kernel/ramdump/ramdump_device_trans.c b/upstream/linux-5.10/kernel/ramdump/ramdump_device_trans.c
new file mode 100755
index 0000000..40c920d
--- /dev/null
+++ b/upstream/linux-5.10/kernel/ramdump/ramdump_device_trans.c
@@ -0,0 +1,753 @@
+/**
+ * @file oss_ramdump_osa.c
+ * @brief Implementation of Ramdump os adapt
+ *
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * @author Qing Wang <wang.qing@sanechips.com.cn>
+ * @ingroup si_ap_oss_ramdump_id
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*******************************************************************************
+ *                           Include header files                              *
+ ******************************************************************************/
+#include "ramdump.h"
+#include <linux/lzo.h>
+#include "ramdump_compress.h"
+#ifdef CONFIG_RAMDUMP_EMMC
+#include "ramdump_emmc.h"
+#endif
+#ifdef CONFIG_MTD_SPI_NAND
+#include "ramdump_spinand.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+*                          Extern function declarations                        *
+*******************************************************************************/
+extern unsigned char *ramdump_phy_to_vir(unsigned long phy, unsigned long size);
+extern int dump_printk_text(char *buffer, unsigned long len);
+
+/*******************************************************************************
+*                          Extern variable declarations                        *
+*******************************************************************************/
+extern unsigned int ramdump_compress_flag;
+extern unsigned char *ramdump_log_buf;
+extern unsigned int ramdump_export_mode;
+
+/*******************************************************************************
+ *                             Macro definitions                               *
+ ******************************************************************************/
+/*Ö¸ÁîÖ¡³¤¶È */
+#define RAMDUMP_INTERACTIVE_DATA_LEN        40
+#define RAMDUMP_INTERACTIVE_ARRAY_LEN       10
+
+/* ramdump ºÍ ¹²ÏíÄÚ´æ½»»¥ÃüÁîÔ¼¶¨ */
+/*ͬ²½ÇëÇó*/
+#define RAMDUMP_PC_INTERACTIVE_REQ                  1
+/*ͬ²½ÇëÇóÓ¦´ð,´«ÊäramdumpµÄÎļþÊýÄ¿*/
+#define RAMDUMP_TRANS_SERVER_INTERACTIVE_RSP        2
+/*ÇëÇó´«µÝÖ¸¶¨Îļþ±àºÅµÄÎļþÐÅÏ¢*/
+#define RAMDUMP_PC_FILE_INFO_READ_REQ               3
+/*ÇëÇó´«µÝÖ¸¶¨Îļþ±àºÅµÄÎļþÐÅÏ¢µÄÓ¦´ð£¬´«ÊäÎļþÃû¼°´óС*/
+#define RAMDUMP_TRANS_SERVER_FILE_INFO_READ_RSP     4
+/*ÇëÇó¶Áȡָ¶¨Îļþ±àºÅµÄÎļþÄÚÈÝ*/
+#define RAMDUMP_PC_FILE_DATA_TRANS_REQ              5
+/*ÇëÇó¶Áȡָ¶¨Îļþ±àºÅµÄÎļþÄÚÈݵÄÓ¦´ð£¬´«ÊäÎļþÄÚÈÝ*/
+#define RAMDUMP_TRANS_SERVER_FILE_DATA_TRANS_RSP    6
+/*´«Êä½áÊø*/
+#define RAMDUMP_PC_FILE_TRANS_DONE_REQ              7
+/*´«Êä½áÊøÓ¦´ð*/ 
+#define RAMDUMP_TRANS_SERVER_FILE_TRANS_DONE_RSP    8
+
+/* ´íÎóÀàÐÍ */
+/*Ö¸Áî´íÎó*/
+#define RAMDUMP_INTERACTIVE_CMD_ERROR               9
+/*ÇëÇó´«µÝÖ¸¶¨Îļþ±àºÅ´í*/
+#define RAMDUMP_FILE_NUMBER_ERROR                   10
+/*ÇëÇó´«µÝÖ¸¶¨ÎļþλÖôóС´í*/
+#define RAMDUMP_FILE_SIZE_ERROR                     11
+
+#define RAMDUMP_DELAY_MS_COUNT (2500)
+
+/*******************************************************************************
+ *                             Type definitions                                *
+ ******************************************************************************/
+/*
+ * struct TRANS WITH AP
+ */
+
+/* trans_server rsp pc, interactive msg struct */
+typedef struct
+{
+	unsigned int cmd;
+	unsigned int file_num;
+} ramdump_trans_server_interactive_req;
+
+/* trans_server rsp pc, file info msg struct */
+typedef struct
+{
+	unsigned int cmd;
+	char    file_name[RAMDUMP_RAMCONF_FILENAME_MAXLEN];
+	unsigned int file_size;
+} ramdump_trans_server_file_info_req;
+
+/* pc req trans_server, file info msg struct */
+typedef struct
+{
+	unsigned int cmd;
+	unsigned int file_id;
+} ramdump_pc_file_info_rsp;
+
+/* trans_server rsp pc, trans data msg struct */
+typedef struct
+{
+	unsigned int cmd;
+	unsigned int buf_addr;
+	unsigned int buf_left_size;
+} ramdump_trans_server_data_trans_req;
+
+/* pc req trans_server, trans data msg struct */
+typedef struct
+{
+	unsigned int   cmd;
+	unsigned int   file_id;      /* Îļþ±àºÅ         */
+	unsigned int   offset;       /* offsetΪÊý¾ÝÆ«ÒÆ */
+	unsigned int   length;       /* lengthΪÊý¾Ý³¤¶È */
+} ramdump_pc_trans_data_rsp;
+
+/*******************************************************************************
+ *                        Local function declarations                          *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *                         Local variable definitions                          *
+ ******************************************************************************/
+char *ramdump_log_buf_region = NULL;
+unsigned int ramdump_log_buf_len = 0;
+
+/*******************************************************************************
+ *                        Global variable definitions                          *
+ ******************************************************************************/
+unsigned char *ramdump_shared_mem_base = NULL;
+unsigned char *ramdump_export_flag_base = NULL;
+int ramdump_file_num = 0;
+ramdump_file_t ramdump_device_fp = {0};
+ramdump_file_t ramdump_spinand_fp = {0};
+ramdump_file_t *g_ramdump_dev_fp;
+unsigned int   ramdump_device_file_cnt = 0;
+unsigned char *ramdump_log_buf = NULL; /* ¸´ÓÃramdump´æ´¢µÄ128KB(Æ«ÒÆ16KB) */
+
+/*******************************************************************************
+ *                      Inline function implementations                        *
+ ******************************************************************************/
+static inline void ramdump_wait_delay( unsigned long ms)
+{
+	volatile int j = 0;
+	for (j = 0; j < 10000; j++);
+}
+/*******************************************************************************
+ *                      extern function implementations                         *
+ ******************************************************************************/
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_oss_data_trans_write
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for ramdump to trans dump data to PC
+*******************************************************************************/
+int ramdump_oss_data_trans_write(unsigned char *buffer, unsigned int size)
+{
+	int ret;
+	ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+
+	if (size > (RAMDUMP_SHARED_MEM_LEN- roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE)));
+		ret = -1;
+
+	while(1){
+		if ((msg->core_flag == 1) && (msg->rw_flag == 1)){
+			memcpy(msg->buf, buffer, size);
+			msg->size = size;
+			msg->core_flag = 0;
+			msg->rw_flag = 2;
+			ret = size;
+			break;
+		}
+		else
+			ramdump_wait_delay(0);
+	}
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_oss_data_trans_read
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for ramdump to trans dump data to PC
+*******************************************************************************/
+int ramdump_oss_data_trans_read(unsigned char *buffer, unsigned int size)
+{
+	int ret;
+	ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+
+	if (size > (RAMDUMP_SHARED_MEM_LEN - roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE)))
+		ret = -1;
+
+	while(1){
+		if ((msg->core_flag == 1) && (msg->rw_flag == 2)){
+			if (size < msg->size)
+				return -1;
+			memcpy(buffer, msg->buf, msg->size);
+			msg->size = size;
+			msg->core_flag = 1;
+			msg->rw_flag = 1;
+			ret = size;
+			break;
+		}
+		else
+			ramdump_wait_delay(0);
+	}
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_oss_data_trans_init
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for map ramdump_shared_mem_base
+*******************************************************************************/
+void ramdump_oss_data_trans_init(void)
+{
+	ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+
+	memset(msg, 0, sizeof(ramdump_shmem_t));
+	msg->core_flag = 1;
+	msg->rw_flag = 1;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_device_init
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for init fp head
+*******************************************************************************/
+int ramdump_device_init(void)
+{
+	int ret = 0;
+
+	ramdump_lzo_init();
+	if(ramdump_export_mode == RAMDUMP_MODE_EMMC)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		ret = ramdump_emmc_init(&ramdump_device_fp);
+#endif
+		g_ramdump_dev_fp = &ramdump_device_fp;
+	}
+	else if(ramdump_export_mode == RAMDUMP_MODE_SPINAND)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		ret = ramdump_spinand_init(&ramdump_spinand_fp);
+#endif
+		g_ramdump_dev_fp = &ramdump_spinand_fp;
+	}
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_device_close
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for print close msg
+*******************************************************************************/
+void ramdump_device_close(void)
+{
+	if(ramdump_export_mode == RAMDUMP_MODE_EMMC)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		ramdump_emmc_close(&ramdump_device_fp);
+#endif
+	}
+	else if (ramdump_export_mode == RAMDUMP_MODE_SPINAND)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		ramdump_spinand_close(&ramdump_spinand_fp);
+#endif
+	}
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_fill_header
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) 
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for  ramdump file header
+*******************************************************************************/
+int ramdump_fill_header(char *file_name, unsigned int file_size, ramdump_file_t *fp, unsigned int offset)
+{
+	if (ramdump_device_file_cnt >= RAMDUMP_FILE_NUM_MAX)
+		return -1;
+
+	fp->file_fp[ramdump_device_file_cnt].magic = 0x3A3A3A3A;
+	strncpy(fp->file_fp[ramdump_device_file_cnt].file_name, file_name, RAMDUMP_RAMCONF_FILENAME_MAXLEN - 1);
+	fp->file_fp[ramdump_device_file_cnt].offset = offset;
+	fp->file_fp[ramdump_device_file_cnt].size = file_size;
+	return 0;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:    ramdump_device_write_file
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:    void 
+* ÆäËü˵Ã÷:    This function is used for write file infomation
+*******************************************************************************/
+int ramdump_device_write_file(ramdump_trans_server_file_info_req *server_to_cap)
+{
+	int ret = -1;
+	
+	if(ramdump_export_mode == RAMDUMP_MODE_EMMC)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		if (ramdump_emmc_offset >= RAMDUMP_TRANS_EMMC_LEN)
+			return -1;
+
+		ret = ramdump_fill_header(server_to_cap->file_name, 
+								 server_to_cap->file_size, 
+								 &ramdump_device_fp, 
+								 ramdump_emmc_offset);
+#endif
+	}
+	else if(ramdump_export_mode == RAMDUMP_MODE_SPINAND)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		if (ramdump_spinand_offset >= RAMDUMP_SPINAND_LEN)
+			return -1;
+
+		ret = ramdump_fill_header(server_to_cap->file_name, 
+								  server_to_cap->file_size,
+								  &ramdump_spinand_fp, 
+								  ramdump_spinand_offset);
+#endif
+	}
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:	ramdump_device_write_file
+* ²ÎÊý˵Ã÷:	 
+*   (´«Èë²ÎÊý) fp£º	  Îļþ¾ä±ú
+*   (´«³ö²ÎÊý) file_size Îļþ´óС
+* ·µ »Ø Öµ:	³É¹¦·µ»Ø0£¬Ê§°Ü·µ»Ø-1 
+* ÆäËü˵Ã÷:	This function is used for write file infomation
+*******************************************************************************/
+int ramdump_device_modify_file_size(ssize_t file_size)
+{
+	int ret = -1;
+	ramdump_file_t *fp = g_ramdump_dev_fp;
+
+	if(fp)
+	{
+		fp->file_fp[ramdump_device_file_cnt].size = file_size;
+		return 0;
+	}
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:	ramdump_device_write_file_head
+* ²ÎÊý˵Ã÷:	 
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:	void 
+* ÆäËü˵Ã÷:	This function is used for write file head
+*******************************************************************************/
+int ramdump_device_write_file_head(void)
+{
+	int ret = -1;
+	
+	if(ramdump_export_mode == RAMDUMP_MODE_EMMC)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		ret = ramdump_emmc_write_file_head(&ramdump_device_fp);		
+#endif
+	}
+	else if(ramdump_export_mode == RAMDUMP_MODE_SPINAND)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		ret = ramdump_spinand_write_file_head(&ramdump_spinand_fp);
+#endif
+	}
+	return ret;
+}
+
+int ramdump_do_write_log_txt(ramdump_file_t *fp)
+{
+	int ret = -1;
+	size_t dst_len = 0;	
+	size_t send_len = 0;
+	ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+	char *buf = NULL;
+
+	memset(ramdump_log_buf, 0, RAMDUMP_LOG_BUF);
+	ret = dump_printk_text(ramdump_log_buf, RAMDUMP_LOG_BUF);
+	if(ret < 0){
+		printk("ramdump printk log buf failed!!\n");
+		return ret;
+	}
+	if (ramdump_compress_flag == 1){
+		ret = ramdump_lzo_compress(ramdump_log_buf, RAMDUMP_LOG_BUF, msg->buf, &dst_len);
+		buf = msg->buf;
+	}
+	if (ret != LZO_E_OK){
+		dst_len = RAMDUMP_LOG_BUF;
+		buf = ramdump_log_buf;
+	}
+	fp->file_num += 1;
+	fp->file_fp[ramdump_device_file_cnt].magic = 0x3A3A3A3A;
+	strncpy(fp->file_fp[ramdump_device_file_cnt].file_name, "cap_log_buf.txt", RAMDUMP_RAMCONF_FILENAME_MAXLEN - 1);
+
+	if (fp == &ramdump_device_fp)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		fp->file_fp[ramdump_device_file_cnt].size = roundup(dst_len, RAMDUMP_EMMC_ALIGN_SIZE);
+		fp->file_fp[ramdump_device_file_cnt].offset = ramdump_emmc_offset;
+		ret = mmc_bwrite(RAMDUMP_EMMC_ADDR + ramdump_emmc_offset, dst_len, buf);
+		ramdump_emmc_write_file_head(fp);
+		ramdump_emmc_offset = ramdump_emmc_offset + roundup(dst_len, RAMDUMP_EMMC_ALIGN_SIZE);
+#endif
+	}
+	else if (fp == &ramdump_spinand_fp)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		send_len = roundup(dst_len, RAMDUMP_FLASH_ALIGN_SIZE);
+		fp->file_fp[ramdump_device_file_cnt].size = send_len;
+		fp->file_fp[ramdump_device_file_cnt].offset = ramdump_spinand_offset;
+		ret = write_data(RAMDUMP_SPINAND_ADDR + ramdump_spinand_offset, send_len, buf);
+		ramdump_spinand_offset = ramdump_spinand_offset + send_len;
+#endif
+	}
+	else
+	{
+		printk("ramdump_do_write_logbuf error fp!\n");
+		return -1;
+	}
+	ramdump_device_file_cnt += 1;
+	return ret;
+}
+
+int ramdump_do_write_logbuf(ramdump_file_t *fp)
+{
+	char   *buf = NULL;
+	int	ret  = -1;
+	size_t dst_len = 0;
+	size_t send_len = 0;
+	ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+
+	if(!fp)
+	{
+		printk("ramdump_do_write_logbuf error: fp is Null\n");
+		return -1;
+	}
+
+	ramdump_log_buf_region = log_buf_addr_get();
+	ramdump_log_buf_len = log_buf_len_get();
+
+	if (ramdump_compress_flag == 1){
+		ret = ramdump_lzo_compress(ramdump_log_buf_region, ramdump_log_buf_len, msg->buf, &dst_len);
+		buf = msg->buf;
+	}
+	if (ret != LZO_E_OK){
+		dst_len = ramdump_log_buf_len;
+		buf = ramdump_log_buf_region;
+	}
+
+	fp->file_num += 1;
+	fp->file_fp[ramdump_device_file_cnt].magic = 0x3A3A3A3A;
+	strncpy(fp->file_fp[ramdump_device_file_cnt].file_name, "cap_log_buf.bin", RAMDUMP_RAMCONF_FILENAME_MAXLEN - 1);
+
+	if (fp == &ramdump_device_fp)
+	{
+#ifdef CONFIG_RAMDUMP_EMMC
+		fp->file_fp[ramdump_device_file_cnt].size = roundup(dst_len, RAMDUMP_EMMC_ALIGN_SIZE);
+		ret = mmc_bwrite(RAMDUMP_EMMC_ADDR + ramdump_emmc_offset, dst_len, buf);
+		fp->file_fp[ramdump_device_file_cnt].offset = ramdump_emmc_offset;
+		ramdump_emmc_write_file_head(fp);
+		ramdump_emmc_offset = ramdump_emmc_offset + roundup(dst_len, RAMDUMP_EMMC_ALIGN_SIZE);
+#endif
+	}
+	else if (fp == &ramdump_spinand_fp)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		send_len = roundup(dst_len, RAMDUMP_FLASH_ALIGN_SIZE);
+		fp->file_fp[ramdump_device_file_cnt].size = send_len;
+		fp->file_fp[ramdump_device_file_cnt].offset = ramdump_spinand_offset;
+		ret = write_data(RAMDUMP_SPINAND_ADDR + ramdump_spinand_offset, send_len, buf);
+		ramdump_spinand_offset = ramdump_spinand_offset + send_len;
+#endif
+	}
+	else
+	{
+		printk("ramdump_do_write_logbuf error fp!\n");
+		return -1;
+	}
+	
+	ramdump_device_file_cnt += 1;
+	ramdump_do_write_log_txt(fp);
+
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:	ramdump_device_write_logbuf
+* ²ÎÊý˵Ã÷:	 
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:	void 
+* ÆäËü˵Ã÷:	This function is used for  write cap logbuf
+*******************************************************************************/
+int ramdump_device_write_logbuf(void)
+{
+	int ret = -1;
+
+	ret = ramdump_do_write_logbuf(g_ramdump_dev_fp);
+	if (ret < 0)
+		ramdump_printf("device memory trans file:cap_log_buf error!!!\n");
+	else
+		ramdump_printf("device memory trans file:cap_log_buf success!!!\n");
+	return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:	ramdump_device_write_data
+* ²ÎÊý˵Ã÷:	 
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:	void 
+* ÆäËü˵Ã÷:	This function is used for write data
+*******************************************************************************/
+int ramdump_device_write_data(ramdump_shmem_t *msg, unsigned int size, ssize_t *dstlen)
+{
+	int ret = 0;
+		
+	if(ramdump_export_mode == RAMDUMP_MODE_EMMC)
+	{		
+#ifdef CONFIG_RAMDUMP_EMMC
+		ret = ramdump_emmc_write_data(msg, &ramdump_device_fp, size);
+		if(ret < 0)
+			*dstlen = 0;
+		else
+			*dstlen += roundup(ret, RAMDUMP_EMMC_ALIGN_SIZE);
+#endif
+	}
+	else if(ramdump_export_mode == RAMDUMP_MODE_SPINAND)
+	{
+#ifdef CONFIG_MTD_SPI_NAND
+		ret = ramdump_spinand_write_data(msg, &ramdump_spinand_fp, size);
+		if(ret < 0)
+			*dstlen = 0;
+		else
+			*dstlen += ret;
+#endif
+	}
+	else
+		return 0;
+	return ret;
+}
+
+/*******************************************************************************
+ *                  Global function implementations                            *
+ ******************************************************************************/
+void ramdump_shared_mem_init(void)
+{
+	ramdump_shared_mem_base = ramdump_phy_to_vir((unsigned long)RAMDUMP_SHARED_MEM_BASE, (unsigned long)RAMDUMP_MEM_LEN);
+	ramdump_export_flag_base = ramdump_phy_to_vir((unsigned long)IRAM_BASE_ADDR_RAMDUMP_MODE, sizeof(unsigned long));
+	ramdump_log_buf = ramdump_shared_mem_base + 0x4000;
+	ramdump_flash_alloc_transbuf();
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:	ramdump_data_transfer_to_device
+* ²ÎÊý˵Ã÷:
+*   (´«Èë²ÎÊý) void
+*   (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ:	void 
+* ÆäËü˵Ã÷:	This function is used for ramdump to trans dump data to ap
+*******************************************************************************/
+void ramdump_data_transfer_to_device(void)
+{
+	int data_trans_max;
+	int file_cnt = 0;
+	int file_size = 0;
+	int file_offset = 0;
+	int file_left_size = 0;
+	int file_trans_size = 0;
+	int error_cmd = 0;
+	int ret = 0;
+	ssize_t file_dstlen = 0;
+
+	unsigned int req_buf[RAMDUMP_INTERACTIVE_ARRAY_LEN] = {0};
+	ramdump_trans_server_interactive_req cap_to_server_msg = {0};
+
+	/* interactive begin */
+	if(ramdump_device_init() < 0)
+		return;
+	data_trans_max = RAMDUMP_SHARED_MEM_LEN - roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE) - RAMDUMP_COMPRESS_OUT_LEN;
+	cap_to_server_msg.cmd = RAMDUMP_PC_INTERACTIVE_REQ;
+	ramdump_oss_data_trans_write((unsigned char*)(&cap_to_server_msg), sizeof(cap_to_server_msg));
+
+	for(;;)
+	{
+		ramdump_oss_data_trans_read((unsigned char *)req_buf, RAMDUMP_INTERACTIVE_DATA_LEN);
+		switch (*(unsigned int *)req_buf)
+		{
+			case RAMDUMP_TRANS_SERVER_INTERACTIVE_RSP:
+			{
+				ramdump_pc_file_info_rsp cap_to_server_msg ={0};
+				ramdump_trans_server_interactive_req *server_to_cap_msg = (ramdump_trans_server_interactive_req *)req_buf;
+				/* data from server to cap */
+				ramdump_file_num = server_to_cap_msg->file_num;
+				ramdump_device_fp.file_num  = ramdump_file_num;
+				ramdump_spinand_fp.file_num = ramdump_file_num;
+
+				/* data from cap to server */
+				cap_to_server_msg.cmd = RAMDUMP_PC_FILE_INFO_READ_REQ;
+				cap_to_server_msg.file_id = file_cnt;
+
+				ramdump_oss_data_trans_write(
+					(unsigned char*)(&cap_to_server_msg),
+					sizeof(cap_to_server_msg));
+
+				break;
+			}
+			case RAMDUMP_TRANS_SERVER_FILE_INFO_READ_RSP:
+			{
+				ramdump_pc_trans_data_rsp cap_to_server_msg = {0};
+				ramdump_trans_server_file_info_req *server_to_cap_msg = (ramdump_trans_server_file_info_req *)req_buf;
+				/* data from server to cap */
+				/*device memory file create*/
+				if(ramdump_device_write_file(server_to_cap_msg) == -1){
+					cap_to_server_msg.cmd = RAMDUMP_PC_FILE_TRANS_DONE_REQ;
+					ramdump_device_write_file_head();//±£Ö¤³ö´íǰ¼¸¸öÎļþ¾ùд¶Ô¡£
+					ramdump_printf("ramdump write emmc file error!\n");
+				}
+				file_size = server_to_cap_msg->file_size;
+				file_offset = 0;
+				file_left_size = file_size;
+				/* data from cap to server */
+				cap_to_server_msg.cmd = RAMDUMP_PC_FILE_DATA_TRANS_REQ;
+				cap_to_server_msg.file_id = file_cnt;
+				cap_to_server_msg.offset = file_offset;
+				if (file_size >= data_trans_max)
+					cap_to_server_msg.length = data_trans_max;
+				else
+					cap_to_server_msg.length = file_size;
+				file_trans_size = cap_to_server_msg.length;
+				file_left_size = file_left_size - cap_to_server_msg.length;
+				file_offset = file_offset + cap_to_server_msg.length;
+				printk("device memory trans file:%s !!!\n", server_to_cap_msg->file_name);
+				/* interactive data trans */
+				ramdump_oss_data_trans_write(
+					(unsigned char*)(&cap_to_server_msg), 
+					sizeof(cap_to_server_msg));
+
+				break;
+			}
+			case RAMDUMP_TRANS_SERVER_FILE_DATA_TRANS_RSP:
+			{
+				int write_len = 0;
+				ramdump_pc_trans_data_rsp cap_to_server_msg = {0};
+				/* data from server to cap */
+				ramdump_shmem_t *server_to_cap_msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
+				server_to_cap_msg->core_flag = 0;
+				/*data from cap to emmc*/
+				
+				write_len = ramdump_device_write_data(server_to_cap_msg, file_left_size, &file_dstlen);
+				if(write_len < 0)
+				{
+					ramdump_printf("ramdump write emmc data error!\n");
+				}
+				
+				/*ÅжÏÊ£Óà´óС*/
+				if (file_left_size == 0)
+				{
+					file_cnt++;
+					if (file_cnt == ramdump_file_num)
+					{
+						cap_to_server_msg.cmd = RAMDUMP_PC_FILE_TRANS_DONE_REQ;
+					}
+					else
+					{
+						cap_to_server_msg.cmd = RAMDUMP_PC_FILE_INFO_READ_REQ;
+						cap_to_server_msg.file_id = file_cnt;
+					}
+					ramdump_device_modify_file_size(file_dstlen);
+					file_dstlen = 0;
+					ramdump_device_file_cnt++;
+				}
+				else
+				{
+					/* data from cap to server */
+					if (file_left_size >= data_trans_max)
+						cap_to_server_msg.length = data_trans_max;
+					else
+						cap_to_server_msg.length = file_left_size;
+					cap_to_server_msg.cmd = RAMDUMP_PC_FILE_DATA_TRANS_REQ;
+					cap_to_server_msg.file_id = file_cnt;
+					cap_to_server_msg.offset = file_offset;
+					file_left_size = file_left_size - cap_to_server_msg.length;
+					file_offset= file_offset + cap_to_server_msg.length;
+				}
+
+				ramdump_oss_data_trans_write((unsigned char *)(&cap_to_server_msg), sizeof(cap_to_server_msg));
+				continue;
+			}
+			case RAMDUMP_TRANS_SERVER_FILE_TRANS_DONE_RSP:
+			{
+				ramdump_device_write_logbuf();
+				ramdump_device_close();
+				return;
+			}
+			default:
+			{
+				error_cmd = RAMDUMP_INTERACTIVE_CMD_ERROR;
+				ramdump_printf("ramdump trans emmc error:%d!\n", error_cmd);
+				/* interactive data trans */
+				break;
+			}
+		}
+	}
+}
+
+#ifdef __cplusplus
+}
+#endif
+