zte's code,first commit
Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/downloader/cmd_dl_yaffs.c b/boot/common/src/uboot/downloader/cmd_dl_yaffs.c
new file mode 100644
index 0000000..c732457
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_yaffs.c
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_compat_read.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-13
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <jffs2/load_kernel.h>
+#include "downloader_config.h"
+#include "downloader_nand.h"
+#include "downloader_serial.h"
+
+#include "errno.h"
+
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_yaffs_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_yaffs_write(partition_entry_t *part, char *par , unsigned int offset, unsigned int size )
+{
+ char *ack = tsp_console_buffer;
+ unsigned int offset_par = offset;
+ unsigned int leftWriteLength = 0;
+ unsigned int curWriteLength = 0;
+ unsigned int size_fs = 0;
+ unsigned int pagefullsize = 0;
+#ifdef CONFIG_LOAD_CRC
+ unsigned long crc = 0;
+ unsigned long crc1 = 0;
+#endif
+ int ret = 0;
+ nand_info_t *pNandInfo = NULL;
+
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ pagefullsize=pNandInfo->writesize+pNandInfo->oobsize;
+ if((size==0)||(size>(part->part_size/pNandInfo->writesize)*pagefullsize))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+
+ leftWriteLength = size;
+ ret = downloader_nand_erase(part,part->part_size);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ERASE ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+
+ while(leftWriteLength>0)
+ {
+ curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+#ifdef CONFIG_LOAD_CRC
+ sprintf(ack,"DATACRC %08x",curWriteLength);
+#else
+ sprintf(ack,"DATA %08x",curWriteLength);
+#endif
+ downloader_serial_write(ack, strlen(ack)+1);
+#ifdef CONFIG_LOAD_CRC
+ downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4);
+ crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curWriteLength);
+ memcpy((unsigned char *)(&crc1),(unsigned char*)(DOWNLOADER_BUFFER_BASE+curWriteLength),4);
+ if(crc != crc1)
+ {
+ sprintf(ack,"FAIL CRC ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+#else
+ downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
+#endif
+ size_fs = (curWriteLength%pagefullsize)?(curWriteLength/pagefullsize+1)*(pagefullsize): curWriteLength;
+ if(curWriteLength<size_fs)
+ {
+ memset((char *)(DOWNLOADER_BUFFER_BASE+curWriteLength),0xff,size_fs-curWriteLength);
+ }
+ ret = downloader_nand_fs_write( part, offset_par, size_fs, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL YAFFS WRITE %d,%d",offset_par,size_fs);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ leftWriteLength -= curWriteLength;
+ offset_par += (curWriteLength/pagefullsize)*(pNandInfo->writesize);
+ }
+
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+}
+
+
+
+/*******************************************************************************
+ * Function:do_yaffs_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_yaffs_read(partition_entry_t *part, char *par , unsigned int offset, unsigned int size)
+{
+ char *rx_buffer = tsp_console_buffer;
+ char *ack = tsp_console_buffer;
+ unsigned int offset_par = offset;
+ unsigned int size_fs = 0;
+ unsigned int pagefullsize = 0;
+ nand_info_t *pNandInfo = NULL;
+ unsigned int leftReadLength = 0;
+ unsigned int curReadLength = 0;
+ //unsigned long crc = 0;
+ int ret = 0;
+
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ if((size == 0)||(size > part->part_size))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ pagefullsize = pNandInfo->writesize+pNandInfo->oobsize;
+ leftReadLength = size;
+
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ while(leftReadLength>0)
+ {
+ curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
+ size_fs = (curReadLength%pagefullsize)?(curReadLength/pagefullsize+1)*(pagefullsize): curReadLength;
+ downloader_readline(rx_buffer);
+ if(memcmp(rx_buffer,"OKAY",4)==0)
+ {
+ ret = downloader_nand_fs_read( part, offset_par, size_fs, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL YAFFS READ %d,%d, ret = %d",offset_par,size_fs,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);
+
+ }
+ else
+ {
+ sprintf(ack,"FAIL COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EBADRQC; /* Invalid request code */
+ }
+ leftReadLength -= curReadLength;
+ offset_par += (curReadLength/pagefullsize)*(pNandInfo->writesize);
+ }
+ printf("prepare to receive OKAY");
+ downloader_readline(rx_buffer);
+ if(memcmp(rx_buffer,"OKAY",4)==0)
+ {
+ return 0;
+ }
+ else
+ {
+ sprintf(ack,"FAIL COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EBADRQC; /* Invalid request code */
+ }
+
+}
+