[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/storage/mc/inc/msdc_def.h b/mcu/driver/storage/mc/inc/msdc_def.h
new file mode 100644
index 0000000..cd51b11
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/msdc_def.h
Binary files differ
diff --git a/mcu/driver/storage/mc/inc/msdc_reg_adap.h b/mcu/driver/storage/mc/inc/msdc_reg_adap.h
new file mode 100644
index 0000000..c4f9d0b
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/msdc_reg_adap.h
@@ -0,0 +1,160 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    msdc_reg_adap.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This file is intends for memory card common definitions.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef MSDC_REG_ADAP_H
+#define MSDC_REG_ADAP_H
+
+#include "drv_comm.h"
+
+//#define __DRV_MSDC_REG_DBG__
+
+#if !defined(DRV_MSDC_OFF)
+#ifdef __DRV_MSDC_REG_DBG__
+
+#define MSDC_WriteReg(addr,data) DRV_DBG_WriteReg(addr,data)
+#define MSDC_Reg(addr) DRV_DBG_Reg(addr)
+#define MSDC_WriteReg32(addr,data) DRV_DBG_WriteReg32(addr,data)
+#define MSDC_Reg32(addr) DRV_DBG_Reg32(addr)
+#define MSDC_WriteReg8(addr,data) DRV_DBG_WriteReg8(addr,data)
+#define MSDC_Reg8(addr) DRV_DBG_Reg8(addr)
+
+#define MSDC_ClearBits(addr,data) DRV_DBG_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data) DRV_DBG_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data) DRV_DBG_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data) DRV_DBG_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data) DRV_DBG_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data) DRV_DBG_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value) DRV_DBG_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value) DRV_DBG_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value) DRV_DBG_SetData8(addr,bitmask,value)
+
+#else
+
+#define MSDC_WriteReg(addr,data) DRV_WriteReg(addr,data)
+#define MSDC_Reg(addr) DRV_Reg(addr)
+#define MSDC_WriteReg32(addr,data) DRV_WriteReg32(addr,data)
+#define MSDC_WriteReg32_NPW(addr,data) DRV_WriteReg32_NPW(addr,data)
+#define MSDC_Reg32(addr) DRV_Reg32(addr)
+#define MSDC_WriteReg8(addr,data) DRV_WriteReg8(addr,data)
+#define MSDC_Reg8(addr) DRV_Reg8(addr)
+
+#define MSDC_ClearBits(addr,data) DRV_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data) DRV_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data) DRV_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data) DRV_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data) DRV_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data) DRV_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value) DRV_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value) DRV_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value) DRV_SetData8(addr,bitmask,value)
+
+#define MSDC_SET_FIELD_NPW(addr,bitmask,value)      \
+    do {    \
+        volatile kal_uint32 tv = MSDC_Reg32(addr); \
+        tv &= ~(bitmask); \
+        tv |= ((value) << (uffs(bitmask) - 1)); \
+        DRV_WriteReg32_NPW(addr,tv); \
+    } while(0)
+
+#define MSDC_SET_FIELD(addr,bitmask,value)      \
+    do {    \
+        volatile kal_uint32 tv = MSDC_Reg32(addr); \
+        tv &= ~(bitmask); \
+        tv |= ((value) << (uffs(bitmask) - 1)); \
+        MSDC_WriteReg32(addr,tv); \
+    } while(0)
+
+#define MSDC_GET_FIELD(addr,bitmask,value)      \
+    do {    \
+        volatile kal_uint32 tv = MSDC_Reg32(addr); \
+        value = ((tv & (bitmask)) >> (uffs(bitmask) - 1)); \
+    } while(0)
+
+
+#endif//__DRV_MSDC_REG_DBG__
+
+#else //!defined(DRV_MSDC_OFF)
+
+#define MSDC_WriteReg(addr,data)
+#define MSDC_Reg(addr)                        drv_dummy_return()
+#define MSDC_WriteReg32(addr,data)
+#define MSDC_Reg32(addr)                      drv_dummy_return()
+#define MSDC_WriteReg8(addr,data)
+#define MSDC_Reg8(addr)                       drv_dummy_return()
+
+#define MSDC_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value)
+
+#endif //!defined(DRV_MSDC_OFF)
+
+#endif  /* MSDC_REG_ADAP_H */                   
+
diff --git a/mcu/driver/storage/mc/inc/sd_def.h b/mcu/driver/storage/mc/inc/sd_def.h
new file mode 100644
index 0000000..ccabb4e
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sd_def.h
@@ -0,0 +1,1051 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   Sd_def.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Header file of SD/MMC driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#ifndef SD_DEF_H
+#define SD_DEF_H
+
+//RHR ADD
+#include "kal_general_types.h"
+#include "drv_trc.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "kal_non_specific_general_types.h"
+*/
+//RHR
+#include "drv_features.h"
+#include "dcl.h"
+#include "dcl_msdc.h"
+#include "msdc_api.h"
+/*--------------------------------*/
+/*SDC register address */
+/*--------------------------------*/
+
+/*sdmmc register*/
+#define SDC_CFG			(MSDC_ADRS + 0x30)
+#define SDC_CMD			(MSDC_ADRS + 0x34)
+#define SDC_ARG			(MSDC_ADRS + 0x38)
+#define SDC_STS			(MSDC_ADRS + 0x3c)
+#define SDC_RESP0		(MSDC_ADRS + 0x40)
+#define SDC_RESP1		(MSDC_ADRS + 0x44)
+#define SDC_RESP2		(MSDC_ADRS + 0x48)
+#define SDC_RESP3		(MSDC_ADRS + 0x4c)
+#define SDC_BLK_NUM	(MSDC_ADRS + 0x50)
+#define SDC_CSTS		(MSDC_ADRS + 0x58)
+#define SDC_CSTS_EN		(MSDC_ADRS + 0x5c)
+#define SDC_DCRC_STS	(MSDC_ADRS + 0x60)
+/*emmc register*/
+#define EMMC_CFG0		(MSDC_ADRS + 0x70)
+#define EMMC_CFG1		(MSDC_ADRS + 0x74)
+#define EMMC_STS		(MSDC_ADRS + 0x78)
+#define EMMC_IOCON		(MSDC_ADRS + 0x7c)
+/*auto command register*/
+#define SDC_ACMD_RESP	(MSDC_ADRS + 0x80)
+#define SDC_ACMD19_TRG	(MSDC_ADRS + 0x84)
+#define SDC_ACMD19_STS (MSDC_ADRS + 0x88)
+
+
+
+/*SDC_CFG mask*/
+#define SDC_CFG_SDIOINTWKUP 		(0x1 << 0)		 /*RW*/
+#define SDC_CFG_INSWKUP 			(0x1 << 1)		 /*RW*/
+#define SDC_CFG_BUSWIDTH 			(0x3 << 16)		 /*RW*/
+#define SDC_CFG_SDIO 				(0x1 << 19)		 /*RW*/
+#define SDC_CFG_SDIOIDE 			(0x1 << 20)		 /*RW*/
+#define SDC_CFG_INTATGAP 			(0x1 << 21)		 /*RW*/
+#define SDC_CFG_DTOC 				(0xffUL << 24)	 /*RW*/
+
+
+/*SDC_CMD mask*/
+#define SDC_CMD_OPC 				(0x3f <<0)		 /*RW*/
+#define SDC_CMD_BRK 				(0x1 << 6)		 /*RW*/
+#define SDC_CMD_RSPTYP 			(0x7 << 7)		 /*RW*/
+#define SDC_CMD_DTYP 				(0x3 <<11)		 /*RW*/
+#define SDC_CMD_RW 				(0x1 << 13)		 /*RW*/
+#define SDC_CMD_STOP				 (0x1 << 14)		 /*RW*/
+#define SDC_CMD_GOIRQ 				(0x1 << 15)			 /*RW*/
+#define SDC_CMD_BLKLEN 				(0xfff << 16)		 /*RW*/
+#define SDC_CMD_AUTOCMD 			(0x3 << 28)			 /*RW*/
+#define SDC_CMD_VOLSWTH 			(0x1 << 30)		 /*RW*/
+
+/*SDC_STS mask */
+#define SDC_STS_SDCBUSY 			(0x1 << 0)			 /*RW*/
+#define SDC_STS_CMDBUSY 			(0x1 << 1)			 /*RW*/
+#define SDC_STS_SWR_COMPL 			(0x1 << 31)			 /*RW*/
+
+
+/*SDC_DCRC_STS mask*/
+#define SDC_DCRC_STS_NEG 			(0xf << 8)			/*RO*/
+#define SDC_DCRC_STS_POS 			(0xff << 0)			/*RO*/
+
+/*EMMC_CFG0 mask*/
+#define EMMC_CFG0_BOOTSTART 		(0x1 << 0) 		/*W*/
+#define EMMC_CFG0_BOOTSTOP		(0x1 << 1) 		/*W*/
+#define EMMC_CFG0_BOOTMODE 		(0x1 << 2) 		/*RW*/
+#define EMMC_CFG0_BOOTWDLY 		(0x7 << 12) 		/*RW*/
+#define EMMC_CFG0_BOOTACKDIS 		(0x1 << 3) 		/*RW*/
+#define EMMC_CFG0_BOOTSUPP		(0x1 << 15) 		/*RW*/
+
+/*EMMC_CFG1 mask*/
+#define EMMC_CFG1_BOOTDATTMC 		(0xfffff << 0) 		/*RW*/
+#define EMMC_CFG1_BOOTACKTMC 		(0xfffUL << 20) 		/*RW*/
+
+/*EMMC_STS mask*/
+#define EMMC_STS_BOOTCRCERR 		(0x1 << 0) 		/*W1C*/
+#define EMMC_STS_BOOTACKERR 		(0x1 << 1) 		/*W1C*/
+#define EMMC_STS_BOOTDATTMO 		(0x1 << 2)		 /*W1C*/
+#define EMMC_STS_BOOTACKTMO 		(0x1 << 3) 		/*W1C*/
+#define EMMC_STS_BOOTUPSTATE		 (0x1 << 4)		 /*R*/
+#define EMMC_STS_BOOTACKRCV 		(0x1 << 5)		 /*W1C*/
+#define EMMC_STS_BOOTDATRCV 		(0x1 << 6) 		/*R*/
+
+
+/*EMMC_IOCON mask*/
+#define EMMC_IOCON_BOOTRST 		(0x1 << 0)		/*RW*/
+
+
+/*SDC_ACMD19_TRG mask*/
+#define MSDC_ACMD19_TRG_TUNESEL 	(0xf << 0)		 /*RW*/
+
+#define SDC_NO_ARG 0
+
+
+#define SDC_OCR_DEFAULT		0x00FF8000
+#define SDC_OCR_QUERY		0x0
+#define TRY_OCR				20 
+#define SDC_OCR_BUSY			0x80000000
+#define SDC_RCA_DEFAULT		0x0000
+#define	ARG_RCA_MASK		0xffff0000
+#define SDC_RCA_MMC			1
+#define SDC_DSR_DEFAULT		0x0404
+#define SDC_NO_ARG			0
+#define SDC_MAX_BKLENGTH	2048
+#define SDC_MAX_LOCKBK		34
+#define SDC_CMD8_ARG			0x000001AA			// the argument of the CMD8
+#define SD_ACMD41_HCS		0x40000000			// indicate host support high capacity card.
+#define SD_ACMD41_XPC		0x10000000
+#define SD_ACMD41_S18R      0x01000000          // indicate host support 1.8v
+#define SD_CMD6_RESP_LEN	64						// lenght of the CMD6 response
+#define SD_CMD6_QUERY_SWITCH    0x00FF0000          //cmd6 query the function
+#define SD_CMD6_SELECT_SWITCH   0x80FF0000          //cmd6 select the function
+#define SD_CMD6_QUERY_SUPPORT_FUNCTION 0x00FFFFFF  //use to get the functions supported by the card
+#define SD_CMD6_QUERY_HIGH_SPEED		0x00FFFFF1	// argument of CMD6 to query the high speed interface
+#define SD_CMD6_SELECT_HIGH_SPEED	0x80FFFFF1	// argument of CMD6 to query the high speed interface
+#define SD_FUNC_HIGH_SPEED				0x1
+#define SD_CSD_VER_20					0x01
+
+#define SD_FLAG_MMC_MRSW_FAIL  (0x01)		// some special MMC card will fail at multi-read follow a single wirte
+#define SD_FLAG_HCS_SUPPORT	 (0x02)		// support block access mode
+#define SD_FLAG_CMD6_SUPPORT	 (0x04)		// support CMD6 (SD1.1 higher)
+#define SD_FLAG_HS_SUPPORT		 (0x08)		// support high speed interface (SD1.1 higher)
+#define SD_FLAG_HS_ENABLED		 (0x10)		// enable high speed interface (SD1.1 higher)	
+#define SD_FLAG_SD_TYPE_CARD	 (0x20)		// to indicate SD or MMC type card
+#define SD_FLAG_USE_USB_CLK	 (0x40)		// to indicate use USB clock
+#define SD_FLAG_UHS_ENABLED      (0x80)   //enable UHS interface
+#define SD_FLAG_UHS_SUPPORT      (0x100)   //support  UHS interface
+
+
+#define SD_FLAG_LIMITED_HIGH_SPEED_CARD	(0x8000) // to indicate special high speed card that we can only run with 26M
+
+	
+								
+#define MSDC_SD_BLOCK_SIZE		128		// * 4byte
+#define SECTOR_SIZE 512
+
+#define MSDC_TUNE_UHS_SCLK      (100000000)
+
+typedef kal_uint32 SDC_CMD_STATUS;
+// ERROR definition of SDC_CMD_STATUS
+#define NO_ERROR				0
+#define ERR_CMD_TIMEOUT			1
+#define ERR_APP_CMD_NOT_ACCEPT	2
+#define ERR_R3_OCR_BUSY			3
+#define ERR_RCA_FAIL			4
+#define ERR_INVALID_CARD		5
+#define ERR_INVALID_BKLENGTH	6  // over 2048 or not multiple of 4
+#define ERR_DAT_CRCERR			7
+#define ERR_RW_CMDERR			8
+#define ERR_CMD_RSPCRCERR		9
+#define ERR_DAT_TIMEOUT			10
+#define ERR_STATUS				11
+#define ERR_LOCK_UNLOCK_FAILED  12
+#define ERR_APPCMD_FAILED		13
+#define ERR_NOT_SUPPORT_4BITS   14
+#define ERR_NORESP				15
+#define ERR_WRITE_PROTECT		16
+#define ERR_DATA_NOT_READY		17
+#define ERR_CARD_NOT_PRESENT	18
+#define ERR_OCR_NOT_SUPPORT	19
+#define ERR_DAT_ERROR			20
+#define SDIO_4MI_NOT_SUPPORT  21
+#define ERR_MMC_BUS_HS_ERROR	22
+#define ERR_SendEXTCSD			23
+#define ERR_CMD8_INVALID		24
+#define ERR_SD_HS_FAIL			25		// SD change high speed interface fail
+#define ERR_NOT_FOUND			26
+#define ERR_ACB_FAIL			27
+#define ERR_ACB_TIMEOUT			28
+#define ERR_ACB_STA_ENABLE_FAIL	29
+#define ERR_ERRORS				30	// general errors
+#define ERR_INVALID_BLOCK		31
+#define ERR_MMC_SWITCH_ERROR    32
+#define ERR_CARD_BUSY_TIMEOUT   33
+#define ERR_HIGH_SPEED_BUSY     34
+#define ERR_HIGH_SPEED_TIMEOUT  35
+#define ERR_HIGH_SPEED_COMMON_ERROR 36
+#define ERR_HIGH_SPEED_NOT_SUPPORT 37
+#define ERR_HIGH_SPEED_CONSUMPTION 38
+#define ERR_ARGUMENT			39
+
+#define CARD_IS_LOCKED			60
+#define CHECK_DATA_CMD_LOW_FAIL 61
+#define ERR_SWITCH_BUSY 62
+#define ERR_SWITCH_TIMEOUT 63
+#define ERR_SPEED_MODE_UNSUPPORT 64
+#define ERR_DRIVER_TYPE_UNSUPPORT 65
+#define ERR_CURRENT_LIMIT_UNSUPPORT 66
+
+
+/* MMC bus commands */
+#define CMD0_GO_IDLE_STATE          0x00    /* Resets the MMC */
+#define CMD1_SEND_OP_COND           0x01    /* Activates the card's initialization process */
+#define CMD2_ALL_SEND_CID           0x02    /* Asks all cards in ready state to send their CID */
+#define CMD3_SET_RELATIVE_ADDR      0x03    /* Assigns relative address to the card in identification state */
+#define CMD4_SET_DSR                0x04    /* Sets drive stage register DSR */
+#define CMD7_SELECT_CARD            0x07
+#define CMD9_SEND_CSD               0x09    /* Asks the selected card to send its CSD */
+#define CMD10_SEND_CID              0x0A    /* Asks the selected card to send its CID */
+#define CMD11_READ_DAT_UNTIL_STOP_MMC   0x0B
+#define CMD12_STOP_TRANSMISSION     0x0C    /* Stop data transmission */
+#define CMD13_SEND_STATUS           0x0D    /* Asks the selected card to send its status register */
+#define CMD15_GO_INACTIVE_STATE     0x0F
+#define CMD16_SET_BLOCKLEN          0x10    /* Selects a block length for all following block commands */
+#define CMD17_READ_SINGLE_BLOCK     0x11    /* Reads a block of the size selected by the SET_BLOCKLEN command */
+#define CMD18_READ_MULTIPLE_BLOCK   0x12
+#define CMD20_WRITE_DAT_UNTIL_STOP_MMC  0x14
+#define CMD24_WRITE_SINGLE_BLOCK    0x18    /* Writes a block of the size selected by SET_BLOCKLEN command */
+#define CMD25_WRITE_MULTIPLE_BLOCK  0x19     /* Writes multiple block until CMD 12 */
+#define CMD26_PROGRAM_CID           0x1A
+#define CMD27_PROGRAM_CSD           0x1B    /* Programming of the programmable bits of the CSD */
+#define CMD28_SET_WRITE_PROT        0x1C    /* If the card has write protection features, sets the write protection bit */
+#define CMD29_CLR_WRITE_PROT        0x1D    /* If with write protection features, clears the write protection bit */
+#define CMD30_SEND_WRITE_PROT       0x1E    /* If with write protection features, asks the card to send status of write protection bit */
+#define CMD32_TAG_SECTOR_START      0x20    /* Sets the address of the first sector */
+#define CMD33_TAG_SECTOR_END        0x21    /* Sets the address of the last sectore */
+#define CMD34_UNTAG_SECTOR          0x22    /* Removes one previously selected sector */
+#define CMD35_TAG_ERASE_GROUP_START 0x23    /* Sets the address of the first erase group */
+#define CMD36_TAG_ERASE_GROUP_END   0x24    /* Sets the address of the last erase group */
+#define CMD37_UNTAG_ERASE_GROUP     0x25    /* Removes on previously selected erase group */
+#define CMD38_ERASE                 0x26    /* Erases all previously selected sectors */
+#define CMD39_FAST_IO_MMC           0x27
+#define CMD40_GO_IRQ_STATE          0x28    
+#define CMD42_LOCK_UNLOCK           0x2A    /* Used to set/reset the password or lock/unlock the card */
+#define CMD55_APP					0x37	/* Indicates to the card the next cmd is an application specific command */
+#define CMD56_GEN					0x38	/* Used either to transfer a data block or to get a data block form the card for general purpse */
+
+// commnad value for MSDC controller SDC_CMD
+// not include the SDC_CMD  LEN[27:16] !!
+#define SDC_CMD_CMD0			0x0000		/*	response_none*/
+#define SDC_CMD_CMD1			0x0181		/*	response_r3   */
+#define SDC_CMD_CMD2			0x0102		/*	response_r2    */
+#define SDC_CMD_CMD3			0x0083		/*	response_r6   */
+#define SDC_CMD_CMD3_MMC		0x0083		/*	response_r1*/
+#define SDC_CMD_CMD4			0x0004		/*	response_none*/
+#define SDC_CMD_CMD5			0x0185		/*	response_r3*/
+#define SDC_CMD_CMD5_MMC		0x0385		/*	response_r1b*/
+#define SDC_CMD_CMD6			0x0886		/*	response_r1 +single_block + read*/
+#define SDC_CMD_CMD6_MMC		0x0386		/*	response_r1b*/
+#define SDC_CMD_CMD7			0x0387		/*	response_r1b*/
+#define SDC_CMD_CMD8			0x0088		/*	response_r7*/
+#define SDC_CMD_CMD8_MMC40	0x0888		/*	response_r1+single_blokc+read*/
+#define SDC_CMD_CMD9			0x0109		/*	response_r2*/
+#define SDC_CMD_CMD10			0x010a		/* 	response_r2                                                  the response time delay is not NID(5 cycles)*/
+#define SDC_CMD_CMD11			0x4000008b	/*	response_r1+ switch vlot*/
+#define SDC_CMD_CMD11_MMC		0x188b 		/*	response_r1*/
+#define SDC_CMD_CMD12			0x438c		/*	response_r1b+stop command*/
+#define SDC_CMD_CMD13			0x008d		/*	response_r1*/
+#define SDC_CMD_CMD15			0x000f		/*	response_none*/
+#define SDC_CMD_CMD16			0x0090		/*	response_r1*/
+#define SDC_CMD_CMD17			0x0891		/*	response_r1+single_block+read*/
+#define SDC_CMD_CMD18			0x1092		/*	response_r1+mutli_block+read*/
+#define SDC_CMD_CMD19			0x0893		/*	response_r1+single_block_read*/
+#define SDC_CMD_CMD19_MMC		0x0093		/*	response_r1*/
+#define SDC_CMD_CMD20_MMC		0x3894		/*	response_r1+stream_write*/
+#define SDC_CMD_CMD20			0x0394		/*	response_r1b*/
+#define SDC_CMD_CMD23			0x0097		/*	response_r1*/
+#define SDC_CMD_CMD24			0x2898		/*	response_r1+single_block+write*/
+#define SDC_CMD_CMD25			0x3099		/*	response_r1+mutli_block+write*/
+#define SDC_CMD_CMD26			0x009a		/*	response_r1*/
+#define SDC_CMD_CMD26_MMC		0x289a		/*	response_r1+single_block+write*/
+#define SDC_CMD_CMD27			0x289b		/*	response_r1+single_block_write*/
+#define SDC_CMD_CMD28			0x039c		/*	response_r1b*/
+#define SDC_CMD_CMD29			0x039d		/*	response_r1b*/
+#define SDC_CMD_CMD30			0x089e		/*	response_r1+single_block_read*/
+#define SDC_CMD_CMD31_MMC		0x039f		/*	response_r1b*/
+#define SDC_CMD_CMD32			0x00a0		/*	response_r1*/
+#define SDC_CMD_CMD33			0x00a1		/*	response_r1*/
+#define SDC_CMD_CMD35_MMC		0x00a3		/*	response_r1*/
+#define SDC_CMD_CMD36_MMC		0x00a4		/*	response_r1*/
+#define SDC_CMD_CMD38			0x03a6		/*	response_r1b*/
+#define SDC_CMD_CMD39_MMC		0x0227		/*	response_r4*/
+#define SDC_CMD_CMD40_MMC		0x80a8		/*	response_r5*/   
+#define SDC_CMD_CMD42			0x28aa 		/*	response_r1+single_block+write*/    
+#define SDC_CMD_CMD55			0x00b7     	/*	response_r1*/
+#define SDC_CMD_CMD56			0x08b8		/*	response_r1+single_block*/
+#define SDC_CMD_ACMD6			0x0086		/*	response_r1*/
+#define SDC_CMD_ACMD13			0x088d	/*	response_r1+single_block+read*/
+#define SDC_CMD_ACMD22			0x0896	/*	response_r1+single_block+read*/	
+#define SDC_CMD_ACMD23			0x0097	/*	response_r1*/
+#define SDC_CMD_ACMD41			0x01a9	/*	response_r3*/
+#define SDC_CMD_ACMD42			0x00aa	/*	response_r1*/
+#define SDC_CMD_ACMD51			0x08b3	/*	response_r1+single_block+read*/	
+
+#define SDC_CMD_CMD6_SD11		0x0886	// SWITCH
+
+/* SDIO command*/
+#define SDC_CMD_CMD52			0x00b4	/*	response_r5                  STOp field will be set while used to Stop data transfer*/
+#define SDC_CMD_CMD53			0x00b5	/*	response_r5                  the RWand DTYPE will be changed according request*/
+
+
+
+//masks for command error response(32) of SDC_CSTA
+#define SDC_OUT_OF_RANGE		0x80000000
+#define SDC_ADDRESS_ERROR		0x40000000
+#define SDC_BLOCK_LEN_ERROR		0X20000000
+#define SDC_ERASE_SEQ_ERROR		0X10000000
+#define SDC_ERASE_PARAM			0X08000000
+#define SDC_WP_VIOLATION		0X04000000
+#define SDC_CARD_IS_LOCKED		0x02000000
+#define SDC_LOCK_UNLOCK_FAILED	0X01000000
+#define SDC_COM_CRC_ERROR		0X00800000
+#define SDC_ILLEGAL_COMMAND		0X00400000
+#define SDC_CARD_ECC_FAILED		0X00200000
+#define SDC_CC_ERROR			0X00100000
+#define SDC_ERROR				0X00080000
+#define SDC_UNDERRUN			0X00040000
+#define SDC_OVERRUN				0X00020000
+#define SDC_CIDCSD_OVERWRITE	0X00010000
+#define MMC_SWITCH_ERROR		0x00000080
+#define SDC_AKE_SEQ_ERROR		0X00000008
+
+#define SDC_CSTA_MASK 				0xffff0000
+
+//masks for card status contained in R1
+#define R1_AKE_SEQ_ERROR_3			0x00000004
+#define R1_APP_CMD_5				0x00000020
+#define R1_READY_FOR_DATA_8			0x00000100
+#define R1_CURRENT_STATE_9_12		0x00001e00
+#define R1_ERASE_RESET_13			0x00002000
+#define R1_CARD_ECC_DISABLE_14		0x00004000
+#define R1_WP_ERASE_SKIP_15			0x00008000
+#define R1_CID_CSD_OVERWRITE_16		0x00010000
+#define R1_OVERRUN_17				0x00020000
+#define R1_UNDERRUN_18				0x00040000
+#define R1_ERROR_19					0x00080000
+#define R1_CC_ERROR_20				0x00100000
+#define R1_CARD_ECC_FAILED_21		0x00200000
+#define R1_ILLEGAL_COMMAND_22		0x00400000
+#define R1_COM_CRC_ERROR_23			0x00800000
+#define R1_LOCK_UNLOCK_FAILED_24	0x01000000
+#define R1_CARD_IS_LOCKED_25		0x02000000
+#define R1_WP_VIOLATION_26			0x04000000
+#define R1_ERASE_PARAM_27			0x08000000
+#define R1_ERASE_SEQ_ERROR_28		0x10000000
+#define R1_BLOCK_LEN_ERROR_29		0x20000000
+#define R1_ADDRESS_ERROR_30			0x40000000
+#define R1_OUT_OF_RANGE_31			0x80000000
+#define R1_CUR_STATE				0x00001E00
+
+#define R1_CURRENT_STATE(a)	(kal_uint32)(((a) & R1_CUR_STATE) >> 9)
+
+
+#define FUN1_SDR12_DS 0x1
+#define FUN1_SDR25_HS 0x2
+#define FUN1_SDR50 0x4
+#define FUN1_SDR104 0x8
+#define FUN1_DDR50  0x10
+#define FUN2_DEFAULT 0x1
+#define FUN2_FOR_EC  0x2
+#define FUN2_OTP     0x8
+#define FUN2_ASSD    0x10
+#define FUN3_TYPE_A  0x1
+#define FUN3_TYPE_B  0x2
+#define FUN3_TYPE_C  0x4
+#define FUN3_TYPE_D  0x8
+#define FUN4_200MA  0x1
+#define FUN4_400MA  0x2
+#define FUN4_600MA  0x4
+#define FUN4_800MA  0x8
+
+#define FUN1_SET_SDR12_DS (0x0)
+#define FUN1_SET_SDR25_HS (0x1)
+#define FUN1_SET_SDR50 (0x2)
+#define FUN1_SET_SDR104 (0x3)
+#define FUN1_SET_DDR50  (0x4)
+#define FUN2_SET_DEFAULT (0x0)
+#define FUN2_SET_FOR_EC  (0x1)
+#define FUN2_SET_OTP     (0x3)
+#define FUN2_SET_ASSD    (0x4)
+#define FUN3_SET_TYPE_A  (0x0)
+#define FUN3_SET_TYPE_B  (0x1)
+#define FUN3_SET_TYPE_C  (0x2)
+#define FUN3_SET_TYPE_D  (0x3)
+#define FUN4_SET_200MA  (0x0)
+#define FUN4_SET_400MA  (0x1)
+#define FUN4_SET_600MA  (0x2)
+#define FUN4_SET_800MA  (0x3)
+
+/*Card Command Classes(CCC)*/
+#define CCC_BASIC   (1<<0)  //cmd0,1,2,3,4,7,9,10,12,13,15 and for SPI cdm58,59
+#define CCC_STREAM_READ  (1<<1)  //cmd11
+#define CCC_BLOCK_READ (1<<2)   //cmd16,17,18
+#define CCC_STREAM_WRITE (1<<3) //CMD20
+#define CCC_BLOCK_WRITE (1<<4)  //cmd16,24,25,26,27
+#define CCC_ERASE       (1<<5)  //cmd32,33,34,35,36,37,38,39
+#define CCC_WRITE_PROT  (1<<6)  //cmd28,29,30
+#define CCC_LOCK_CARD   (1<<7)  //cmd16,cmd42
+#define CCC_APP_SPEC    (1<<8)  //cmd55,56,57,ACMD
+#define CCC_IO_MODE (1<<9)  //cmd5,39,40,52,53
+#define CCC_SWITCH     (1<<10)  //cmd6,34,35,36,37,50
+
+#define SCR_SPEC_VER_0      0   //system specification 1.0-1.01
+#define SCR_SEC_VER_1      1    //system specification 1.10
+#define SCR_SEC_VER_2      2    //system specification 2.00-3.0x
+
+typedef enum {
+	IDLE_STA,
+	READY_STA,
+	IDENT_STA,
+	STBY_STA,
+	TRAN_STA,
+	DATA_STA,
+	RCV_STA,
+	PRG_STA,
+	DIS_STA,
+	INV_STA
+}T_SDC_STATE;
+
+typedef enum{
+	SD_CMD8_RESP_NORESP,		// before SD2.0 version or MMC
+	SD_CMD8_RESP_INVALID,	// SD 2.0 or higher compliant but voltage condition is not allow
+	SD_CMD8_RESP_VALID		// SD 2.0 or higher compliant
+}SD_CMD8_RESP;
+
+typedef enum{
+	eMMC_boot_partition1 = 1,
+	eMMC_boot_partition2,
+	eMMC_RPMB,
+	eMMC_GP_partition1,
+	eMMC_GP_partition2,
+	eMMC_GP_partition3,
+	eMMC_GP_partition4,
+	eMMC_user_Area
+} eMMC_partitions;
+
+
+
+
+
+typedef struct{
+	kal_bool isEmmcV44;
+	kal_bool supportPartition;
+	kal_bool supportEnhancedPart;
+	kal_uint32 bootPartitionSize; //size of boot partition, the uint is 512-byte
+	kal_uint32 gp1PartitionSize; //size of GP1 partition, the uint is 512-byte
+}t_emmc_info;
+
+#define MSDC_SD_BLOCK_SIZE				128	// x4 bytes
+#define EXT_CSD_BUS_WIDTH_INDEX		183
+#define EXT_CSD_HIGH_SPPED_INDEX		185
+#define EXT_CSD_POW_CLASS_INDEX			187
+#define EXT_CSD_PARTITION_CONFIG_INDEX	179
+#define EXT_CSD_BOOT_BUS_WIDTH_INDEX	177
+#define EXT_CSD_ERASE_GRP_DEF			175
+#define EXT_CSD_RT_FUNCTION_INDEX		162
+#define EXT_CSD_GP_SIZE_MULT_GP0_INDEX	143
+#define EXT_CSD_ENH_SIZE_MULT_INDEX		140
+#define EXT_CSD_ENABLE_HIGH_SPEED	1
+#define MMC_HIGH_DESITY_CHECK_BIT	(0x40000000)
+#define MMC_HIGH_DESITY_CHECK_MSK	(0x60000000)
+
+
+
+#define EMMC_MASK_PARTITION_SETTING	0x1
+#define EMMC_MASK_PARTITION_CONFIG	0x7
+
+
+typedef struct {
+#ifndef MSDC_MMC441_SUPPORT
+	kal_uint8 rev1[183];
+#else
+	kal_uint8 mmc44_rev0[136];	/*[135:0]*/
+	kal_uint32 enh_start_addr; 	/*[139:136]*/
+	kal_uint8 enh_size_mult[3];	/*[142:140]*/
+	kal_uint8 gp_size_mult[12];	/*[154:143]*/
+	kal_uint8 partition_settig;		/*[155]*/
+	kal_uint8 partition_attr;		/*[156]*/
+	kal_uint8 max_enh_size_mult[3];		/*[159:157]*/
+	kal_uint8 partition_support;	/*[160]*/
+	kal_uint8 mmc44_rev1;		/*[161]*/
+	kal_uint8 rst_function;		/*[162]*/
+	kal_uint8 mmc44_rev2[5];		/*[167:163]*/
+	kal_uint8 rpmb_size_mul;		/*[168]*/
+	kal_uint8 fw_config;			/*[169]*/
+	kal_uint8 mmc44_rev3;		/*[170]*/
+	kal_uint8 user_wp;			/*[171]*/
+	kal_uint8 mmc44_rev4;		/*[172]*/
+	kal_uint8 boot_wp;			/*[173]*/
+	kal_uint8 mmc44_rev5;		/*[174]*/
+	kal_uint8 erase_grp_def;		/*[175]*/
+	kal_uint8 mmc44_rev6;		/*[176]*/
+	kal_uint8 boot_bus_width;		/*[177]*/
+	kal_uint8 boot_config_prot;	/*[178]*/
+	kal_uint8 partition_config;		/*[179]*/
+	kal_uint8 mmc44_rev7;		/*[180]*/
+	kal_uint8 erased_mem_cont;	/*[181]*/
+	kal_uint8 mmc44_rev8;		/*[182]*/
+#endif
+	kal_uint8 bus_width;
+	kal_uint8 rev2;
+	kal_uint8 high_speed;
+	kal_uint8 rev3;
+	kal_uint8 power_class;
+	kal_uint8 rev4;
+	kal_uint8 cmd_set_rev;
+	kal_uint8 rev5;
+	kal_uint8 cmd_set;
+	kal_uint8 ext_csd_rev;
+	kal_uint8 rev7;
+	kal_uint8 ext_csd_ver;
+	kal_uint8 rev8;
+	kal_uint8 card_type;
+	kal_uint8 rev9;
+	kal_uint8 out_of_interrupt_time;
+	kal_uint8 partition_switch_time;
+	kal_uint8 pwr_52_195;
+	kal_uint8 pwr_26_195;
+	kal_uint8 pwr_52_360;
+	kal_uint8 pwr_26_360;
+	kal_uint8 rev10;
+	kal_uint8 min_perf_r_4_26;
+	kal_uint8 min_perf_w_4_26;
+	kal_uint8 min_perf_r_8_26_4_52;
+	kal_uint8 min_perf_w_8_26_4_52;
+	kal_uint8 min_perf_r_8_52;
+	kal_uint8 min_perf_w_8_52;
+	kal_uint8 resv11;
+	kal_uint32 sec_count;	/*newly defined in MMC42*/
+#ifndef MSDC_MMC441_SUPPORT
+	kal_uint8 rev12[288];
+#else
+	kal_uint8 mmc44_rev9[5];	/*[220:216]*/
+	kal_uint8 hc_wp_grp_size;		/*221*/
+	kal_uint8 rel_wr_sec_c;		/*222*/
+	kal_uint8 erase_timeout_mult;	/*223*/
+	kal_uint8 hc_erase_grp_size;	/*224*/
+	kal_uint8 acc_size;			/*225*/
+	kal_uint8 boot_size_mul;		/*[226]*/
+	kal_uint8 mmc44_rev10;		/*[227]*/
+	kal_uint8 boot_info;			/*[228]*/
+	kal_uint8 mmc44_rev11[275];		/*[503:229]*/
+#endif
+	kal_uint8 s_cmd_set;
+	kal_uint8 rev13[7];
+}T_EXT_CSD_MMC40;
+
+typedef enum{
+	SD_SPEC_101,
+	SD_SPEC_110,
+	SD_SPEC_200,
+	SD_SPEC_30X
+}SD_SPEC;
+typedef enum{
+	CSD_VER_1_0 = 0,
+	CSD_VER_1_1 = 0,
+	CSD_VER_2_0 = 1,
+	CSD_VER_EXT
+ }CSD_VER_ENUM;
+
+/* Card Specific Data(CSD) register structure */
+typedef struct {
+   kal_uint8   tacc;				   /* read access time-1 */
+   kal_uint8   nsac;				   /* read access time-2 */
+   kal_uint8   tran_speed;			   /* max. data transfer rate */
+   kal_uint16  ccc;					   /* card command classes */
+   kal_uint32  w_blk_len;              /* actual write block length in bytes */
+   kal_uint32  r_blk_len;              /* actual read block length in bytes */
+   kal_uint32  max_w_blk_len;          /* max write data block length */
+   kal_uint32  max_r_blk_len;          /* max read data block length */
+   kal_uint8   w_blk_misali;           /* write block misalighment */
+   kal_uint8   r_blk_misali;           /* read block misalighment */
+   kal_uint8   w_blk_part;             /* partial blocks for write allowed */
+   kal_uint8   r_blk_part;             /* partial blocks for write allowed */
+   kal_uint32  erase_sec_size_mmc;     /* erase sector size */
+   kal_uint32  erase_grp_size_mmc;     /* erase group size */
+   kal_uint32  wp_grp_size_mmc;        /* write protect group size */
+   kal_uint8   erase_blk_en_sd;
+   kal_uint32  erase_sec_size_sd;
+   kal_uint32  wp_prg_size_sd;
+   kal_uint8   wp_grp_enable;          /* write protect group enable */
+   kal_uint64  capacity;               /* capacity in bytes */
+   kal_uint16  cmd_class;              /* card command classes */
+   kal_uint8   temp_wp;                /* temporary write protection  */
+   kal_uint8   perm_wp;                /* permanent write protection  */
+   kal_uint8   dsr_imp;
+   CSD_VER_ENUM 	csd_ver;					/* the version of CSD structure */
+   kal_uint8	spec_ver;					/* defne the MMC system spec. */
+   T_EXT_CSD_MMC40 *ext_csd;				/* pointer to EXT_CSD */
+} T_CSD;
+
+typedef struct {
+	kal_uint8	mid;
+	kal_uint16	oid;
+	kal_uint8	pnm[6];
+	kal_uint8	prv;
+	kal_uint32	psn;
+	kal_uint16	year;
+	kal_uint8	month;
+}T_CID;
+
+typedef struct {
+	kal_uint8 dat_after_erase;
+	kal_uint8 security;
+	kal_uint8 bus_width;
+	kal_uint8 sd_spec3;
+	kal_uint8 cmd_support;
+	SD_SPEC spec_ver;
+}T_SCR;
+
+typedef struct {
+    unsigned char   dat_bus_width:2,
+                    secured_mode:1,
+                    rsv1:5;
+    unsigned char   rsv2:2,
+                    rsv3:6;
+    unsigned short  sd_card_type;
+    unsigned int    size_of_prot_area;
+    unsigned char   speed_class;
+    unsigned char   perf_move;
+    unsigned char   au_size:4,
+                    rsv4:4;
+    unsigned short  erase_size;
+    unsigned char   erase_timeout:6,
+                    erase_offset:2;
+    unsigned char   uhs_speed_grade:4,
+                    uhs_au_size:4;
+    unsigned char   rsv5[49];
+}T_SD_STATUS;
+
+typedef struct {
+	kal_uint32		mSDC_ocr;	// store the OCR
+	kal_uint32		mBKLength;	// store the block length
+	kal_uint32 		mBKNum;		// store the block numbers
+	kal_uint32		flags;		// for some special case handling
+	T_CSD				mCSD;		// card specific data
+	T_CID				mCID;		// card idendtification
+	T_SCR				mSCR;		// only for SD
+	T_SD_STATUS         mSDSts;
+	kal_uint16		mRCA;		// store relative card address
+	T_SDC_STATE		mState;		// indicate the current state
+	kal_bool			mInactive;	// indicate whether card in inactive state
+	kal_uint8		bus_width;	// indicate 4-bits data line enable
+	kal_bool			mWPEnabled;	// indicate write protection is enabled(SD)
+	kal_bool			mIsLocked;	// indicate whether the card is locked by switch
+	kal_bool			mCD_DAT3;	// indicate the pull-up resistor of CD_DAT3 pin
+	kal_bool            mIsBlkAddr;
+	SD_CMD8_RESP	mCMD8Resp;		// receive response after CMD8 (SD2.0 or higher)
+	MSDC_LOCK_TAG	mSDdrv_lock;	// lock for sd_drv adaption layer
+#if defined(MSDC_MMC441_SUPPORT)
+	t_emmc_info		emmc_info;
+#endif
+	kal_uint32 sd_r;
+	kal_uint32 sd_w;
+    T_SWITCH_SUPPROT_FUNCTIONS card_support;
+    T_SWITCH_SUPPROT_FUNCTIONS function_set;
+}T_SDC_HANDLE;
+
+typedef struct{
+	kal_uint32 max_current	: 16;
+	kal_uint32 group6_info	: 16;
+	kal_uint32 group5_info	: 16;
+	kal_uint32 group4_info	: 16;
+	kal_uint32 group3_info	: 16;
+	kal_uint32 group2_info	: 16;
+	kal_uint32 group1_info	: 16;
+	kal_uint32 group6_result: 4;
+	kal_uint32 group5_result: 4;
+	kal_uint32 group4_result: 4;
+	kal_uint32 group3_result: 4;
+	kal_uint32 group2_result: 4;
+	kal_uint32 group1_result: 4;
+	kal_uint32 ver				: 8;
+	kal_uint32 group6_busy	: 16;
+	kal_uint32 group5_busy	: 16;
+	kal_uint32 group4_busy	: 16;
+	kal_uint32 group3_busy	: 16;
+	kal_uint32 group2_busy	: 16;
+	kal_uint32 group1_busy	: 16;
+	kal_uint8  rev[34];
+}T_SWITCH_STATUS;
+
+
+
+typedef enum{
+	SET_PWD,
+	CLR_PWD,
+	LOCK_CARD,
+	UNLOCK_CARD,
+	ERASE
+}SD_LOCK_OP;
+
+typedef enum{
+	BIT_1_MMC40,
+	BIT_4_MMC40,
+	BIT_8_MMC40
+}BUS_WIDHT_MMC40;
+typedef enum{
+	HS_26M = 1,
+	HS_52M = 2
+}EXT_CSD_CARD_TYPE_MMC40;
+
+
+
+
+
+// bit masks     
+#define BIT_MASK_1 0x01
+#define BIT_MASK_2 0x03
+#define BIT_MASK_3 0x07
+#define BIT_MASK_4 0x0F
+#define BIT_MASK_5 0x1F
+#define BIT_MASK_6 0x3F
+#define BIT_MASK_7 0x7F
+#define BIT_MASK_8 0xFF
+#define GET_BIT(byte, bit_pos, bit_mask)    (((byte) & ((bit_mask)<<(bit_pos)))>> (bit_pos))
+
+#ifndef __MSDC_BASIC_LOAD__
+#define SD_TRACE2(a,b,c,d)	MD_TRC_##b(c, d)
+#else
+#define SD_TRACE2(a,b,c,d)	dbg_print("SD error in file %d, line %d\n\r", c,d)
+#endif
+#define SD_INITIALIZE_STATUS_CHECK()	\
+{\
+	if(NO_ERROR != status)\
+	{\
+	    MSDC_ERR("[MSDC][%s %d]%x\r\n",__FUNCTION__,__LINE__,status);\
+		SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);\
+		goto err;\
+	}\
+}
+#define MSDC_ERROR		1
+#define MSDC_OK			0
+
+#define SD_IS_SDC_BUSY()  	(!!(MSDC_Reg32(SDC_STS)&SDC_STS_SDCBUSY))
+#define SD_IS_CMD_BUSY() 	(!!(MSDC_Reg32(SDC_STS)&SDC_STS_CMDBUSY))
+#define SD_IS_R1B_BUSY()	(!(MSDC_Reg32(MSDC_PS)&(1<<16)))
+
+#define MSDC_BD_MAX 128 
+extern msdc_gpd_t MSDC_gpd[SD_NUM];
+extern msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+extern msdc_bd_t MSDC_bd[SD_NUM][MSDC_BD_MAX];
+extern T_SDC_HANDLE * gSD;
+extern T_SDC_HANDLE	gSD_blk[SD_NUM];
+SDC_CMD_STATUS SD_SendCmd(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms);
+void SD_Cmd8(void);
+
+SDC_CMD_STATUS SD_Reset(void);
+SDC_CMD_STATUS SD_Cmd55(kal_uint16 rca);
+SDC_CMD_STATUS SD_Cmd1_MMC(void);
+SDC_CMD_STATUS SD_Acmd41_SD(void);
+SDC_CMD_STATUS SD_GetCID(kal_uint32 Cid[4]);
+SDC_CMD_STATUS SD_ValidateRCA(kal_uint16* pRca);
+SDC_CMD_STATUS SD_SetDSR(void);
+SDC_CMD_STATUS SD_SelectCard(kal_uint16 rca);
+SDC_CMD_STATUS SD_GetCSD(kal_uint16 rca, kal_uint32 Csd[4]);
+SDC_CMD_STATUS SD_GetStatus(kal_uint16 rca, kal_uint32* resp);
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength);
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer);
+SDC_CMD_STATUS SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num);
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer);
+SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num);
+SDC_CMD_STATUS SD_SetBusWidth(SD_BITWIDTH width);
+SDC_CMD_STATUS SD_ReadSCR(kal_uint32* scr);
+SDC_CMD_STATUS SD_ReadSDStatus(kal_uint32* sd_status);
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40(kal_uint32* rxbuffer);
+SDC_CMD_STATUS SD_Initialize(void);
+SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum);
+SDC_CMD_STATUS SD_SetPreEraseBlk(kal_uint32 num);
+SDC_CMD_STATUS SD_CheckStatus(void);
+SDC_CMD_STATUS SD_Switch_MMC40(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set);
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void);
+SDC_CMD_STATUS SD_SwitchSpeedMode(void);
+
+SDC_CMD_STATUS SD_GpdWriteMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data);
+SDC_CMD_STATUS SD_GpdReadMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data );
+
+kal_bool SD_QMU_Init(void);
+
+void SD_closeFastFormat(void);
+void SD_startFastFormat(void);
+
+extern SDC_CMD_STATUS SD_StopTrans(void);
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*following 2 API is used to declare the beginning and ending of high level format*/
+void SD_startFastFormat(void);
+void SD_closeFastFormat(void);
+
+int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags);
+int  ReadSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer);
+int  WriteSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer);
+
+
+
+
+
+#endif // end of SD_DEF_H
+
+
diff --git a/mcu/driver/storage/mc/inc/sdio_def.h b/mcu/driver/storage/mc/inc/sdio_def.h
new file mode 100644
index 0000000..71e7d08
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sdio_def.h
@@ -0,0 +1,76 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2001
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   Sd_def.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Header file of SDIO driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#ifndef SDIO_DEF_H
+#define SDIO_DEF_H
+/*HW part*/
+#define SDIO_CFG				(MSDC_ADRS+0x54)
+#define SDIO_STA				(MSDC_ADRS+0x58)
+//#define SDC_CFG_SDIO		0x00080000
+#define SDiO_CFG_INTEN		0x1	// enable interrupt
+#define SDiO_CFG_INTSEL		0x2	// interrupt signal selection 0: use DAT[1], 1: use DAT[5]
+#define SDiO_CFG_DSBSEL		0x4	// data block start bit selection
+
+#if defined(DRV_MSDC_MT6238_SERIES)
+#define SDIO_CFG2	(MSDC_ADRS2+0x54)
+#define SDIO_STA2	(MSDC_ADRS2+0x58)
+#endif
+
+#define SDIO_R4_CARD_READY		0x80
+#define IO_ARG_RW_FLAG			0x80000000
+#define IO_ARG_RAW_FLAG			0x08000000		
+#define MSDC_WORK_OCR			0x8000
+
+#define R5_COM_CRC_ERROR       (1<<7)
+#define R5_ILLEGAL_COMMAND     (1<<6)
+#define R5_IO_CURRENT_STATE    (3<<4)
+#define R5_ERROR                 (1<<3)
+#define R5_RFU                   (1<<2)
+#define R5_FUNCTION_NUMBER      (1<<1)
+#define R5_OUT_OF_RANGE         (1<<0)
+#define R5_ERROR_CHECK          (R5_COM_CRC_ERROR|R5_ILLEGAL_COMMAND|R5_ERROR|R5_FUNCTION_NUMBER|R5_OUT_OF_RANGE)
+
+#define SDIO_STATUS_CHECK 	\
+{\
+	if(NO_ERROR != status)\
+	{\
+		SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);\
+		goto err;\
+	}\
+}
+
+#endif // end of SD_DEF_H
diff --git a/mcu/driver/storage/mc/inc/sdio_test.h b/mcu/driver/storage/mc/inc/sdio_test.h
new file mode 100644
index 0000000..d4d5639
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sdio_test.h
@@ -0,0 +1,1238 @@
+
+#ifndef __PRECOMP_H
+#define __PRECOMP_H
+
+//#include "equates.h"
+//#include "i2128reg.h"
+/*I2128 register*/
+
+/************************************************************************
+*                     C O M P I L E R   F L A G S
+*************************************************************************
+*/
+
+/************************************************************************
+*                          C O N S T A N T S
+*************************************************************************
+*/
+#define MCR_MEM_MAPPED_LENGTH   0x800   /* MCR memory-mapped length */
+
+/* IPN2128 MAC configuration register (MCR) offset definition */
+/* system control */
+#define MCR_SCR                 0x0000 //
+#define MCR_QSR0                0x0008 //== 2128's MCR_MAISR
+#define MCR_MAISR               MCR_QSR0
+/* non-used for SDIO */
+#define MCR_QSR1                0x000C
+#define MCR_TXQIER              0x0014
+/*--------------*/
+#define MCR_MRBS                0x0018 //
+
+/* used to R/W EEPROM */
+#define MCR_ECSR                0x0040 //
+#define MCR_ERWCR               0x0044 //
+#define MCR_EADR                0x0048 //
+
+/*queue*/
+#define MCR_QCR                 0x0100 //== 2128's MCR_DPCR
+#define MCR_DPCR                MCR_QCR
+#define MCR_ISAR                0x0104 //0x0004
+#define MCR_IER                 0x0108 //0x0010
+
+/* used to query SDIO bus status */
+#define MCR_SDRDR               0x0110
+#define MCR_SDCR                0x0114
+#define MCR_SDSR                0x0118
+#define MCR_GPCR                0x0120    //GPIO
+#define MCR_PSCTL               0x012c
+
+/*----------*/
+#define MCR_DRNGR               0x0188
+#define MCR_AIFSR               0x018C
+//#define MCR_TQCWR               0x0190
+#define MCR_AC0CWR              0x0194
+/*
+#define MCR_AC1CWR              0x0198
+#define MCR_AC2CWR              0x019C
+#define MCR_AC3CWR              0x01A0
+*/
+/*security engine*/
+#define MCR_SKACR               0x0200
+#define MCR_SKADR0              0x0204
+#define MCR_SKADR1              0x0208
+#define MCR_SKADR2              0x020C
+#define MCR_SKADR3              0x0210
+#define MCR_SKADR4              0x0214
+#define MCR_SKADR5              0x0218
+#define MCR_SCPR0               0x021C
+#define MCR_SCPR1               0x0220 //non-used in both 2128 and 2128
+
+#ifdef SUPPORT_TKIP_ON_THE_FLY
+/* MIC key */
+#define MCR_MICKEY0             0x0224
+#define MCR_MICKEY1             0x0228
+#endif      /* TKIP_ON_THE_FLY */
+
+/*phyical layer control interface*/
+#define MCR_PCICR               0x0240
+#define MCR_PCCR                0x0244
+#define MCR_PBAR                0x0248
+#define MCR_PPORCR0             0x0280
+#define MCR_PPORCR1             0x0284
+#define MCR_PPDRCR0             0x0288
+#define MCR_PPDRCR1             0x028C
+#define MCR_PPDRCR2             0x0290
+#define MCR_PPMCR               0x0294
+#define MCR_PSCR                0x02A0
+#define MCR_PSPR                0x02A4
+#define MCR_LCR                 0X02A8
+/*transmitter control*/
+#define MCR_ACWLR               0x0300
+#define MCR_MPTCR               0x0304
+#define MCR_NPTCR               0x0308
+#define MCR_NTTCR               0x030C
+#define MCR_TXOPGBNTCR          0x0310
+#define MCR_NDTCR               0x0314
+#define MCR_NCSTCR              0x0318
+
+/*receiver control*/
+#define MCR_DRCR                0x0360
+#define MCR_RFECR               0x0364
+#define MCR_RFFCR               0x0368
+#define MCR_RPCR                0x036C
+#define MCR_CACR                0x0374
+#define MCR_RFBCR               0x0380
+#define MCR_OMAR0               0x03A0
+#define MCR_OMAR1               0x03A4
+#define MCR_CBR0                0x03A8
+#define MCR_CBR1                0x03AC
+#define MCR_AMAR0               0x03B0
+#define MCR_AMAR1               0x03B4
+#define MCR_AMAR2               0x03B8
+#define MCR_AMAR3               0x03BC
+#define MCR_AMAR4               0x03C0
+#define MCR_AMAR5               0x03C4
+#define MCR_AMAR6               0x03C8
+#define MCR_AMAR7               0x03CC
+#define MCR_AMAR8               0x03D0
+/*MAC protocol timing control*/
+#define MCR_MPDR                0x0400
+#define MCR_TNTDR               0x0404
+#define MCR_STDR                0x0408
+#define MCR_EPDDR               0x040C
+#define MCR_CRFCR0              0x0410
+//#define MCR_CRFCR1              0x0414--
+#define MCR_DTR                 0x0418
+#define MCR_BCWR                0x041C
+#define MCR_RFTPCR              0x0420
+#define MCR_LTTR0               0x0440
+#define MCR_LTTR1               0x0444
+#define MCR_TTAR0               0x0448
+#define MCR_TTAR1               0x044C
+#define MCR_TTAR2               0x0450
+/*NVA control*/
+#define MCR_LNR                 0x0470
+#define MCR_NRTR                0x0474
+#define MCR_NSUR                0x0478
+/*beacon generation*/
+#define MCR_BGCR0               0x0480
+#define MCR_BGCR1               0x0484
+#define MCR_SWBCCR              0x0488
+#define MCR_SWBCDR              0x048C
+#define MCR_ARRCR               0x0490
+#define MCR_AFRCR               0x0494
+#define MCR_ATFCR               0x0498
+#define MCR_ATBCR               0x049C
+
+/*miscellaneous and debug port*/
+/*
+#define MCR_GPIOCR              0x0050
+*/
+#define MCR_PRBCR               0x0080
+#define MCR_PRBSR               0x0084//--
+/*
+#define MCR_PFWDR               0x0088
+*/
+#define MCR_PRBDR               0x008C
+/*
+#define MCR_BPSR                0x0090
+*/
+#define MCR_CTPR1               0x0094 //--
+#define MCR_MPTR                0x03FC
+/*
+#define MCR_CTPR2               0x0098
+#define MCR_LNUIR0              0x0500
+#define MCR_LNUIR1              0x0504
+#define MCR_LNUIR2              0x0508
+*/
+/* Debug Register 0 (PRBDR) bit definitions */
+#define PRBDR_RN_FREEZE                 BIT(7)
+/* ----- System Control ----- */
+/* System Control Register (SCR) bit definitions */
+#define SCR_PCI_CLKRUN_ENABLE           BIT(31)
+#define SCR_ASSERT_PCI_CLKRUN           BIT(30)
+#define SCR_RADIO_PD_ACTIVE_EDGE        BIT(26)
+#define SCR_RADIO_PD_REQ                BIT(25)
+#define SCR_GPIO_PD_N                   BIT(24)
+/*
+#define SCR_SEC_CLK20M_ENABLE           BIT(20)
+#define SCR_MAC_CLK20M_ENABLE           BIT(19)
+#define SCR_MAC_CLK40M_ENABLE           BIT(18)
+#define SCR_MAC_CLK33M_ENABLE           BIT(17)
+#define SCR_PLL_ENABLE                  BIT(16)
+*/
+#define SCR_SEC_CLK_ENABLE              BIT(20)
+#define SCR_MAC_CLK_ENABLE              BIT(19)
+#define SCR_FIFO_CLK_ENABLE             BIT(18)
+#define SCR_HST_CLK_ENABLE              BIT(17)
+#define SCR_CLK_ALL_EN                  BITS(17,20)
+#define SCR_PAU_ENABLE                  BIT(7)
+#define SCR_MAC_REGRST                  BIT(3)
+#define SCR_MAC_RST                     BIT(2)
+#define SCR_BB_SIORST                   BIT(1)
+#define SCR_BB_MRST                     BIT(0)
+#define SCR_RST_ALL                     BITS(0,3)
+
+/* SDIO Read Done/Error Register  (SDRDER) bit definitions */
+#define SDRDR_BLOCK_BYTE_COUNT          BITS(6,16)
+#define SDRDR_BLOCK_BYTE_MODE           BIT(5)
+#define SDRDR_CRC_ERROR                 BIT(4)
+#define SDRDR_MIC_RESULT_READ_DONE      BIT(3)
+#define SDRDR_RX_DATA_READ_DONE         BIT(2)
+#define SDRDR_RX_STATUS_READ_DONE       BIT(1)
+#define SDRDR_TX_STATUS_READ_DONE       BIT(0)
+
+/* SDIO Status Register  (SDSR) bit definitions */
+#define SDSR_TX_STATUS_UNDER_RUN        BIT(7)
+#define SDSR_RX_STATUS_UNDER_RUN        BIT(6)
+#define SDSR_RX_DATA_UNDER_RUN          BIT(5)
+#define SDSR_MIC_RESULT_UNDER_RUN       BIT(4)
+#define SDSR_TX_DATA_LEN_OUT_OF_RANGE   BIT(3)
+#define SDSR_TXD_BUF_EMPTY_STATUS       BIT(2)
+#define SDSR_TXD_BUF_OVERFLOW           BIT(1)
+
+/* IRQ Status and Acknowledge Register (ISAR) bit definitions */
+#define ISAR_EXTERNAL_INT               BIT(22)
+#define ISAR_MAC_ABNORMAL_INT           BIT(21) //
+#define ISAR_PHY_CCA_INDICATE_BUSY      BIT(20)
+#define ISAR_RFIFO_OVERFLOW_INT         BIT(19)
+#define ISAR_PRE_TBTT_INT               BIT(18)
+#define ISAR_TBTT_INT                   BIT(17)
+#define ISAR_ATIM_W_TIMEUP_INT          BIT(16)
+#define ISAR_SDIO_ABNORMAL_INT          BIT(9)  //
+#define ISAR_TX_BUFFER_EMPTY_INT        BIT(8)
+#define ISAR_BEACON_TX_RX_OK_INT        BIT(7)
+#define ISAR_SECURITY_Q_EMPTY_INT       BIT(6)
+#define ISAR_AC0_Q_EMPTYINT             BIT(5)
+#define ISAR_MIC_OK_INT                 BIT(4)
+#define ISAR_RX2_OK_INT                 BIT(3)
+#define ISAR_RX1_OK_INT                 BIT(2)
+#define ISAR_TX2_OK_INT                 BIT(1)
+#define ISAR_TX1_OK_INT                 BIT(0)
+
+#define ISAR_AC0_TX_DONE                (ISAR_TX1_OK_INT | ISAR_TX2_OK_INT)
+#define ISAR_AC0_EVENT                  (ISAR_AC0_TX_DONE | ISAR_AC0_Q_EMPTYINT)
+#define ISAR_TX_Q_EVENT                 (ISAR_AC0_EVENT | ISAR_TX_BUFFER_EMPTY_INT)
+#define ISAR_RX_Q_EVENT                 BITS(2,3)
+#define ISAR_RX_DATA_Q_DONE_INT         ISAR_RX_Q_EVENT
+
+/* Queue Status Register 0 (QSR0) bit definitions */
+#define QSR0_ABNORMAL_Q_NO              BITS(12,15)
+#define QSR0_RFD_CHECK_SUM_ERR          BIT(10)
+#define QSR0_TBD_CHECK_SUM_ERR          BIT(9)
+#define QSR0_TFD_CHECK_SUM_ERR          BIT(8)
+#define SDIOSR_RX_DATA_PORT_UNDER_RUN   BIT(5)
+#define QSR0_RX_DATA_Q_OPERATING        BIT(4)
+#define QSR0_SEC_ENGINE_OP_TX_Q_EMPTY   BIT(3)
+#define QSR0_SEC_ENGINE_OP_TX_DONE      BIT(2)
+#define QSR0_SEC_ENGINE_OP_TX_EVENT     BITS(2,3)
+#define QSR0_SEC_ENGINE_OP_RX_Q_EMPTY   BIT(1)
+#define QSR0_SEC_ENGINE_OP_RX_DONE      BIT(0)
+#define QSR0_SEC_ENGINE_OP_RX_EVENT     BITS(0,1)
+
+/* Queue Status Register 1 (QSR1) bit definitions */
+#define QSR1_AC0_QUEUE_EMPTY            BIT(7)
+#define QSR1_AC0_TX_DONE                BIT(6)
+#define QSR1_AC0_EVENT                  BITS(6.7)
+#define QSR1_AC0_OPERATING              BIT(24)
+
+/* IRQ Enable Register (IER) bit definitions */
+#define IER_GLOBAL_ENABLE               BIT(31)
+#define IER_EXTERNAL_INT               BIT(22)
+#define IER_MAC_ABNORMAL_INT           BIT(21) //
+#define IER_PHY_CCA_INDICATE_BUSY      BIT(20)
+#define IER_RFIFO_OVERFLOW_INT         BIT(19)
+#define IER_PRE_TBTT_INT               BIT(18)
+#define IER_TBTT_INT                   BIT(17)
+#define IER_ATIM_W_TIMEUP_INT          BIT(16)
+#define IER_SDIO_ABNORMAL_INT          BIT(9)  //
+#define IER_TX_BUFFER_EMPTY_INT        BIT(8)
+#define IER_BEACON_TX_RX_OK_INT        BIT(7)
+#define IER_SECURITY_Q_EMPTY_INT       BIT(6)
+#define IER_AC0_Q_EMPTYINT             BIT(5)
+#define IER_MIC_OK_INT                 BIT(4)
+#define IER_RX2_OK_INT                  BIT(3)
+#define IER_RX1_OK_INT                  BIT(2)
+#define IER_TX2_OK_INT                  BIT(1)
+#define IER_TX1_OK_INT                  BIT(0)
+
+#define IER_ENABLE_MAJOR                BITS(0,8)
+//#define IER_ENABLE_ALL                  (IER_ENABLE_MAJOR | BIT(9) | BITS(16,22))
+#define IER_ENABLE_ALL                  (IER_ENABLE_MAJOR | BIT(9) | BITS(16,21))
+
+/* Tx Queue Interrupt Enable Register (TXQIER) bit definitions */
+#define TXQIER_TS3_QUEUE_EMPTY_EN       BIT(21)
+#define TXQIER_TS3_TX_DONE_EN           BIT(20)
+#define TXQIER_TS3_EVENT_EN             BITS(20,21)
+#define TXQIER_TS2_QUEUE_EMPTY_EN       BIT(19)
+#define TXQIER_TS2_TX_DONE_EN           BIT(18)
+#define TXQIER_TS2_EVENT_EN             BITS(18,19)
+#define TXQIER_TS1_QUEUE_EMPTY_EN       BIT(17)
+#define TXQIER_TS1_TX_DONE_EN           BIT(16)
+#define TXQIER_TS1_EVENT_EN             BITS(16,17)
+#define TXQIER_TS0_QUEUE_EMPTY_EN       BIT(15)
+#define TXQIER_TS0_TX_DONE_EN           BIT(14)
+#define TXQIER_TS0_EVENT_EN             BITS(14,15)
+#define TXQIER_AC3_QUEUE_EMPTY_EN       BIT(13)
+#define TXQIER_AC3_TX_DONE_EN           BIT(12)
+#define TXQIER_AC3_EVENT_EN             BITS(12,13)
+#define TXQIER_AC2_QUEUE_EMPTY_EN       BIT(11)
+#define TXQIER_AC2_TX_DONE_EN           BIT(10)
+#define TXQIER_AC2_EVENT_EN             BITS(10,11)
+#define TXQIER_AC1_QUEUE_EMPTY_EN       BIT(9)
+#define TXQIER_AC1_TX_DONE_EN           BIT(8)
+#define TXQIER_AC1_EVENT_EN             BITS(8,9)
+#define TXQIER_AC0_QUEUE_EMPTY_EN       BIT(7)
+#define TXQIER_AC0_TX_DONE_EN           BIT(6)
+#define TXQIER_AC0_EVENT_EN             BITS(6,7)
+#define TXQIER_ALL_ACQ_EVENT_EN         BITS(6,13)
+#define TXQIER_TQ1_TIMEOUT_EN           BIT(5)
+#define TXQIER_TQ1_QUEUE_EMPTY_EN       BIT(4)
+#define TXQIER_TQ1_TX_DONE_EN           BIT(3)
+#define TXQIER_TQ1_EVENT_EN             BITS(3,5)
+#define TXQIER_TQ0_TIMEOUT_EN           BIT(2)
+#define TXQIER_TQ0_QUEUE_EMPTY_EN       BIT(1)
+#define TXQIER_TQ0_TX_DONE_EN           BIT(0)
+#define TXQIER_TQ0_EVENT_EN             BITS(0,2)
+#define TXQIER_ALL_TXQ_EVENT_EN         BITS(0,5)
+
+/* Maximum Receive Buffer Size Register (MRBS) bit definitions */
+#define MRBSR_MAX_RECV_BUFFER_SIZE      BITS(0,15)
+
+/* EEPROM Control and Status Register (ECSR) bit definitions */
+#define ECSR_EE_TYPE_NOT_PRESENT        0               /* EEPROM not present */
+#define ECSR_EE_CSERR                   BIT(3)     /* EEPROM checksum error */
+#define ECSR_EE_RDY                     BIT(2)     /* EEPROM access complete */
+#define ECSR_EE_RECALL                  BIT(1)     /* recall operation from EEPROM */
+#define ECSR_EE_SERIAL                  BIT(0)     /* EEPROM serial access mode enable */
+
+/* EEPROM Read/Write Control Register (ERWCR) bit definitions */
+#define ERWCR_EECS                      BIT(7)     /* EEPROM Chip Select */
+#define ERWCR_EESK                      BIT(6)     /* EEPROM Clock */
+#define ERWCR_EEDI                      BIT(5)     /* EEPROM Data Input */
+#define ERWCR_EEDO                      BIT(4)     /* EEPROM Data Output */
+#define ERWCR_EE_READ                   BIT(1)     /* EEPROM read access */
+#define ERWCR_EE_WRITE                  BIT(0)     /* EEPROM write access */
+
+/* EEPROM Address and Data Register (EADR) bit definitions */
+#define EADR_EE_ADDR                    BITS(16,23) /* EEPROM address */
+#define EADR_EE_DATA                    BITS(0,15)  /* EEPROM data */
+
+
+/* ----- Queue ----- */
+/* Queue Command Register (QCR) bit definitions */
+#define QCR_RX_DATA_Q_STOP              BIT(25)
+#define QCR_RX_DATA_Q_START             BIT(24)
+#define QCR_SEC_ENGINE_OP_TX_STOP       BIT(23)
+#define QCR_SEC_ENGINE_OP_TX_START      BIT(22)
+#define QCR_SEC_ENGINE_OP_RX_STOP       BIT(21)
+#define QCR_SEC_ENGINE_OP_RX_START      BIT(20)
+#define QCR_TS3_STOP                    BIT(19)
+#define QCR_TS3_START                   BIT(18)
+#define QCR_TS2_STOP                    BIT(17)
+#define QCR_TS2_START                   BIT(16)
+#define QCR_TS1_STOP                    BIT(15)
+#define QCR_TS1_START                   BIT(14)
+#define QCR_TS0_STOP                    BIT(13)
+#define QCR_TS0_START                   BIT(12)
+#define QCR_AC3_STOP                    BIT(11)
+#define QCR_AC3_START                   BIT(10)
+#define QCR_AC2_STOP                    BIT(9)
+#define QCR_AC2_START                   BIT(8)
+#define QCR_AC1_STOP                    BIT(7)
+#define QCR_AC1_START                   BIT(6)
+#define QCR_AC0_STOP                    BIT(5)
+#define QCR_AC0_START                   BIT(4)
+#define QCR_TQ1_STOP                    BIT(3)
+#define QCR_TQ1_START                   BIT(2)
+#define QCR_TQ0_STOP                    BIT(1)
+#define QCR_TQ0_START                   BIT(0)
+
+/* Queue Resume Command Register (QRCR) bit definitions */
+
+#define QRCR_RXQ_RESUME                 BIT(12)
+#define QRCR_SEC_ENGINE_OP_TX_RESUME    BIT(11)
+#define QRCR_SEC_ENGINE_OP_RX_RESUME    BIT(10)
+#define QRCR_TS3_RESUME                 BIT(9)
+#define QRCR_TS2_RESUME                 BIT(8)
+#define QRCR_TS1_RESUME                 BIT(7)
+#define QRCR_TS0_RESUME                 BIT(6)
+#define QRCR_AC3_RESUME                 BIT(5)
+#define QRCR_AC2_RESUME                 BIT(4)
+#define QRCR_AC1_RESUME                 BIT(3)
+#define QRCR_AC0_RESUME                 BIT(2)
+#define QRCR_TQ1_RESUME                 BIT(1)
+#define QRCR_TQ0_RESUME                 BIT(0)
+
+/* TS Token Control Register (TSTCR) bit definitions */
+#define TSTCR_TS3_TIMER_ENABLE          BIT(19)
+#define TSTCR_TS2_TIMER_ENABLE          BIT(18)
+#define TSTCR_TS1_TIMER_ENABLE          BIT(17)
+#define TSTCR_TS0_TIMER_ENABLE          BIT(16)
+#define TSTCR_TOKEN_P_RENEW             BIT(8)
+#define TSTCR_TOKEN_P_3                 BITS(6,7)
+#define TSTCR_TOKEN_P_2                 BITS(4,5)
+#define TSTCR_TOKEN_P_1                 BITS(2,3)
+#define TSTCR_TOKEN_P_0                 BITS(0,1)
+
+/* TS TX Limit Register (TSTXLR) bit definitions */
+#define TSTXLR_TS3_TX_LIMIT             BITS(24,31)
+#define TSTXLR_TS2_TX_LIMIT             BITS(16,23)
+#define TSTXLR_TS1_TX_LIMIT             BITS(8,15)
+#define TSTXLR_TS0_TX_LIMIT             BITS(0,7)
+
+/* Arbitration Inter Frame Spacing Register (AIFSR) bit definitions */
+#define AIFSR_TQ_RN_ADD_1_EN            BIT(24)
+#define AIFSR_AC3_RN_ADD_1_EN           BIT(23)
+#define AIFSR_AC2_RN_ADD_1_EN           BIT(22)
+#define AIFSR_AC1_RN_ADD_1_EN           BIT(21)
+#define AIFSR_AC0_RN_ADD_1_EN           BIT(20)
+#define AIFSR_AIFS_TQ                   BITS(16,19)
+#define AIFSR_AIFS_3                    BITS(12,15)
+#define AIFSR_AIFS_2                    BITS(8,11)
+#define AIFSR_AIFS_1                    BITS(4,7)
+#define AIFSR_AIFS_0                    BITS(0,3)
+
+/* TQs Contention Window Register (TQCWR) bit definitions */
+#define TQCWR_TQ_CW_MAX                 BITS(16,31)
+#define TQCWR_TQ_CW_MIN                 BITS(0,7)
+
+/* AC0 Contention Window Register (AC0CWR) bit definitions */
+#define AC0CWR_AC0_CW_MAX               BITS(16,31)
+#define AC0CWR_AC0_CW_MIN               BITS(0,7)
+
+/* AC1 Contention Window Register (AC1CWR) bit definitions */
+#define AC1CWR_AC1_CW_MAX               BITS(16,31)
+#define AC1CWR_AC1_CW_MIN               BITS(0,7)
+
+/* AC2 Contention Window Register (AC2CWR) bit definitions */
+#define AC2CWR_AC2_CW_MAX               BITS(16,31)
+#define AC2CWR_AC2_CW_MIN               BITS(0,7)
+
+/* AC3 Contention Window Register (AC3CWR) bit definitions */
+#define AC3CWR_AC3_CW_MAX               BITS(16,31)
+#define AC3CWR_AC3_CW_MIN               BITS(0,7)
+
+
+/* ----- Security Engine ----- */
+/* Security Key Access Control Register (SKACR, offset 0x0200) */
+#define SKACR_ACCESS_START              BIT(31)
+#define SKACR_READ_WRITE                BIT(30)
+
+#ifdef SUPPORT_TKIP_ON_THE_FLY
+#define SKACR_MICKEY_ENABLE             BIT(16)
+#endif      /* TKIP_ON_THE_FLY */
+
+#define SKACR_TABLE_SIZE                BITS(8,15)
+#define SKACR_KEY_INDEX                 BITS(0,7)
+
+/* Security Key Access Data Register 0 (SKADR0, offset 0x0204) */
+#define SKADR0_KEY_ID                   BITS(30,31)
+#define SKADR0_CHECK_ALL                BITS(27,29)
+#define SKADR0_CHECK_A2                 BIT(29)
+#define SKADR0_CHECK_A1                 BIT(28)
+#define SKADR0_CHECK_KEY_ID             BIT(27)
+#define SKADR0_CIPHER_SUITE             BITS(24,26)
+#define SKADR0_KEY_MAPPING_ADDR         BITS(0,23)
+
+/* Security Key Access Data Register 1 (SKADR0, offset 0x0208) */
+#define SKADR1_KEY_MAPPING_ADDR         BITS(0,23)
+
+/* Security Key Access Data Register 2 (SKADR0, offset 0x020C) */
+#define SKADR2_KEY_VALUE                BITS(0,31)
+
+/* Security Key Access Data Register 3 (SKADR0, offset 0x0210) */
+#define SKADR3_KEY_VALUE_8_31           BITS(8,31)
+#define SKADR3_KEY_VALUE_0_7            BITS(0,7)
+
+/* Security Key Access Data Register 4 (SKADR0, offset 0x0214) */
+#define SKADR4_KEY_VALUE                BITS(0,31)
+
+/* Security Key Access Data Register 5 (SKADR0, offset 0x0218) */
+#define SKADR5_KEY_VALUE_8_31           BITS(8,31)
+#define SKADR5_KEY_VALUE_0_7            BITS(0,7)
+
+/* Security Control Parameter Register 0 (SCPR0, offset 0x021C) */
+#define SCPR0_FRAME_CONTROL_MASK        BITS(16,31)
+#define SCPR0_SEQUENCE_CONTROL_MASK     BITS(0,15)
+
+/* Security Control Parameter Register 1 (SCPR1, offset 0x0220) */
+#define SCPR1_TKIP_IV_ENDIAN            BIT(31)
+#define SCPR1_TKIP_EIV_ENDIAN           BIT(30)
+#define SCPR1_QOS_CONTROL_MASK          BITS(0,15)
+
+/* ----- Physical Layer Control Interface ----- */
+/* PHY Control Interface Configuration Register (PCICR) bit definitions */
+#define PCICR_CHIP_ID_VERSION           BITS(12,31) /* chip ID and version */
+#define PCICR_RF_SW_CTRL                BIT(4)     /* RF software control */
+#define PCICR_RF_CTRL_MODE              BITS(0,2)   /* RF control mode */
+
+/* PAU Control Configuration register (PCCR) */
+#define PCCR_BCIMODE                    BIT(0)
+
+/* PHY BCI Access Register (PBAR) bit definitions */
+#define PBAR_PHY_BCI_ACCESS_START       BIT(25)     /* PHY BCI access command/status */
+#define PBAR_PHY_BCI_RW_CTRL            BIT(24)     /* PHY BCI read/write control */
+#define PBAR_PHY_BCI_INDEX              BITS(16,23)  /* PHY BCI access CR register index */
+#define PBDR_PHY_BCI_WR_DATA            BITS(8,15)   /* PHY BCI write data */
+#define PBDR_PHY_BCI_RD_DATA            BITS(0,7)    /* PHY BCI read data */
+
+/* PHY Power Management Control Register (PPMCR) bit definitions */
+#define PPMCR_GPIO_CAL                  BIT(29)    /* GPIO for RF power control */
+#define PPMCR_GPIO_RF_SHDN              BIT(28)    /* GPIO for RF power control */
+#define PPMCR_GPIO_PA2_EN               BIT(22)    /* GPIO for RF 2.4G PA enable */
+#define PPMCR_GPIO_PA5_EN               BIT(21)    /* GPIO for RF 5G PA enable */
+#define PPMCR_GPIO_RF_TX                BIT(20)    /* GPIO for RF Tx control */
+#define PPMCR_GPIO_RF_RX                BIT(19)    /* GPIO for RF Rx control */
+#define PPMCR_GPIO_TR_SW                BIT(18)    /* GPIO for BB TX */
+#define PPMCR_BB_TX_PE                  BIT(17)    /* GPIO for RF Tx/Rx control */
+#define PPMCR_BB_RX_PE                  BIT(16)    /* GPIO for RF Tx/Rx control */
+
+/* PHY Synthesizer Programming Register (PSPR) bit definitions */
+#define PSPR_SYNTH_PROG_START           BIT(31)    /* synthesizer programming command/status */
+#define PSPR_RW_CTL                     BIT(30)    /* synthesizer RW control */
+#define PSPR_SYNTH_DATA                 BITS(0,23)  /* synthesizer programming data */
+
+/* LED Configuration Register (LCR) bit definitions */
+#define LCR_LED_GPIO_OUTPUT             BIT(19)    /* LED GPIO Output control */
+#define LCR_LED_POLARITY                BIT(18)    /* LEDOn polarity */
+#define LCR_LED_MODE                    BITS(16,17) /* LED mode */
+#define LCR_LED_POLARITY_POSITIVE       0
+#define LCR_LED_POLARITY_NEGATIVE       BIT(18)
+#define LCR_LED_MODE                    BITS(16,17) /* LED mode */
+#define LCR_LED_MODE_GPIO               0
+#define LCR_LED_MODE_TX                 BIT(16)
+#define LCR_LED_MODE_RX                 BIT(17)
+#define LCR_LED_MODE_TX_RX              BITS(16,17)
+#define LCR_LED_ON_CNT                  BITS(8,15)  /* LED On count */
+#define LCR_LED_OFF_CNT                 BITS(0,7)   /* LED Off count */
+
+/* ----- Transmitter Control ----- */
+/* ATIM/CFP Window Length Register (ACWLR) bit definitions */
+#define ACWLR_CFP_MAX_DURATION          BITS(16,31) /* CFP max duration */
+#define ACWLR_ATIM_WINDOW               BITS(0,15)  /* ATIM window */
+
+/* MAC Protocol Timing Control Register (MPTCR) bit definitions */
+#define MPTCR_OPERATION_MODE            BITS(30,31) /* operation mode */
+#define MPTCR_OPERATION_MODE_ESS_STA    0               /* Infrastructure STA */
+#define MPTCR_OPERATION_MODE_IBSS       BIT(30)    /* ad hoc */
+#define MPTCR_OPERATION_MODE_ESS_AP     BIT(31)    /* Infrastructure AP */
+#define MPTCR_EN_COMP_NEXT_PRE_TBTT_TIME    BIT(29)
+#define MPTCR_TBTT_ENABLE               BIT(27)    /* enable TBTT comparator */
+#define MPTCR_DTIM_ENABLE               BIT(26)    /* enable DTIM comparator */
+#define MPTCR_CFP_START_ENABLE          BIT(25)    /* enable CFPStart comparator */
+#define MPTCR_TXOP_GB_ENABLE            BIT(24)    /* enable TXOP Guard Band event comparator */
+#define MPTCR_EN_COMP_NEXT_TBTT_TIME    BIT(23)
+#define MPTCR_EN_COMP_TXOP_GB_NEXT_TIME     BIT(22)
+#define MPTCR_EN_COMP_NEXT_DTIM_TIME    BIT(21)
+#define MPTCR_EN_COMP_NEXT_CFP_START_TIME   BIT(20)
+#define MPTCR_EN_COMP_TS3_TIMER_NEXT_TIME   BIT(19)
+#define MPTCR_EN_COMP_TS2_TIMER_NEXT_TIME   BIT(18)
+#define MPTCR_EN_COMP_TS1_TIMER_NEXT_TIME   BIT(17)
+#define MPTCR_EN_COMP_TS0_TIMER_NEXT_TIME   BIT(16)
+#define MPTCR_PRE_TBTT_GEN_PERIOD       BITS(0,15)  /* pre-TBTT generation period */
+
+/* Next Pre-TBTT Time Control Register (NPTCR) bit definitions */
+#define NPTCR_NEXT_PRE_TBTT_TIME        BITS(0,25)  /* next pre-TBTT time */
+
+/* Next TBTT Time Control Register (NTTCR) bit definitions */
+#define NTTCR_TBTT_GEN_PERIOD           BITS(16,31) /* TBTT generation period */
+#define NTTCR_NEXT_TBTT_TIME            BITS(0,15)  /* next TBTT time */
+
+/* TXOP Guard Band Next Time Control Register (TXOPGBNTCR) bit definitions */
+#define TXOPGBNTCR_TXOP_GB_NEXT_TIME    BITS(0,18)  /* next TXOP Guard Band time */
+
+/* Next DTIM Time Control Register (NDTCR) bit definitions */
+#define NDTCR_DTIM_GEN_PERIOD           BITS(16,31) /* DTIM generation period */
+#define NDTCR_NEXT_DTIM_TIME            BITS(0,15)  /* next DTIM time */
+
+/* Next CFP Start Time Control Register (NCSTCR) bit definitions */
+#define NCSTCR_CFP_START_GEN_PERIOD     BITS(16,31) /* CFPStart generation period */
+#define NCSTCR_NEXT_CFP_START_TIME      BITS(0,15)  /* next CFPStart time */
+
+/* AC TXOP Limit Register 0 (ACTXOPR0) bit definitions */
+#define ACTXOPR0_AC1_LIMIT              BITS(16,31) /* TXOP limit of AC1 */
+#define ACTXOPR0_AC0_LIMIT              BITS(0,15)  /* TXOP limit of AC0 */
+
+/* AC TXOP Limit Register 1 (ACTXOPR1) bit definitions */
+#define ACTXOPR1_AC3_LIMIT              BITS(16,31) /* TXOP limit of AC3 */
+#define ACTXOPR1_AC2_LIMIT              BITS(0,15)  /* TXOP limit of AC2 */
+
+/* TS Timer Generation Period Control Register (TSTGPCR) bit definitions */
+#define TSTGPCR_TS3_TIMER_GEN_PERIOD    BITS(24,31) /* TS3 timer generation period */
+#define TSTGPCR_TS2_TIMER_GEN_PERIOD    BITS(16,23) /* TS2 timer generation period */
+#define TSTGPCR_TS1_TIMER_GEN_PERIOD    BITS(8,15)  /* TS1 timer generation period */
+#define TSTGPCR_TS0_TIMER_GEN_PERIOD    BITS(0,7)   /* TS0 timer generation period */
+
+/* TS Timer Next Time Control Register 0 (TSTNTCR0) bit definitions */
+#define TSTNTCR0_TS1_TIMER_NEXT_TIME    BITS(16,31) /* TS1 timer next time */
+#define TSTNTCR0_TS0_TIMER_NEXT_TIME    BITS(0,15)  /* TS0 timer next time */
+
+/* TS Timer Next Time Control Register 1 (TSTNTCR1) bit definitions */
+#define TSTNTCR1_TS3_TIMER_NEXT_TIME    BITS(16,31) /* TS3 timer next time */
+#define TSTNTCR1_TS2_TIMER_NEXT_TIME    BITS(0,15)  /* TS2 timer next time */
+
+/* TXOP Release Control Register (TRCR) bit definitions */
+#define TRCR_TX_TIME                    BITS(16,24)
+#define TRCR_END_PACKET_TYPE            BIT(6)
+#define TRCR_TX_RATE                    BITS(0,5)
+
+
+/* ----- Receiver Control ----- */
+/* Data Receiver Control Register (DRCR) bit definitions */
+#define DRCR_ADDR_1_VALIDATION          BIT(16)    /* Addr 1 validation for data */
+#define DRCR_MGT_BSSID_VALIDATION       BIT(15)    /* bc/mc mgt BSSID validation */
+#define DRCR_ADDR_3_OWN_SA_FILTERING    BIT(14)    /* Addr 3 own SA filtering for bc/mc data with ToDS=0, FromDS=1 */
+#define DRCR_ADDR_3_BSSID_VALIDATION    BIT(13)    /* Addr 3 BSSID validation for bc/mc data with ToDS=0, FromDS=0 */
+#define DRCR_ADDR_2_BSSID_VALIDATION    BIT(12)    /* Addr 2 BSSID validation for bc/mc data with ToDS=0, FromDS=1 */
+#define DRCR_RX_BROADCAST_ENABLE        BIT(11)    /* Rx bc MPDU enable bit */
+#define DRCR_RX_ALL_MULTICAST_ENABLE    BIT(10)    /* Rx all mc MPDUs enable bit */
+#define DRCR_RX_MULTICAST_ENABLE        BIT(9)     /* Rx multicast MPDU enable bit */
+#define DRCR_PROMISCUOUS_MODE           BIT(8)     /* promiscuous mode enable bit */
+#define DRCR_FCS_ERROR_FRAME_DISCARD    BIT(0)     /* Rx frame with FCS error discard control bit */
+
+/* Receive Frame Block Configuration Register (RFBCR) bit definitions */
+#define RFBCR_BB_CR_D_INDEX             BITS(24,30)   /* BB CR D index */
+#define RFBCR_BB_CR_C_INDEX             BITS(16,22)   /* BB CR C index */
+#define RFBCR_BB_CR_B_INDEX             BITS(8,14)    /* BB CR B index */
+#define RFBCR_BB_CR_A_INDEX             BITS(0,6)     /* BB CR A index */
+
+
+/* ----- MAC Protocol Timing Control ----- */
+/* MAC Processing Delay Registet (MPDR) bit definitions */
+#define MPDR_MAC_PRC_DELAY_2            BITS(16,23) /* MAC processing delay M2 */
+#define MPDR_MAC_PRC_DELAY_1            BITS(0,7)   /* MAC processing delay M1 */
+
+/* Transmit to Next Transmit Delay Register (TNTDR) bit definitions */
+#define TNTDR_TX_PIFS_CCA               BITS(16,31)
+#define TNTDR_TX_SIFS_TX                BITS(0,15)
+#define TNTDR_RADIA_LONG_SLOT            0x01f40082
+#define TNTDR_RADIA_SHORT_SLOT           0x01180082
+#define TNTDR_MAXIM_LONG_SLOT            0x01f40082
+#define TNTDR_MAXIM_SHORT_SLOT           0x01180082
+#define TNTDR_RFMD_LONG_SLOT             0x01f40082
+#define TNTDR_RFMD_SHORT_SLOT            0x01180082
+
+/* Slot Time Duration Register (STDR) bit definitions */
+#define STDR_SLOT_TIME_2                BITS(16,31) /* slot time with M2 */
+#define STDR_SLOT_TIME_1                BITS(0,15)  /* slot time with M1 */
+#define STDR_LONG_SLOT                  0x01900190
+#define STDR_SHORT_SLOT                 0x00b400b4
+
+/* EIFS and Probe Delay Duration Register (EPDDR) bit definitions */
+#define EPDDR_PROBE_DELAY               BITS(16,31) /* ProbeDelay */
+#define EPDDR_EIFS_TIME                 BITS(0,15)  /* EIFS */
+
+/* Control Response Frame Control Register 0 (CRFCR0) bit definitions */
+#define CRFCR0_RSP_SAME_PREAMBLE        BIT(31)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_9M  BITS(25,29)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_6M  BITS(20,24)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_11M BITS(15,19)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_5_5M    BITS(10,14)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_2M  BITS(5,9)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_1M  BITS(0,4)
+
+/* Control Response Frame Control Register 1 (CRFCR1) bit definitions */
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_54M BITS(25,29)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_48M BITS(20,24)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_36M BITS(15,19)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_24M BITS(10,14)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_18M BITS(5,9)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_12M BITS(0,4)
+
+#define CRFCR_CTRL_RSP_TX_RATE_1M       RATE_CODE_1M
+#define CRFCR_CTRL_RSP_TX_RATE_2M       RATE_CODE_2M
+#define CRFCR_CTRL_RSP_TX_RATE_5_5M     RATE_CODE_5_5M
+#define CRFCR_CTRL_RSP_TX_RATE_11M      RATE_CODE_11M
+#define CRFCR_CTRL_RSP_TX_RATE_6M       (RATE_CODE_6M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_9M       (RATE_CODE_9M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_12M      (RATE_CODE_12M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_18M      (RATE_CODE_18M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_24M      (RATE_CODE_24M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_36M      (RATE_CODE_36M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_48M      (RATE_CODE_48M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_54M      (RATE_CODE_54M | 0x00000010)
+
+/* DCF Timeout Register (DTR) bit definitions */
+
+/* Beacon Contention Window Register (BCWR) bit definitions */
+
+/* TSF Timer Adjustment Register 0 (TTAR0) bit definitions */
+#define TTAR0_TSF_TIMER_VALUE_CHANGE    BIT(1)     /* TSF timer value change command/status */
+#define TTAR0_TSF_TIMER_OFFSET_ADJUST   BIT(0)     /* TSF timer offset adjust command/status */
+
+
+/* ----- Network Allocation Vector (NAV) Control ----- */
+/* Local NAV Register (LNR) bit definitions */
+#define LNR_NAV                         BITS(0,25)  /* local NAV value */
+
+/* NAV Reset Timeout Register (NRTR) bit definitions */
+#define NRTR_CAP_RECOVERY_TIME          BITS(16,19) /* CAP recovery time for AP */
+#define NRTR_RTS_NAV_RESET_TIMEOUT      BITS(0,8)   /* RTS NAV reset timeout */
+
+/* NAV Software Update Register (NSUR) bit definitions */
+#define NSUR_NAV_UPDATE                 BIT(31)    /* NAV update command and status */
+#define NSUR_NAV_UPDATE_VALUE           BITS(0,25)  /* NAV updated value */
+
+
+/* ----- Beacon Generation ----- */
+/* Beacon Generation Control Register 0 (BGCR0) bit definitions */
+#define BGCR0_TX_TIMESTAMP_OFFSET       BITS(16,23)
+#define BGCR0_TRANSMISSION_POWER        BITS(8,15)
+#define BGCR0_BEACON_TX_RATE            BITS(0,5)   /* beacon tx rate */
+
+/* Beacon Generation Control Register 1 (BGCR1) bit definitions */
+#define BGCR1_BC_OWN                    BIT(31)    /* BC own bit */
+#define BGCR1_BEACON_SN                 BITS(16,27)
+#define BGCR1_BEACON_LENGTH             BITS(8,15)
+#define BGCR1_BC_LENGTH                 BITS(0,7)
+
+/* SW Beacon Content Control Register (SWBCCR) bit definitions */
+#define SWBCCR_BC_ACCESS_START          BIT(7)
+#define SWBCCR_BC_RW_CTRL               BIT(6)
+#define SWBCCR_BC_READ                  0
+#define SWBCCR_BC_WRITE                 BIT(6)
+#define SWBCCR_BC_INDEX                 BITS(0,5)
+
+
+/* ----- Transmit Frame Architecture ----- */
+/* Transmit Frame Control Block (TFCB) field definitions */
+/* TFD Control Flag field */
+#define TFCB_FLAG_EOL                   BIT(0)     /* Last TFCB indication bit */
+#define TFCB_FLAG_NB                    BIT(1)     /* Null TBB pointer indication bit */
+#define TFCB_FLAG_MORE                  BIT(2)     /* More Frag bit */
+#define TFCB_FLAG_CFB                   BIT(3)     /* Contention Free Burst bit */
+#define TFCB_FLAG_SEC                   BIT(4)     /* Security Engine Operation */
+#define TFCB_FLAG_PAIRED                BIT(5)     /* Paired bit */
+/* Security Operation Mode field */
+#define TFCB_SEC_MODE                   BITS(0,3)
+#define TFCB_SEC_MODE_NORMAL            0
+#define TFCB_SEC_MODE_SEC_ENGINE        BIT(3)
+#define TFCB_SEC_MODE_NONE              0x00
+#define TFCB_SEC_MODE_WEP_40            0x01
+#define TFCB_SEC_MODE_TKIP              0x02
+#define TFCB_SEC_MODE_WRAP              0x03
+#define TFCB_SEC_MODE_CCMP              0x04
+#define TFCB_SEC_MODE_WEP_104           0x05
+#define TFCB_SEC_MODE_2120_CCMP         0x07
+#define TFCB_SEC_MODE_TKIP_MIC          0x0A
+#define TFCB_SEC_MODE_ENCRYPT_AES_CHAIN 0x0C
+#define TFCB_SEC_MODE_ENCRYPT_AES_SEQ   0x0D
+#define TFCB_SEC_MODE_DECRYPT_AES_CHAIN 0x0E
+#define TFCB_SEC_MODE_DECRYPT_AES_SEQ   0x0F
+/* Initialiazation Vector (IV) field */
+#define TFCB_IV_WEP_KEY_ID              BITS(30,31)   /* Key ID subfield */
+#define TFCB_IV_WEP_PAD                 BITS(24,29)   /* Pad subfield */
+#define TFCB_IV_WEP_IV                  BITS(0,23)    /* Initialization vector subfield */
+#define TFCB_IV_TKIP_KEY_ID             BITS(30,31)
+#define TFCB_IV_TKIP_EXT_IV             BIT(29)
+#define TFCB_IV_TKIP_PAD                BITS(24,28)
+#define TFCB_IV_TKIP_RC4_KEY_2          BITS(16,23)
+#define TFCB_IV_TKIP_RC4_KEY_1          BITS(8,15)
+#define TFCB_IV_TKIP_RC4_KEY_0          BITS(0,7)
+#define TFCB_IV_CCMP_KEY_ID             BITS(30,31)
+#define TFCB_IV_CCMP_EXT_IV             BIT(29)
+#define TFCB_IV_CCMP_PAD                BITS(16,28)
+#define TFCB_IV_CCMP_IV_1               BITS(8,15)
+#define TFCB_IV_CCMP_IV_0               BITS(0,7)
+#define TFCB_IV_WRAP_KEY_ID             BITS(30,31)
+#define TFCB_IV_WRAP_PAD                BITS(28,29)
+#define TFCB_IV_WRAP_REPLAY_COUNTER     BITS(0,27)
+/* Extended IV field */
+#define TFCB_EIV_TKIP_TSC_5             BITS(24,31)
+#define TFCB_EIV_TKIP_TSC_4             BITS(16,23)
+#define TFCB_EIV_TKIP_TSC_3             BITS(8,15)
+#define TFCB_EIV_TKIP_TSC_2             BITS(0,7)
+#define TFCB_EIV_CCMP_IV_5              BITS(24,31)
+#define TFCB_EIV_CCMP_IV_4              BITS(16,23)
+#define TFCB_EIV_CCMP_IV_3              BITS(8,15)
+#define TFCB_EIV_CCMP_IV_2              BITS(0,7)
+/* TCI Control Flag field */
+#define TFCB_CTRL_RTS                   BIT(7)
+#define TFCB_CTRL_CTS                   BIT(6)
+#define TFCB_CTRL_QOS_CF_POLL           BIT(5)
+#define TFCB_CTRL_TSF                   BIT(4)
+#define TFCB_CTRL_NO_ACK                BIT(3)
+#define TFCB_CTRL_DELAY                 BIT(2)
+#define TFCB_CTRL_CFB                   BIT(1)
+#define TFCB_CTRL_MORE                  BIT(0)
+/* TID & MAC Header Control Flag field */
+#define TFCB_TID                        BITS(0,3)
+#define TFCB_FRAG                       BIT(7)
+#define TFCB_TX_ANT                     BIT(6)
+#define TFCB_MAC_HEADER_EIV_PRESENT     BIT(5)
+#define TFCB_MAC_HEADER_IV_PRESENT      BIT(4)
+/* Multirate Switching Control field */
+#define TFCB_MULTIRATE_STEP_NUM         BITS(14,15)
+#define TFCB_MULTIRATE_1_STEP_SWITCH    0
+#define TFCB_MULTIRATE_2_STEP_SWITCH    BIT(14)
+#define TFCB_MULTIRATE_MPDU_RETRY_LIMIT_2   BITS(7,13)
+#define TFCB_MULTIRATE_MPDU_RETRY_LIMIT_1   BITS(0,6)
+/* Transmission Rates field */
+#define TFCB_TX_RATE_2                  BITS(8,13)
+#define TFCB_TX_RATE_1                  BITS(0,5)
+/* Transmit Status field */
+#define TFCB_STATUS_FRAG_SWSKIP         BIT(15)
+#define TFCB_STATUS_TX_RATE             BITS(8,15)
+#define TFCB_STATUS_TIMEUP_ERR          BIT(4)
+#define TFCB_STATUS_FRAG_SKIP_ERR       BIT(3)
+#define TFCB_STATUS_RTS_RETRY_ERR       BIT(2)
+#define TFCB_STATUS_MPDU_RETRY_ERR      BIT(1)
+#define TFCB_STATUS_OK                  BIT(0)
+#define TFCB_STATUS_MASK                (TFCB_STATUS_OK | \
+                                        TFCB_STATUS_MPDU_RETRY_ERR | \
+                                        TFCB_STATUS_RTS_RETRY_ERR | \
+                                        TFCB_STATUS_FRAG_SKIP_ERR | \
+                                        TFCB_STATUS_TIMEUP_ERR    | \
+                                        TFCB_STATUS_FRAG_SWSKIP)
+
+/* Transmit Frame Descriptor (TFD) Checksum size */
+#define TFCB_TFD_SIZE                   0x0c        //TFD legth for check sum calculation
+#define TFCB_TSI_SIZE                   0x10        //Transmit Status Information
+
+
+
+/* Transmit Buffer Block (TBB) field definitions */
+/* TBB Flag field */
+#define TBB_FLAG_EOL                    BIT(0)     /* Last TBB indication bit */
+
+/* Transmit Buffer Block (TBB) size definiton */
+#define TBB_REVBUFFER_SIZE              32
+#define TBB_TBD_SIZE                    12
+
+
+/* ----- Receive Frame Architecture ----- */
+/* Receive Frame Block (RFB) field definitions */
+/* RFB Flag field */
+#define RFB_FLAG_EOL                    BIT(0)     /* RFB EL Bit */
+/* Receive Status Bits */
+#define RFB_STATUS_FCS_ERR              BIT(1)
+#define RFB_STATUS_OK                   BIT(0)
+#define RFB_STATUS_MASK                 (RFB_STATUS_OK | RFB_STATUS_FCS_ERR)
+/* Receive Security Status Bits */
+#define RFB_SECSTATUS_DATA_PRIVACY_MASK     BITS(0,3)
+#define RFB_SECSTATUS_FORMAT_ERR            BIT(11)
+#define RFB_SECSTATUS_RXICV_ERR             BIT(10)
+#define RFB_SECSTATUS_RXKEYDIS_ERR          BIT(9)
+#define RFB_SECSTATUS_RXKEY_NOT_FOUND_ERR   BIT(8)
+#define RFB_SECSTATUS_RXDEC_ERR_MASK        BITS(8,11)
+/* Receive Frame Descriptor (RFD) size */
+#define RFB_RFD_SIZE                    0x08
+#define RFB_RX_BUFFER_MAC_HEADER_SIZE   32
+#define RFB_RSI_SIZE                    48
+
+
+/* ----- Transmission rate codes ----- */
+#define RATE_CODE_RATE_MASK             0x0F
+#define RATE_CODE_1M                    0x00
+#define RATE_CODE_2M                    0x01
+#define RATE_CODE_5_5M                  0x02
+#define RATE_CODE_11M                   0x03
+#define RATE_CODE_6M                    0x0B
+#define RATE_CODE_9M                    0x0F
+#define RATE_CODE_12M                   0x0A
+#define RATE_CODE_18M                   0x0E
+#define RATE_CODE_24M                   0x09
+#define RATE_CODE_36M                   0x0D
+#define RATE_CODE_48M                   0x08
+#define RATE_CODE_54M                   0x0C
+
+#define RATE_CODE_PREAMBLE_MASK         0x10
+#define RATE_CODE_LONG_PREAMBLE         0x00
+#define RATE_CODE_SHORT_PREAMBLE        0x10
+
+#define RATE_CODE_OFDM_MASK             0x20
+#define RATE_CODE_CCK                   0x00
+#define RATE_CODE_OFDM                  0x20
+
+/* CCK mode, long preamble */
+#define TX_RATE_LONG_PREAMBLE_1M        (RATE_CODE_1M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_2M        (RATE_CODE_2M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_5_5M      (RATE_CODE_5_5M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_11M       (RATE_CODE_11M | RATE_CODE_LONG_PREAMBLE)
+
+/* CCK mode, short preamble */
+#define TX_RATE_SHORT_PREAMBLE_2M       (RATE_CODE_2M | RATE_CODE_SHORT_PREAMBLE)
+#define TX_RATE_SHORT_PREAMBLE_5_5M     (RATE_CODE_5_5M | RATE_CODE_SHORT_PREAMBLE)
+#define TX_RATE_SHORT_PREAMBLE_11M      (RATE_CODE_11M | RATE_CODE_SHORT_PREAMBLE)
+
+/* OFDM mode */
+#define TX_RATE_OFDM_6M                 (RATE_CODE_6M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_9M                 (RATE_CODE_9M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_12M                (RATE_CODE_12M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_18M                (RATE_CODE_18M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_24M                (RATE_CODE_24M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_36M                (RATE_CODE_36M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_48M                (RATE_CODE_48M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_54M                (RATE_CODE_54M | RATE_CODE_OFDM)
+
+
+/* IPN2128 Baseband control register (BBCR) offset definition */
+#define BBCR_CR0                0
+#define BBCR_CR1                1
+#define BBCR_CR2                2
+#define BBCR_CR3                3
+#define BBCR_CR4                4
+#define BBCR_CR5                5
+#define BBCR_CR6                6
+#define BBCR_CR7                7
+#define BBCR_CR8                8
+#define BBCR_CR9                9
+#define BBCR_CR10               10
+#define BBCR_CR11               11
+#define BBCR_CR12               12
+#define BBCR_CR13               13
+#define BBCR_CR14               14
+#define BBCR_CR15               15
+#define BBCR_CR16               16
+#define BBCR_CR17               17
+#define BBCR_CR18               18
+#define BBCR_CR19               19
+#define BBCR_CR20               20
+#define BBCR_CR21               21
+#define BBCR_CR22               22
+#define BBCR_CR23               23
+#define BBCR_CR24               24
+#define BBCR_CR25               25
+#define BBCR_CR26               26
+#define BBCR_CR27               27
+#define BBCR_CR28               28
+#define BBCR_CR29               29
+#define BBCR_CR30               30
+#define BBCR_CR31               31
+#define BBCR_CR32               32
+#define BBCR_CR33               33
+#define BBCR_CR34               34
+#define BBCR_CR35               35
+#define BBCR_CR36               36
+#define BBCR_CR37               37
+#define BBCR_CR38               38
+#define BBCR_CR39               39
+#define BBCR_CR45               45
+#define BBCR_CR46               46
+#define BBCR_CR80               80
+#define BBCR_CR81               81
+#define BBCR_CR82               82
+#define BBCR_CR83               83
+#define BBCR_CR84               84
+#define BBCR_CR85               85
+#define BBCR_CR86               86
+#define BBCR_CR87               87
+#define BBCR_CR88               88
+#define BBCR_CR89               89
+#define BBCR_CR90               90
+#define BBCR_CR91               91
+#define BBCR_CR92               92
+#define BBCR_CR93               93
+#define BBCR_CR94               94
+#define BBCR_CR95               95
+#define BBCR_CR96               96
+#define BBCR_CR97               97
+#define BBCR_CR98               98
+#define BBCR_CR99               99
+#define BBCR_CR100              100
+#define BBCR_CR101              101
+#define BBCR_CR102              102
+#define BBCR_CR103              103
+#define BBCR_CR104              104
+#define BBCR_CR105              105
+#define BBCR_CR106              106
+#define BBCR_CR107              107
+#define BBCR_CR108              108
+#define BBCR_CR109              109
+#define BBCR_CR110              110
+#define BBCR_CR111              111
+#define BBCR_CR112              112
+#define BBCR_CR113              113
+#define BBCR_CR114              114
+#define BBCR_CR115              115
+#define BBCR_CR116              116
+#define BBCR_CR117              117
+#define BBCR_CR118              118
+#define BBCR_CR119              119
+#define BBCR_CR120              120
+#define BBCR_CR121              121
+#define BBCR_CR122              122
+#define BBCR_CR123              123
+#define BBCR_CR124              124
+#define BBCR_CR125              125
+#define BBCR_CR126              126
+#define BBCR_CR127              127
+#define BBCR_CR128              128
+#define BBCR_CR129              129
+
+/* IPN2128 Baseband control register (BBCR) definition */
+/* CR24 bit definitions */
+#define CR24_RX_MODULATION_TYPE         BIT(7)
+#define CR24_RX_OFDM                    BIT(7)
+#define CR24_RX_CCK                     0x00
+#define CR24_RX_PREAMBLE_TYPE           BIT(6)
+#define CR24_RX_SHORT_PREAMBLE          BIT(6)
+#define CR24_RX_LONG_PREAMBLE           0x00
+#define CR24_RX_RATE                    BITS(2,5)
+#define CR24_RX_RATE_1M                 (RATE_CODE_1M << 2)
+#define CR24_RX_RATE_2M                 (RATE_CODE_2M << 2)
+#define CR24_RX_RATE_5_5M               (RATE_CODE_5_5M << 2)
+#define CR24_RX_RATE_11M                (RATE_CODE_11M << 2)
+#define CR24_RX_RATE_6M                 (RATE_CODE_6M << 2)
+#define CR24_RX_RATE_9M                 (RATE_CODE_9M << 2)
+#define CR24_RX_RATE_12M                (RATE_CODE_12M << 2)
+#define CR24_RX_RATE_18M                (RATE_CODE_18M << 2)
+#define CR24_RX_RATE_24M                (RATE_CODE_24M << 2)
+#define CR24_RX_RATE_36M                (RATE_CODE_36M << 2)
+#define CR24_RX_RATE_48M                (RATE_CODE_48M << 2)
+#define CR24_RX_RATE_54M                (RATE_CODE_54M << 2)
+
+/* CR29 bit definitions */
+#define CR29_RX_ANTENNA                 BIT(7)
+#define CR29_LNA_STATUS                 BIT(5)
+#define CR29_VGA_GAIN                   BITS(0,4)
+
+/* LET Control */
+#define LED_BLINKING_ON_TIME_1          20  /* LED blinking on time: 80 ms */
+#define LED_BLINKING_OFF_TIME_1         6   /* LED blinking off time: 24 ms */
+#define LED_BLINKING_ON_TIME_2          20  /* LED blinking on time: 80 ms */
+#define LED_BLINKING_OFF_TIME_2         3   /* LED blinking off time: 12 ms */
+
+#define LCR_DEFAULT_VALUE       (LCR_LED_MODE_TX_RX | \
+                                LCR_LED_POLARITY_POSITIVE | \
+                                ((LED_BLINKING_ON_TIME_1 << 8) & LCR_LED_ON_CNT) | \
+                                (LED_BLINKING_OFF_TIME_1 & LCR_LED_OFF_CNT))
+
+
+/************************************************************************
+*                         D A T A   T Y P E S
+*************************************************************************
+*/
+
+/* MCR structure for MCR init and RF init*/
+typedef struct _MCRLIST_STRUC {
+	unsigned short   offset;
+	kal_uint32    initValue;
+} MCRLIST_STRUC, *PMCRLIST_STRUC;
+
+
+
+
+/************************************************************************
+*                             M A C R O S
+*************************************************************************
+*/
+
+/************************************************************************
+*                    D A T A   D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/************************************************************************
+*                 F U N C T I O N   D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/*equates.h*/
+/************************************************************************
+*                     C O M P I L E R   F L A G S
+*************************************************************************
+*/
+
+/************************************************************************
+*                          C O N S T A N T S
+*************************************************************************
+*/
+
+#ifndef BIT
+//#define BIT(n)              ( (ULONG)1 << (n) )
+#define BIT(n)              ( (kal_uint32)1 << (n) )
+#define BITS2(m,n)          ( BIT(m) | BIT (n) )
+#define BITS3(m,n,o)    ( BIT(m) | BIT (n) | BIT (o) )
+#define BITS4(m,n,o,p)  ( BIT(m) | BIT (n) | BIT (o) | BIT(p) )
+
+/* bits range: for example BITS(16,23) = 0xFF0000
+ *   ==>  (BIT(m)-1)   = 0x0000FFFF     ~(BIT(m)-1)   => 0xFFFF0000
+ *   ==>  (BIT(n+1)-1) = 0x00FFFFFF
+ */
+#define BITS(m,n)       ( ~(BIT(m)-1)  &  ((BIT(n)-1)|BIT(n)) )
+#endif
+
+
+/* MAC address */
+#define DEFAULT_MAC_ADDR        {0x00, 0x08, 0x22, 0xFE, 0x00, 0x01}
+#define NULL_MAC_ADDR           {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+#define BROADCAST_MAC_ADDR      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+
+/* Chip ID and revision */
+#define IPN2128                 0x21280000
+#define IPN2126                 0x21260000
+
+#define CHIP_ID_VERSION_MASK    BITS(8,31) /* mask for chip ID and version */
+#define CHIP_ID_MASK    BITS(16,31)                 /* mask for chip ID */
+#define FPGA_VERSION_MASK       BITS(0,15)  /* mask for FPGA emulation platform version */
+
+#define IPN2128_FPGA            0x01            // FPGA version driver set 1
+#define IPN2128_BCI_P           0x00            // BCI parallel interface set 1
+
+/* Adapter Types Supported */
+#define IPN2128_MINI_PCI        0x00
+#define IPN2128_CARDBUS         0x01
+
+/* Supported RF chipsets */
+#define RF_RFMD                 0x00000001  /* RF MicroDevice */
+#define RF_MAXIM                0x00000002  /* Maxim */
+#define RF_AIROHA               0x00000003  /* Airoha */
+
+
+#define MAC_ADDRESS_LENGTH              6
+#define MAC_ADDR_LEN MAC_ADDRESS_LENGTH
+
+/* Ethernet Frame Sizes */
+//#define ETHERNET_ADDRESS_LENGTH         6
+#define ETHERNET_HEADER_SIZE            14
+#define MINIMUM_ETHERNET_PACKET_SIZE    60
+#define MAXIMUM_ETHERNET_PACKET_SIZE    1514
+
+/* IEEE 802.11 WLAN Frame Sizes */
+#define WLAN_MAC_HEADER_SIZE            24      /* Address 4 excluded */
+#define MINIMUM_WLAN_PACKET_SIZE        16
+#define MAXIMUM_WLAN_PACKET_SIZE        4096    // including encryption needed
+
+/* PS-Poll frame MAC header size */
+#define WLAN_PSPOLL_MAC_HEADER_SIZE     16
+
+#define FRAME_BODY_MAX_LEN              2304    /* maximum length of MPDU */
+
+#define WLAN_MAC_FCS_LEN                4   /* length of FCS field in MAC frame */
+#define WLAN_MAC_IV_LEN                 4   /* length of IV field in encrypted MAC frame */
+#define WLAN_MAC_ICV_LEN                4   /* length of ICV field in encrypted MAC frame */
+#define WLAN_MAC_EXT_IV_LEN             4   /* length of Extented ICV field in encrypted MAC frame */
+#define WLAN_MAC_MIC_LEN                8   /* length of MIC field in encrypted MAC frame */
+#define WLAN_MAC_REPLAY_CTR_LEN         4   /* length of Replay Counter field in encrypted MAC frame */
+#define WLAN_MAC_CKIP_MIC_LEN           4   /* length of CKIP MIC */
+#define WLAN_MAC_CKIP_SEQ_LEN           4   /* length of CKIP SEQ */
+
+#define CCM_IB_FLAGS                    0x59
+#define CCM_CTR_FLAGS                   0x01
+
+//#define TCB_BUFFER_SIZE                 0XE0 // 224
+#define COALESCE_BUFFER_SIZE            2048    /* 4k bytes */
+//#define ETH_MAX_COPY_LENGTH             0x80 // 128
+
+// Make receive area 1536 for 16 bit alignment.
+//#define RCB_BUFFER_SIZE       MAXIMUM_ETHERNET_PACKET_SIZE
+//#define RCB_BUFFER_SIZE                 1520 // 0x5F0
+
+/* Wireless LAN packet buffer size (padding for 16-byte alignment) */
+#define WLAN_PACKET_BUFFER_SIZE         (((MAXIMUM_WLAN_PACKET_SIZE + 15) >> 4) << 4)
+
+/* transmit buffer size (padding for 16-byte alignment) */
+#define TX_BUFFER_SIZE                  WLAN_PACKET_BUFFER_SIZE
+
+/* receive buffer size (padding for 16-byte alignment) */
+#define RX_BUFFER_SIZE                  WLAN_PACKET_BUFFER_SIZE
+
+//- Area reserved for all Non Transmit command blocks
+//#define MAX_NON_TX_CB_AREA              512
+
+/* IEEE 802.11 defined time constant */
+#define TU                          1024  /* Time uint: 1024 microseconds */
+
+/*  Ndis/Adapter driver constants */
+#define MAX_PHYS_DESC               16
+
+#define NUM_TX_QUEUES               4
+
+/* System wide Equates */
+//#define MAX_NUMBER_OF_EISA_SLOTS    15
+//#define MAX_NUMBER_OF_PCI_SLOTS     15
+
+#define  MAX_ARRAY_SEND_PACKETS                 8
+
+/* Number of RFBs - minimum, default, and maximum */
+#define NIC_MIN_NUM_RFBS                    4
+#define NIC_DEF_NUM_RFBS                    20
+#define NIC_MAX_NUM_RFBS                    1024
+
+/* Maximum number of remote STA records */
+#define MAX_NUM_REMOTE_STA_RECORDS          16
+
+/* Maximum number of supported physical layer network subtypes */
+#define MAX_NUM_SUPPORTED_NETWORK_TYPE      3
+
+/* Maximum number of scan results */
+#define MAX_NUM_SCAN_RESULTS        32
+
+/* Miscellaneous Equates */
+//#define CR      0x0D        // Carriage Return
+//#define LF      0x0A        // Line Feed
+
+#ifndef FALSE
+#define FALSE       0
+#define TRUE        1
+#endif
+
+#define DRIVER_NULL ((ULONG)0xffffffff) // reopen Jay 0613
+//#define DRIVER_ZERO 0
+
+// in order to make our custom oids hopefully somewhat unique
+// we will use 0xFF (indicating implementation specific OID)
+//               A0 (first byte of non zero intel unique identifier)
+//               C9 (second byte of non zero intel unique identifier)
+//               XX (the custom OID number - providing 255 possible custom oids)
+
+
+
+/************************************************************************
+*                             M A C R O S
+*************************************************************************
+*/
+
+/************************************************************************
+*                    D A T A   D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/************************************************************************
+*                 F U N C T I O N   D E C L A R A T I O N S
+*************************************************************************
+*/
+
+
+
+/* Chip ID and revision */
+#define IPN2128                 0x21280000
+#define IPN2126                 0x21260000
+#define CHIP_ID_REV             IPN2128
+
+
+typedef struct i2126mgmt_   i2126mgmt_t;
+typedef i2126mgmt_t         MP_ADAPTER, *PMP_ADAPTER;
+
+
+/* Macros to read and write MAC control registers (MCRs) */
+#define NIC_MCR_READ(_pAdapter, _register, _pValue) \
+        IPC_2126_MCR_Read(_register, (kal_uint32 *)(_pValue))
+
+#define NIC_MCR_WRITE(_pAdapter, _register, _value) \
+        IPC_2126_MCR_Write( _register, (kal_uint32)(_value))
+
+#endif /* __PRECOMP_H */
+
diff --git a/mcu/driver/storage/mc/inc/usbms_msdc.h b/mcu/driver/storage/mc/inc/usbms_msdc.h
new file mode 100644
index 0000000..0db32ac
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/usbms_msdc.h
@@ -0,0 +1,89 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   usbms_msdc.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Header file of memory card host driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+
+
+typedef enum {
+	MSDC_MEM_TYPE_EXT = 0,
+	MSDC_MEM_TYPE_SIMPLUS = 1,
+	MSDC_MEM_TYPE_TCARD2 = 2		
+}MSDC_EXT_MEM_TYPE;
+
+typedef enum {
+	DEV_STATUS_OK = 0,
+	DEV_STATUS_MEDIA_CHANGE,
+	DEV_STATUS_NOMEDIA,
+	DEV_STATUS_WP,
+	DEV_STATUS_MAX
+} MSDC_DEV_STATUS;
+
+kal_bool usbms_read_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_gpd_read_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_write_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_gpd_write_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type);
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_format_all(MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_prevmedia_removal_all(kal_bool enable);
+kal_bool usbms_query_max_bd_num(kal_uint16 * max_bd_num);
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type);
+
+	
+
diff --git a/mcu/driver/storage/mc/src/dcl_memory_card.c b/mcu/driver/storage/mc/src/dcl_memory_card.c
new file mode 100644
index 0000000..679e351
--- /dev/null
+++ b/mcu/driver/storage/mc/src/dcl_memory_card.c
@@ -0,0 +1,3668 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    dcl_memory_card.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *	This Module defines DCL (Driver Common Layer) of the memory card driver and SDIO driver.
+ *	The memory card driver provide here include SD, MMC, MS/MSPro.
+ *	In thie file, DclSD_xxx is the API for SD driver, Dcl_SDIO_xxx is the API for SDIO driver, and DclMS_xxx is the API for MS and MSPro driver.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "dcl.h"
+#include "msdc_def.h"
+
+#ifdef DCL_MSDC_INTERFACE
+#if !defined(DRV_MSDC_OFF)
+#include "msdc_reg_adap.h"
+#include "intrCtrl.h"
+#include "sd_def.h"
+#include "drv_trc.h"
+#include "cache_sw.h"
+#include "kal_public_api.h"
+#include "init.h"
+#include "qmu_bm.h"
+
+/**************************************************************************
+following defines options used in this file
+***************************************************************************/
+/*SD related handle*/
+#define DCL_SD_HANDLE_SD1	(MSDC_ADRS|SD_MSDC1)
+#if defined(__MSDC2_SD_MMC__)
+#define DCL_SD_HANDLE_SD2	(MSDC2_ADRS|SD_MSDC2)
+#endif
+
+
+#define DCL_SD_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*SDIO related handle*/
+#define DCL_SDIO_HANDLE_SDIO1	(MSDC_ADRS|SD_MSDC1)
+#if defined(__MSDC2_SD_SDIO__)
+#define DCL_SDIO_HANDLE_SDIO2	(MSDC2_ADRS|SD_MSDC2)
+#endif
+#define DCL_SDIO_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*MS related handle*/
+#define DCL_MS_HANDLE	(MSDC_ADRS|0)
+#define DCL_MS_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*following definition is to help easy search for incomplete part*/
+#define DCL_SD_IMPLEMENTATION_ASSERT ASSERT(0)
+
+/**************************************************************************
+following defines static global variables used in this file
+***************************************************************************/
+static kal_bool fgMSDCInit = KAL_FALSE;
+static kal_bool fgSDInit = KAL_FALSE;
+#if defined(__MSDC_SD_SDIO__)
+static kal_bool fgSDIOInit = KAL_FALSE;
+#endif
+
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+static kal_bool fgMSInit = KAL_FALSE;
+DCL_UINT32	u4ms16KBuffer[4*1024]; // 16K MS buffer
+#endif
+
+/*following variable is used to replace the compile option usage in the code*/
+static kal_uint32 u4MSDCSupport;//stand for wihch HW MSDC will be used
+
+
+
+//static kal_semid dclMsdcArb[3];
+static MSDC_LOCK_TAG dclMsdcLock[3];
+/**************************************************************************
+*	following defines global variables and definitions used for resource contention
+*	with uint16 stands for a resource, every resource is composed as following:
+*	using[15:13]   |   occupied[12]   |   magic[11:4]   |   RFU[3:0]
+***************************************************************************/
+static kal_uint16			sdResource[3];
+//static kal_uint16			msdcResource[3];
+
+#define DCL_SD_RESOURCE_OCCUPIED	0x1000
+#define DCL_SD_RESOURCE_USING_MAX	0xE000
+#define DCL_SD_RESOURCE_USING_INCREMENT	0x2000
+#define DCL_SD_RESOURCE_MAGIC_MAX 0x0ff0
+#define DCL_SD_RESOURCE_MAGIC_UNIT 0x0010
+#define DCL_SD_GET_MAGIC_FROM_HANDLE(a) (a & DCL_SD_RESOURCE_MAGIC_MAX)
+#define DCL_SD_GET_DUMMY_HANDLE(a) (a & (~DCL_SD_RESOURCE_MAGIC_MAX))
+static sd_select_enum DCL_SD_USING_RESOURCE_START(DCL_HANDLE handle)
+{
+	sd_select_enum sel;
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+    {
+        if(DCL_SD_RESOURCE_OCCUPIED != (sdResource[sel] & DCL_SD_RESOURCE_OCCUPIED))
+        {
+            ASSERT(0);
+        }
+        if((handle & DCL_SD_RESOURCE_MAGIC_MAX) != (sdResource[sel] & DCL_SD_RESOURCE_MAGIC_MAX))
+        {
+            ASSERT(0);
+        }
+    }
+
+    #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+    #endif
+    
+    return sel;
+}
+
+static void DCL_SD_USING_RESOURCE_END(DCL_HANDLE handle,sd_select_enum sel)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+    return;
+}
+
+/*******************************************************************************
+*	following defines global variables and definitions used for debuging on resource management 
+********************************************************************************/
+typedef struct{
+	kal_uint32	callerRetAddr;
+	kal_uint32	ownerThdId;
+} DCL_SD_DBG_RESOURCE;
+
+
+/**************************************************************************
+*	following defines function tables of SD layer and MSDC layer. These function tables should only be accessed by functions in this file
+*	I should pay some time to remove hard coding of array exntries.
+***************************************************************************/
+static SDDriver_t			*sdDriverTable[3];
+static MSDCDriver_t		msdcDriverTable[3];
+#if defined(__MSDC_SD_SDIO__)
+static SDIODriver_t		*sdioDriverTable[2];
+#endif
+
+/******************************************************************************************
+*following are extern variables from other file
+******************************************************************************************/
+extern SDDriver_t sd_driver_MTK1;
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+extern SDDriver_t sd_driver_MTK2;
+#endif
+
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+#else
+extern void SD_SetRedDlt(kal_uint32 redDlt);
+#endif
+
+#if defined(__MSDC_MSPRO__)
+// global variables
+extern MSP_HANDLE		gMSP;
+#endif
+/**************************************************************************
+followings are static functions that are only called by functions in this file
+***************************************************************************/
+
+/*************************************************************************
+* FUNCTION
+*  DclMSDC_init
+*
+* DESCRIPTION
+* 	This function is to initialize MSDC related HW and SW.
+*	This file is to be only called by DCL driver, so we set it statis.
+*	Users should not remove "static" keyword unless you know MTK's memory card driver well.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	None
+*
+*************************************************************************/
+static void DclMSDC_init(void)
+{
+	/*to get information about how many HW MSDC we will use*/
+#if (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)|| defined(__MSDC_MSPRO__)) || defined(__MSDC_SD_SDIO__)
+	u4MSDCSupport |= DCL_MSDC_HW_MSDC1;
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+	u4MSDCSupport |= DCL_MSDC_HW_MSDC2;
+#endif
+
+	if(u4MSDCSupport & DCL_MSDC_HW_MSDC1){
+		MSDC_Initialize();
+
+        #if defined(MSDC_QMU_ENABLE)
+		SD_QMU_Init();
+		#endif
+		
+		//dclMsdcArb[0] = kal_create_sem("MSDC1_lock", 1);
+		init_MSDC_lock(&dclMsdcLock[0], "DCL_MSDC0_LOCK");
+	}
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+	/*if MSDC2 is not compiled, there will be no MSDC_Initialize2, should wrap here*/
+	if(u4MSDCSupport & DCL_MSDC_HW_MSDC2){
+		MSDC_Initialize2();
+		//dclMsdcArb[1] = kal_create_sem("MSDC2_lock", 1);
+		init_MSDC_lock(&dclMsdcLock[1], "DCL_MSDC1_LOCK");
+	}
+#endif
+
+	/*init MSDC driver tables, since the functions in every msdc drivers are few, we register then one by one*/
+	msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD1)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SIMPLUS)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)	
+	msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD2)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl2;
+#endif
+}
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+static DCL_STATUS ConfigGpdList(sd_select_enum sel ,qbm_gpd *head,qbm_gpd*tail,msdc_gpd_t * gpd,msdc_gpd_t * gpd_end)
+{
+#if 1
+    MSDC_Blk[sel].head = head;
+    MSDC_Blk[sel].tail = tail;
+    MSDC_Blk[sel].gpd = gpd;
+    MSDC_Blk[sel].gpd_end = gpd_end;
+    
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+    #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+    #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+    #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+    #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+                #if defined(MSDC_SCAT_BUF_FLUSH)/* || defined(ATEST_DRV_MSDC)*/
+/* under construction !*/
+                #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+                #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+                #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+    #ifdef MSDC_GPD_BD_BUF_CACHED
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+    #endif
+/* under construction !*/
+#endif
+
+    return STATUS_OK;
+}
+
+static DCL_BOOL DclSD_PollExistence(DCL_UINT8 irqMSDCCode, DCL_UINT32 addrReg_MSDC_PS, sd_select_enum sel)
+{
+	return MSDC_Blk[sel].mIsPresent;
+}
+
+//Sextern kal_bool DMA_Valid_Addr_Chk(const void *src, kal_uint32 length);
+static DCL_STATUS DclSD_CtrlCmdRead(sd_select_enum sel, SD_CTRL_READ_T *prRead)
+{
+#ifdef __MSDC_SD_MMC__
+//	DCL_UINT32 addrs
+	DCL_UINT32 maxBlk;
+	DCL_SDC_CMD_STATUS status;
+	DCL_UINT32	u4Sector; //this specify the starting sector to read
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to read
+	void			*bufferAddr; //we will move move data from card to this address
+	SDDriver_t	*sdDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prRead->u4Sector;
+	u4Sectors = prRead->u4Sectors;
+	bufferAddr = prRead->bufferAddr;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*check that ending block should be smaller than maximum block number*/
+	if((u4Sector + u4Sectors ) > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+#if defined(MSDC_CACHED_SUPPORT)
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__EMMC_BOOTING__)
+    MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+#else
+	/*tell buffer type each time this function called*/
+    if (INT_QueryIsCachedRAM(bufferAddr, u4Sectors * DCL_SECTOR_SIZE)){
+		MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+	}
+	else
+		MSDC_Blk[sel].isCachedBuf = KAL_FALSE;
+#endif
+#endif
+
+   
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+	sdDriver = sdDriverTable[sel];
+	/*block address or byte address*/
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+	if(u4Sectors > 1)
+	{
+		status = sdDriver->mulBlkRd(u4Sector, bufferAddr, u4Sectors);
+	}
+	else{
+		status = sdDriver->singleBlkRd(u4Sector, bufferAddr);
+	}
+			
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+	return status;
+#endif
+}
+
+static DCL_STATUS DclSD_CtrlCmdGpdRead(sd_select_enum sel, SD_CTRL_GPD_READ_T *prRead)
+{
+    #ifdef __MSDC_SD_MMC__
+//	DCL_UINT32 addrs
+	DCL_UINT32 maxBlk;
+	DCL_SDC_CMD_STATUS status;
+	DCL_UINT32	u4Sector; //this specify the starting sector to read
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to read
+	SDDriver_t	*sdDriver;
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prRead->u4Sector;
+	u4Sectors = prRead->u4Sectors;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*check that ending block should be smaller than maximum block number*/
+	if((u4Sector + u4Sectors ) > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+    status=ConfigGpdList(sel,(qbm_gpd *)(prRead->bufferHead),(qbm_gpd*)(prRead->bufferTail),&MSDC_gpd[sel],&MSDC_gpd_end[sel]);
+
+    if(status !=NO_ERROR)
+        return status;
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+	sdDriver = sdDriverTable[sel];
+	/*block address or byte address*/
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+
+	status = sdDriver->GpdMulBlkRd(u4Sector, u4Sectors,&MSDC_gpd[sel]);
+				
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+	return status;
+#endif
+}
+
+extern kal_bool INT_QueryIsROMSpace(kal_uint32 addr);
+
+static DCL_STATUS DclSD_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_WRITE_T *prWrite)
+{
+#ifdef __MSDC_SD_MMC__
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	DCL_SDC_CMD_STATUS status=0;
+	DCL_UINT32	u4Sector; //this specify the starting sector to Write
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to Write
+	void			*bufferAddr; //we will move move data from this address to the card
+	SDDriver_t	*sdDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prWrite->u4Sector;
+	u4Sectors = prWrite->u4Sectors;
+	bufferAddr = prWrite->bufferAddr;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*check that ending block should be smaller than maximum block number*/
+	if((u4Sector + u4Sectors ) > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+#if defined(MSDC_CACHED_SUPPORT)
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__EMMC_BOOTING__)
+    MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+#else
+	/*tell buffer type each time this function called*/
+    if (INT_QueryIsCachedRAM(bufferAddr, u4Sectors * DCL_SECTOR_SIZE)){
+		MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+	}
+	else
+		MSDC_Blk[sel].isCachedBuf = KAL_FALSE;
+#endif
+#endif
+
+   
+    //
+    // To check if data is put on serial flash or nor flash.
+    //
+#ifdef MSDC_CACHED_SUPPORT
+	if (INT_QueryIsROMSpace((kal_uint32)bufferAddr) || 
+	    INT_QueryIsROMSpace((kal_uint32)bufferAddr + u4Sectors*0x200)) {
+	    
+	    //MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+        MSDC_Blk[sel].isRomSpace = KAL_TRUE;
+	        
+	}
+    else {
+        MSDC_Blk[sel].isRomSpace = KAL_FALSE;
+    }
+#endif	
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+	sdDriver = sdDriverTable[sel];
+	/*block address or byte address*/
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+	#endif//defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+	if(u4Sectors > 1)
+	{
+		if((SD20_HCS_CARD==MSDC_Blk[sel].mMSDC_type)
+            || (SD20_LCS_CARD==MSDC_Blk[sel].mMSDC_type)
+            || (SD_CARD == MSDC_Blk[sel].mMSDC_type))
+			sdDriver->setPreEraseCnt(u4Sectors);
+		status = sdDriver->mulBlkWr(u4Sector, bufferAddr, u4Sectors);
+	}
+	else{
+		status = sdDriver->singleBlkWr(u4Sector, bufferAddr);
+	}
+			
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+	return status;
+#endif
+}
+
+
+static DCL_STATUS DclSD_CtrlCmdGpdWrite(sd_select_enum sel, SD_CTRL_GPD_WRITE_T *prWrite)
+{
+    #ifdef __MSDC_SD_MMC__
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	DCL_SDC_CMD_STATUS status=0;
+	DCL_UINT32	u4Sector; //this specify the starting sector to Write
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to Write
+	SDDriver_t	*sdDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prWrite->u4Sector;
+	u4Sectors = prWrite->u4Sectors;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*check that ending block should be smaller than maximum block number*/
+	if((u4Sector + u4Sectors ) > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+    status=ConfigGpdList(sel,(qbm_gpd *)(prWrite->bufferHead),(qbm_gpd*)(prWrite->bufferTail),&MSDC_gpd[sel],&MSDC_gpd_end[sel]);
+    if(status !=NO_ERROR)
+        return status;
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+	sdDriver = sdDriverTable[sel];
+	/*block address or byte address*/
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+	#endif//defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+	
+	if((SD20_HCS_CARD==MSDC_Blk[sel].mMSDC_type)
+        || (SD20_LCS_CARD==MSDC_Blk[sel].mMSDC_type)
+        || (SD_CARD == MSDC_Blk[sel].mMSDC_type)
+        || (SD30_CARD == MSDC_Blk[sel].mMSDC_type))
+		sdDriver->setPreEraseCnt(u4Sectors);
+	status = sdDriver->GpdMulBlkWr(u4Sector, u4Sectors,&MSDC_gpd[sel]);	
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+	return status;
+#endif
+}
+
+
+#if defined(MSDC_ODD_SUPPORT)
+static DCL_STATUS DclSD_CtrlCmdReadOdd(sd_select_enum sel, SD_CTRL_READ_ODD_T *prRead)
+{
+#ifdef __MSDC_SD_MMC__
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	DCL_SDC_CMD_STATUS status=0;
+	DCL_UINT32	u4Sector; //this specify the starting sector to read
+	DCL_UINT32	u4Size; //this specify the number of bytes to read
+	void			*bufferAddr; //we will move move data from card to this address
+	SDDriver_t	*sdDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prRead->u4Sector;
+	u4Size = prRead->u4Size;
+	bufferAddr = prRead->bufferAddr;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Size || u4Size > 512 || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+	
+
+
+	sdDriver = sdDriverTable[sel];
+
+	/*set block length to u4Size*/
+	SD_SetBlength(u4Size);
+
+	/*block address or byte address*/
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+	if(u4Size > 1)
+	{
+		ASSERT(0);
+	}
+	else{
+		status = sdDriver->singleBlkRd(u4Sector, bufferAddr);
+	}
+
+	/*set the block length back to 512*/
+	SD_SetBlength(DCL_SECTOR_SIZE);
+			
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+	return status;
+#endif
+}
+
+static DCL_STATUS DclSD_CtrlCmdWriteOdd(sd_select_enum sel, SD_CTRL_WRITE_ODD_T *prWrite)
+{
+#ifdef __MSDC_SD_MMC__
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	DCL_SDC_CMD_STATUS status=0;
+	DCL_UINT32	u4Sector; //this specify the starting sector to Write
+	DCL_UINT32	u4Size; //this specify the number of bytes to Write
+	void			*bufferAddr; //we will move move data from this address to the card
+	SDDriver_t	*sdDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prWrite->u4Sector;
+	u4Size = prWrite->u4Size;
+	bufferAddr = prWrite->bufferAddr;
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		//ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	maxBlk = gSD_blk[sel].mCSD.capacity/512;	
+	/*sectors & sector check*/
+	if(0 == u4Size || u4Size > 512 || u4Sector >= maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*power on MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_FALSE);
+	
+
+
+	sdDriver = sdDriverTable[sel];
+	/*set block length to u4Size*/
+	SD_SetBlength(u4Size);
+	
+	/*block address or byte address*/ 
+	if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+		u4Sector = u4Sector;
+	else
+		u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+	if(u4Size > 512)
+	{
+		ASSERT(0);
+	}
+	else{
+		status = sdDriver->singleBlkWr(u4Sector, bufferAddr);
+		SD_WriteSingleBlock(u4Sector, bufferAddr);
+	}
+
+	/*set the block length back to 512*/
+	SD_SetBlength(DCL_SECTOR_SIZE);
+	
+	/*power down MSDC module*/
+	msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+	return status;
+#endif
+}
+#endif
+/***************************************************************************************
+followings are DCL SD API exported 
+*****************************************************************************************/
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to initialize the SD driver related resource.
+*	This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_STATUS DclSD_Initialize(void)
+{
+	kal_uint32	maskedValue;
+	
+	maskedValue = SaveAndSetIRQMask();
+	/*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+	if(KAL_FALSE == fgMSDCInit){
+		fgMSDCInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		DclMSDC_init();
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+
+
+	maskedValue = SaveAndSetIRQMask();
+	if(KAL_FALSE == fgSDInit){
+		fgSDInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		/*init SD driver tables, there are too many entries in SD driver, so we hook it by pointer*/
+#ifdef __MSDC_SD_MMC__		
+		sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD1)] = &sd_driver_MTK1;
+#endif
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SIMPLUS)] = &sd_driver_MTK1; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)		
+		sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD2)] = &sd_driver_MTK2;
+#endif
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+	
+	return STATUS_OK;
+}
+
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__CARD_DOWNLOAD__)
+DCL_STATUS DclSD_DeInitialize(void)
+{
+    fgMSDCInit  = KAL_FALSE;
+    fgSDInit    = KAL_FALSE;
+	#if defined(__MSDC_SD_SDIO__)
+    fgSDIOInit  = KAL_FALSE;
+	#endif
+    #if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+    fgMSInit    = KAL_FALSE;    
+    #endif 
+
+    MSDC_DeInit();
+    
+    return STATUS_OK;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to get SD DCL handler.
+*
+* PARAMETERS
+*	eDev - only valid for DCL_SD.
+*	flags -following bit stand for specific meaning.
+*		DCL_SD_FLAGS_CARD1: to get a handle for card 1
+*		DCL_SD_FLAGS_CARD2: to get a handle for card 2
+*		DCL_SD_FLAGS_SIMPLUS: to get a handle for sim plus
+*		Other values are prohibited
+* RETURNS
+*  DCL_HANDLE_INVALID - Open failed.
+*  other value - a valid handle
+*
+*************************************************************************/
+DCL_HANDLE DclSD_Open(DCL_DEV dev, DCL_FLAGS flags)
+{	
+	if (dev != DCL_SD)
+	{
+		ASSERT(0);
+		return DCL_HANDLE_INVALID;
+	}
+
+    /* Return Invalid handle directly if it is SYS_INIT phase */
+    if (KAL_TRUE == kal_query_systemInit())
+        return DCL_HANDLE_INVALID;
+        
+	if(flags & DCL_SD_FLAGS_DEVICE_CARD1){
+		if(DCL_SD_FLAGS_DEVICE_CARD1 != (flags & DCL_SD_FLAGS_DEVICE_ALL)){
+			ASSERT(0);
+		}
+		if(flags & DCL_SD_FLAGS_USAGE_CMD){/*wanna get handle to control MSDC1, need contention for action handle*/
+			kal_uint16	magic;
+
+			//
+			// To prevent resource to be occupied twice, use semaphore to gate here.
+			//
+			get_MSDC_lock(&dclMsdcLock[0]);
+			/*
+			if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+			{
+				kal_take_sem(dclMsdcArb[0], 1);
+			
+				// from here, we are the only one gets CMD right to MSDC1, but check the maic first
+			if(sdResource[0] & DCL_SD_RESOURCE_OCCUPIED)
+				ASSERT(0);
+			}
+			*/
+
+			/*process the magic of the resource as rolling counter*/
+			magic = (sdResource[0] & DCL_SD_RESOURCE_MAGIC_MAX);
+			if(DCL_SD_RESOURCE_MAGIC_MAX == magic) /*if means 0x0FF0 achieved*/
+				magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+			else
+				magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+			
+			sdResource[0] = (DCL_SD_RESOURCE_OCCUPIED | magic);
+				
+			return (DCL_SD_HANDLE_SD1 | magic);
+		}
+		else{/*just wanna get handle to get information of this device, return handle directly*/
+			return DCL_SD_HANDLE_SD1;
+		}
+	}
+	else if(flags & DCL_SD_FLAGS_DEVICE_CARD2){
+#if defined(__MSDC2_SD_MMC__)
+		if(DCL_SD_FLAGS_DEVICE_CARD2 != (flags & DCL_SD_FLAGS_DEVICE_ALL)){
+			ASSERT(0);
+		}
+		if(flags & DCL_SD_FLAGS_USAGE_CMD){/*wanna get handle to control MSDC2, need contention action handle*/
+			kal_uint16	magic;
+			
+			//
+			// The same as MSDC1.
+			//
+			get_MSDC_lock(&dclMsdcLock[1]);
+			/*
+			if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+			{
+				kal_take_sem(dclMsdcArb[1], 1);
+			
+				// from here, we are the only one gets CMD right to MSDC2, but check the maic first
+			if(sdResource[1] & DCL_SD_RESOURCE_OCCUPIED)
+				ASSERT(0);
+			}
+			*/
+			
+			/*process the magic of the resource as rolling counter*/
+			magic = (sdResource[1] & DCL_SD_RESOURCE_MAGIC_MAX);
+			if(DCL_SD_RESOURCE_MAGIC_MAX == magic) /*if means 0x0FF0 achieved*/
+				magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+			else
+				magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+			
+			sdResource[1] = (DCL_SD_RESOURCE_OCCUPIED | magic);
+			
+			return (DCL_SD_HANDLE_SD2 | magic);
+		}
+		else{/*just wanna get handle to get information of this device, return handle directly*/
+			return DCL_SD_HANDLE_SD2;
+		}
+#else
+		ASSERT(0);
+		return 0;
+#endif
+	}
+	
+	return 0;
+}
+
+DCL_STATUS DclSD_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	DCL_SD_IMPLEMENTATION_ASSERT;
+	return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+
+#define DCL_MSDC_FUNTION_TABLE
+#ifdef	DCL_MSDC_FUNTION_TABLE
+
+#ifdef __MSDC_SD_MMC__
+typedef DCL_STATUS (*DCL_SD_CTRL_API) (DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data);
+
+
+DCL_STATUS DCL_SD_CTRL_API_READ(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status=0;
+	SD_CTRL_READ_T *prRead;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+
+	prRead = &(data->rSDRead);
+	status = DclSD_CtrlCmdRead(sel, prRead);
+			
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status=0;
+	SD_CTRL_WRITE_T *prWrite;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prWrite = &(data->rSDWrite);
+	status = DclSD_CtrlCmdWrite(sel, prWrite);
+			
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_READ_ODD_SIZE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status=0;
+#if defined(MSDC_ODD_SUPPORT)	
+	SD_CTRL_READ_ODD_T *prRead;
+	sd_select_enum sel;
+
+	/*currently we only support on SD1, check it*/
+	if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+		ASSERT(0);
+	}
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prRead = &(data->rSDReadOdd);
+	status = DclSD_CtrlCmdReadOdd(sel, prRead);
+			
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+#else
+	ASSERT(0);
+#endif	
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE_ODD_SIZE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status=0;
+#if defined(MSDC_ODD_SUPPORT)	
+			SD_CTRL_WRITE_ODD_T *prWrite;
+			sd_select_enum sel;
+
+			/*currently we only support on SD1, check it*/
+			if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+				ASSERT(0);
+			}
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prWrite = &(data->rSDWriteOdd);
+			status = DclSD_CtrlCmdWriteOdd(sel, prWrite);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+#else
+	ASSERT(0);
+#endif
+	
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_INIT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status=0;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+				|| DCL_SD_HANDLE_SIMPLUS == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+#if defined(__MSDC2_SD_MMC__)
+				|| DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+				)
+			{
+				msdcDriverTable[sel].modulePDN(KAL_FALSE);
+				status = sdDriverTable[sel]->sdInititalize();
+				msdcDriverTable[sel].modulePDN(KAL_TRUE);
+			}
+			else{
+				ASSERT(0);
+			}
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+
+	
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_INITED(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_INITED_T *prInited;
+	sd_select_enum sel;
+
+	prInited = &(data->rSDInited);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	prInited->fgInited = MSDC_Blk[sel].mIsInitialized;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_ANALOG_SWITCH(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T *prSwitch;
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prSwitch = &(data->rSDSwitch);
+	sel = prSwitch->u4TargetInterface;
+	MSDC_Switch_Card(sel);
+
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+			
+	status = NO_ERROR;
+#else
+	ASSERT(0);
+	status = STATUS_INVALID_CMD;
+#endif
+
+	return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FAST_FORMAT_START(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	sd_select_enum sel;
+
+	/*currently we only support fast format on SD1, check it*/
+	if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+		ASSERT(0);
+	}
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+#ifdef __MSDC_SD_MMC__
+	SD_startFastFormat();
+#endif		
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FAST_FORMAT_STOP(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	sd_select_enum sel;
+
+	/*currently we only support fast format on SD1, check it*/
+	if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+		ASSERT(0);
+	}
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+#ifdef __MSDC_SD_MMC__			
+	SD_closeFastFormat();
+#endif
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_FAST_FORMAT_RUNNING(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_FAST_FORMAT_T *ff = &(data->rSDFastFormat);
+	sd_select_enum sel;
+
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+#ifdef __DRV_MSDC_FAST_FORMAT__
+	ff->enable = (DCL_BOOL)MSDC_Blk[sel].MSDC_fastFormat;
+#endif
+
+	return STATUS_OK;		 
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GET_CAPACITY(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_GET_CAPACITY_T *prGetCapacity;
+	sd_select_enum sel;
+			
+	prGetCapacity = &(data->rSDGetCapacity);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	prGetCapacity->pu8Capacity = gSD_blk[sel].mCSD.capacity;
+	prGetCapacity->gHighCapacityCard = SD_FLAG_HCS_SUPPORT ? KAL_TRUE:KAL_FALSE;
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_EXISTENCE_T *prExistence;
+	sd_select_enum sel;
+/*this function differs to SD_CTRL_CMD_POLL_EXISTENCE, we only get status from global variables*/			
+	prExistence = &(data->rSDExistence);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	prExistence->fgPresent = MSDC_Blk[sel].mIsPresent;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_POLL_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+//	DCL_SDC_CMD_STATUS status;
+	SD_CTRL_EXISTENCE_T *prPollExistence;
+	sd_select_enum sel;
+
+	/*this function differs to SD_CTRL_CMD_IS_EXISTENCE, we will get card's status again*/
+
+	/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+	if (DCL_SD_HANDLE_SIMPLUS == handle){ 
+		ASSERT(0);
+	}
+#endif
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+		
+	prPollExistence = &(data->rSDExistence);
+	if (SD_MSDC1 == sel 
+#if defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		|| SD_T_CARD_2 == sel
+#endif
+		)
+	{
+		prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC0, MSDC_PS, sel);
+	}
+#if defined(__MSDC2_SD_MMC__)
+	if (SD_MSDC2 == sel){
+		prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC1, MSDC_PS2, sel);
+	}
+#endif
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_SET_CLEAR_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_EXISTENCE_T *prExistence;
+	sd_select_enum sel;
+
+	prExistence = &(data->rSDExistence);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	MSDC_Blk[sel].mIsPresent =(kal_bool)prExistence->fgPresent;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE_PROTECTION(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_WRITE_PROTECTION_T *prWP;
+	sd_select_enum sel;
+			
+	prWP = &(data->rSDWriteProrect);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	prWP->fgReadOnly = gSD_blk[sel].mWPEnabled;
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_QUERY_EVER_PLUGOUT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_QUERY_EVER_PLUGOUT_T *prQueryPlugOut;
+	sd_select_enum sel;
+
+	/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+	if(DCL_SD_HANDLE_SIMPLUS == handle){ 
+		ASSERT(0);
+	}
+#endif
+
+	prQueryPlugOut = &(data->rSDQueryEverPugOut);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	prQueryPlugOut->fgEverPLugOut = MSDC_Blk[sel].MSDC_everPlugOut;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_RESET_EVER_PLUGOUT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+//	DCL_SDC_CMD_STATUS status;
+	sd_select_enum sel;
+
+	/*everPLugOut is set true in hot plug interrupt and DCL provide function to set false*/
+
+	/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__			
+	if(DCL_SD_HANDLE_SIMPLUS == handle){ 
+		ASSERT(0);
+	}
+#endif
+			
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	MSDC_Blk[sel].MSDC_everPlugOut = KAL_FALSE;
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FORCE_SINGLE_LINE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_FORCE_SINGLE_LINE_T *prForceSingleLine;
+	sd_select_enum sel;
+
+	/*SIM_PLUS only runs in single line*/
+#ifdef __SIM_PLUS__
+	if(DCL_SD_HANDLE_SIMPLUS != handle){ 
+		ASSERT(0);
+	}
+#endif
+			
+	/*should add a assertion check for the MSDC that only support single line mode*/
+	prForceSingleLine = &(data->rSDForceSingleLine);
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	MSDC_Blk[sel].trySingleLine = (kal_bool)prForceSingleLine->fgIsItTrue;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GO_IDLE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	sd_select_enum sel;
+
+	/*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_CACHEABLE_BUFFER(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{	
+#ifdef MSDC_CACHED_SUPPORT
+	SD_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prCachedBuffer = &(data->rSDCacheableBuf);
+	MSDC_Blk[sel].isCachedBuf = prCachedBuffer->fgIsCACHEABLE;
+
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+#endif
+
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_SET_READ_FLAG(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{        
+			DCL_SDC_CMD_STATUS status; 
+			sd_select_enum sel;
+			SD_CTRL_SET_READ_TEST_FLAG_T *readFlag;
+			
+			readFlag =&(data->rSDSetReadTestFlag);
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			status = sdDriverTable[sel]->sdSetReadTestFlag(readFlag->readTestFlag);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return status;
+			
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_READ_TEST(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+			
+			DCL_SDC_CMD_STATUS status;  
+			sd_select_enum sel;
+			
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			msdcDriverTable[sel].modulePDN(KAL_FALSE);
+			status = sdDriverTable[sel]->sdSetReadTest();
+			msdcDriverTable[sel].modulePDN(KAL_TRUE);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return status;
+		
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_UPLL_CLOCK(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+			
+			DCL_SDC_CMD_STATUS status;  
+			sd_select_enum sel;
+			
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			//msdcDriverTable[sel].modulePDN(KAL_FALSE);
+			status = sdDriverTable[sel]->sdSetUpllClock();
+			//msdcDriverTable[sel].modulePDN(KAL_TRUE);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return status;
+		
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_CALLBACK(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{		
+			DCL_SDC_CMD_STATUS status;
+			SD_CTRL_CALLBACK_T *callBack;
+			sd_select_enum sel;
+			
+			callBack =&(data->rSDCallBackFunc);
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			status = sdDriverTable[sel]->sdSetCallBack(callBack->callback1,callBack->callback2,callBack->callback3,callBack->callback4,callBack->callback5,callBack->callback6);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return status;		 
+}
+DCL_STATUS DCL_SD_CTRL_API_FLUSH_SECTORS(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{		
+			DCL_SDC_CMD_STATUS status;
+			SD_CTRL_FLUSH_T *flush;
+			sd_select_enum sel;
+			
+			flush =&(data->rSDFlush);
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			status = sdDriverTable[sel]->eraseBlk(flush->startSector,flush->sectorNum);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return status;		 
+}
+DCL_STATUS DCL_SD_CTRL_API_GET_AND_CLEAR_MEDIA_CHANGED(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{		
+//			DCL_SDC_CMD_STATUS status;
+			SD_CTRL_MEDIA_CHANGED_T *changed;
+			sd_select_enum sel;
+
+			changed = &(data->rSDMediaChanged);
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			changed->changed = MSDC_GetMediaChanged(sel);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			return STATUS_OK;		 
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GPD_READ(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+    DCL_SDC_CMD_STATUS status=0;
+	SD_CTRL_GPD_READ_T *prRead;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+
+	prRead = &(data->rSDReadGPD);
+	status = DclSD_CtrlCmdGpdRead(sel, prRead);
+			
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+
+	return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_GPD_WRITE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+    DCL_SDC_CMD_STATUS status=0;
+	SD_CTRL_GPD_WRITE_T *prWrite;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prWrite = &(data->rSDWriteGPD);
+	status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+			
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+
+	return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_GET_BD_STRUCT_NUM(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SD_CTRL_MAX_BD_STRUCT_NUM_T *prNum;
+	sd_select_enum sel;
+
+	sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+	prNum = &(data->rSDMaxBD);
+	
+	prNum->max_bd_num=MSDC_BD_MAX;	
+	DCL_SD_USING_RESOURCE_END(handle,sel);
+    return STATUS_OK;
+}
+DCL_SD_CTRL_API	DclSD_APITbl[SD_CTRL_CMD_DUMMY_END - SD_CTRL_CMD_BASE] = 
+{
+	DCL_SD_CTRL_API_READ,
+	DCL_SD_CTRL_API_WRITE,
+	DCL_SD_CTRL_API_READ_ODD_SIZE,
+	DCL_SD_CTRL_API_WRITE_ODD_SIZE,
+	DCL_SD_CTRL_API_INIT,
+	DCL_SD_CTRL_API_IS_INITED,
+	DCL_SD_CTRL_API_ANALOG_SWITCH,
+	DCL_SD_CTRL_API_FAST_FORMAT_START,
+	DCL_SD_CTRL_API_FAST_FORMAT_STOP,
+	DCL_SD_CTRL_API_IS_FAST_FORMAT_RUNNING,
+	DCL_SD_CTRL_API_GET_CAPACITY,
+	DCL_SD_CTRL_API_IS_EXISTENCE,
+	DCL_SD_CTRL_API_POLL_EXISTENCE,
+	DCL_SD_CTRL_API_SET_CLEAR_EXISTENCE,
+	DCL_SD_CTRL_API_WRITE_PROTECTION,
+	DCL_SD_CTRL_API_QUERY_EVER_PLUGOUT,
+	DCL_SD_CTRL_API_RESET_EVER_PLUGOUT,
+	DCL_SD_CTRL_API_FORCE_SINGLE_LINE,
+	DCL_SD_CTRL_API_GO_IDLE,
+	DCL_SD_CTRL_API_CACHEABLE_BUFFER,
+	DCL_SD_CTRL_API_SET_CALLBACK,
+	DCL_SD_CTRL_API_SET_READ_FLAG,
+	DCL_SD_CTRL_API_SET_READ_TEST,
+	DCL_SD_CTRL_API_SET_UPLL_CLOCK,
+	DCL_SD_CTRL_API_FLUSH_SECTORS,
+	DCL_SD_CTRL_API_GET_AND_CLEAR_MEDIA_CHANGED,
+	DCL_SD_CTRL_API_GPD_READ,
+	DCL_SD_CTRL_API_GPD_WRITE,
+	DCL_SD_CTRL_API_GET_BD_STRUCT_NUM,
+};
+#endif
+
+// for debugging
+DCL_CTRL_CMD_T dcl_sd_cmd_start = SD_CTRL_CMD_BASE;
+DCL_CTRL_CMD_T dcl_sd_cmd_end = SD_CTRL_CMD_DUMMY_END;
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+#ifdef __MSDC_SD_MMC__
+
+	DCL_SDC_CMD_STATUS status = 0;
+
+  // Mark here because we use dclsd_open to take semaphore.
+  /*
+	//dispatch
+	if (SD_CTRL_CMD_DUMMY_END > cmd && SD_CTRL_CMD_BASE <= cmd){
+		if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle))
+				//kal_take_sem(dclMsdcArb[0], 1);
+				get_MSDC_lock(&dclMsdcLock[0]);
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+			else if (DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle))
+				//kal_take_sem(dclMsdcArb[1], 1);
+				get_MSDC_lock(&dclMsdcLock[1]);
+#endif
+		}
+  */
+
+		#if 0
+/* under construction !*/
+		#else
+		status = DclSD_APITbl[cmd - SD_CTRL_CMD_BASE](handle, cmd, data);
+		#endif
+
+    // Remove give semaphore, we move it to dclsd_close.
+    /*
+		if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle))
+				//kal_give_sem(dclMsdcArb[0]);
+				free_MSDC_lock(&dclMsdcLock[0]);
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+			else if (DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle))
+				//kal_give_sem(dclMsdcArb[1]);
+				free_MSDC_lock(&dclMsdcLock[1]);
+#endif
+		}
+		
+	}
+	else{
+		ASSERT(0);
+		status = STATUS_INVALID_CMD;
+	}
+    */
+
+	/*status central wrapper here, this is an inefficient but readable way*/
+	switch(status){
+		case NO_ERROR:
+			return STATUS_OK;
+			//break;			
+		case ERR_CMD_TIMEOUT:/*fall through*/
+			return STATUS_ERROR_TIMEOUT;
+			//break;
+		case ERR_DAT_CRCERR:
+    case ERR_CMD_RSPCRCERR:	
+			return STATUS_ERROR_CRCERROR;
+		//	break;			
+		case ERR_WRITE_PROTECT:
+			return STATUS_ERROR_READONLY;
+		//	break;
+		default:
+			//ASSERT(0);
+			return status;
+			//return STATUS_ERROR_WRONG_STATE;
+	//	break;
+	}
+	
+	/*should not arrive here*/
+	ASSERT(0);
+	return STATUS_FAIL;
+
+#endif//__MSDC_SD_MMC__
+}
+
+#else//DCL_MSDC_FUNTION_TABLE
+
+/*************************************************************************
+* FUNCTION
+*  DclSD_Control
+*
+* DESCRIPTION
+*  This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+*	handle - a valid handle return by DclGPIO_Open()
+*  cmd   - a control command for GPIO module
+*          1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+*          2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+*          3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+*          4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+*          5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+*          6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+*          7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+*          8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+*          9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+*          10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+*          11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+*          12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+*          13. GPIO_CMD_SET_TM_DIR: to set TM direction
+*  data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+*             2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+*             3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+*             4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+*             5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+*             6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+*             7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+*             8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+*             9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+*             10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+*             11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+*             12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+*             13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+*	STATUS_OK - command is executed successfully.
+*	STATUS_FAIL - command is failed.
+*  STATUS_INVALID_CMD - The command is invalid.
+*  STATUS_INVALID_HANDLE - The handle is invalid.
+*  STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SDC_CMD_STATUS status;
+
+	switch(cmd){
+		case SD_CTRL_CMD_READ:
+		{
+			SD_CTRL_READ_T *prRead;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prRead = &(data->rSDRead);
+			status = DclSD_CtrlCmdGpdRead(sel, prRead);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+		}
+		case SD_CTRL_CMD_WRITE:
+		{
+			SD_CTRL_WRITE_T *prWrite;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prWrite = &(data->rSDWrite);
+			status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+		}
+		case SD_CTRL_CMD_READ_ODD_SIZE:
+		{
+			SD_CTRL_READ_ODD_T *prRead;
+			sd_select_enum sel;
+
+			/*currently we only support on SD1, check it*/
+			if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+				ASSERT(0);
+			}
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prRead = &(data->rSDReadOdd);
+			status = DclSD_CtrlCmdReadOdd(sel, prRead);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+		}
+		case SD_CTRL_CMD_WRITE_ODD_SIZE:
+		{
+			SD_CTRL_WRITE_ODD_T *prWrite;
+			sd_select_enum sel;
+
+			/*currently we only support on SD1, check it*/
+			if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+				ASSERT(0);
+			}
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prWrite = &(data->rSDWriteOdd);
+			status = DclSD_CtrlCmdWriteOdd(sel, prWrite);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+		}
+		
+		case SD_CTRL_CMD_INIT:
+		{
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+				|| DCL_SD_HANDLE_SIMPLUS == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+#if defined(__MSDC2_SD_MMC__)
+				|| DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+				)
+			{
+				msdcDriverTable[sel].modulePDN(KAL_FALSE);
+				status = sdDriverTable[sel]->sdInititalize();
+				msdcDriverTable[sel].modulePDN(KAL_TRUE);
+			}
+			else{
+				ASSERT(0);
+			}
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+		}
+		case SD_CTRL_CMD_ANALOG_SWITCH:
+		{
+
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+			SD_CTRL_ANALOG_SWITCH_T *prSwitch;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prSwitch = &(data->rSDSwitch);
+			sel = prSwitch->u4TargetInterface;
+			MSDC_Switch_Card(sel);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			
+			status = NO_ERROR;
+#else
+			ASSERT(0);
+			status = STATUS_INVALID_CMD;
+#endif
+			break;
+		}
+		case SD_CTRL_CMD_FAST_FORMAT_START:
+		{
+			sd_select_enum sel;
+
+			/*currently we only support fast format on SD1, check it*/
+			if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+				ASSERT(0);
+			}
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			SD_startFastFormat();
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			status = NO_ERROR;
+			break;
+		}
+		case SD_CTRL_CMD_FAST_FORMAT_STOP:
+		{
+			sd_select_enum sel;
+
+			/*currently we only support fast format on SD1, check it*/
+			if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+				ASSERT(0);
+			}
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			SD_closeFastFormat();
+
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			status = NO_ERROR;
+			break;
+		}
+		case SD_CTRL_CMD_GET_CAPACITY:
+		{
+			SD_CTRL_GET_CAPACITY_T *prGetCapacity;
+			sd_select_enum sel;
+			
+			prGetCapacity = &(data->rSDGetCapacity);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			prGetCapacity->pu8Capacity = gSD_blk[sel].mCSD.capacity;
+			prGetCapacity->gHighCapacityCard = SD_FLAG_HCS_SUPPORT ? KAL_TRUE:KAL_FALSE;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_IS_EXISTENCE: /*this function differs to SD_CTRL_CMD_POLL_EXISTENCE, we only get status from global variables*/
+		{
+			SD_CTRL_EXISTENCE_T *prExistence;
+			sd_select_enum sel;
+			
+			prExistence = &(data->rSDExistence);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			prExistence->fgPresent = MSDC_Blk[sel].mIsPresent;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_POLL_EXISTENCE: /*this function differs to SD_CTRL_CMD_IS_EXISTENCE, we will get card's status again*/
+		{
+			SD_CTRL_EXISTENCE_T *prPollExistence;
+			sd_select_enum sel;
+
+			/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+			if(DCL_SD_HANDLE_SIMPLUS == handle){ 
+				ASSERT(0);
+			}
+#endif
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			
+			prPollExistence = &(data->rSDExistence);
+			if(SD_MSDC1 == sel 
+#if defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+				|| SD_T_CARD_2 == sel
+#endif
+				)
+			{
+				prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC0, MSDC_PS, sel);
+			}
+#if defined(DRV_MSDC_MT6238_SERIES)
+			if(SD_MSDC2 == sel){
+				prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC1, MSDC_PS2, sel);
+			}
+#endif
+
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_SET_CLEAR_EXISTENCE:
+		{
+			SD_CTRL_EXISTENCE_T *prExistence;
+			sd_select_enum sel;
+			
+			prExistence = &(data->rSDExistence);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].mIsPresent = prExistence->fgPresent;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_WRITE_PROTECTION:
+		{
+			SD_CTRL_WRITE_PROTECTION_T *prWP;
+			sd_select_enum sel;
+			
+			prWP = &(data->rSDWriteProrect);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			*(prWP->fgReadOnly) = gSD_blk[sel].mWPEnabled;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_QUERY_EVER_PLUGOUT:
+		{
+			SD_CTRL_QUERY_EVER_PLUGOUT_T *prQueryPlugOut;
+			sd_select_enum sel;
+
+			/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+			if(DCL_SD_HANDLE_SIMPLUS == handle){ 
+				ASSERT(0);
+			}
+#endif
+
+			prQueryPlugOut = &(data->rSDQueryEverPugOut);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			*(prQueryPlugOut->fgEverPLugOut) = gMSDC_Handle->MSDC_everPlugOut;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_RESET_EVER_PLUGOUT: /*everPLugOut is set true in hot plug interrupt and DCL provide function to set false*/
+		{
+			sd_select_enum sel;
+
+			/*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__			
+			if(DCL_SD_HANDLE_SIMPLUS == handle){ 
+				ASSERT(0);
+			}
+#endif
+			
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].MSDC_everPlugOut = KAL_FALSE;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_FORCE_SINGLE_LINE: /*this function can be the last way to bring up a card with lower throughput*/
+		{
+			SD_CTRL_FORCE_SINGLE_LINE_T *prForceSingleLine;
+			sd_select_enum sel;
+
+			/*SIM_PLUS only runs in single line*/
+#ifdef __SIM_PLUS__
+			if(DCL_SD_HANDLE_SIMPLUS != handle){ 
+				ASSERT(0);
+			}
+#endif
+			
+			/*should add a assertion check for the MSDC that only support single line mode*/
+			prForceSingleLine = &(data->rSDForceSingleLine);
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].trySingleLine = prForceSingleLine->fgIsItTrue;
+			status = STATUS_OK;
+			break;
+		}
+		case SD_CTRL_CMD_GO_IDLE: /*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+		{
+			sd_select_enum sel;
+
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+			status = STATUS_OK;
+			break;
+		}
+#ifdef MSDC_CACHED_SUPPORT
+		case SD_CTRL_CMD_CACHEABLE_BUFFER: /*This function is to notify that we will operate on a cacheable buffer*/
+		{
+			SD_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prCachedBuffer = &(data->rSDCacheableBuf);
+			MSDC_Blk[sel].isCachedBuf = prCachedBuffer->fgIsCACHEABLE;
+
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			status = STATUS_OK;
+			break;
+		}
+#endif
+        case SD_CTRL_CMD_FLUSH: 
+        {
+            DCL_SDC_CMD_STATUS status;
+			SD_CTRL_FLUSH_T *flush;
+			sd_select_enum sel;
+			
+			flush =&(data->rSDFlush);
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			status = sdDriverTable[sel]->eraseBlk(flush->startSector,flush->sectorNum);
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;	
+        }
+        case SD_CTRL_CMD_GPD_READ:
+            SD_CTRL_GPD_READ_T *prRead;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prRead = &(data->rSDRead);
+			status = DclSD_CtrlCmdGpdRead(sel, prRead);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+        case SD_CTRL_CMD_GPD_WRITE:
+            SD_CTRL_GPD_WRITE_T *prWrite;
+			sd_select_enum sel;
+
+			sel=DCL_SD_USING_RESOURCE_START(handle);
+			
+			prWrite = &(data->rSDWrite);
+			status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+			
+			DCL_SD_USING_RESOURCE_END(handle,sel);
+			break;
+        case SD_CTRL_CMD_GET_BD_STRUCT_NUM:
+            SD_CTRL_MAX_BD_STRUCT_NUM_T *prNum;
+        	sd_select_enum sel;
+
+        	sel=DCL_SD_USING_RESOURCE_START(handle);
+        			
+        	prNum = &(data->rSDMaxBD);
+        	
+        	prNum->max_bd_num=MSDC_BD_MAX;	
+        	DCL_SD_USING_RESOURCE_END(handle,sel);
+            break;
+		default:
+			ASSERT(0);
+			status = STATUS_INVALID_CMD;
+			break;
+	}
+
+	/*status central wrapper here, this is an inefficient but readable way*/
+	switch(status){
+		case NO_ERROR:
+			return STATUS_OK;
+			break;			
+		case ERR_CMD_TIMEOUT:/*fall through*/
+		case MSDC_GPT_TIMEOUT_ERR:
+			return STATUS_ERROR_TIMEOUT;
+			break;
+		case ERR_DAT_CRCERR:
+			return STATUS_ERROR_CRCERROR;
+			break;			
+		case ERR_WRITE_PROTECT:
+			return STATUS_ERROR_READONLY;
+			break;
+		case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+		case STATUS_INVALID_CTRL_DATA:
+			return status;
+			break;
+		default:
+			ASSERT(0);
+			return STATUS_FAIL;
+		break;
+	}
+	
+	/*should not arrive here*/
+	ASSERT(0);
+	return STATUS_FAIL;
+}
+
+#endif//DCL_MSDC_FUNTION_TABLE
+
+DCL_STATUS DclSD_Close(DCL_HANDLE handle)
+{
+	sd_select_enum sel;
+
+	sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+	/*check whether it is action handle, if not, return directly*/
+	if(0 == DCL_SD_GET_MAGIC_FROM_HANDLE(handle)){
+		return STATUS_OK;
+	}
+	else{
+		kal_uint16	magic;
+		//jinxing remove this . since we never do free later.
+		//DCL_SD_USING_RESOURCE_START(handle);
+		/*after this point, we think that none should be able to use this action handle*/
+		
+		/*process the magic of the resource*/
+		magic = (sdResource[sel] & DCL_SD_RESOURCE_MAGIC_MAX);
+		if(DCL_SD_RESOURCE_MAGIC_MAX == magic){ /*if means 0x0FF0 achieved*/
+			magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+		}
+		else{
+			magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+		}
+		sdResource[sel] = magic;
+
+		//
+		// To make a pair of taking and giving semaphore, add back the following action.
+		//
+		free_MSDC_lock(&dclMsdcLock[sel]);
+		/*
+		if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+			kal_give_sem(dclMsdcArb[sel]);
+		*/
+
+		return STATUS_OK;
+	}		
+}
+
+/***************************************************************************************
+followings are DCL SDIO API exported 
+*****************************************************************************************/
+
+
+/**************************************************************************
+followings are DCL API exported 
+***************************************************************************/
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to initialize the SD driver related resource. 
+*	This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+#if defined(__MSDC_SD_SDIO__)
+extern SDIODriver_t sdio_driver_MTK1;//guilin
+DCL_STATUS DclSDIO_Initialize(void)
+{
+	kal_uint32	maskedValue;
+
+	maskedValue = SaveAndSetIRQMask();
+	/*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+	if(KAL_FALSE == fgMSDCInit){
+		fgMSDCInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		DclMSDC_init();
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+
+	maskedValue = SaveAndSetIRQMask();
+	if(KAL_FALSE == fgSDIOInit){
+		fgSDIOInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		/*init SD driver tables, there are too many entries in SD driver, so we hook it by pointer*/
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)		
+		sdioDriverTable[DCL_SDIO_GET_SEL_FROM_HANDLE(DCL_SDIO_HANDLE_SDIO1)] = &sdio_driver_MTK1;
+#endif
+
+#if defined(__MSDC2_SD_SDIO__)
+		sdioDriverTable[DCL_SDIO_GET_SEL_FROM_HANDLE(DCL_SDIO_HANDLE_SDIO2)] = &sdio_driver_MTK2; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+	
+	return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to get SD DCL handler.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_HANDLE DclSDIO_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+	kal_uint32 retAddr = 0;
+	kal_uint32 thdId;	
+
+	if (dev != DCL_SDIO)
+	{
+		ASSERT(0);
+		return DCL_HANDLE_INVALID;
+	}
+    
+    GET_RETURN_ADDRESS(retAddr);
+
+	thdId = (kal_uint32)kal_get_current_thread_ID();
+
+	//drv_trace4(TRACE_GROUP_8, MSDC_DCL_SD_OPEN, flags, retAddr, thdId , drv_get_current_time());
+
+	if(flags & DCL_SDIO_FLAGS_SDIO1){
+		if(DCL_SDIO_FLAGS_SDIO1 != (flags & DCL_SDIO_FLAGS_ALL)){
+			ASSERT(0);
+		}
+		get_MSDC_lock(&dclMsdcLock[0]);
+		return DCL_SDIO_HANDLE_SDIO1;
+	}
+#if defined(__MSDC2_SD_SDIO__)
+	else if(flags & DCL_SDIO_FLAGS_SDIO2){
+		if(DCL_SDIO_FLAGS_SDIO2 != (flags & DCL_SDIO_FLAGS_ALL)){
+			ASSERT(0);
+		}
+		get_MSDC_lock(&dclMsdcLock[1]);
+		return DCL_SDIO_HANDLE_SDIO2;
+	}
+#endif
+}
+
+DCL_STATUS DclSDIO_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	DCL_SD_IMPLEMENTATION_ASSERT;
+	return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	//DCL_SD_IMPLEMENTATION_ASSERT;
+	//ASSERT(0);
+	//return 	STATUS_UNSUPPORTED;
+	// guilin
+    sd_select_enum sel;
+    
+    sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+    sdioDriverTable[sel]->hisr_callback(DCL_SDIO_FUCN_0, callback);
+    sdioDriverTable[sel]->hisr_callback(DCL_SDIO_FUCN_1, callback);
+
+    return STATUS_OK;
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+*  DclGPIO_Control
+*
+* DESCRIPTION
+*  This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+*	handle - a valid handle return by DclGPIO_Open()
+*  cmd   - a control command for GPIO module
+*          1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+*          2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+*          3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+*          4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+*          5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+*          6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+*          7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+*          8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+*          9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+*          10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+*          11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+*          12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+*          13. GPIO_CMD_SET_TM_DIR: to set TM direction
+*  data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+*             2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+*             3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+*             4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+*             5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+*             6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+*             7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+*             8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+*             9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+*             10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+*             11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+*             12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+*             13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+*	STATUS_OK - command is executed successfully.
+*	STATUS_FAIL - command is failed.
+*  STATUS_INVALID_CMD - The command is invalid.
+*  STATUS_INVALID_HANDLE - The handle is invalid.
+*  STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclSDIO_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_BOOL status;/*in the world of SDIO driver, the return value is either trur or false*/
+    sd_select_enum sel;
+
+    sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+    msdcDriverTable[sel].modulePDN(KAL_FALSE);
+	
+	switch(cmd){
+		case SDIO_CTRL_CMD_REG_WR:
+		{
+			SDIO_CTRL_REG_RW_T *prRegWr;
+
+			prRegWr = &data->rSDIORegRw;
+			status = sdioDriverTable[sel]->regWr(prRegWr->function, prRegWr->addr, prRegWr->data, prRegWr->op);
+			break;
+		}
+		case SDIO_CTRL_CMD_REG_WR_ISR:
+		{
+			SDIO_CTRL_REG_RW_T *prRegWrIsr;
+
+			prRegWrIsr = &data->rSDIORegRw;
+			status = sdioDriverTable[sel]->regWrInIsr(prRegWrIsr->function, prRegWrIsr->addr, prRegWrIsr->data, prRegWrIsr->op);
+			break;
+		}
+		case SDIO_CTRL_CMD_DATA_WR:
+		{
+			SDIO_CTRL_DAT_RW_T *prDatWr;
+
+			prDatWr = &data->rSDIODatRw;
+			status = sdioDriverTable[sel]->dataWr(prDatWr->function, prDatWr->addr, (DCL_UINT8  *)prDatWr->buffer, prDatWr->op, prDatWr->count, prDatWr->block);
+			break;
+		}
+		case SDIO_CTRL_CMD_REG_RD:
+		{
+			SDIO_CTRL_REG_RW_T *prRegRd;
+
+			prRegRd = &data->rSDIORegRw;
+			status = sdioDriverTable[sel]->regRd(prRegRd->function, prRegRd->addr, &prRegRd->data, prRegRd->op);
+			break;			
+		}
+		case SDIO_CTRL_CMD_DATA_RD:
+		{
+			SDIO_CTRL_DAT_RW_T *prDatRd;
+
+			prDatRd = &data->rSDIODatRw;
+			status = sdioDriverTable[sel]->dataRd(prDatRd->function, prDatRd->addr, (DCL_UINT8  *)prDatRd->buffer, prDatRd->op, prDatRd->count, prDatRd->block);
+			break;
+		}
+		case SDIO_CTRL_CMD_CHECK_INTR:
+		{
+			SDIO_CTRL_CHECK_INTR_T *prCheckIntr;
+
+			prCheckIntr = &data->rSDIOCheckIntr;
+			status = sdioDriverTable[sel]->checkIntr(prCheckIntr->function, prCheckIntr->pending);
+			break;
+		}
+		case SDIO_CTRL_CMD_ENABLE_INTR:
+		{
+			SDIO_CTRL_ENABLE_T *prEnableIntr;
+
+			prEnableIntr = &data->rSDIOEnable;
+			status = sdioDriverTable[sel]->enableIntr(prEnableIntr->function, prEnableIntr->enable);
+			break;
+		}
+		case SDIO_CTRL_CMD_INIT:
+		{
+			status = sdioDriverTable[sel]->sdioInititalize();
+			break;
+		}
+		case SDIO_CTRL_CMD_ABORT:
+		{
+			DCL_SDIO_function_id_enum function;
+
+			function = data->rSDIOFunction;
+			status = sdioDriverTable[sel]->abort(function);
+			break;
+		}
+		case SDIO_CTRL_CMD_SW_RST:
+		{
+			status = sdioDriverTable[sel]->swRst();
+			break;
+		}
+		case SDIO_CTRL_CMD_QUERY_BLK_SIZE:
+		{
+			DCL_SDIO_function_id_enum function;
+
+			function = data->rSDIOFunction;
+			status = sdioDriverTable[sel]->qryBlkSize(function);
+			break;
+		}
+		case SDIO_CTRL_CMD_SET_BLK_SIZE:
+		{
+			SDIO_CTRL_SET_BLK_SIZE_T *prSetBlkSize;
+
+			prSetBlkSize = &data->rSDIOSetBlkSize;
+			status = sdioDriverTable[sel]->setBlkSize(prSetBlkSize->function, prSetBlkSize->size);
+			break;
+		}
+		case SDIO_CTRL_CMD_ENABLE_IO:
+		{
+			SDIO_CTRL_ENABLE_T *prEnableIO;
+
+			prEnableIO = &data->rSDIOEnable;
+			status = sdioDriverTable[sel]->enableIO(prEnableIO->function, prEnableIO->enable);
+			break;
+		}
+		case SDIO_CTRL_CMD_SET_BUS_WIDTH:
+		{
+			DCL_SD_BITWIDTH busWidth;
+
+			busWidth = data->rSDIOBusWidth;
+			status = sdioDriverTable[sel]->setBusWidth(busWidth);
+			break;
+		}
+        //---------------------------------------------------------------------
+        case SDIO_CTRL_CMD_CMD52_READ:
+            {
+                SDIO_CTRL_CMD52_T *prCMD52;
+                
+                prCMD52 = &data->rSDIOCMD52;
+                status = sdioDriverTable[sel]->cmd52_read(prCMD52->func, prCMD52->addr, &prCMD52->rdata, &prCMD52->r5_resp);
+                break;
+            }
+        case SDIO_CTRL_CMD_CMD52_WRITE:
+            {
+                SDIO_CTRL_CMD52_T *prCMD52;
+                
+                prCMD52 = &data->rSDIOCMD52;
+                status = sdioDriverTable[sel]->cmd52_write(prCMD52->func, prCMD52->addr, prCMD52->wdata, &prCMD52->r5_resp);
+                break;
+            }
+        case SDIO_CTRL_CMD_CMD52_WRITE_READ:
+            {
+                SDIO_CTRL_CMD52_T *prCMD52;
+                sd_select_enum sel;
+                
+                prCMD52 = &data->rSDIOCMD52;
+                sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+                status = sdioDriverTable[sel]->cmd52_write_read(prCMD52->func, prCMD52->addr, prCMD52->wdata, &prCMD52->rdata, &prCMD52->r5_resp);
+                break;
+            }
+        case SDIO_CTRL_CMD_CMD53_READ:
+            {
+                SDIO_CTRL_CMD53_T *prCMD53;
+                
+                prCMD53 = &data->rSDIOCMD53;
+                status = sdioDriverTable[sel]->cmd53_read(prCMD53->func, prCMD53->addr, prCMD53->buffer, prCMD53->op, prCMD53->count, prCMD53->block, &prCMD53->r5_resp);
+                break;
+            }
+        case SDIO_CTRL_CMD_CMD53_WRITE:
+            {
+                SDIO_CTRL_CMD53_T *prCMD53;
+                
+                prCMD53 = &data->rSDIOCMD53;
+                status = sdioDriverTable[sel]->cmd53_write(prCMD53->func, prCMD53->addr, prCMD53->buffer, prCMD53->op, prCMD53->count, prCMD53->block, &prCMD53->r5_resp);
+                break;
+            }
+        case SDIO_CTRL_CMD_MCUDMA_READ:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->mcudma_read(&prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_MCUDMA_WRITE:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->mcudma_write(prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_CLKPADRED_READ:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->clkpadred_read(&prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_CLKPADRED_WRITE:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->clkpadred_write(prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_FORCEMCU_READ:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->forcemcu_read(&prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_FORCEMCU_WRITE:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->forcemcu_write(prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_GETCLK:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->getclk(&prCMDREG->data);
+                break;                
+            }
+        case SDIO_CTRL_CMD_SETCLK:
+            {
+                SDIO_CTRL_CMD_REG_T *prCMDREG;
+                
+                prCMDREG = &data->rSDIOCMDREG;
+                status = sdioDriverTable[sel]->setclk(prCMDREG->data);
+                break;                
+            }
+		case SDIO_CTRL_CMD_GET_BLK_SIZE:
+		{
+			SDIO_CTRL_SET_BLK_SIZE_T *prSetBlkSize;
+
+			prSetBlkSize = &data->rSDIOSetBlkSize;
+			status = sdioDriverTable[sel]->getBlkSize(prSetBlkSize->function, &prSetBlkSize->size);
+			break;
+		}
+        //---------------------------------------------------------------------
+		default:
+			ASSERT(0);
+			status = STATUS_INVALID_CMD;
+			break;
+	}
+    msdcDriverTable[sel].modulePDN(KAL_TRUE);
+    kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d status=%d",__FUNCTION__,__LINE__,(cmd - SDIO_CTRL_CMD_REG_WR),status);//guilin
+	/*status central wrapper here, this is an inefficient but readable way*/
+	switch(status){
+		case NO_ERROR:
+			return STATUS_OK;
+		//	break;			
+		case ERR_CMD_TIMEOUT:/*fall through*/
+		case MSDC_GPT_TIMEOUT_ERR:
+			return STATUS_ERROR_TIMEOUT;
+		//	break;
+		case ERR_DAT_CRCERR:
+			return STATUS_ERROR_CRCERROR;
+		//	break;			
+		case ERR_WRITE_PROTECT:
+			return STATUS_ERROR_READONLY;
+		//	break;
+		case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+		case STATUS_INVALID_CTRL_DATA:
+			return status;
+		//	break;
+		default:
+			//ASSERT(0);
+			return STATUS_FAIL;
+		break;
+	}
+	
+	/*should not arrive here*/
+	ASSERT(0);
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Close(DCL_HANDLE handle)
+{
+//	DCL_SD_IMPLEMENTATION_ASSERT;
+//	return STATUS_UNSUPPORTED;
+
+    sd_select_enum sel;
+
+    sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+    free_MSDC_lock(&dclMsdcLock[sel]);
+
+    return STATUS_OK;
+}
+#endif
+/****************************************************************************************************
+*	followings are functions used by DCL MS API, these functions can only be called in this file.
+******************************************************************************************************/
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+static DCL_STATUS DclMS_CtrlCmdRead(sd_select_enum sel, SD_CTRL_READ_T *prRead)
+{
+#if defined(__MSDC_MSPRO__)
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	DCL_MSP_STATUS status;
+	DCL_UINT32	u4Sector; //this specify the starting sector to read
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to read
+	void			*bufferAddr; //we will move move data from card to this address
+	MSDriver_t	*msDriver;
+	
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prRead->u4Sector;
+	u4Sectors = prRead->u4Sectors;
+	bufferAddr = prRead->bufferAddr;
+	msDriver = msDriverTable[sel];
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	
+	if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+		kal_uint16 read;
+		
+		maxBlk = gMSP.user_block*gMSP.block_size;
+	
+		/*sectors & sector check*/
+		if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector > maxBlk){
+			ASSERT(0);
+			status = STATUS_INVALID_CTRL_DATA;
+			return status;
+		}
+
+		/*check that ending block should be smaller than maximum block number*/
+		if((u4Sector + u4Sectors - 1) > maxBlk){
+			ASSERT(0);
+			status = STATUS_INVALID_CTRL_DATA;
+			return status;
+		}
+	
+		/*power on MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+		
+		status = msDriver->mspRdWrData(u4Sector, u4Sectors, bufferAddr, &read, MSP_READ);
+		
+		/*power down MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+	}
+	else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+		/*followings are the local variables related to MS, since we have to calculate physical block in MS*/
+		kal_uint8 PagesPerBlk,page,readpage,len,*ptr, extra[4];
+		kal_uint32 lba,pba;
+		
+		/*Capacity information is stored in MBR in MS so we don't do capacity check*/
+		
+		gMS.is_write = KAL_FALSE;
+		PagesPerBlk = gMS.PagesPerBlk;
+		lba = u4Sector/PagesPerBlk; //calculate in which Blk does the starting sector locate
+		page = u4Sector%PagesPerBlk;//calculate with how many offset of page does the starting sector locate
+		ptr = (kal_uint8*) bufferAddr;
+		
+		/*power on MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+		
+		while(1)
+		{
+			/*if all ofo the sectors wanna read reside in the same blk, we read them in ms readBlock; otherwise read them separately*/
+			if(PagesPerBlk - page < u4Sectors)
+				len = PagesPerBlk - page;
+			else
+				len = u4Sectors;
+			
+			ASSERT(len >= 1 && len <= 32);
+			
+			status = msDriver->msLogToPhy(gMS.pLPTbl, lba, &pba);
+			if(status != MS_NOERROR)
+				return status;//return FS_MSDC_READ_SECTOR_ERROR;
+			if(len == 1){
+				status = msDriver->msRdSinglePage(pba, page, (kal_uint32*)ptr, NULL);
+			}
+			else{
+				status = msDriver->msRdBlk(pba, (kal_uint32*)ptr, NULL, page, len, &readpage);
+			}
+			if(status != MS_NOERROR)
+				return status;//return FS_MSDC_READ_SECTOR_ERROR;
+
+			/*following part comes from M2 compliant test*/
+			//============ change the update status ====================//
+			status = msDriver->msRdExtraData(pba, 0, (kal_uint32*)extra);
+		    	if(MS_UPDATE_STATUS(extra[OVERWRITE_FLAG]) == 0)
+    			{
+    				kal_uint32 i;
+	    			kal_uint16 *FreeTable, *LPTable, spareblk;
+	    			kal_uint8  readpage;
+				// find a unused block from FreeTable, erase it and write updated info into it
+
+				LPTable = gMS.pLPTbl;
+				FreeTable = gMS.pFreeTbl;			
+				i = 0;
+				
+				/*find an i that satisfys FreeTable[i] != 0xFFFF*/
+				while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE));
+				
+				spareblk = FreeTable[i-1];
+				status = msDriver->msRdBlk(pba,(kal_uint32*)u4ms16KBuffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage);
+				extra[0] |= MS_OVFLG_UDST;
+				status = msDriver->msWrExtraData(spareblk, 0, (kal_uint32 *)extra);
+				status = msDriver->msWrBlk(spareblk,(kal_uint32*)u4ms16KBuffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage);
+				status = msDriver->msEraseBlk(pba);
+				// update the LPTable and FreeTable
+				LPTable[MS_GetLPIndex(lba)] = spareblk;
+				FreeTable[i-1] = pba;    		
+    			}
+			//================================//
+			
+			u4Sectors -= len;
+			if(u4Sectors == 0)
+				break;
+			page = 0;
+			ptr += 	MS_PAGE_SIZE*len;
+			lba++;	
+		}
+
+		/*power down MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+	}
+	else{/*neither MSPro nor MS*/
+		ASSERT(0);
+	}
+#else
+	/*if  __MSDC_MSPRO__ is undefined, it is impossible to support read*/
+	ASSERT(0);
+	return STATUS_UNSUPPORTED;
+#endif
+}
+
+static DCL_STATUS DclMS_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_READ_T *prWrite)
+{
+#if defined(__MSDC_MSPRO__)
+	DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+	SDC_CMD_STATUS status;
+	DCL_UINT32	u4Sector; //this specify the starting sector to Write
+	DCL_UINT32	u4Sectors; //this specify the number of sectors to Write
+	void			*bufferAddr; //we will move move data from this address to the card
+	MSDriver_t	*msDriver;
+
+	/*parameters in prRead should not be changed, take these as local variable*/
+	u4Sector = prWrite->u4Sector;
+	u4Sectors = prWrite->u4Sectors;
+	bufferAddr = prWrite->bufferAddr;
+	msDriver = msDriverTable[sel];
+
+	/*requirement check here*/
+	if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+		ASSERT(0);
+		status = STATUS_ERROR_WRONG_STATE;
+		return status;
+	}
+
+	if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+		kal_uint16 write;
+		
+		maxBlk = gMSP.user_block*gMSP.block_size;
+	
+		/*sectors & sector check*/
+		if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector > maxBlk){
+			ASSERT(0);
+			status = STATUS_INVALID_CTRL_DATA;
+			return status;
+		}
+
+		/*check that ending block should be smaller than maximum block number*/
+		if((u4Sector + u4Sectors - 1) > maxBlk){
+			ASSERT(0);
+			status = STATUS_INVALID_CTRL_DATA;
+			return status;
+		}
+	
+		/*power on MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+		
+		status = msDriver->mspRdWrData(u4Sector, u4Sectors, bufferAddr, &write, MSP_WRITE);
+		
+		/*power down MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+	}
+	else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+		/*followings are the local variables related to MS, since we have to calculate physical block in MS*/
+		kal_uint32 lba, pba, i, spareblk;
+		kal_uint8 *p = NULL, *ptr;
+		kal_uint8 PagesPerBlk, page, pages, extra[4], owflag, len;
+		kal_uint16 *LPTable, *FreeTable;
+
+
+		/*Capacity information is stored in MBR in MS so we don't do capacity check*/
+		
+		gMS.is_write = KAL_TRUE;
+		LPTable = gMS.pLPTbl;
+		FreeTable = gMS.pFreeTbl;
+		PagesPerBlk = gMS.PagesPerBlk;
+		lba = u4Sector/PagesPerBlk; //calculate in which Blk does the starting sector locate
+		len = page = u4Sector%PagesPerBlk;//calculate with how many offset of page does the starting sector locate
+		ptr = (kal_uint8*) bufferAddr;
+		p = (kal_uint8 * )u4ms16KBuffer;
+
+
+		/*power on MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+		
+		while(1)
+		{
+			if(PagesPerBlk - page < u4Sectors){
+				len = PagesPerBlk - page;
+			}
+			else{
+				len = u4Sectors;
+			}
+			ASSERT(len >= 1 && len <= 32);
+			status = msDriver->msLogToPhy(LPTable, lba, &pba);
+			if(status != MS_NOERROR)
+				return status;
+
+			// set update status to 0
+			status = msDriver->msRdExtraData(pba, 0, (kal_uint32 *)extra);
+			owflag = extra[0];
+			extra[0] &= ~MS_OVFLG_UDST;
+			status = msDriver->msWrOverWriteFlag(pba, 0, extra[0]);
+		
+			// read the entire block
+			status = msDriver->msRdBlk(pba, (kal_uint32*)p, (kal_uint32 *)extra, 0, PagesPerBlk, &pages);
+			if(status != MS_NOERROR)
+			{
+				return status;
+			}
+			if(gMS.uc_pages != 0)
+			{
+				status = msDriver->msLogToPhy(LPTable, lba, &pba);
+				status = msDriver->msRdExtraData(pba, 0, (kal_uint32 *)extra);
+				owflag = extra[0];
+				extra[0] &= ~MS_OVFLG_UDST;
+				status = msDriver->msWrExtraData(pba, 0, (kal_uint32 *)extra);
+			}
+			// update the page in the memory
+			kal_mem_cpy((kal_uint8*)(p+page*MS_PAGE_SIZE), (kal_uint8*)ptr, MS_PAGE_SIZE*len);
+			// find a unused block from FreeTable, erase it and write updated info into it
+			i = 0;
+			while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE));
+			spareblk = FreeTable[i-1];
+			status = msDriver->msEraseBlk(spareblk);
+			if(status != MS_NOERROR)
+				return status;
+			extra[0] = (owflag|MS_OVFLG_UDST);
+			status = msDriver->msWrBlk(spareblk, (kal_uint32*)p, (kal_uint32*)extra, 0, PagesPerBlk, &pages);
+			if(status != MS_NOERROR)
+				return status;
+			// update the LPTable and FreeTable
+			LPTable[MS_GetLPIndex(lba)] = spareblk;
+			FreeTable[i-1] = pba;
+			// erase original block
+			status = msDriver->msEraseBlk(pba);
+			if(status != MS_NOERROR)
+				return status;
+			if(gMS.uc_pages || gMS.de_pages)
+			{
+				kal_uint32 pages;
+				if(gMS.uc_pages)
+					pages = gMS.uc_pages;
+				else
+					pages = gMS.de_pages;
+				for(i=0;i<32;i++)
+				{
+					if(pages & (1<<i))
+					{
+						status = msDriver->msRdExtraData(spareblk, i, (kal_uint32 *)extra);
+						extra[0] &= ~MS_OVFLG_PGST;
+						status = msDriver->msWrExtraData(spareblk, i, (kal_uint32 *)extra);
+					}
+				}
+			}
+			status = msDriver->msRdExtraData(spareblk, 0x18, (kal_uint32 *)extra);
+			u4Sectors -= len;
+			if(u4Sectors == 0) break;
+			ptr += 	MS_PAGE_SIZE*len;		
+			page = 0;
+			lba++;			
+		}
+		/*power down MSDC module*/
+		msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+	}
+	else{/*neither MSPro nor MS*/
+		ASSERT(0);
+	}
+#else
+	/*if  __MSDC_MSPRO__ is undefined, it is impossible to support write*/
+	ASSERT(0);
+	return STATUS_UNSUPPORTED;
+#endif	
+}
+
+
+/***************************************************************************************
+followings are DCL MSPro API exported 
+*****************************************************************************************/
+
+
+/***************************************************************************************
+followings are DCL SD API exported 
+*****************************************************************************************/
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to initialize the SD driver related resource.
+*	This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_STATUS DclMS_Initialize(void)
+{
+	DCL_UINT32 msdcSupport;
+	kal_uint32	maskedValue;
+
+	maskedValue = SaveAndSetIRQMask();	
+	/*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+	if(KAL_FALSE == fgMSDCInit){
+		fgMSDCInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		DclMSDC_init();
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+
+	maskedValue = SaveAndSetIRQMask();
+	if(KAL_FALSE == fgMSInit){
+		RestoreIRQMask(maskedValue);
+		fgMSInit = KAL_TRUE;
+		/*
+			Init MS driver tables, there are too many entries in MS driver, so we hook it by pointer.
+			Notes that we don't have MSPro 2 driver that can run synchronously with MSPro, both uses the same driver.
+			We use a global variable and compile option for this.
+		*/
+#if defined(__MSDC_MSPRO__)	
+		msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(DCL_MS_HANDLE)] = &ms_driver_MTK1;
+#endif
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+	
+	return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to get MS DCL handler.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_HANDLE DclMS_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+	if (dev != DCL_MS)
+	{
+		ASSERT(0);
+		return DCL_HANDLE_INVALID;
+	}
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	DCL_SD_IMPLEMENTATION_ASSERT;
+	return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+*  DclGPIO_Control
+*
+* DESCRIPTION
+*  This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+*	handle - a valid handle return by DclGPIO_Open()
+*  cmd   - a control command for GPIO module
+*          1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+*          2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+*          3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+*          4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+*          5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+*          6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+*          7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+*          8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+*          9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+*          10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+*          11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+*          12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+*          13. GPIO_CMD_SET_TM_DIR: to set TM direction
+*  data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+*             2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+*             3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+*             4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+*             5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+*             6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+*             7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+*             8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+*             9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+*             10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+*             11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+*             12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+*             13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+*	STATUS_OK - command is executed successfully.
+*	STATUS_FAIL - command is failed.
+*  STATUS_INVALID_CMD - The command is invalid.
+*  STATUS_INVALID_HANDLE - The handle is invalid.
+*  STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclMS_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+#if defined(__MSDC_MSPRO__)
+	MSP_STATUS status;	
+	
+	switch(cmd){
+		case MS_CTRL_CMD_READ:
+		{
+			MS_CTRL_READ_T *prRead;
+			sd_select_enum sel;
+
+			prRead = &data->rSDRead;
+			sel = DCL_MS_GET_SEL_FROM_HANDLE(handle);	
+
+			status = DclMS_CtrlCmdRead(sel, prRead);
+			break;
+		}
+		case MS_CTRL_CMD_WRITE:
+		{
+			MS_CTRL_WRITE_T *prWrite;
+			sd_select_enum sel;
+
+			prWrite = &data->rSDWrite;
+			sel = DCL_MS_GET_SEL_FROM_HANDLE(handle);	
+
+			status = DclMS_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_READ_T * prWrite);
+			break;
+		}
+		case MS_CTRL_CMD_INIT:
+		{
+			if(DCL_MS_HANDLE == handle){
+				status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].mspInit();
+			}
+			else{
+				ASSERT(0);
+			}
+			break;
+		}
+		case MS_CTRL_CMD_FORMAT:
+		{			
+			if(DCL_MS_HANDLE != handle){
+				ASSERT(0);
+			}
+
+			if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+				status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].mspFormat(MSP_FULL, NULL);
+			}
+			else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+				status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].msFormat();
+			}
+			else{
+				ASSERT(0);
+				status = STATUS_ERROR_WRONG_STATE;
+			}
+			
+			break;
+		}
+		case MS_CTRL_CMD_GET_CAPACITY:
+		{
+			MS_CTRL_GET_CAPACITY_T *prGetCapacity;
+			DCL_UINT32* pMBR;
+			
+			prGetCapacity = &data->rMSGetCapacity;
+			if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+				*(prGetCapacity->pu8Capacity) = gMSP.user_block * gMSP.block_size;
+			}
+			else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+				int i = 0;
+				kal_uint8 c = gMS.Capacity;
+
+				// get index for MS_MBR
+				while((c >>= 1) != 2)
+					i++;
+				pMBR = MS_MBR[i];
+				/*byte 12~ byte 15 (start from byte 0) records device's capacity in MBR*/
+				*(prGetCapacity->pu8Capacity) = *(DCL_UINT32 *)(pMBR+3);
+			}
+			else{
+				ASSERT(0);
+				status = STATUS_ERROR_WRONG_STATE;
+			}
+			
+			break;
+		}
+		case MS_CTRL_CMD_EXISTENCE: /*this function differs to MS_CTRL_CMD_EXISTENCE, we only get status from global variables*/
+		{
+			MS_CTRL_EXISTENCE_T *prExistence;
+			sd_select_enum sel;
+			
+			prExistence = &data->rMSExist;
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			*(prExistence->fgPresent) = MSDC_Blk[sel].mIsPresent;
+			break;
+		}
+		case MS_CTRL_CMD_GO_IDLE: /*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+		{
+			sd_select_enum sel;
+
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+			break;
+		}
+		case MS_CTRL_CMD_CACHEABLE_BUFFER: /*This function is to notify that we will operate on a cacheable buffer*/
+		{
+			MS_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+			sd_select_enum sel;
+
+			prCachedBuffer = &data->rMSCacheableBuf;
+			sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+			MSDC_Blk[sel].mIsInitializedmIsInitialized = prCachedBuffer->fgIsCACHEABLE;
+			break;
+		}
+		default:
+			ASSERT(0);
+			status = STATUS_INVALID_CMD;
+			break;
+	}
+
+	/*status central wrapper here, this is an inefficient but readable way*/
+	switch(status){
+		case NO_ERROR:
+			return STATUS_OK;
+			break;			
+		case ERR_CMD_TIMEOUT:/*fall through*/
+		case MSDC_GPT_TIMEOUT_ERR:
+			return STATUS_ERROR_TIMEOUT;
+			break;
+		case ERR_DAT_CRCERR:
+			return STATUS_ERROR_CRCERROR;
+			break;			
+		case ERR_WRITE_PROTECT:
+			return STATUS_ERROR_READONLY;
+			break;
+		case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+		case STATUS_INVALID_CTRL_DATA:
+			return status;
+			break;
+		default:
+			ASSERT(0);
+			return STATUS_FAIL;
+		break;
+	}
+	
+	/*should not arrive here*/
+	ASSERT(0);
+	return STATUS_FAIL;
+#else
+	/*if (__MSDC_MSPRO__) is not defined, it is impossible to support this command*/
+	ASSERT(0);
+	return STATUS_UNSUPPORTED;
+#endif
+}
+
+DCL_STATUS DclMS_Close(DCL_HANDLE handle)
+{
+	DCL_SD_IMPLEMENTATION_ASSERT;
+	return STATUS_UNSUPPORTED;
+}
+#endif
+
+#else /*!defined(DRV_MSDC_OFF)*/
+
+static kal_bool fgMSDCInit = KAL_FALSE;
+DCL_STATUS DclSD_Initialize(void)
+{
+	kal_uint32	maskedValue;
+	
+	maskedValue = SaveAndSetIRQMask();
+	/*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+	if(KAL_FALSE == fgMSDCInit){
+		fgMSDCInit = KAL_TRUE;
+		RestoreIRQMask(maskedValue);
+		MSDC_Initialize();
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DclSD_DeInitialize(void)
+{
+	return STATUS_FAIL;
+}
+
+DCL_HANDLE DclSD_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+   return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclSD_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSD_Close(DCL_HANDLE handle)
+{
+	return STATUS_FAIL;
+}
+
+
+DCL_STATUS DclSDIO_Initialize(void)
+{
+	return STATUS_FAIL;
+}
+
+DCL_HANDLE DclSDIO_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+   return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclSDIO_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Close(DCL_HANDLE handle)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Initialize(void)
+{
+	return STATUS_FAIL;
+}
+
+DCL_HANDLE DclMS_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+   return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclMS_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Close(DCL_HANDLE handle)
+{
+	return STATUS_FAIL;
+}
+
+
+#endif /*!defined(DRV_MSDC_OFF)*/
+
+#endif //DCL_MSDC_INTERFACE
+
diff --git a/mcu/driver/storage/mc/src/msdc.c b/mcu/driver/storage/mc/src/msdc.c
new file mode 100644
index 0000000..28328cf
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc.c
@@ -0,0 +1,3956 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   msdc.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   driver functons for MSDC controller
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "md_drv_sap.h"
+#include "drv_msgid.h"
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "hisr_config.h"
+#include "config_hw.h"
+#include "init.h"
+
+#include "kal_trace.h"
+#include "dcl.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"  
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_public_api.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h"       /* Task message communiction */
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "drv_hisr.h"
+#include "sleepdrv_interface.h"
+#include "eint.h"
+
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "msdc_api.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "../../../devdrv/iomux/inc/drv_iomux.h"
+
+//! EMB
+#include "FTL.h"
+
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+#include "sdio_sw.h"
+#endif
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#elif defined(__MSDC_MSPRO__)
+#include "mspro_def.h"
+#endif
+#include "upll_ctrl.h"
+//#include "gpio_sw.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#ifdef DRV_LSD
+#include "msdc_lsd.h"
+#endif
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1		CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM	CG_CON1_SIM
+#endif
+
+#ifndef MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET1
+#endif
+
+#else /*when MSDC_TEST_MSDC2_FROM_MSDC1_CODE is defined, we direct CON1 related macro to CON0 related*/
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET0
+#endif
+#endif//MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#endif
+
+
+
+
+/*
+#if !(defined __MSDC_NOT_SUPPORT_HOT_PLUG__)
+#if defined(MT6218B_FN) || defined(MT6219_EV) ||defined(MT6217)||defined(MT6227)||defined(MT6226)||defined(MT6226M)\
+		|| defined(MT6225)
+#define USE_INT26_CARD_DETECTION
+#endif
+#endif
+*/
+
+
+#if defined (WISDOM35B_DEMO_BB)
+extern const char gpio_SD_det_pin;
+#endif
+
+// global variable
+MSDC_HANDLE MSDC_Blk[SD_NUM];
+
+#if (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)|| defined(__MSDC_MSPRO__)) || defined(__MSDC_SD_SDIO__)
+MSDC_HANDLE	*gMSDC_Handle = &(MSDC_Blk[0]);
+
+#if defined(__UBL__) && defined(__EMMC_BOOTING__)
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_Sector[128];
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_eCSD[128];
+#ifdef MSDC_CACHED_SUPPORT
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32	msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
+#endif
+#else
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_Sector[128];
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_eCSD[128];
+#ifdef MSDC_CACHED_SUPPORT
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32	msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
+#endif
+#endif
+//Light 120907
+#define MSDC_DMA_BURSTLEN_LIMIT 0xFFFFFFFF//4294966784  //32bit 
+//#define MSDC_DMA_BURSTLEN_LIMIT 65024
+kal_bool MSDC_useDMA4ByteBurst = KAL_FALSE;
+
+/* Debug log */
+kal_uint32 MSDC_DebugLevel;
+
+/* IO configurations */
+static struct msdc_cust msdc_cap = {
+    0,                   /* host clock source             */
+    1,                   /* command latch edge            */
+    1,                   /* read data latch edge          */
+    1,                   /* write data latch edge         */
+    
+    {6, 6, 0, 0, 1, 0, 1},
+    {4, 4, 0, 0, 1, 0, 1},
+    {4, 4, 0, 0, 1, 0, 1},
+    
+    8,                   /* data pins                     */
+    0,                   /* data address offset           */
+
+    /* hardware capability flags     */
+    0, 
+};
+
+#ifdef  __TST_WRITE_TO_FILE__
+/*error recording: add this additional global variable to use when in error recording*/
+MSDC_HANDLE MSDC_ErrorRecordingBlk;
+#endif
+
+#if defined(DRV_MSDC_SHARE_BY_SWITCH)
+sd_select_enum current_card; // active card
+#if !defined(__CUST_NEW__)
+extern kal_char MSDC_GetLDO_GPIO(void);
+extern kal_char MSDC_GetSwitch_GPIO(void);
+extern kal_char MSDC_GetEXTLDO_GPIO(void);
+extern kal_char MSDC_GetSwitchDirection(void);
+kal_char gpio_simplug_ldo_switch;
+kal_char gpio_ext_sd_ldo_switch;
+kal_char gpio_sim_msdc_switch;
+#endif
+#endif
+
+#if !defined(DRV_LSD) && defined(__DRV_DBG_MEMORY_TRACE_SUPPORT__) && !defined(__UBL__)
+msdc_debugMessage msdc_msgArray[MSDC_DBG_ARRAY_SIZE];
+kal_uint32 msdc_msdIndex;
+#endif
+
+#define MSDC_EINT_NUM       MSDC_EINT_NO
+
+
+// system control blocks
+
+// function predeclaration
+void MSDC_DMAInit(void);
+void MSDC_INT_Init(void);
+void MSDC_DMA_Callback(void);
+void MSDC_EINT_Handler(void);
+void MSDC_turnOnVMC(kal_bool turnOnLdo);
+#ifdef R1B_INTERRUPT_MODE
+static void MSDC_R1B_Init();
+#endif
+
+
+extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
+extern kal_bool INT_USBBoot(void);
+extern kal_int8 MSDC_GetDLTFromOPCLK(kal_uint32 opClk, kal_uint8 *setRED);
+extern void SD_Sleep4Wait(kal_int32 sleep_tick);
+extern void msdc_tune_init(void);
+
+#ifdef __CARD_DOWNLOAD__
+extern kal_bool MSDC_QueryIsPowerControllable(void);
+extern void MSDC_SetPower(kal_bool enable);
+#endif
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+
+#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+#error "__MSDC_NOT_SUPPORT_HOT_PLUG__ shouldn't be defined."
+#endif
+extern const unsigned char MSDC_EINT_NO;
+static kal_uint32 MSDC_debounceTime;
+static kal_bool cardDetectionEINTPolarity;
+#endif
+
+#if defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_START_TIMER(kal_uint16 x)
+{
+    gMSDC_Handle->is_timeout = KAL_FALSE;
+}
+#else// defined(__UBL__) || defined(__FUE__)
+
+kal_bool MSDC_START_TIMER(kal_uint16 x)
+{
+    //DCL_HANDLE gpt_handle;
+    DCL_STATUS status;
+    SGPT_CTRL_START_T start;
+
+#if defined(MSDC_DEBUG_INFO)
+    strcpy(gMSDC_Handle->msdc_fname, __FILE__);
+    gMSDC_Handle->msdc_lines = __LINE__;
+#endif
+
+    gMSDC_Handle->is_timeout = KAL_FALSE;
+    start.u2Tick = x;
+    start.pfCallback = MSDC_TimeOutHandler;
+    start.vPara = NULL;
+    //gpt_handle= module |MSDC_GPT_CB_MAGIC_NUM;
+    status = DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start);
+    //dbg_print("start timer++++++++%d+++++\r\n",drv_get_current_time());
+    if (STATUS_OK == status)
+        return KAL_TRUE;
+    else
+        return KAL_FALSE;
+}
+#endif// defined(__UBL__) || defined(__FUE__)
+
+#if defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_STOP_TIMER()
+{
+    return KAL_TRUE;
+}
+#else// defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_STOP_TIMER()
+{
+    
+
+    //MSDC_GPTI_StopItem(gMSDC_Handle->gpt_handle);
+    DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_STOP, 0);
+    if (gMSDC_Handle->is_timeout ||!gMSDC_Handle->mIsPresent)
+    {
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+    }
+    //dbg_print("stop timer +++++++%d++++++++\r\n",drv_get_current_time());
+    return KAL_TRUE;
+}
+#endif// defined(__UBL__) || defined(__FUE__)
+
+#if !defined(__FUE__) && !defined(__UBL__)
+void MSDC_GPTI_BusyWait(kal_uint16 len)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+kal_uint8 MSDC_GPTI_GetHandle(DCL_HANDLE *handle)
+{
+    //DCL_HANDLE gpt_handle;
+    *handle = DclSGPT_Open(DCL_GPT_CB, 0);
+
+    //*handle = 0xFF & gpt_handle;
+
+    return KAL_TRUE;
+}
+
+#endif//!defined(__FUE__) && !defined(__UBL__)
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetClock
+*
+* DESCRIPTION
+*
+* PARAMETERS
+*	clock: the desired operating clock rate in the unit of kHz
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint32  MSDC_SetClock(kal_uint32 bus_clock,kal_bool ddr_mode)
+{
+	kal_uint32 msdc_clock,op_clock=0;
+	kal_uint32 div,mode;
+	if (!gMSDC_Handle->msdc_clock)
+	{
+		/*didn't set source clock*/
+		MSDC_ERR("[MSDC][%s %d]set clock before set source clock\r\n",__FUNCTION__,__LINE__);
+		return MSDC_ERROR;
+	}
+	
+	msdc_clock=gMSDC_Handle->msdc_clock;
+
+	if (!(bus_clock))
+	{
+		MSDC_RESET();
+		MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
+		MSDC_ERR("[MSDC][%s %d]can't set bus clock to %d\r\n",__FUNCTION__,__LINE__,bus_clock);
+		return MSDC_ERROR;
+	}
+
+	/* Check the MAX bus clock which could be supportted by driver */
+	if (bus_clock > gMSDC_Handle->op_clock_max)
+	    bus_clock = gMSDC_Handle->op_clock_max;
+   
+	/*need disable irq*/
+	
+	MSDC_ENABLE_CARD_CLOCK(KAL_FALSE);
+	
+	if (ddr_mode){
+		mode=USE_DDR_MODE;
+		if (bus_clock>=(msdc_clock >> 2)){
+			div=0;
+			op_clock=msdc_clock >> 2;
+		}
+		else
+		{
+			bus_clock=bus_clock << 1;
+			div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
+			op_clock=(msdc_clock>>2)/div;
+			op_clock=op_clock>>1;
+		} 
+	}
+	else 
+	{
+	    if (bus_clock >=msdc_clock)
+        {  
+            //dbg_print("entry bus_clock==msdc_clock\r\n");
+	    	mode =USE_MSDC_SRC_CK;
+		    div=0;
+		    op_clock=msdc_clock;
+        }
+        else
+        {
+            mode =USE_CLOCK_DIV;
+    		if (bus_clock >= (msdc_clock >> 1))
+    		{
+    		    
+    			div=0;
+    			op_clock=msdc_clock>>1;
+                //dbg_print("entry bus_clock >= (msdc_clock>>1),op_clock=%d\r\n",op_clock);
+    		} else {
+    		    
+        		div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
+        		op_clock=(msdc_clock >> 2)/div;
+                //dbg_print("entry bus_clock <(msdc_clock>>1),bus_clock=%d ,op_clock=%d,msdc_clock=%d\r\n",bus_clock,op_clock,msdc_clock);
+    		}
+        }
+	}
+	
+	gMSDC_Handle->op_clock=op_clock;
+	gMSDC_Handle->msdc_clock=msdc_clock;
+    //dbg_print("op_clock=%d ,msdc_clock=%d,div=%x\r\n",op_clock,msdc_clock,div);
+	BitFieldWrite32((kal_uint32 *)MSDC_CFG, mode, MSDC_CFG_CKMOD);
+	BitFieldWrite32((kal_uint32 *)MSDC_CFG,div,MSDC_CFG_CKDIV);
+	if (MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_CFG)&MSDC_CFG_CKSTB),500))
+	{
+		MSDC_ERR("[MSDC][%s %d]wait clock stable 500ms,then timeout \r\n",__FUNCTION__,__LINE__);
+		return MSDC_ERROR;
+	}
+    //dbg_print("MSDC_CFG=%x\r\n",MSDC_Reg32(MSDC_CFG));
+	
+	/*open irq*/
+    MSDC_CRIT("[MSDC][%s %d] SET_CLK(%dkHz): SCLK(%dkHz) MODE(%d) DDR(%d) DIV(%d)\r\n",
+           __FUNCTION__,__LINE__, bus_clock / 1000, op_clock / 1000, mode, ddr_mode, div);
+           
+	MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
+    return MSDC_OK;
+
+}
+
+kal_uint32  uffs(kal_uint32 x)
+{
+	kal_uint32 r=1;
+	if (!x)
+	{
+		return 0	;
+	}
+	if (!(x&0xffff))
+	{
+		x>>=16;
+		r+=16;
+	}
+	if (!(x&0xff))
+	{
+		x>>=8;
+		r+=8;
+	}
+	if (!(x&0xf))
+	{
+		x>>=4;
+		r+=4;
+	}
+	if (!(x&0x3))
+	{
+		x>>=2;
+		r+=2;
+	}
+	if (!(x&0x1))
+	{
+		x>>=1;
+		r+=1;
+	}
+	return r;
+}
+
+
+void msdc_sleep(kal_uint32 ticks)
+{
+   if ((kal_query_systemInit() == KAL_TRUE)
+    #ifdef  __TST_WRITE_TO_FILE__ 			/*error recording: considering error recording additionally*/
+                || (KAL_TRUE == INT_QueryExceptionStatus())
+    #endif
+    #ifndef __MTK_TARGET__
+                || KAL_TRUE == FTL_isPollingMode()
+    #endif                
+      )
+    {
+        MSDC_GPTI_BusyWait(ticks*5);
+    }
+    else
+    {
+        kal_sleep_task(ticks);
+    } 
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetClockSource
+*
+* DESCRIPTION
+*
+* PARAMETERS
+*	type: the desired operating clock source
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+#if (CHIP_VER == 0)
+void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
+{
+    kal_uint32 orig_val;
+       // 3'b000: 26MHz
+	// 3'b001: 40MHz
+	// 3'b010: 50MHz
+	// 3'b011: 60MHz
+	// 3'b100: 69MHz
+	// 3'b101: 80MHz
+	// 3'b110: 96MHz
+	// 3'b111: 100MHz
+	#define MSDC_SOURCE_SEL_ADDR (0xBF814004)
+    orig_val=MSDC_Reg32(MSDC_SOURCE_SEL_ADDR);
+    orig_val=orig_val&(~0x7);
+	switch (type)
+	{
+		case SRC_26M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
+			gMSDC_Handle->msdc_clock=26000000;
+			gMSDC_Handle->op_clock_max = 13000000;
+			break;
+			
+		case SRC_40M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_40M);
+			gMSDC_Handle->msdc_clock=40000000;
+			gMSDC_Handle->op_clock_max = 20000000;
+			break;
+		case SRC_50M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_50M);
+			gMSDC_Handle->msdc_clock=50000000;
+            gMSDC_Handle->msdc_clock=35000000;
+			gMSDC_Handle->op_clock_max = 17000000;
+			break;
+		case SRC_60M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_60M);
+			gMSDC_Handle->msdc_clock=60000000;
+			gMSDC_Handle->op_clock_max = 30000000;
+			break;
+		case SRC_69M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_69M);
+			gMSDC_Handle->msdc_clock=69000000;
+			gMSDC_Handle->op_clock_max = 35000000;
+			break;
+		case SRC_80M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_80M);
+			gMSDC_Handle->msdc_clock=80000000;
+			gMSDC_Handle->op_clock_max = 40000000;
+			break;
+		case SRC_96M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_96M);
+			gMSDC_Handle->msdc_clock=96000000;
+			gMSDC_Handle->op_clock_max = 48000000;
+			break;
+		case SRC_100M:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_100M);
+			gMSDC_Handle->msdc_clock=100000000;
+			gMSDC_Handle->op_clock_max = 50000000;
+			break;
+		default:
+			MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
+			gMSDC_Handle->msdc_clock=26000000;
+			MSDC_ERR("[MSDC][%s %d]unknow source CLK %d\r\n",__FUNCTION__,__LINE__,type);
+			break;
+	}
+}
+#elif (CHIP_VER == 1)
+
+#define MSDC_OP_SCLK            (200000000)
+#define MSDC_MAX_SCLK           (200000000)
+void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
+{
+    gMSDC_Handle->msdc_clock = MSDC_OP_SCLK;
+    gMSDC_Handle->op_clock_max = MSDC_MAX_SCLK;
+}
+
+#endif
+/*************************************************************************
+* FUNCTION
+*  MSDC_Check_Card_Present
+*
+* DESCRIPTION
+*	c
+*
+* PARAMETERS
+*	ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_Check_Card_Present(void)
+{
+#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+    return gMSDC_Handle->mIsPresent;
+#else
+    return KAL_TRUE;
+#endif
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_PDNControl
+*
+* DESCRIPTION
+*	Enable power saving or not.
+*
+* PARAMETERS
+*	ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+#define MSDC_PDN_EN
+void MSDC_PDNControl(kal_bool ON)
+{
+    if (ON) {
+    #if !defined(ATEST_DRV_ENABLE)
+    
+        #if defined(MSDC_PDN_EN)
+        PDN_SET(PDN_MSDC0);
+        #endif
+    
+        SleepDrv_SleepEnable(gMSDC_Handle->msdc_sm_hdl);
+    #endif
+    }
+    else {
+    #if !defined(ATEST_DRV_ENABLE)
+
+        #if defined(MSDC_PDN_EN)
+        PDN_CLR(PDN_MSDC0);
+        #endif
+    
+        SleepDrv_SleepDisable(gMSDC_Handle->msdc_sm_hdl);
+    #endif
+    }
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_TimeOutHandler
+*
+* DESCRIPTION
+*	Callback function of gpt timer, and launched while MSDC busy for a while
+
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_TimeOutHandler(void *parameter)
+{
+	gMSDC_Handle->is_timeout=KAL_TRUE;
+	kal_set_eg_events(gMSDC_Handle->MSDC_Events,
+		EVENT_DMA_DONE|EVENT_XFER_DONE|EVENT_CMD_DONE,KAL_OR);
+	MSDC_ERR("[MSDC][%s %d] Enter timeout handler \r\n",__FUNCTION__,__LINE__);
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_GetCardStatus
+*
+* DESCRIPTION
+*	Check currently card is present or not.
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	msdc_eint_state
+*
+*
+*************************************************************************/
+int MSDC_GetCardStatus(void * DriveData, int AckType)
+{
+   return 0;
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_SendCardInd
+*
+* DESCRIPTION
+*	Send card indication to the specified module.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_SendCardInd(module_type dest_id, sd_select_enum sel, kal_uint32 msg_id)
+{
+   
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_GetMediaChanged
+*
+* DESCRIPTION
+*	Check if the media is changed, and clear the status after function call
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_GetMediaChanged(sd_select_enum sel)
+{
+    kal_bool ret;
+
+    ENTER_CRITICAL();
+    ret = (MSDC_Blk[sel].mIsChanged ) ? (KAL_TRUE) : (KAL_FALSE);
+    MSDC_Blk[sel].mIsChanged = KAL_FALSE;
+    EXIT_CRITICAL();
+
+    return ret;
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_InvertN
+*
+* DESCRIPTION
+* 	Invert the order of bytes eg,
+* 	src: 0x01 0x02, len: 2 => dest: 0x02 0x01
+*
+* PARAMETERS
+*	1. dest: used for store inverted result
+*	2. src: source for inverting
+*	3. len: bytes for inverting
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	1. make sure dest has the same size with src.
+*************************************************************************/
+void MSDC_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
+{
+    int i;
+
+    for (i = 0; i < len; i++)
+        *(dest + len - 1 - i) = *(src + i);
+
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_Config_INS_WP
+*
+* DESCRIPTION
+* 	Configure the pull up or pull down status for INS and WP pin
+*
+* PARAMETERS
+*	1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*	2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
+*	2. MT6218B and MT6217, WP is configured with data lines.
+*************************************************************************/
+void MSDC_Config_INS_WP(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
+{
+
+}
+
+void MSDC_InitializeSwitchGpio()
+{
+
+	#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	DCL_HANDLE handle;
+#if !defined(__CUST_NEW__)
+    GPIO_LDO_SWITCH = MSDC_GetLDO_GPIO();
+    GPIO_EXT_SD_LDO_SWITCH = MSDC_GetEXTLDO_GPIO();
+    GPIO_SIM_MSDC_SWITCH = MSDC_GetSwitch_GPIO();
+#endif
+    //GPIO_ModeSetup(GPIO_SIM_MSDC_SWITCH, 0); // gpio mode (replaced by DCL)
+    handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+    DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+    DclGPIO_Close(handle);
+    //GPIO_InitIO(OUTPUT, GPIO_SIM_MSDC_SWITCH); // replaced by DCL
+    handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+    DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+    DclGPIO_Close(handle);
+    /*bewlow comes after JRD SIM+ issue on 2007_03_08, use custom setting instead of fix value*/
+    //GPIO_WriteIO(MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH); // replaced by DCL
+    handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+
+    if (0 == MSDC_GetSwitchDirection())
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+    else if (1 == MSDC_GetSwitchDirection())
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+    else
+    {
+        DclGPIO_Close(handle);
+        ASSERT(0);
+    }
+
+    DclGPIO_Close(handle);
+    /*end of changes of JRD SIM+ issue on 2007_03_08*/
+#endif
+
+}
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+#if defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+kal_bool EINT_DefaultPolarity = KAL_FALSE;
+#else
+kal_bool EINT_DefaultPolarity = KAL_FALSE;
+#endif
+#endif
+
+void MSDC_ConfigPin(kal_uint32 pullmode)
+{
+	/* 
+	 * Note that the CLK signal is a output signal,
+	 * and it should be kept to the default value.
+	 * that is, PULL DOWN
+	 */
+    switch (pullmode)
+    {
+        case MSDC_PIN_PULL_UP:
+
+    	    /* For CMD pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 1);
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
+            /* For DATA pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 1);
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
+            break;
+            
+        case MSDC_PIN_PULL_DOWN:
+
+    	    /* For CMD pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 1);
+            /* For DATA pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 1);
+            
+            break;
+        case MSDC_PIN_PULL_NONE:
+        default:
+        
+    	    /* For CMD pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
+            MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
+            /* For DATA pin */
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
+            MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
+                
+            break;
+    }
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetHostPower
+*
+* DESCRIPTION
+*	enable or disable the power of host
+*
+* PARAMETERS*
+*	on:  KAL_TURE enable the power, KAL_FALSE disable the power
+*
+* RETURNS
+*   
+* 	KAL_FALSE: fail to set the power
+* 	KAL_TURE:   success to set the power     
+* 
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetHostPower(kal_bool on)
+{
+	kal_bool ret = KAL_TRUE;
+	
+	return ret;
+}
+
+#if (CHIP_VER == 0)
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetVddPower
+*
+* DESCRIPTION
+*	enable or disable the power of host
+*
+* PARAMETERS*
+*	on:   KAL_TURE enable the power, KAL_FALSE disable the power
+*	volt:  the voltage of vdd  3300 mean 3.3v
+* RETURNS
+*   
+* 	KAL_FALSE: fail to set the power
+* 	KAL_TURE:   success to set the power     
+* 
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetVddPower(kal_bool on,kal_uint32 volt)
+{
+	kal_bool ret =KAL_TRUE;
+	if (on)
+	{
+		if (volt == 3300)
+		{
+			MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+		}
+		else
+		{
+			ret = KAL_FALSE;
+		}
+	}
+	else
+	{
+		MSDC_ConfigPin(MSDC_PIN_PULL_DOWN);
+	}
+	return ret;
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetSignalPower
+*
+* DESCRIPTION
+*	enable or disable the power of host
+*
+* PARAMETERS*
+*	on:  KAL_TURE enable the power, KAL_FALSE disable the power
+*	volt: the voltage of signal , 3300 mean 3.3v  ,1800 mean 1.8v
+* RETURNS
+*   
+* 	KAL_FALSE: fail to set the power
+* 	KAL_TURE:   success to set the power     
+* 
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+/*
+	CARD_PWR 1   LEVEL_PWR33 0             1.8v
+	CARD_PWR 1   LEVEL_PWR33 1		3.3v
+	CARD_PWR0						0v
+*/
+#define MSDC_CARD_PWR		26
+#define MSDC_LEVEL_PWR33		27
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+	DCL_HANDLE handle;
+	kal_bool ret =KAL_TRUE;
+	if (on)
+	{
+		handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
+        DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+    	DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+		//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+		
+    		DclGPIO_Close(handle);
+		if (volt == 3300)
+		{
+			handle = DclGPIO_Open(DCL_GPIO, MSDC_LEVEL_PWR33);
+            DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+	    	DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+			//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+			
+	    	DclGPIO_Close(handle);
+			MSDC_CRIT("[MSDC][%s %d]set signal power to 3.3v\r\n",__FUNCTION__,__LINE__);
+            gMSDC_Handle->signal_volt=3300;
+		}
+		else if (volt ==1800)
+		{
+			handle = DclGPIO_Open(DCL_GPIO,MSDC_LEVEL_PWR33);
+            DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+	   		DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+			//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+			
+	   		DclGPIO_Close(handle);
+			MSDC_CRIT("[MSDC][%s %d]set signal power to 1.8v\r\n",__FUNCTION__,__LINE__);
+            gMSDC_Handle->signal_volt=1800;
+		} 
+		else
+		{
+			MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",__FUNCTION__,__LINE__,volt);
+			ret = KAL_FALSE;
+		}
+	}
+	else
+	{
+		/*set signal volt to 0v*/
+		handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
+        DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+    	DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+		//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+		
+   		DclGPIO_Close(handle);
+		MSDC_CRIT("[MSDC][%s %d]set signal power to 0v\r\n",__FUNCTION__,__LINE__);
+        gMSDC_Handle->signal_volt=0;
+	}
+		
+	return ret;
+}
+
+#elif (CHIP_VER == 1)
+
+#define LDO_VMC             0
+#define LDO_VMCH            1
+#define LDO_VIO18_PMU       2
+
+static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
+static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
+
+static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt) 
+{
+    PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+    PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
+    DCL_HANDLE handle;
+
+    /* Open PMU handle */
+    handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+    
+    switch(powerID) {
+        case LDO_VMC:
+            /* Set enable control */
+            pmu_en.mod = VMC;
+            pmu_en.enable = 1;
+
+            /* Set voltage */
+            pmu_volsel.mod = VMC;
+            pmu_volsel.voltage = powerVolt;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        case LDO_VMCH:
+            /* Set enable control */
+            pmu_en.mod = VMCH;
+            pmu_en.enable = 1;
+
+            /* Set voltage */
+            pmu_volsel.mod = VMCH;
+            pmu_volsel.voltage = powerVolt;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        default:
+        break;
+    }
+
+    /* Close PMU handle */
+    DclPMU_Close(handle);
+    
+    return 1;
+}
+
+static kal_uint32 hwPowerDown(kal_uint32 powerID) 
+{
+    PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+    DCL_HANDLE handle;
+
+    /* Open PMU handle */
+    handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+    switch(powerID) {
+        case LDO_VMC:
+            /* Set enable control */
+            pmu_en.mod = VMC;
+            pmu_en.enable = 0;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+        break;
+
+        case LDO_VMCH:
+            /* Set enable control */
+            pmu_en.mod = VMCH;
+            pmu_en.enable = 0;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        default:
+        break;
+    }
+
+    /* Close PMU handle */
+    DclPMU_Close(handle);
+
+    return 1;
+}
+
+static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId, 
+    PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
+{
+    if (on) { // want to power on
+        if (*status == 0) {  // can power on 
+            MSDC_CRIT("msdc LDO<%s> power on<%d>\r\n", 
+                powerId ? "VMCH" : "VMC", powerVolt);     
+
+            hwPowerOn(powerId, powerVolt);
+            
+            *status = powerVolt;             
+        } else if (*status == powerVolt) {
+            MSDC_CRIT("msdc LDO<%s><%d> power on again!\r\n", 
+                powerId ? "VMCH" : "VMC", powerVolt);    
+        } else { // for sd3.0 later
+            MSDC_CRIT("msdc LDO<%s> change<%d> to <%d>\r\n", 
+                powerId ? "VMCH" : "VMC", *status, powerVolt);
+
+            hwPowerDown(powerId);
+            hwPowerOn(powerId, powerVolt);
+            
+            *status = powerVolt;
+        }
+    } else {  // want to power off
+        if (*status != 0) {  // has been powerred on
+            MSDC_CRIT("msdc LDO<%s> power off\r\n", powerId ? "VMCH" : "VMC");   
+
+            hwPowerDown(powerId);
+            
+            *status = 0;
+        } else {
+            MSDC_CRIT("LDO<%s> not power on\r\n", powerId ? "VMCH" : "VMC");    
+        }                
+    }  
+    
+    return 0;          
+}
+
+void msdc_set_smt(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+    clk &= 0xF;
+    cmd &= 0xF;
+    dat &= 0xF;
+    
+    /* For CLK pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT, clk);
+    /* For CMD pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT, cmd);
+    /* For DATA pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT, dat);
+}
+
+void msdc_set_slew_rate(int clk,int cmd, int dat)
+{
+    clk &= 0x1;
+    cmd &= 0x1;
+    dat &= 0x1;
+    
+    /* For CLK pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSR, clk);
+    /* For CMD pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSR, cmd);
+    /* For DATA pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSR, dat);
+}
+
+void msdc_set_rdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+    clk &= 0xF;
+    cmd &= 0xF;
+    dat &= 0xF;
+    
+    /* For CLK pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKRDSEL, clk);
+    /* For CMD pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDRDSEL, cmd);
+    /* For DATA pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATRDSEL, dat);
+}
+
+void msdc_set_tdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+    clk &= 0xF;
+    cmd &= 0xF;
+    dat &= 0xF;
+    
+    /* For CLK pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKTDSEL, clk);
+    /* For CMD pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDTDSEL, cmd);
+    /* For DATA pin */
+    MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATTDSEL, dat);
+}
+
+void msdc_set_driving(struct msdc_cust *hw, kal_bool sd_18)
+{
+    if (sd_18) {
+        /* For CLK pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_18);
+        /* For CMD pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_18);
+        /* For DATA pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_18);
+    } else {
+        /* For CLK pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_33);
+        /* For CMD pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_33);
+        /* For DATA pin */
+        MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_33);
+    }
+
+}
+
+int msdc_io_init()
+{
+    struct msdc_cust *pmsdc_cust = NULL;
+
+    pmsdc_cust = &msdc_cap;
+
+    if (!pmsdc_cust) {
+        MSDC_ERR("<%s> : Invalid host ID!\r\n", __FUNCTION__);
+        goto exit;
+    }
+
+    /* RDSEL Init */
+    msdc_set_rdsel(pmsdc_cust->io_clk.rdsel, pmsdc_cust->io_cmd.rdsel,
+                    pmsdc_cust->io_dat.rdsel);
+    
+    /* TDSEL Init */
+    msdc_set_tdsel(pmsdc_cust->io_clk.tdsel, pmsdc_cust->io_cmd.tdsel,
+                    pmsdc_cust->io_dat.tdsel);
+                    
+    /* SMTen Init */
+    msdc_set_smt(pmsdc_cust->io_clk.smten, pmsdc_cust->io_cmd.smten,
+                    pmsdc_cust->io_dat.smten);
+
+    /* Slew Rate Init */
+    msdc_set_slew_rate(pmsdc_cust->io_clk.slew, pmsdc_cust->io_cmd.slew,
+                        pmsdc_cust->io_dat.slew);
+                    
+    /* IO driving Init */
+    msdc_set_driving(pmsdc_cust, 0);
+
+exit:
+
+    return 1;
+}
+
+void msdc_pin_init()
+{
+    /* Pin config for MSDC0 */
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+    /* Set to MSDC function(INS and WP) */
+    IOMUX_set_module_func(0, sel_msdc0p_0);
+#else
+    /* Set GPIO/EINT function, both for INS and WP */
+    IOMUX_set_module_func(4, sel_msdc0p_0);
+
+    #ifdef ATEST_DRV_MSDC
+    GPIO_init();
+    EINT_Setting_Init();
+    #endif
+    
+#endif
+
+    IOMUX_set_module_func(0, sel_msdc0p_1);
+    IOMUX_set_module_func(0, sel_msdc0p_2);
+    
+    return;
+}
+
+kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
+{
+	kal_bool ret =KAL_TRUE;
+
+	if (on)
+	    MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+	    
+	if (volt == 3300)
+	{
+		msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
+	}
+	else
+	{
+	    MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n", 
+	        __FUNCTION__, __LINE__, volt);
+
+		ret = KAL_FALSE;
+	}
+
+	if (!on)
+	    MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+		
+	return ret;
+}
+
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+	kal_bool ret =KAL_TRUE;
+	if (volt == 3300)
+	{
+		msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
+		msdc_set_driving(&msdc_cap, 0);
+	}
+	else if (volt ==1800)
+	{
+        msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
+        msdc_set_driving(&msdc_cap, 1);
+	} 
+	else
+	{
+	    MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n", 
+	        __FUNCTION__, __LINE__, volt);
+	        
+		ret = KAL_FALSE;
+	}
+		
+	return ret;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetAllPower
+*
+* DESCRIPTION
+*	enable or disable the power of host\Vdd\signal
+*
+* PARAMETERS*
+*
+* RETURNS
+*   
+* KAL_FALSE: fail to set the power
+* KAL_TURE:   success to set the power     
+* 
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetAllPower(kal_bool on)
+{
+	kal_bool ret=KAL_TRUE;
+	
+	if (on)
+	{
+		MSDC_SetHostPower(on);
+		MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
+		MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
+	}
+	else
+	{
+		MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
+		MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
+		MSDC_SetHostPower(on);
+		
+	}
+	return ret;
+	
+}
+
+void power_cycle(kal_uint32 interval_ticks)
+{
+    MSDC_SetVddPower(0,gMSDC_Handle->vdd_volt);
+    msdc_sleep(interval_ticks);
+    MSDC_SetVddPower(1,gMSDC_Handle->vdd_volt);
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetBusWidth
+*
+* DESCRIPTION
+*	set the bus width to 1 ,4 8
+*
+* PARAMETERS*
+*	bus_width :   set to 1 ,4 ,8
+* RETURNS     
+* 
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+void MSDC_SetBusWidth(SD_BITWIDTH bus_width)
+{
+	kal_uint32 val;
+	val=MSDC_Reg32(SDC_CFG)&(~SDC_CFG_BUSWIDTH);
+	switch(bus_width)
+	{
+	default:
+	case BIT_1W:
+		val |=(MSDC_BUS_1BITS << 16);
+        gMSDC_Handle->bus_width=1;
+		break;
+	case BIT_4W:
+		val |=(MSDC_BUS_4BITS <<16);
+        gMSDC_Handle->bus_width=4;
+		break;
+    case BIT_8W:
+        val |=(MSDC_BUS_8BITS<<16);
+        gMSDC_Handle->bus_width=8;
+        break;
+	}
+	MSDC_WriteReg32(SDC_CFG,val);
+
+	MSDC_CRIT("[MSDC][%s %d]Set to %d-bit bus width\r\n", __FUNCTION__, 
+	    __LINE__, gMSDC_Handle->bus_width);
+}
+
+void MSDC_FatalErrorHandle()
+{
+	/*reset msdc*/
+	MSDC_RESET();
+	/*stop dma*/
+	MSDC_STOP_DMA();
+	/*clear fifo*/
+	MSDC_CLR_FIFO_EX();
+	/*clear ints*/
+	MSDC_CLR_INT();
+	/**/
+}
+
+ kal_uint32 MSDC_PollInts(kal_uint32 int_mask,kal_uint32 timeout_ms)
+{
+	kal_uint32 intsts;
+	if (!MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_INT)&int_mask),timeout_ms))
+	{
+			intsts=MSDC_Reg32(MSDC_INT);
+			MSDC_WriteReg32(MSDC_INT,intsts&int_mask);
+			return intsts&int_mask;
+	}
+
+	MSDC_ERR("[MSDC][%s %d]poll INT %d, SW timeout\r\n",__FUNCTION__,__LINE__,timeout_ms);
+	return 0;
+}
+/*************************************************************************
+* FUNCTION
+
+*  MSDC_Initialize
+*
+* DESCRIPTION
+*	Initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*
+*
+* RETURNS
+*  1: initailized failed
+*  0: successful
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+extern kal_semid dualMsdcArb;
+
+void MSDC_Probe (void)
+{
+    if (gMSDC_Handle->mIsProbeMSDC)
+        return;
+
+    /* PDN disable first */
+    MSDC_PDNControl(KAL_FALSE);
+    
+    #if (CHIP_VER == 1)
+    msdc_io_init();
+    #endif
+    
+    /*check card present or not*/
+#if defined(MSDC_HOTPLUG_EN)
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+    if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
+        gMSDC_Handle->mIsPresent=KAL_FALSE;
+    else
+        gMSDC_Handle->mIsPresent=KAL_TRUE;
+#else       /* _MSDC_INTERNAL_CD_INT_PIN_ */
+    {
+    DCL_HANDLE handle;
+
+    GPIO_CTRL_READ_T data;
+    
+    /* when use EINT for card detect,get the status */
+    handle = DclGPIO_Open(DCL_GPIO, MSDC_INS_GPIO);
+    DclGPIO_Control(handle, GPIO_CMD_READ, (DCL_CTRL_DATA_T *)&data);
+
+    if (data.u1IOData)
+        gMSDC_Handle->mIsPresent = KAL_FALSE;
+    else
+        gMSDC_Handle->mIsPresent = KAL_TRUE;
+
+    DclGPIO_Close(handle);
+    }
+#endif
+#else       /* MSDC_HOTPLUG_EN */
+    gMSDC_Handle->mIsPresent = KAL_TRUE;
+#endif
+    MSDC_CRIT("[MSDC][%s %d]Card is %s\r\n",__FUNCTION__,__LINE__,
+        gMSDC_Handle->mIsPresent ? "Present" : "Not Present");
+
+    /* If card is not exist, step over the INIT flow */
+    if (gMSDC_Handle->mIsPresent)
+        gMSDC_Handle->mIsProbeMSDC = KAL_TRUE;
+    else {
+        gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
+        goto exit;
+    }
+
+	/*set MSDC as the controller of SD*/
+	MSDC_SET_FIELD(MSDC_CFG, MSDC_CFG_MODE, 1);
+	
+	/*reset MSDC ,clear FIFO*/
+	MSDC_RESET();
+	MSDC_CLR_FIFO_EX();
+	MSDC_DEBUG("[MSDC][%s %d]reset MSDC,clear FIFO\r\n",__FUNCTION__,__LINE__);
+	
+    /*write crc timeout detection*/
+    MSDC_SetData32(MSDC_PATCH_BIT0,1<<30,(1<<30));	
+    /*Configure To Default Data Timeout */
+    MSDC_SetData32(SDC_CFG,SDC_CFG_DTOC,(DEFAULT_DTOC<<24));
+    /*set bus width to 1 */
+    MSDC_SetBusWidth(BIT_1W);
+
+    /* Tuning parameters INIT */
+    msdc_tune_init();
+
+exit:
+    MSDC_PDNControl(KAL_TRUE);
+
+    /* Shut card power */
+	MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+
+	/* Defaultly turn VMC to 1.8V to save power */
+	MSDC_SetSignalPower(KAL_TRUE, gMSDC_Handle->signal_volt);
+}
+
+void MSDC_Initialize(void)
+{    
+    /* INIT MSDC debug flag */
+    MSDC_SetDebugLevel(K_NOTICE);
+
+	MSDC_CRIT("[MSDC][%s %d]Start init MSDC...\r\n",__FUNCTION__,__LINE__);
+
+ 	/*check MSDC is initalized or not */
+	if (gMSDC_Handle->mIsInitMSDC)
+		return;
+
+    gMSDC_Handle->mIsProbeMSDC = 0;
+    
+    /*init gSD*/
+	kal_mem_set(gSD,0,sizeof(T_SDC_HANDLE));
+	
+	/* Set voltage of single and card power */
+	gMSDC_Handle->signal_volt = 1800;
+	gMSDC_Handle->vdd_volt = 3300;
+
+    #if !defined(ATEST_DRV_ENABLE)
+    /* Get Sleep handler */
+	gMSDC_Handle->msdc_sm_hdl = SleepDrv_GetHandle(SMP);
+	MSDC_CRIT("[MSDC][%s %d]MSDC Slp Handler: %d\r\n",
+	    __FUNCTION__, __LINE__, gMSDC_Handle->msdc_sm_hdl);
+	#endif
+	
+	/*set clock source */
+	MSDC_SetClockSource(SRC_80M);
+
+    #if (CHIP_VER == 1)
+    /* Pin MUX setting and IO settings */
+    msdc_pin_init();
+    #endif
+	
+    /*get gpt handle*/
+    if (gMSDC_Handle->gpt_handle==0)
+        MSDC_GPTI_GetHandle(&gMSDC_Handle->gpt_handle);
+
+    /*clear and disable all interrupt*/
+    MSDC_ClearBits32(MSDC_INTEN,MSDC_Reg32(MSDC_INTEN));
+    MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
+    
+    /* INIT the MSDC related registers */
+    MSDC_Probe();
+    
+    /*init  INT handle*/
+    MSDC_INT_Init();
+
+    /*set the function support by host*/
+    gMSDC_Handle->host_support.function1=FUN1_SDR12_DS|FUN1_SDR25_HS|FUN1_SDR50|FUN1_SDR104|FUN1_DDR50;
+    gMSDC_Handle->host_support.function2=FUN2_DEFAULT;
+    gMSDC_Handle->host_support.function3=FUN3_TYPE_B;
+    gMSDC_Handle->host_support.function4=FUN4_200MA|FUN4_400MA|FUN4_600MA|FUN4_800MA;
+
+    gMSDC_Handle->mIsInitMSDC = KAL_TRUE;
+    
+    MSDC_DEBUG("[MSDC][%s %d]finish init MSDC\r\n",__FUNCTION__,__LINE__);
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_DeInit
+*
+* DESCRIPTION
+*	De-initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void MSDC_DeInit(void)
+{
+    /* Shutdown Card power Only */
+	MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+    
+    gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
+    gMSDC_Handle->mIsInitialized = KAL_FALSE;
+
+    return;
+}
+
+
+#ifdef  __TST_WRITE_TO_FILE__
+/*error recording: add this function to do MSDC reset when error recording*/
+void MSDC_ErrorRecordingReset()
+{
+
+   	
+}
+#endif
+
+#ifndef DRV_LSD
+/*************************************************************************
+* FUNCTION
+*  BitFieldWrite32
+*
+* DESCRIPTION
+*	Write src to dest at mask position
+*
+* PARAMETERS
+*	dest: destination to be update
+*	src: value to be written
+*	mask: bit mask
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+// Note: mask must be a continuous area during 32bits. eg,
+// dest : 00A30000 , src : BF, mask : 0000BF00.
+// after BitFieldCpy, dest : 00A3BF00, copy src to dest at mask position.
+void BitFieldWrite32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
+{
+    kal_uint8 bit_pos;
+    kal_uint32 tmp;
+
+    bit_pos = 0;
+    tmp = MSDC_Reg32(dest);
+
+    // get bit positoin
+    while (!((mask >> bit_pos++) & 1));
+
+    //use mask clear the corresponding area
+    tmp &= ~mask;
+    //shift src to the corresponding positiion
+    src <<= (bit_pos - 1);
+    //copy src into destination
+    tmp |= src;
+    MSDC_WriteReg32(dest, tmp);
+}
+#endif
+
+#ifdef MSDC_USED_STUFF
+/*************************************************************************
+* FUNCTION
+*  BitFieldRead32
+*
+* DESCRIPTION
+*	read src to dest at mask position
+*
+* PARAMETERS
+*	dest: destination to store
+*	src: value to be written
+*	mask: bit mask
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+
+// Note: mask must ve continuous area during 32 bits.eg,
+// src : 00A3BF00, mask : 00FF0000
+// after BitFieldRead, dest : A3
+void BitFieldRead32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
+{
+    kal_uint8 bit_pos = 0;
+
+    while (!((mask >> bit_pos++) & 1));
+
+    src &= mask;
+    *(kal_uint32 *)dest = src >> (bit_pos - 1);
+}
+#endif//MSDC_USED_STUFF
+
+// get the bit field value of start_bit with width bits
+// note 1) start_bit start from bit 0
+//		2) prepare dest with initialized with zeros
+//		3) width must less than 32 if using the retrun value as a result
+// eg,
+// src:00110110, start_bit:2,width:3 => dest:101
+void GetBitFieldN(kal_uint8* dest, kal_uint8* src, kal_uint16 start_bit, kal_uint16 width)
+{
+    int i;
+    kal_uint16 bytes, bits;
+
+    //kal_mem_set(dest,0,width/8+1);
+    kal_mem_set(dest, 0, (width / 8) + (0 == (width % 8) ? 0 : 1));
+
+    for ( i = 0; i < width; i++)
+    {
+        bytes = (start_bit + i) / 8;
+        bits  = (start_bit + i) % 8;
+        *(dest + i / 8) |= (kal_uint8)(((*(src + bytes) >> bits) & 1) << (i % 8));
+    }
+
+    /*in MT6238, address of kal_uint32 is checked strictly, and we don't need the return value of this function*/
+    /*change it's return type to void*/
+    return ;
+}
+
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+void MSDC_SetLatchTuning(void)
+{
+    
+}
+#else
+void MSDC_SetIOCONRegDLT(void)
+{
+
+}
+#endif//#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+void msdc_dump_reg(void)
+{
+    int idx;
+
+    MSDC_CRIT("****** [00]MSDC_CFG       : %x\r\n", MSDC_Reg32(MSDC_CFG));
+    MSDC_CRIT("****** [04]MSDC_IOCON     : %x\r\n", MSDC_Reg32(MSDC_IOCON));
+    MSDC_CRIT("****** [08]MSDC_PS        : %x\r\n", MSDC_Reg32(MSDC_PS));
+    MSDC_CRIT("****** [0C]MSDC_INT       : %x\r\n", MSDC_Reg32(MSDC_INT));
+    MSDC_CRIT("****** [10]MSDC_INTEN     : %x\r\n", MSDC_Reg32(MSDC_INTEN));
+    MSDC_CRIT("****** [14]MSDC_FIFOCS    : %x\r\n", MSDC_Reg32(MSDC_FIFOCS));
+    MSDC_CRIT("****** [18]MSDC_TXDATA    : %x\r\n", MSDC_Reg32(MSDC_TXDATA));
+    MSDC_CRIT("****** [1C]MSDC_RXDATA    : --------\r\n");
+    MSDC_CRIT("****** [30]SDC_CFG        : %x\r\n", MSDC_Reg32(SDC_CFG));
+    MSDC_CRIT("****** [34]SDC_CMD        : %x\r\n", MSDC_Reg32(SDC_CMD));
+    MSDC_CRIT("****** [38]SDC_ARG        : %x\r\n", MSDC_Reg32(SDC_ARG));
+    MSDC_CRIT("****** [3C]SDC_STS        : %x\r\n", MSDC_Reg32(SDC_STS));
+    MSDC_CRIT("****** [40]SDC_RESP0      : %x\r\n", MSDC_Reg32(SDC_RESP0));
+    MSDC_CRIT("****** [44]SDC_RESP1      : %x\r\n", MSDC_Reg32(SDC_RESP1));
+    MSDC_CRIT("****** [48]SDC_RESP2      : %x\r\n", MSDC_Reg32(SDC_RESP2));
+    MSDC_CRIT("****** [4C]SDC_RESP3      : %x\r\n", MSDC_Reg32(SDC_RESP3));
+    MSDC_CRIT("****** [50]SDC_BLK_NUM    : %x\r\n", MSDC_Reg32(SDC_BLK_NUM));
+    MSDC_CRIT("****** [58]SDC_CSTS       : %x\r\n", MSDC_Reg32(SDC_CSTS));
+    MSDC_CRIT("****** [5C]SDC_CSTS_EN    : %x\r\n", MSDC_Reg32(SDC_CSTS_EN));
+    MSDC_CRIT("****** [60]SDC_DATCRC_STS : %x\r\n", MSDC_Reg32(SDC_DCRC_STS));
+    MSDC_CRIT("****** [70]EMMC_CFG0      : %x\r\n", MSDC_Reg32(EMMC_CFG0));
+    MSDC_CRIT("****** [74]EMMC_CFG1      : %x\r\n", MSDC_Reg32(EMMC_CFG1));
+    MSDC_CRIT("****** [78]EMMC_STS       : %x\r\n", MSDC_Reg32(EMMC_STS));
+    MSDC_CRIT("****** [7C]EMMC_IOCON     : %x\r\n", MSDC_Reg32(EMMC_IOCON));
+    MSDC_CRIT("****** [80]SD_ACMD_RESP   : %x\r\n", MSDC_Reg32(SDC_ACMD_RESP));
+    MSDC_CRIT("****** [84]SD_ACMD19_TRG  : %x\r\n", MSDC_Reg32(SDC_ACMD19_TRG));
+    MSDC_CRIT("****** [88]SD_ACMD19_STS  : %x\r\n", MSDC_Reg32(SDC_ACMD19_STS));
+    MSDC_CRIT("****** [90]DMA_SA         : %x\r\n", MSDC_Reg32(MSDC_DMA_SA));
+    MSDC_CRIT("****** [94]DMA_CA         : %x\r\n", MSDC_Reg32(MSDC_DMA_CA));
+    MSDC_CRIT("****** [98]DMA_CTRL       : %x\r\n", MSDC_Reg32(MSDC_DMA_CTL));
+    MSDC_CRIT("****** [9C]DMA_CFG        : %x\r\n", MSDC_Reg32(MSDC_DMA_CFG));
+    MSDC_CRIT("****** [A8]DMA_LENGTH     : %x\r\n", MSDC_Reg32(MSDC_DMA_LENGTH));
+    MSDC_CRIT("****** [B0]PATCH_BIT0     : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT0));
+    MSDC_CRIT("****** [B4]PATCH_BIT1     : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT1));
+    MSDC_CRIT("****** [E0]SD30_PAD_CTL0  : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL0));
+    MSDC_CRIT("****** [E4]SD30_PAD_CTL1  : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL1));
+    MSDC_CRIT("****** [E8]SD30_PAD_CTL2  : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL2));
+    MSDC_CRIT("****** [EC]PAD_TUNE       : %x\r\n", MSDC_Reg32(MSDC_PAD_TUNE));
+    MSDC_CRIT("****** [F0]DAT_RD_DLY0    : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY0));
+    MSDC_CRIT("****** [F4]DAT_RD_DLY1    : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY1));
+    MSDC_CRIT("****** [100]MAIN_VERSION  : %x\r\n", MSDC_Reg32(MSDC_VERSION));
+    MSDC_CRIT("****** [104]ECO_VERSION   : %x\r\n", MSDC_Reg32(MSDC_ECO_VER));
+
+    for (idx = 0; idx < 26; idx++) {
+        MSDC_WriteReg32(MSDC_DBG_SEL, idx);
+        MSDC_CRIT("=*=*=* MSDC_DBG_SEL:%d => MSDC_DBG_OUT:%x\r\n",
+                                          idx, MSDC_Reg32(MSDC_DBG_OUT));
+    }
+
+    MSDC_CRIT("====== MSDC Register and Debug Register Dump End   ======\r\n");
+}
+
+#ifdef _MSDC_DMA_
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMAInit
+*
+* DESCRIPTION
+*	Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMAInit(void)
+{
+
+}
+void MSDC_StartDMA(void)
+{
+	kal_uint32 ints=MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | 
+	                MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
+	                MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
+	//kal_uint32 ints=MSDC_DAT_INTS;
+	kal_uint32 abnormal_ints;
+    abnormal_ints=MSDC_Reg32(MSDC_INT)&ints;
+	if(0 != abnormal_ints)
+	{
+		/*error, have irq before we enable it*/
+	    MSDC_ERR("[MSDC][%s %d]abnormal irq %x\r\n",__FUNCTION__,__LINE__,abnormal_ints);
+		MSDC_WriteReg32(MSDC_INT,abnormal_ints);
+	}
+	MSDC_SetBits32(MSDC_INTEN, ints);
+	MSDC_SET_FIELD(MSDC_DMA_CTL, MSDC_DMA_CTL_START, 1);
+    gMSDC_Handle->is_timeout=KAL_FALSE;
+	MSDC_START_TIMER(MSDC_DMA_DAT_TMO);
+}
+SDC_CMD_STATUS MSDC_ConfigDMA(kal_uint32 * buffer,kal_uint32 num,msdc_gpd_t * gpd_ptr,kal_bool isLastBuf)
+{
+    kal_uint32 dma_ctl_arg;
+    #define BURST_8Byte		3
+	#define BURST_16Byte	4
+	#define BURST_32Byte	5
+	#define BURST_64Byte	6
+	/*if (gpd_ptr==NULL)
+	{
+		gMSDC_Handle->error=ERR_ARGUMENT;
+		#ifdef MSDC_DEBUG_PRINT
+		dbg_print("[MSDC][ERROR][%s %d]gpd_ptr point to zero\r\n",__FUNCTION__,__LINE__);
+		#endif
+		return ERR_ARGUMENT;
+	}*/
+	//set to DMA mode
+	//BitFieldWrite32((kal_uint32 *)MSDC_CFG, 0, MSDC_CFG_PIO);
+	MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_PIO);
+	gMSDC_Handle->dma_xfer=1;
+	if ((buffer==NULL) && (gpd_ptr != NULL))
+	{
+        /*use link list based DMA */
+
+        #ifdef MSDC_DMA_CHKSUM_EN
+        /*Enable descriptor 's checksum*/
+        MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
+        #else
+        /*Disable descriptor 's checksum*/
+        MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 0);
+        #endif
+
+        /*descriptor mode and burst size=64Bytes*/
+        dma_ctl_arg=(BURST_64Byte<<12)|MSDC_DMA_CTL_MODE;
+        MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
+        /*write DMA start address to GPD's physical address*/
+        MSDC_WriteReg32(MSDC_DMA_SA,gpd_ptr);
+	}
+	else if((buffer != NULL)&& (gpd_ptr == NULL))
+	{	
+		
+		/*use basic DMA*/
+		/*burst size\last buffer*/
+        dma_ctl_arg = (isLastBuf==KAL_TRUE)? ((BURST_64Byte<<12)|MSDC_DMA_CTL_LASTBUF) : (BURST_64Byte<<12);
+		MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
+		/*set xfer size*/
+		MSDC_WriteReg32(MSDC_DMA_LENGTH,num);
+		/*set address*/
+		MSDC_WriteReg32(MSDC_DMA_SA,buffer);
+	}
+    else
+    {
+        //wrong argument
+    }
+	return  NO_ERROR;
+}
+SDC_CMD_STATUS MSDC_WaitDMADone()
+{
+	kal_uint32 status;
+	kal_uint32 ints= MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | 
+	                MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
+	                MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
+
+	/*wait DMA done*/
+	kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE|EVENT_DMA_DONE,KAL_OR_CONSUME,&status,KAL_SUSPEND);
+	MSDC_STOP_TIMER();
+    MSDC_DEBUG("[MSDC][%s]msdc_int=%x\r\n",__FUNCTION__,gMSDC_Handle->msdc_int);
+	if (gMSDC_Handle->is_timeout)
+	{
+		MSDC_ERR("[MSDC][%s %d]wait DMA done GPT timeout\r\n",__FUNCTION__,__LINE__);
+		msdc_dump_reg();
+		gMSDC_Handle->error=MSDC_GPT_TIMEOUT_ERR;
+	}
+    /*Disable interrupt*/
+    MSDC_ClearBits32(MSDC_INTEN,ints);
+	/*stop dma*/
+	MSDC_STOP_DMA();
+	return gMSDC_Handle->error;
+}
+kal_uint32 MSDC_CheckCardBusy(kal_bool send_stop,kal_uint32 timeout_ms)
+{
+	kal_uint32 start_time,status;
+	kal_uint32 err,count=0;
+	start_time = drv_get_current_time(); 
+		
+	do{
+		err=SD_GetStatus(gSD->mRCA, &status);
+		if(err)
+		{
+			break;
+		}
+		count++;
+		if(count%5000==0)
+		{
+			if(send_stop)
+			{
+				SD_StopTrans();
+			}
+		}
+	}while((!(status&R1_READY_FOR_DATA_8)||(R1_CURRENT_STATE(status)==7))&&(drv_get_duration_ms(start_time) <=timeout_ms));
+	if (!(drv_get_duration_ms(start_time) <=timeout_ms))
+	{
+		MSDC_ERR("[MSDC][%s %d]card busy timeout\r\n",__FUNCTION__,__LINE__);
+		gMSDC_Handle->error=err=ERR_CARD_BUSY_TIMEOUT;
+	}
+	return err;
+}
+/************************************************************************
+* FUNCTION
+*  MSDC_DMATransferFinal_In_Callback
+*
+* DESCRIPTION
+*	Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+#if defined(MSDC_START_DMA_IN_CALLBACK)
+
+void MSDC_DMATransferFinal_In_Callback(void)
+{
+
+}
+
+kal_uint32 MSDC_DMATransferFinal(void)
+{
+
+}
+#endif
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMATransfer
+*
+* DESCRIPTION
+*	MSDC using DAM for data transfer
+*
+* PARAMETERS
+*	adrs: data buffer
+*	count: bytes to be transfered
+*	isTx: ture for move data from MSDC to data buffer and vise versa
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+void MSDC_DMATransferFirst( kal_bool isWrite,kal_bool isLinkListBuf)
+{
+	kal_uint32 * adrs;
+	
+	kal_set_eg_events(gMSDC_Handle->MSDC_Events,0,KAL_AND);
+    if (isLinkListBuf)
+    {
+        /*configure DMA*/
+        MSDC_ConfigDMA(NULL,gMSDC_Handle->total_count,(msdc_gpd_t *)gMSDC_Handle->buf_addr,1);
+    }
+    else
+    {
+        adrs=gMSDC_Handle->buf_addr;
+    	#ifdef MSDC_CACHED_SUPPORT
+    	if (gMSDC_Handle->isRomSpace)
+    	{
+    		gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_UNCACHED_TRANSFER_SIZE) ? (MSDC_UNCACHED_TRANSFER_SIZE) : gMSDC_Handle->total_count;
+    		/*copy from upper application buffer*/
+    		if (isWrite)
+    		{   
+    			kal_mem_cpy((void *)msdc_uncachedBuf,(void*)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count);
+    		}
+    		adrs=(kal_uint32 *)msdc_uncachedBuf;       
+    	}
+    	else if (gMSDC_Handle->isCachedBuf)
+        {
+            //clear cache  
+            gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
+            clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gMSDC_Handle->buf_addr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count));
+            Data_Mem_Barrier();
+        }  
+        else
+    	#endif 
+    	{
+    		gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
+    	} 
+        /*configure DMA*/
+        MSDC_ConfigDMA(adrs,gMSDC_Handle->trans_count,NULL,(gMSDC_Handle->total_count==gMSDC_Handle->trans_count));
+    }
+		
+}
+#if !defined(MSDC_START_DMA_IN_CALLBACK)
+kal_uint32 MSDC_DMATransferFinal(kal_bool isWrite,kal_bool isLinkListBuf)
+{
+	kal_uint32 status;
+	while(1)
+	{
+		/*start DMA*/
+		MSDC_StartDMA();
+		/*wait DMA finish*/
+		status=MSDC_WaitDMADone();
+		if (status!=NO_ERROR)
+		{
+		    MSDC_ERR("[MSDC][%s %d]INTS<%x>\r\n",__FUNCTION__,__LINE__,gMSDC_Handle->msdc_int);
+			goto done;
+		}
+        if (isLinkListBuf)
+        {
+            MSDC_DEBUG("[MSDC]link list DMA finish\r\n");
+            break;
+        }
+        else
+        {
+    		/*copy RX data when use cached buffer*/
+    		#ifdef MSDC_CACHED_SUPPORT
+    		if (gMSDC_Handle->isCachedBuf)
+    		{
+    		    /*if (!isWrite)
+                        {         
+        			    kal_mem_cpy((void *)gMSDC_Handle->buf_addr,(void *)msdc_uncachedBuf,gMSDC_Handle->trans_count);
+                        }*/
+                 //invalidate_dcache((gMSDC_Handle->buf_addr&~CPU_CACHE_LINE_SIZE_MASK),(gMSDC_Handle->trans_count+CPU_CACHE_LINE_SIZE_MASK)&~CPU_CACHE_LINE_SIZE_MASK);
+    		}
+    		#endif
+    		/*check need do further transfer or not */
+    		gMSDC_Handle->total_count-=gMSDC_Handle->trans_count;
+    		if (gMSDC_Handle->total_count==0)
+    		{
+    			gMSDC_Handle->error=NO_ERROR;
+    			goto done;
+    		}
+    		gMSDC_Handle->buf_addr+=gMSDC_Handle->trans_count;
+    		MSDC_DMATransferFirst( isWrite,isLinkListBuf);
+        }
+	}
+done:
+	
+	return status;
+}
+#endif //!defined(MSDC_START_DMA_IN_CALLBACK)
+
+#endif // DMA
+
+void* GetMsdcHandle(kal_uint8 id)
+{
+    return (void*)&MSDC_Blk[id];
+}
+
+#ifdef R1B_INTERRUPT_MODE
+static void MSDC_R1B_Init()
+{
+    
+}
+#endif
+
+// ===========================================================
+//     MSDC common lock
+// ===========================================================
+
+#if !defined(__FUE__) && !defined(__UBL__)
+
+void init_MSDC_lock(PMSDC_LOCK_TAG lock, const kal_char *str)
+{
+    if (lock->mtd_mutex == NULL)
+    {
+        strcpy((char *)lock->name, str);
+        lock->mtd_mutex = kal_create_mutex((kal_char *)lock->name);
+        lock->lock_count = 0;
+        lock->owner_id = NULL;
+    }
+}
+
+static kal_uint8 msdc_lock_user = 0;
+
+void get_MSDC_lock(PMSDC_LOCK_TAG lock)
+{
+    if (msdc_lock_user > 0)
+        ;//ASSERT(0); // init debugging purpose
+    else
+        msdc_lock_user ++;
+
+    if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
+        return;
+
+    if (kal_if_hisr() == KAL_TRUE || kal_if_lisr() == KAL_TRUE)
+    {
+        kal_uint32 retaddr0 = 0;
+        GET_RETURN_ADDRESS(retaddr0);
+        EXT_ASSERT(0, retaddr0, 0, 0);
+    }
+
+    if ( kal_get_current_task() == lock->owner_id )
+    {
+        force_ASSERT(0 != lock->lock_count, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
+        lock->lock_count++;
+    }
+    else
+    {
+        if (lock->mtd_mutex == NULL)
+        {
+            init_MSDC_lock(lock, (const kal_char *)lock->name);
+        }
+
+        kal_take_mutex(lock->mtd_mutex);
+     //   lock->owner_id = kal_get_task_self_id();
+     		lock->owner_id = kal_get_current_task();
+        lock->lock_count++;
+    }
+}
+
+void free_MSDC_lock(PMSDC_LOCK_TAG lock)
+{
+    if (msdc_lock_user != 1)
+        ;//ASSERT(0); // init debugging purpose
+    else
+        msdc_lock_user --;
+
+    if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
+        return;
+
+    if ( kal_get_current_task() == lock->owner_id )
+    {
+        force_ASSERT(lock->lock_count > 0, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
+        lock->lock_count--;
+
+        if (0 == lock->lock_count)
+        {
+            lock->owner_id = NULL;
+
+            if (lock->mtd_mutex != NULL)
+                kal_give_mutex(lock->mtd_mutex);
+        }
+    }
+    else
+    {
+        force_ASSERT(0, (kal_uint32)lock->owner_id, (kal_uint32)kal_get_current_task(), (kal_uint32)lock->mtd_mutex);
+    }
+}
+
+#else /* __FUE__, __UBL__ */
+
+//#define init_MSDC_lock(x)
+
+//#define get_MSDC_lock(x)
+
+//#define free_MSDC_lock(x)
+
+#endif /* !defined(__FUE__) && !defined(__UBL__) */
+
+#ifdef _MSDC_INT_
+
+#ifdef USE_INT26_CARD_DETECTION
+void MSDC_CardDetect_LISR(void)
+{
+    
+}
+#endif //USE_INT26_CARD_DETECTION
+
+
+#ifdef DRV_LSD
+kal_uint32 MSDC_CARD_INSERT_COUNTER, MSDC_CARD_REMOVE_COUNTER;
+kal_uint32 notifiedFMT;//this variable is to sync the state, since we only allow FMT get disk infor to be the first operation that access SD
+
+
+void MSDC_LSD_HISR(void)
+{
+    
+
+}
+
+void MSDC_unsealMountOperation(void)
+{
+    /*notifiedFMT may be modified by FMT and MMI tasks, but it is no need to protect this, any task that preempt FMT just get mount fail*/
+    if (1 == notifiedFMT) /*FMT may call this function no matter card exits or not*/
+    {
+        notifiedFMT = 2;
+    }
+
+}
+#endif
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+void MSDC_CD_Entry()
+{
+    /* Reverse the polarity */
+    cardDetectionEINTPolarity = !cardDetectionEINTPolarity;
+    EINT_Set_Polarity(MSDC_EINT_NUM, cardDetectionEINTPolarity); 
+
+    gMSDC_Handle->mIsChanged=KAL_TRUE;
+    
+    /*memory card insertion\removal */
+    if (!cardDetectionEINTPolarity)
+    {
+        gMSDC_Handle->mIsPresent=KAL_FALSE;
+        gMSDC_Handle->mIsInitialized=KAL_FALSE;
+    #ifdef MSDC_MUST_RECORD_PLUGOUT
+        if (KAL_FALSE == gMSDC_Handle->mIsPresent)
+            gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
+    #endif//MSDC_MUST_RECORD_PLUGOUT
+
+        MSDC_CRIT("[MSDC]Card Remove(EINT)\r\n");
+        MSDC_DeInit();
+    }
+    else
+    {
+        gMSDC_Handle->mIsPresent=KAL_TRUE;
+        gMSDC_Handle->mIsInitialized=KAL_FALSE;
+
+        MSDC_CRIT("[MSDC]Card Insert(EINT)\r\n");
+        MSDC_Probe();
+    }
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_INT_Init
+*
+* DESCRIPTION
+*	Initialize MSDC's interrupt
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_INT_Init(void)
+{
+	/*create events group*/
+	gMSDC_Handle->MSDC_Events=kal_create_event_group("MSDC Event");
+	/*register HISR*/
+	DRV_Register_HISR(DRV_MSDC_HISR_ID,MSDC_HISR_Entry);
+	/*register LISR*/
+	IRQ_Register_LISR(MD_IRQID_MSDC0,MSDC_LISR,"MSDC ISR");
+	IRQSensitivity(MD_IRQID_MSDC0,LEVEL_SENSITIVE);
+	IRQUnmask(MD_IRQID_MSDC0);
+	/*clear IRQ */
+	MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
+
+	/*register IRQ for card detect*/
+	/*enable card detect interrupt*/
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+    /*enable card detect*/
+    MSDC_SET_FIELD(MSDC_PS, MSDC_PS_CDEN, 1);
+    MSDC_SET_FIELD(MSDC_INTEN, MSDC_INTEN_CDSC, 1);
+#else
+
+    /* Polarity setting, default triggered by low level */
+    cardDetectionEINTPolarity = EINT_DefaultPolarity;
+
+    /* SW debounce time is 300ms */
+    MSDC_debounceTime=30;
+    
+    EINT_Mask(MSDC_EINT_NUM);    //need check the MSDC_EINT_NO ,unused current time
+
+    /* Level trigger */
+    EINT_Set_Sensitivity(MSDC_EINT_NUM, KAL_FALSE);
+    
+    EINT_Registration(MSDC_EINT_NUM,KAL_TRUE,cardDetectionEINTPolarity,MSDC_CD_Entry,KAL_TRUE);
+    EINT_SW_Debounce_Modify(MSDC_EINT_NUM,MSDC_debounceTime);
+    EINT_UnMask(MSDC_EINT_NUM);
+    
+#endif
+}
+void MSDC_LISR(void)
+{
+	/*Mask IRQ*/
+	IRQMask(MD_IRQID_MSDC0);
+	/*save IRQ information*/
+	gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
+	/*call hisr*/
+	drv_active_hisr(DRV_MSDC_HISR_ID);
+	
+}
+
+void MSDC_DatIrqHandle(kal_uint32 intsts)
+{
+	if (intsts & MSDC_INT_XFER_COMPL){
+		gMSDC_Handle->error=NO_ERROR;
+		kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
+	}
+	else if (intsts & MSDC_INT_DXFER_DONE)
+	{
+		
+		gMSDC_Handle->error=NO_ERROR;
+		kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_DMA_DONE,KAL_OR);
+	}
+	else
+	{
+		
+		/*mean some error */
+		if (intsts & MSDC_INT_DATCRCERR)
+		{
+			gMSDC_Handle->error=ERR_DAT_CRCERR;
+			MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT CRCERR!\r\n",__FUNCTION__, 
+			    __LINE__, gMSDC_Handle->cmd & 0x3F);
+		}
+		else if (intsts & MSDC_INT_DATTMO)
+		{
+			gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+			MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT TMO!\r\n",__FUNCTION__, 
+			    __LINE__, gMSDC_Handle->cmd & 0x3F);
+		} else if (intsts & MSDC_INT_BD_CS_ERR) {
+		
+			gMSDC_Handle->error = ERR_DAT_TIMEOUT;
+			MSDC_ERR("[MSDC][%s %d]CMD%d DMA BD checksum ERR!\r\n",__FUNCTION__, 
+			    __LINE__, gMSDC_Handle->cmd & 0x3F);
+		} else if (intsts & MSDC_INT_GPD_CS_ERR) {
+		
+			gMSDC_Handle->error = ERR_DAT_TIMEOUT;
+			MSDC_ERR("[MSDC][%s %d]CMD%d DMA GPD checksum ERR!\r\n",__FUNCTION__, 
+			    __LINE__, gMSDC_Handle->cmd & 0x3F);
+		}
+		
+		/*for poll mode exit*/
+		gMSDC_Handle->abort=1;
+
+		if (gMSDC_Handle->dma_xfer)
+		{
+			kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
+		}
+	}
+}
+void MSDC_CmdIrqHandle(kal_uint32 intsts)
+{
+	if ((intsts&MSDC_INT_CMDRDY)||(intsts&MSDC_INT_ACMDRDY)||(intsts&MSDC_INT_ACMD19_DONE))
+	{
+		gMSDC_Handle->error=NO_ERROR;
+	}
+	else if ((intsts&MSDC_INT_RSPCRCERR)||(intsts&MSDC_INT_ACMDCRCERR))
+	{
+		gMSDC_Handle->error=ERR_CMD_RSPCRCERR;
+	}
+	else if ((intsts&MSDC_INT_ACMDTMO)||(intsts&MSDC_INT_CMDTMO))
+	{
+		gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+	}
+	kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_CMD_DONE,KAL_OR);
+}
+
+void MSDC_CardDetectHandle(kal_uint32 intsts)
+{
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+
+
+    gMSDC_Handle->mIsChanged=KAL_TRUE;
+    
+    /*memory card insertion\removal */
+    if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
+    {
+        /*Card detection pin is logic high*/
+        gMSDC_Handle->mIsPresent=KAL_FALSE;
+        gMSDC_Handle->mIsInitialized=KAL_FALSE;
+    #ifdef MSDC_MUST_RECORD_PLUGOUT
+        if (KAL_FALSE == gMSDC_Handle->mIsPresent)
+        gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
+    #endif//MSDC_MUST_RECORD_PLUGOUT
+
+        MSDC_CRIT("[MSDC]Card Remove\r\n");
+        MSDC_DeInit();
+
+        }
+    else
+    {
+        /*Card detection pin is logic low*/
+        gMSDC_Handle->mIsPresent=KAL_TRUE;
+        gMSDC_Handle->mIsInitialized=KAL_FALSE;
+
+        MSDC_CRIT("[MSDC]Card Insert\r\n");
+        MSDC_Probe();
+    }
+
+#endif
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_HISR_Entry
+*
+* DESCRIPTION
+*	Set corresponding enevt and wake up waiting task.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_HISR_Entry(void)
+{
+	kal_uint32 cmdsts =MSDC_INT_CMDRDY|MSDC_INT_CMDTMO|MSDC_INT_RSPCRCERR;
+	kal_uint32 acmdsts =MSDC_INT_ACMDRDY|MSDC_INT_ACMDTMO|MSDC_INT_ACMDCRCERR|MSDC_INT_ACMD19_DONE;
+	kal_uint32 datsts =MSDC_INT_XFER_COMPL | MSDC_INT_DXFER_DONE |
+	                    MSDC_INT_DATCRCERR | MSDC_INT_DATTMO |
+	                    MSDC_INT_BD_CS_ERR | MSDC_INT_GPD_CS_ERR;
+
+    kal_uint32 intsts_pure;
+    kal_uint32 inten, intsts;
+
+	/*Mask IRQ*/
+	IRQMask(MD_IRQID_MSDC0);
+	/*save IRQ information*/
+	gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
+
+	intsts_pure=gMSDC_Handle->msdc_int;
+	inten=MSDC_Reg32(MSDC_INTEN);
+
+	intsts=intsts_pure&inten;
+	/*clear all interrupt*/
+	MSDC_WriteReg32(MSDC_INT,intsts);
+	/*data transfer interrupt*/
+	if (intsts&datsts)
+	{
+		MSDC_DatIrqHandle(intsts);	
+	}
+	/*command interrupt*/
+	if (intsts&(cmdsts|acmdsts))
+	{
+		MSDC_CmdIrqHandle(intsts);
+	}
+	/*card detect interrupt*/
+	if(intsts & MSDC_INT_CDSC) 
+	{
+		MSDC_CardDetectHandle(intsts);
+	}
+	/*mmc interrupt*/
+
+	/*unmask irq*/
+	IRQUnmask(MD_IRQID_MSDC0);
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMA_Callback
+*
+* DESCRIPTION
+*	Call back while DMA has done the data transfer.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMA_Callback(void)
+{
+
+}
+
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+void MSDC_changeSwContext(sd_select_enum sel)
+{
+    gMSDC_Handle = &MSDC_Blk[sel];
+    gSD = &gSD_blk[sel];
+}
+
+/*
+	this function do not consider race condition issue, caller should make sure this function is called without risk
+	currently, this function is called in sdio_drv.c and sd_drv.c
+*/
+void MSDC_backupHwSetting()
+{
+    /*backup MSDC_CFG, MSDC_IOCON, SDC_CFG*/
+    gMSDC_Handle->setting_MSDC_CFG = MSDC_Reg32(MSDC_CFG);
+    gMSDC_Handle->setting_MSDC_IOCON = MSDC_Reg32(MSDC_IOCON);
+    gMSDC_Handle->setting_SDC_CFG = MSDC_Reg32(SDC_CFG);
+}
+
+void MSDC_retreiveHwSetting()
+{
+    MSDC_WriteReg32(MSDC_CFG, gMSDC_Handle->setting_MSDC_CFG);
+    MSDC_WriteReg32(MSDC_IOCON, gMSDC_Handle->setting_MSDC_IOCON);
+    MSDC_WriteReg32(SDC_CFG, gMSDC_Handle->setting_SDC_CFG);
+}
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+void MSDC_Switch_Card(sd_select_enum sel)
+{
+    
+}
+#endif
+
+#endif //end of MSDC_INT
+
+
+void MSDC_turnOnVMC(kal_bool turnOnLdo)
+{
+    
+}
+
+#if defined(MSDC_TRACE_LEVEL3)
+void MSDC_add_dbg_msg( msdc_dbg_Event event, kal_uint32 data1, kal_uint32 data2)
+{
+
+}
+#endif
+
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+void MSDC_Switch_SDIO(sd_select_enum sel)
+{
+    
+
+}
+#endif
+
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+
+/*following should be the value defined in custom files*/
+#define MSDC_SWITCH_2_SD		1
+#define MSDC_SWITCH_2_SDIO	0
+#define MSDC_SWITCH_GPIO		20
+typedef enum
+{
+    MSDC_SWITCH_DIRECTION_SD,
+    MSDC_SWITCH_DIRECTION_SDIO
+} MSDC_SWITCH_DIRECTION;
+
+
+void MSDC_Switch_init()
+{
+   
+}
+
+/*
+	direction:
+		0 :	cmmb
+		1 :	sd card
+*/
+
+void MSDC_Switch(sd_select_enum direction)
+{
+    
+}
+#endif
+
+
+#else
+#ifdef DRV_LSD
+void MSDC_LSD_HISR(void)
+{
+}
+#endif
+#endif // end of  (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__))
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "msdc_def.h"
+
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR REMOVE
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "stacklib.h"
+#include "eint.h"
+#include "fat_fs.h"
+*/
+//RHR
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"  
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h"     
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+//#include "gpt_sw.h"
+#include "drv_comm.h"
+#include "drv_hisr.h"
+#include "msdc_def.h"
+#include "dcl.h"
+
+/* Debug log */
+kal_uint32 MSDC_DebugLevel;
+
+#define LDO_VMC             0
+#define LDO_VMCH            1
+#define LDO_VIO18_PMU       2
+
+static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
+static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
+
+static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt) 
+{
+    PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+    PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
+    DCL_HANDLE handle;
+
+    /* Open PMU handle */
+    handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+    
+    switch(powerID) {
+        case LDO_VMC:
+            /* Set enable control */
+            pmu_en.mod = VMC;
+            pmu_en.enable = 1;
+
+            /* Set voltage */
+            pmu_volsel.mod = VMC;
+            pmu_volsel.voltage = powerVolt;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        case LDO_VMCH:
+            /* Set enable control */
+            pmu_en.mod = VMCH;
+            pmu_en.enable = 1;
+
+            /* Set voltage */
+            pmu_volsel.mod = VMCH;
+            pmu_volsel.voltage = powerVolt;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        default:
+        break;
+    }
+
+    /* Close PMU handle */
+    DclPMU_Close(handle);
+    
+    return 1;
+}
+
+static kal_uint32 hwPowerDown(kal_uint32 powerID) 
+{
+    PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+    DCL_HANDLE handle;
+
+    /* Open PMU handle */
+    handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+    switch(powerID) {
+        case LDO_VMC:
+            /* Set enable control */
+            pmu_en.mod = VMC;
+            pmu_en.enable = 0;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+        break;
+
+        case LDO_VMCH:
+            /* Set enable control */
+            pmu_en.mod = VMCH;
+            pmu_en.enable = 0;
+
+            DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+            
+        break;
+
+        default:
+        break;
+    }
+
+    /* Close PMU handle */
+    DclPMU_Close(handle);
+
+    return 1;
+}
+
+static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId, 
+    PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
+{
+    if (on) { // want to power on
+        if (*status == 0) {  // can power on 
+            hwPowerOn(powerId, powerVolt);
+            
+            *status = powerVolt;             
+        } else if (*status == powerVolt) {
+        } else { // for sd3.0 later
+
+            hwPowerDown(powerId);
+            hwPowerOn(powerId, powerVolt);
+            
+            *status = powerVolt;
+        }
+    } else {  // want to power off
+        if (*status != 0) {  // has been powerred on
+
+            hwPowerDown(powerId);
+            
+            *status = 0;
+        } else {
+        }                
+    }  
+    
+    return 0;          
+}
+
+kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
+{
+	kal_bool ret =KAL_TRUE;
+	    
+	if (volt == 3300)
+	{
+		msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
+	}
+	else
+	{
+		ret = KAL_FALSE;
+	}
+		
+	return ret;
+}
+
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+	kal_bool ret =KAL_TRUE;
+	if (volt == 3300)
+	{
+		msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
+	}
+	else if (volt ==1800)
+	{
+        msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
+	} 
+	else
+	{
+		ret = KAL_FALSE;
+	}
+		
+	return ret;
+}
+
+/*here are dummy API*/
+void MSDC_Initialize(void) 
+{
+    /* INIT MSDC debug flag */
+    MSDC_SetDebugLevel(K_WARNIN);
+    
+    /* Shut card power and signal power */
+	MSDC_SetVddPower(KAL_FALSE, 3300);
+	MSDC_SetSignalPower(KAL_FALSE, 3300);
+}
+
+void MSDC_PDNControl(kal_bool ON) {}
+int MSDC_GetCardStatus(void * DriveData, int AckType) {return 0;}
+//kal_bool MSDC_GetMediaChanged(void * id) {}
+kal_bool MSDC_GetMediaChanged(sd_select_enum id) {return 0;}
+MSDC_HANDLE MSDC_Blk[SD_NUM];
+MSDC_HANDLE	*gMSDC_Handle = &(MSDC_Blk[0]);
+//kal_bool MSDC_everPlugOut;
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/msdc2.c b/mcu/driver/storage/mc/src/msdc2.c
new file mode 100644
index 0000000..d96043f
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc2.c
@@ -0,0 +1,1049 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   msdc2.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   driver functons for MSDC controller
+ *   
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/ 
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"  
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h"       /* Task message communiction */
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "stacklib.h"
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+#include "eint.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "fat_fs.h"
+#include "dma_hw.h"
+#include "dma_sw.h"
+#include "drv_hisr.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#if defined(__MSDC2_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+#include "sdio_sw.h"
+#endif
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#elif defined(__MSDC_MSPRO__)
+#include "mspro_def.h"
+#endif
+#include "upll_ctrl.h"
+//#include "gpio_hw.h"
+//#include "gpio_sw.h"
+//#include "sim_hw.h"
+#ifdef __MULTI_BOOT__
+#include "syscomp_config.h"
+#include "multiboot_config.h"
+#endif   /*__MULTI_BOOT__*/
+//#include "sim_hw.h"
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON0
+#error "__CLKG_DEFINE__ & DRVPDN_CON0 are all defined"
+#else
+#define DRVPDN_CON0		CG_CON0
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM	CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR	CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET	CG_SET0
+#endif
+#endif
+
+
+
+
+#pragma arm section zidata = "NONCACHEDZI",  rwdata = "NONCACHEDRW"
+kal_uint32 MSDC_Sector2[128] = {0};
+MSDC_HANDLE *msdc2_handle = &MSDC_Blk[SD_MSDC2];
+
+#ifdef MSDC_CACHED_SUPPORT
+kal_uint32	msdc_uncachedBuf2[MSDC_UNCACHED_BUF_SIZE/4];	
+#endif
+#pragma arm section zidata, rwdata
+
+// function predeclaration
+void MSDC_DMAInit2(void);
+void MSDC_INT_Init2(void);
+void MSDC_DMA_Callback2(void);
+extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
+extern boot_mode_type stack_query_boot_mode(void); 
+extern kal_bool INT_USBBoot(void);
+extern kal_uint32 MSDC_GetCustom(void);
+/*************************************************************************
+* FUNCTION
+*  MSDC_SetClock
+*
+* DESCRIPTION
+*
+* PARAMETERS
+*	clock: the desired operating clock rate in the unit of kHz
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void MSDC_SetClock2(kal_uint32 clock)
+{
+	kal_uint32 cfg;
+
+	if(clock == 0)
+		return;
+	MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);
+	cfg = ((msdc2_handle->msdc_clock+clock-1)/clock);
+	if(cfg <=2 )
+	{		
+		cfg = 0;
+		msdc2_handle->op_clock = msdc2_handle->msdc_clock/2;
+	}
+	else
+	{
+		cfg = (cfg >> 2) + (cfg&3 != 0);	
+		msdc2_handle->op_clock = msdc2_handle->msdc_clock/(4*cfg);
+	}
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)cfg,MSDC_CFG_SCLKF);
+	MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_SIEN);
+	
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_Check_Card_Present2
+*
+* DESCRIPTION
+*	c
+*
+* PARAMETERS
+*	ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_Check_Card_Present2(void)
+{
+#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	return msdc2_handle->mIsPresent;
+#else
+	return KAL_TRUE;
+#endif
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_PDNControl
+*
+* DESCRIPTION
+*	Enable power saving or not.
+*
+* PARAMETERS
+*	ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_PDNControl2(kal_bool ON)
+{
+	msdc2_handle->mIsPWDown = ON;
+	if(ON)
+	{	// OFF		
+		MSDC_CLR_INT2();
+		MSDC_CLR_INT2();
+		#if defined(MSDC_USE_USB_CLK) && defined(__MSDC2_SD_MMC__)
+		if(gSD_blk[SD_MSDC2].flags & SD_FLAG_USE_USB_CLK)
+			UPLL_Disable(UPLL_OWNER_MSDC2);
+		#endif
+		DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);		
+	}
+	else
+	{	// ON
+		DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+		#if defined(MSDC_USE_USB_CLK) && defined(__MSDC2_SD_MMC__)
+		if(gSD_blk[SD_MSDC2].flags & SD_FLAG_USE_USB_CLK)
+			UPLL_Enable(UPLL_OWNER_MSDC2);		
+		#endif
+	}
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_TimeOutHandler2
+*
+* DESCRIPTION
+*	Callback function of gpt timer, and launched while MSDC busy for a while
+
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_TimeOutHandler2(void *parameter)
+{
+	tst_sys_trace("MSDC_TimeOutHandler2");
+	msdc2_handle->is_timeout = KAL_TRUE;
+	#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+	kal_set_eg_events(msdc2_handle->MSDC_Events,
+				(EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
+				KAL_OR);	
+	#else
+	kal_set_eg_events(msdc2_handle->MSDC_Events,
+				(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
+				KAL_OR);	
+	#endif	
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_GetCardStatus
+*
+* DESCRIPTION
+*	Check currently card is present or not.
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	msdc_eint_state
+*
+*
+*************************************************************************/
+int MSDC_GetCardStatus2(void * DriveData, int AckType)
+{
+	MSDC_HANDLE *msdc = (MSDC_HANDLE *)DriveData;;
+
+	// a debounce mechanism 
+    if(kal_query_systemInit() == KAL_FALSE)
+    {
+        kal_sleep_task(100);        
+    }    
+	ENTER_CRITICAL();
+	msdc->send_ilm = KAL_TRUE;
+	EXIT_CRITICAL();
+	
+	
+	if(!msdc->mIsPresent)
+		MSDC_PDNControl2(KAL_TRUE);
+	return 0;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_Config_INS_WP
+*
+* DESCRIPTION
+* 	Configure the pull up or pull down status for INS and WP pin
+*
+* PARAMETERS
+*	1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*	2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
+*	2. MT6218B and MT6217, WP is configured with data lines.
+*************************************************************************/
+void MSDC_Config_INS_WP2(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
+{
+	kal_uint32 msdc_cfg,iocon;
+		
+	msdc2_handle->ins_level = ins;
+	//#if defined(MT6218B) || defined(MT6217)
+	// INS use PRCFG3, WP use PRCFG0
+	MSDC_SetData32(MSDC_CFG2,  MSDC_CFG_PRCFG0, (wp << 22));
+	MSDC_SetData32(MSDC_IOCON2,  MSDC_IOCON_PRCFG3, (ins << 8));
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_Initialize
+*
+* DESCRIPTION
+*	Initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*	
+*
+* RETURNS
+*  1: initailized failed 
+*  0: successful
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+void MSDC_Initialize2(void)
+{	
+
+	// turn on the power of controler
+	DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+#if defined(__MSDC_MS__)
+	MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_MSDC);
+	msdc2_handle->mMSDC_type = MS_CARD;
+#elif defined(__MSDC_MSPRO__)
+	MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_MSDC);
+	msdc2_handle->mMSDC_type = MSPRO_CARD;	
+	FS_MspDrvAll = FS_MspDrv;
+#elif (defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__))
+	MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_MSDC)	;
+	msdc2_handle->mMSDC_type = SD_CARD;
+#endif		
+	msdc2_handle->msdc_clock = MSDC_CLOCK;
+
+	if(msdc2_handle->gpt_handle == 0)
+		MSDC_GPTI_GetHandle(&msdc2_handle->gpt_handle);
+	#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+	MSDC_Config_INS_WP2(MSDC_IOCTRL_PULL_UP,MSDC_IOCTRL_PULL_UP);
+	#else
+	MSDC_Config_INS_WP2(MSDC_IOCTRL_PULL_DOWN,MSDC_IOCTRL_PULL_UP);
+	// first time if card is present, no card insertion interrupt generated
+	msdc2_handle->mIsPresent = KAL_TRUE; 
+	#endif
+	// turn on the power of memory card
+	MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_VDDPD);
+	MSDC_SET_FIFO2(1);
+	
+	if(MSDC_GetCustom() & MSDC2_HOT_PLUG)
+	{
+		// enable card detection
+		MSDC_WriteReg32(MSDC_PS2, MSDC_PS_CDEN|MSDC_PS_PIEN0|MSDC_PS_POEN0);
+		if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+			else
+				msdc2_handle->mIsPresent = KAL_TRUE;	
+		}
+		else
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_TRUE;
+			else
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+		}
+		MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_PINEN);
+	}
+	else
+	{
+		msdc2_handle->mIsPresent = KAL_TRUE;
+	}
+					
+	#ifdef MSDC_INT
+	MSDC_INT_Init2();	
+	#endif	// end of MSDC_INT
+	#ifdef MSDC_DMA
+	MSDC_DMAInit2();
+	#endif	
+	#ifdef __MULTI_BOOT__
+	if(stack_query_boot_mode() != NORMAL_BOOT)
+		msdc2_handle->send_ilm = KAL_FALSE;
+	else
+		msdc2_handle->send_ilm = KAL_TRUE;
+	#else
+		msdc2_handle->send_ilm = KAL_FALSE;
+	#endif
+		
+	DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);	
+}
+
+void MSDC_SetIOCONRegDLT2(void)
+{
+	kal_uint32 factor;
+	
+	/*set DLT field according to SCLKF seeting*/
+	factor = msdc2_handle->msdc_clock/msdc2_handle->op_clock;
+	BitFieldWrite32((kal_uint32*)MSDC_IOCON2,(kal_uint32)(factor/2),MSDC_IOCON_DLT);
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_GetMediaChanged
+*
+* DESCRIPTION
+*	Check if the media is changed, and clear the status after function call
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*! combined to MSDC_GetMediaChanged(), and removed in HAL [20101203 Samuel]
+kal_bool MSDC_GetMediaChanged2(void* id)
+{	
+	kal_bool ret;
+
+	ENTER_CRITICAL();
+	msdc2_handle = (MSDC_HANDLE *)id;		
+	ret = (msdc2_handle->mIsChanged )?(KAL_TRUE):(KAL_FALSE);
+	msdc2_handle->mIsChanged = KAL_FALSE;	
+	EXIT_CRITICAL();
+		
+	return ret; 
+}
+*/
+
+#ifdef MSDC_DMA 
+extern kal_uint8 DMA_GetChannel(DMA_Master DMA_CODE);
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMAInit
+*
+* DESCRIPTION
+*	Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+void MSDC_DMAInit2(void)
+{	
+	msdc2_handle->msdc_dmaport = DMA_GetChannel(DMA_MSDC2);
+	msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+	msdc2_handle->msdc_menu.TMOD.cycle = 0x4;
+	msdc2_handle->msdc_menu.master = DMA_MSDC2;
+	msdc2_handle->msdc_menu.addr = NULL;
+	msdc2_handle->msdc_input.type = DMA_HWRX;
+	msdc2_handle->msdc_input.size = DMA_LONG;
+	msdc2_handle->msdc_input.count = 0;
+	msdc2_handle->msdc_input.menu = &msdc2_handle->msdc_menu;
+}
+
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMATransfer
+*
+* DESCRIPTION
+*	MSDC using DAM for data transfer 
+*
+* PARAMETERS
+*	adrs: data buffer
+*	count: bytes to be transfered
+*	isTx: ture for move data from MSDC to data buffer and vise versa
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+void MSDC_DMATransferFirst2(kal_uint32 adrs,kal_uint32 count, kal_bool isTx)
+{
+	kal_uint32 total_count;
+	kal_bool is_aligned, is_poll;
+
+	DMA_Stop(msdc2_handle->msdc_dmaport);	
+
+#ifdef MSDC_CACHED_SUPPORT
+	if (KAL_TRUE == msdc2_handle->isCachedBuf){
+		msdc2_handle->msdc_menu.addr = (kal_uint32)msdc_uncachedBuf2;
+		msdc2_handle->cachedBufCopyPtr = adrs;
+	}
+	else
+#endif	
+	msdc2_handle->msdc_menu.addr = adrs;
+	
+	
+	if(isTx)
+	{
+		msdc2_handle->timeout_period = (50 + (count>>5));
+		msdc2_handle->msdc_input.type = DMA_HWTX;		
+		if(count <= MSDC_WRITE_THD_POLL)
+		{
+			msdc2_handle->msdc_input.callback = NULL;
+			is_poll = KAL_TRUE;			
+		}
+		else
+		{
+			msdc2_handle->msdc_input.callback = MSDC_DMA_Callback2;
+			is_poll = KAL_FALSE;
+		}
+	}
+	else
+	{
+	   msdc2_handle->timeout_period = (50 + (count>>7));
+		msdc2_handle->msdc_input.type = DMA_HWRX;	
+		if(count <= MSDC_READ_THD_POLL)
+		{
+			msdc2_handle->msdc_input.callback = NULL;
+			is_poll = KAL_TRUE;
+		}
+		else
+		{
+			msdc2_handle->msdc_input.callback = MSDC_DMA_Callback2;
+			is_poll = KAL_FALSE;
+		}
+	}
+
+	if(kal_query_systemInit() == KAL_TRUE 
+#ifdef  __TST_WRITE_TO_FILE_ONLY__	/*error recording: considering error recording additionally*/
+		|| (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+	)
+	{
+		msdc2_handle->msdc_input.callback = NULL;
+		is_poll = KAL_TRUE;
+	}	
+
+#ifndef MSDC_CACHED_SUPPORT
+	if(adrs%4 == 0)
+	{
+		is_aligned = KAL_TRUE;
+		total_count = count;
+	}
+	else
+	{
+		is_aligned = KAL_FALSE;
+		total_count = count<<2;
+	}
+#else
+	if(adrs%4 == 0 || KAL_TRUE == msdc2_handle->isCachedBuf)
+	{
+		is_aligned = KAL_TRUE;
+		total_count = count;
+	}
+	else
+	{
+		is_aligned = KAL_FALSE;
+		total_count = count<<2;
+	}
+#endif
+	msdc2_handle->total_count = total_count;
+	msdc2_handle->is_poll = is_poll;
+	msdc2_handle->is_aligned = is_aligned;
+	{
+		if(is_aligned)
+		{
+			#if defined(USE_DMA_BURST)
+			MSDC_SET_FIFO2(4);
+			#else
+			msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_FALSE;
+			#endif
+#ifdef MSDC_CACHED_SUPPORT
+			if(KAL_TRUE == msdc2_handle->isCachedBuf)
+				msdc2_handle->msdc_input.count = (total_count > MSDC_UNCACHED_TRASNFER_SIZE)?(MSDC_UNCACHED_TRASNFER_SIZE):(total_count);
+			else 
+#endif			
+			msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+#ifdef MSDC_CACHED_SUPPORT
+	if(KAL_TRUE == msdc2_handle->isCachedBuf){ 
+		/*have do memory copy stuff here*/
+		if(DMA_HWTX == msdc2_handle->msdc_input.type){
+			/*copy from upper application buffer*/
+			kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+			msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+		}
+	}
+#endif	
+			msdc2_handle->msdc_input.size = DMA_LONG;		
+			DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_FALSE);
+			msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count*4;
+		}
+		else
+		{
+#ifdef MSDC_CACHED_SUPPORT
+			if(KAL_TRUE == msdc2_handle->isCachedBuf)
+				ASSERT(0);
+#endif		
+			#if defined(USE_DMA_BURST)
+			MSDC_SET_FIFO2(1);
+			#else
+			
+			msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+			#endif
+			msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+			msdc2_handle->msdc_input.size = DMA_BYTE;
+			DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_TRUE);
+			msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count;
+		}
+		
+	}
+}
+kal_uint32 MSDC_DMATransferFinal2(void)
+{
+	kal_uint32 total_count = msdc2_handle->total_count, t1;
+	kal_bool is_poll = msdc2_handle->is_poll;
+	kal_bool is_aligned = msdc2_handle->is_aligned;
+
+	t1 = drv_get_current_time();
+	if(msdc2_handle->timeout_period > MSDC_TIMEOUT_PERIOD_DAT)
+		msdc2_handle->timeout_period = MSDC_TIMEOUT_PERIOD_DAT;
+	MSDC_START_TIMER2(msdc2_handle->timeout_period);
+	if(is_poll)
+	{
+		while(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+				msdc2_handle->is_timeout = KAL_TRUE;
+		}
+	}
+	else
+	{
+		kal_uint32 flags;
+		kal_retrieve_eg_events(msdc2_handle->MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);				
+	}				
+	MSDC_STOP_TIMER2();
+	if(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && msdc2_handle->is_timeout)
+		return MSDC_GPT_TIMEOUT_ERR;
+	
+	total_count -= msdc2_handle->msdc_input.count;
+	if(total_count == 0){
+#ifdef MSDC_CACHED_SUPPORT
+	if(KAL_TRUE == msdc2_handle->isCachedBuf){
+		if(DMA_HWRX == msdc2_handle->msdc_input.type){
+			/*copy to upper application's buffer*/
+			kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+		}
+	}
+#endif					
+		return MSDC_NOERROR;
+	}
+	
+#ifdef MSDC_CACHED_SUPPORT
+	if(KAL_TRUE == msdc2_handle->isCachedBuf){
+		/*have do memory copy stuff here*/
+		if(DMA_HWTX == msdc2_handle->msdc_input.type){
+			/*copy from upper application buffer*/
+			kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+		}
+		else{
+			/*copy to upper application's buffer*/
+			kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+		}
+		msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+	}
+#endif		
+	while(1)
+	{
+		if(is_aligned)
+		{
+			#if defined(USE_DMA_BURST)
+			MSDC_SET_FIFO(4);
+			#else
+			msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_FALSE;
+			#endif
+#ifdef MSDC_CACHED_SUPPORT
+			if(KAL_TRUE == msdc2_handle->isCachedBuf)
+				msdc2_handle->msdc_input.count = (total_count > MSDC_UNCACHED_TRASNFER_SIZE)?(MSDC_UNCACHED_TRASNFER_SIZE):(total_count);
+			else 
+#endif						
+			msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+			msdc2_handle->msdc_input.size = DMA_LONG;		
+			DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_FALSE);
+#ifdef MSDC_CACHED_SUPPORT
+			/*we don't need to increase the addr when encounter cached buffer, since we only have a fix size uncached buffer to use*/
+			if(KAL_FALSE == msdc2_handle->isCachedBuf)
+#endif			
+			{
+				msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count*4;
+			}
+			msdc2_handle->timeout_period = 1 + (msdc2_handle->msdc_input.count>>7);
+		}
+		else
+		{
+#ifdef MSDC_CACHED_SUPPORT
+			if(KAL_TRUE == msdc2_handle->isCachedBuf)
+				ASSERT(0);
+#endif			
+			#if defined(USE_DMA_BURST)
+			MSDC_SET_FIFO(1);
+			#else
+			msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+			#endif
+			msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+			msdc2_handle->msdc_input.size = DMA_BYTE;
+			DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_TRUE);
+			msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count;
+			msdc2_handle->timeout_period = 1 + (msdc2_handle->msdc_input.count>>9);
+		}
+		
+		// wait until running bit clr
+		if(msdc2_handle->msdc_input.type == DMA_HWTX)
+			msdc2_handle->timeout_period <<= 2 ;
+		if(msdc2_handle->mMSDC_type == MMC_CARD)
+			msdc2_handle->timeout_period <<= 1;
+		
+		t1 = drv_get_current_time();
+		MSDC_START_TIMER2(msdc2_handle->timeout_period);
+		if(is_poll)
+		{
+			while(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+			{
+				if(drv_get_duration_ms(t1) > msdc2_handle->timeout_period*11)
+					msdc2_handle->is_timeout = KAL_TRUE;				
+			}
+		}
+		else
+		{
+			kal_uint32 flags;
+			kal_retrieve_eg_events(msdc2_handle->MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);				
+		}				
+		MSDC_STOP_TIMER2();
+		if(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && msdc2_handle->is_timeout)
+			return MSDC_GPT_TIMEOUT_ERR;
+		total_count -= msdc2_handle->msdc_input.count;
+		if(total_count == 0)
+			break;		
+#ifdef MSDC_CACHED_SUPPORT
+	if(KAL_TRUE == msdc2_handle->isCachedBuf){ 
+		/*have do memory copy stuff here*/
+		if(DMA_HWTX == msdc2_handle->msdc_input.type){
+			/*copy from upper application buffer*/
+			kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+		}
+		else{
+			/*copy to upper application's buffer*/
+			kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+		}
+		msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+	}
+#endif				
+	}
+
+#ifdef MSDC_CACHED_SUPPORT
+	if(KAL_TRUE == msdc2_handle->isCachedBuf){
+		if(DMA_HWRX == msdc2_handle->msdc_input.type){
+			/*copy to upper application's buffer*/
+			kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+		}
+	}
+#endif
+	return MSDC_NOERROR;
+}
+
+
+#endif // DMA
+
+#ifdef MSDC_INT
+/*************************************************************************
+* FUNCTION
+*  MSDC_INT_Init
+*
+* DESCRIPTION
+*	Initialize MSDC's interrupt
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+void MSDC_INT_Init2(void)
+{
+	
+   msdc2_handle->MSDC_Events = kal_create_event_group("MSDC2");
+   DRV_Register_HISR(DRV_MSDC2_HISR_ID, MSDC_HISR_Entry2);
+   IRQ_Register_LISR(IRQ_MSDC2_CODE, MSDC_LISR2,"MSDC_LISR2");
+   IRQSensitivity(IRQ_MSDC2_CODE,LEVEL_SENSITIVE);
+   IRQUnmask(IRQ_MSDC2_CODE);
+   
+	// enable MSDC interrupt
+	MSDC_CLR_INT();	
+	#if !defined(MSDC_USE_INT)
+	MSDC_DISABLE_INT2();// (active)turn off other interrupt event except pin interrupt		
+	#else
+	MSDC_ENABLE_INT2();// (deactive)
+	#endif
+	
+}
+void MSDC_LISR2(void)
+{
+	IRQMask(IRQ_MSDC2_CODE);
+	drv_active_hisr(DRV_MSDC2_HISR_ID);
+} 
+/*************************************************************************
+* FUNCTION
+*  MSDC_HISR_Entry
+*
+* DESCRIPTION
+*	Set corresponding enevt and wake up waiting task.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+void MSDC_HISR_Entry2(void)
+{
+	kal_uint16 msdc_int = 0;
+
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+	kal_uint16 msc_sta;
+
+	FS_MspDrvAll = FS_MspDrv;
+	TurnOnMSDC2();
+	msc_sta = MSDC_Reg(MSC_STA2);
+	if(msc_sta & MSC_STA_SIF)
+		kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_MSIFIRQ,KAL_OR);
+	else
+		kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_MSRDYIRQ,KAL_OR);
+
+	msdc_int = MSDC_Reg(MSDC_INTR);
+	if(msdc_int & MSDC_INT_PINIRQ)
+	{
+		msdc2_handle->mIsInitialized = KAL_FALSE;	
+		msdc2_handle->mIsChanged = KAL_TRUE;		
+		kal_set_eg_events(msdc2_handle->MSDC_Events,
+			(EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
+			KAL_OR);								
+		if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+			else
+				msdc2_handle->mIsPresent = KAL_TRUE;	
+		}
+		else
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_TRUE;
+			else
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+		}
+		if(msdc2_handle->mIsPresent == KAL_FALSE)
+		{			
+			MSDC_CLR_FIFO2();
+			MSDC_CLR_INT2();
+			MSDC_CLR_INT2();
+			DMA_Stop(msdc2_handle->msdc_dmaport);		
+		}
+		#if !defined(FMT_NOT_PRESENT)
+			MSDC_SendCardInd(MOD_FMT, SD_MSDC2);		
+		#endif		
+	}
+#else // sd/mmc start here
+	TurnOnMSDC2();		
+	msdc_int = MSDC_Reg(MSDC_INTR2);
+   #if defined(__MSDC2_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+	/*SDIO*/
+	if(msdc_int & MSDC_INT_SDIOIRQ)
+	{	    
+      SDIO_HISR_Entry();		   		 
+	} 
+	#endif 	
+
+	if(msdc_int & MSDC_INT_PINIRQ)
+	{
+		msdc2_handle->mIsInitialized = KAL_FALSE;				
+		msdc2_handle->mIsChanged = KAL_TRUE;				
+		if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+			else
+				msdc2_handle->mIsPresent = KAL_TRUE;	
+		}
+		else
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_TRUE;
+			else
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+		}
+		if(msdc2_handle->mIsPresent == KAL_FALSE)
+		{
+			MSDC_CLR_FIFO2();
+			MSDC_CLR_INT2();
+			MSDC_CLR_INT2();
+			DMA_Stop(msdc2_handle->msdc_dmaport);		
+		}	
+		#if !defined(FMT_NOT_PRESENT)
+			MSDC_SendCardInd(MOD_FMT, SD_MSDC2);		
+		#endif
+	}	
+	#endif // MSDC_MS
+	IRQUnmask(IRQ_MSDC2_CODE);				
+}
+/*************************************************************************
+* FUNCTION
+*  MSDC_DMA_Callback
+*
+* DESCRIPTION
+*	Call back while DMA has done the data transfer.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+void MSDC_DMA_Callback2(void)
+{
+	kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_DMAIRQ,KAL_OR);			
+}
+
+#endif //end of MSDC_INT
+#endif // end of  (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)) && defined(__MSDC2_SD_MMC__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/msdc_fake_kal.c b/mcu/driver/storage/mc/src/msdc_fake_kal.c
new file mode 100644
index 0000000..ddebaea
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc_fake_kal.c
@@ -0,0 +1,203 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2007
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   msdc_fake_kal.c
+ *
+ * Project:
+ * --------
+ *   Maui
+ *
+ * Description:
+ * ------------
+ *   Resource Manager fake kal code body for multiplatform using
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "drv_comm.h"
+
+#if (defined(__UBL__) || defined(__FUE__)) && (defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__))
+
+#include "msdc_def.h"
+#include "msdc_fake_kal.h"
+
+kal_bool kal_if_hisr(void)
+{
+  return KAL_FALSE;
+}
+
+kal_semid kal_create_sem(kal_char *name, kal_uint32 initial_count)
+{
+  return NULL;
+}
+
+kal_status kal_take_sem(kal_semid ext_sem_id_ptr, kal_wait_mode wait_mode)
+{
+  return 0;
+}
+
+void kal_give_sem(kal_semid ext_sem_id_ptr)
+{
+}
+
+void* kal_get_current_thread_ID(void)
+{
+  return NULL;
+}
+
+ilm_struct* allocate_ilm(module_type module_id)
+{
+  return NULL;
+}
+
+kal_bool msg_send_ext_queue(ilm_struct *ilm_ptr)
+{
+  return KAL_TRUE;
+}
+
+void* construct_int_local_para(kal_uint16 local_para_size, kal_uint32 auto_reset,
+                               kal_char* file_ptr, kal_uint32 line)
+{
+	ASSERT(0);
+	return NULL;
+}
+
+#if 0 // [Carlos] move to dummy
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#endif//defined(__UBL__) && (defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__))
+
diff --git a/mcu/driver/storage/mc/src/msdc_test.c b/mcu/driver/storage/mc/src/msdc_test.c
new file mode 100644
index 0000000..917628b
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc_test.c
@@ -0,0 +1,8529 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc_test.c
+ *
+ * Project:
+ * --------
+ *   MT6268ADVT
+ *
+ * Description:
+ * ------------
+ *   This file is used when doing msdc dvt, when enable __MSDC_BASIC_LOAD__, functions here will replace ssdbg1_main.
+ *   The target of this file is to merge as many DVT loads into single test load as possible.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "kal_public_api.h"      
+#include "drv_features.h"
+#if (defined( __MSDC_BASIC_LOAD__) || defined(DRV_MSDC_BT)) //this should be defined as global option, without this option, this file won't be compiled
+#include "stack_common.h"
+#include "stack_msgs.h"
+#include "app_ltlcom.h"       /* Task message communiction */
+#include "kal_public_api.h"
+//guilin #include "tst_ltlcom.h"
+#include "kal_debug.h"
+#include "syscomp_config.h"
+#include "task_config.h"      /* Task creation */
+#include "cache_sw.h"
+#include "stacklib.h"         /* Basic type for dll, evshed, stacktimer */
+
+#include "event_shed.h"       /* Event scheduler */
+
+#include "stack_timer.h"      /* Stack timer */
+
+#include "string.h"
+#include "uart_sw.h"
+
+#include "stack_timer.h"      /* Stack timer */
+
+#include <stdlib.h>
+
+#include "stdio.h"
+#include "uart_sw.h"
+#include "fat_fs.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+
+
+#include "fs_gprot.h"
+#include "config_hw.h"
+#include "intrCtrl.h"
+
+#include "dma_hw.h"
+#include "dma_sw.h"
+
+#include "pwic.h"
+
+#include "dcl.h"
+#include "dcl_msdc.h"
+#include "eint.h"
+
+//extern void srand(unsigned int seed);
+//extern int rand(void);
+
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1		CG_CON1
+#endif
+
+#ifdef DRVPDN_CON0
+#error "__CLKG_DEFINE__ & DRVPDN_CON0 are all defined"
+#else
+#define DRVPDN_CON0		CG_CON0
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET1
+#endif
+#endif
+
+
+#define MSDC_DVT
+#ifdef MSDC_DVT
+
+#ifdef __MSDC_BASIC_LOAD__
+typedef struct ssdbg1_context_struct_t
+{
+    stack_timer_struct  ssdbg1_timer0;
+    stack_timer_struct  ssdbg1_base_timer;
+    event_scheduler     *ssdbg1_event_scheduler_ptr;
+    eventid             ssdbg1_event_id;
+} ssdbg1_context_struct_t;
+
+extern ssdbg1_context_struct_t ssdbg1_context;
+
+typedef struct ssdbg2_context_struct_t
+{
+    stack_timer_struct  ssdbg2_timer0;
+
+    stack_timer_struct  ssdbg2_base_timer;
+    event_scheduler     *ssdbg2_event_scheduler_ptr;
+    eventid             ssdbg2_event_id;
+} ssdbg2_context_struct_t;
+
+extern ssdbg2_context_struct_t ssdbg2_context;
+
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    kal_uint32 id;
+} ssdbg1_localpara_struct;
+
+
+#endif
+
+#define LEN		32*1024
+//#define LEN		512*1024
+#define TIMES  100
+//static kal_uint8 MyTxbuf[LEN];
+//static kal_uint8 MyRxbuf[LEN];
+//static kal_uint8 buffer[1024*8];
+//static kal_uint32 fcount = 0;
+#define BYTES_PER_ACCESS		17839
+//#define WRITE_TEST
+//#define CACHED_TEST
+
+//#define NOT_4BYTES_ALIGN
+
+__align(4) kal_uint8 r[LEN + 3], w[LEN + 3], w1[LEN + 3], r2[LEN + 3], w2[LEN + 3];
+
+volatile kal_bool check_read_content = KAL_TRUE;
+double	bestReadThroughput, worstReadThroughput, bestWriteThroughput, worstWriteThroughput;
+
+#ifdef CACHED_TEST
+kal_bool	cachedTest;
+double	cachedBestReadThroughput, cachedWorstReadThroughput, cachedBestWriteThroughput, cachedWorstWriteThroughput;
+#pragma arm section zidata = "CACHEDZI"
+__align(4) kal_uint8 cached_r[LEN + 3], cached_w[LEN + 3];
+#pragma arm section zidata
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+#define TESTBLNUMMAX 1024
+
+
+kal_int32 testblnum = 32;
+#define TESTLOOP 1
+#define ADDREND 100
+#define ADDREND2 (ADDREND*10)
+
+
+//
+// For each project, config gpio setting at first.
+//
+
+#define CLKSRCNUM 4 // 0~3
+#define SCLKFNUM 4 // 0~3,255
+
+#pragma arm section zidata = "NONCACHEDZI",  rwdata = "NONCACHEDRW"
+kal_uint32 msdc_sector_buf1[128] = {0};
+kal_uint32 msdc_sector_buf2[128] = {0};
+kal_uint32 msdc_sector_buf3[128] = {0};
+kal_uint8 MSDC_Sector_guilin81[129 * 4] = {0};
+kal_uint8 MSDC_Sector_guilin82[129 * 4] = {0};
+
+kal_uint32	msdc_uncachedBuf1[TESTBLNUMMAX * 512 / 4];
+kal_uint32	msdc_uncachedBuf2[TESTBLNUMMAX * 512 / 4];
+#pragma arm section zidata, rwdata
+
+kal_uint32 cachemsdc_sector_buf1[128] = {0};
+kal_uint32 cachemsdc_sector_buf2[128] = {0};
+kal_uint32 cachemsdc_uncachedBuf1[TESTBLNUMMAX * 512 / 4];
+kal_uint32 cachemsdc_uncachedBuf2[TESTBLNUMMAX * 512 / 4];
+
+extern kal_bool MSDC_useDMA4ByteBurst;
+kal_uint32 test_clksrc;
+kal_uint32 test_sclkf;
+kal_uint32 testsectors;
+kal_uint32 gspeed = 0;
+
+typedef struct
+{
+    kal_int32 bit14;
+    kal_int32 isread1;
+    kal_int32 clksrc;
+    kal_int32 sclkf;
+    kal_int32 clock;
+    kal_int32 addr;
+    kal_int32 blnum;
+    kal_int32 speed;
+} CLKTEST;
+
+CLKTEST test_statistic[1000];
+
+
+#define ESCKEY (0x1b)
+
+void msdc_dbg_print(char *fmt, ...);
+void msdc_dbg_input(kal_uint32 *value);
+void guilin_sleep(kal_uint32 x);
+#endif
+
+void dummyFunction(void) {}
+
+#if defined(MSDC_SDIO_DVT) || defined(MSDC2_SDIO_DVT)
+kal_bool waitingSDIOTest = KAL_TRUE;/*if SDIO test is doing, we have to make both task wait for SDIO test done*/
+#else
+kal_bool waitingSDIOTest = KAL_FALSE;
+#endif
+
+#ifdef MSDC2_SDIO_DVT
+extern MSDC_HANDLE *msdc2_handle ;
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+/*
+#if 1
+void MSDC_DVT_readWrite(void)
+{
+    kal_int32 status;
+
+    dbg_print("[%s %d]\r\n",__FUNCTION__,__LINE__);
+    gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+    gMSDC_Handle->mIsInitialized = KAL_FALSE;
+    //MSDC_Initialize();
+    //status=SD_Initialize();
+    status = DclSD_Initialize();
+    dbg_print("[%s %d]SD_Initialize=%d \r\n",__FUNCTION__,__LINE__,status);
+    //status = MountDevice_NEW(&MSDC_Blk[0], 0, 0, 0);
+    //dbg_print("[%s %d]MountDevice_NEW=%d \r\n",__FUNCTION__,__LINE__,status);
+    status = SD_Initialize();
+    //MSDC_PDNControl(0);
+
+
+}
+#else
+void MSDC_DVT_readWrite(void)
+{
+
+
+
+#ifdef MULTIPLE_WRITE_TEST
+	gMSDC_Handle->mIsPresent = KAL_TRUE;
+	simple_multi_write_test();
+	return;
+#endif
+
+
+
+
+	kal_int32 i,j, result = 0, count = 0;
+	kal_uint32 access = 17893;
+	FS_HANDLE hFile=0, wFile = 0;
+	kal_wchar full_name[100];
+	kal_uint32  file_size,len,total_len;
+	kal_uint32 time_1,time_2;
+	double rate;
+	volatile kal_bool format = 0;
+	kal_uint8 offset1 = 0,offset2 = 0;
+	kal_uint32 timeUsedinFS;
+	 int card;
+        kal_uint8 path[10];
+        FS_DiskInfo info;
+
+	kal_uint32	testTimes = 0;
+
+
+
+	result = FS_TestMSDC(gMSDC_Handle);
+	if(result < FS_NO_ERROR){
+		dbg_print("memory card card not present %d !!\r\n", result);
+		return;
+        	while(1)
+        		kal_sleep_task(1000);
+	}
+
+	card = FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
+
+        if (card >= FS_NO_ERROR)
+        {
+            kal_wsprintf((WCHAR*) path, "%c:\\", card);
+
+            result = FS_GetDiskInfo((WCHAR*) path, &info, FS_DI_BASIC_INFO | FS_DI_FREE_SPACE);
+            if (result < RTF_NO_ERROR)
+            {
+            	ASSERT(0);
+            }
+
+
+        }
+        else{
+        	dbg_print("memory card card not present!!\r\n");
+        	return;
+        	while(1)
+        		kal_sleep_task(1000);
+        }
+
+#ifdef HW_FAST_FORMAT_TEST
+	while(1){
+		time_1 = drv_get_current_time();
+		result = FS_GeneralFormat((WCHAR*) path, FS_FORMAT_HIGH, NULL);
+		if(FS_NO_ERROR == result){
+			time_2 = drv_get_current_time();
+			dbg_print("format done %d, %f\n\r", time_2 - time_1, (double)(0.0005 * writeSectorsCount * 32000)/(double)(writeTimeCount));
+			writeSectorsCount = writeTimeCount = 0;
+			kal_sleep_task(1500);
+		}
+		else{
+			dbg_print("format failed: %d \n\r", result);
+			while(1)
+        			kal_sleep_task(1000);
+
+		}
+	}
+#endif
+	//DumpDiskInfo("d:\\");
+	kal_wsprintf(full_name, "%c:\\Write.bin", card);
+	for(i=0;i<LEN+3;i++)
+	{
+		w[i+offset1] = i%256;
+		r[i+offset2] = 0;
+
+#ifdef	CACHED_TEST
+		cached_w[i+offset1] = i%256;
+		cached_r[i+offset2] = 0;
+#endif
+
+	}
+
+#if defined(NOT_4BYTES_ALIGN)
+		// test W to B or B to W(DMA)
+		offset1 = (kal_uint32)w % 4;
+		if(offset1 == 0)
+			offset1 = 1;
+		else
+			offset1 = 0;
+
+		offset2 = (kal_uint32)r % 4;
+		if(offset2 == 0)
+			offset2 = 1;
+		else
+			offset2 = 0;
+		for(i=0;i<LEN+3;i++)
+		{
+			w[i+offset1] = i%256;
+			r[i+offset2] = 0;
+		}
+#endif
+
+
+	while(1){
+
+
+#if 1//write
+
+		count++;
+		//Search_Dir(L"C:\\");
+		FS_Delete(full_name);
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest)
+				cachedTest = KAL_FALSE;
+			else
+				cachedTest = KAL_TRUE;
+
+			if(KAL_TRUE == cachedTest)
+				dbg_print("\r\n===========Cached Write Test Start(%d) ====================\r\n",count);
+			else
+#endif
+		dbg_print("\r\n==================Write Test Start(%d) ====================\r\n",count);
+
+		hFile = FS_Open(full_name, FS_CREATE|FS_READ_WRITE);
+		if(hFile <= 0){
+			dbg_print("open file failed \r\n");
+			return ;
+		}
+		//ASSERT(hFile>0);
+
+#if defined(NOT_4BYTES_ALIGN)
+		// test W to B or B to W(DMA)
+		offset1 = (kal_uint32)w % 4;
+		if(offset1 == 0)
+			offset1 = 1;
+		else
+			offset1 = 0;
+
+		offset2 = (kal_uint32)r % 4;
+		if(offset2 == 0)
+			offset2 = 1;
+		else
+			offset2 = 0;
+		for(i=0;i<LEN+3;i++)
+		{
+			w[i+offset1] = i%256;
+			r[i+offset2] = 0;
+		}
+#endif
+		i = 0;
+		total_len = 0;
+
+		kal_get_time(&time_1);
+		//readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2 = 0;
+		//writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+		while(1)
+		{
+
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest)
+				result = FS_Write(hFile,cached_w+offset1,LEN,&len);
+			else
+#endif
+			result = FS_Write(hFile,w+offset1,LEN,&len);
+			total_len += len;
+			i++;
+			if(result < 0 ){
+				if(result == RTF_DISK_FULL){
+					dbg_print("Disk Full %d\r\n", total_len);
+					FS_Close(hFile);
+					return;
+				}
+				else{
+					dbg_print("write fail %d at: %d \r\n",result, total_len);
+					FS_Close(hFile);
+					return;
+
+					break;
+				}
+			}
+			if(len != LEN){
+				dbg_print("write length not correct \r\n");
+				FS_Close(hFile);
+				return;
+			}
+			if(i%TIMES == 0)
+			{
+				kal_get_time(&time_2);
+			   rate = (double)(LEN*TIMES)/(double)(time_2-time_1);
+				dbg_print("write[%d], total: %d, rate %f \r\n", i, total_len,rate/0.004615);
+				//dbg_print("%d, %d, %d , %d\r\n", writeTime3 , writeTime4 , writeTime5,writeTime6);
+				//readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2= 0;
+				//writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest){
+				if((rate/0.004615) > cachedBestWriteThroughput || 0 == cachedBestWriteThroughput)
+					cachedBestWriteThroughput = (rate/0.004615);
+				if((rate/0.004615) < cachedWorstWriteThroughput || 0 == cachedWorstWriteThroughput)
+					cachedWorstWriteThroughput = (rate/0.004615);
+			}
+			else
+#endif
+			{
+				if((rate/0.004615) > bestWriteThroughput || 0 == bestWriteThroughput)
+					bestWriteThroughput = (rate/0.004615);
+				if((rate/0.004615) < worstWriteThroughput || 0 == worstWriteThroughput)
+					worstWriteThroughput = (rate/0.004615);
+			}
+
+				kal_get_time(&time_1);
+
+
+				if(i == TIMES*5) break;
+			}
+		}
+		FS_Close(hFile);
+
+#ifdef	CACHED_TEST
+		if(KAL_TRUE == cachedTest)
+			dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestWriteThroughput, cachedWorstWriteThroughput);
+		else
+#endif
+		dbg_print("\r\nbest: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+
+		dbg_print("\r\n==================Write Test End(%d) ====================\r\n",count);
+#endif //write
+
+#if 1 // read test
+
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest)
+				dbg_print("\r\n==========Cached Read Test Start(%d) ====================\r\n",count);
+			else
+#endif
+		dbg_print("\r\n==================Read Test Start(%d) ====================\r\n",count);
+
+		timeUsedinFS = 0;
+		i = 0;
+		total_len = 0;
+		hFile = FS_Open(full_name, FS_READ_WRITE);
+		if(hFile <= 0){
+			dbg_print("FS open failed\r\n");
+			return;
+		}
+
+		ASSERT(hFile>0);
+
+		while(1){
+			kal_get_time(&time_1);
+
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest)
+				result = FS_Read(hFile,cached_r +offset1,LEN,&len);
+			else
+#endif
+			result = FS_Read(hFile,r+offset2,LEN,&len);
+
+			kal_get_time(&time_2);
+			timeUsedinFS += (time_2 - time_1);
+			i++;
+			total_len += len;
+
+			if(check_read_content)
+			{
+#ifdef	CACHED_TEST
+				if(KAL_TRUE == cachedTest){
+					for(j=0;j<len;j++){
+						if(cached_r[j+offset2] != cached_w[j+offset1])
+						{
+							dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+							while(1);
+						}
+
+					}
+				}
+				else
+#endif
+				{
+					for(j=0;j<len;j++){
+						if(r[j+offset2] != w[j+offset1])
+						{
+							dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+							FS_Close(hFile);
+							return;
+						}
+
+					}
+				}
+				dbg_print(".");
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest)
+				memset(cached_r,0,sizeof(cached_r));
+			else
+#endif
+				memset(r,0,sizeof(r));
+			}
+			if(result < 0){
+				if(result != RTF_DISK_FULL){
+					dbg_print("read fail %d, at: %d \r\n", result, total_len);
+					FS_Close(hFile);
+					return;
+				}
+				else{
+					dbg_print("Disk Full \r\n");
+					FS_Close(hFile);
+					return;
+				}
+			}
+			if(len != LEN){
+				dbg_print("length not correct \r\n");
+				FS_Close(hFile);
+				return;
+			}
+			if(i%TIMES == 0){
+
+			   rate = (double)(LEN*TIMES)/(double)timeUsedinFS;
+				dbg_print("read[%d], total: %d, rate: %f \r\n", i, total_len,rate/0.004615);
+
+#ifdef	CACHED_TEST
+			if(KAL_TRUE == cachedTest){
+				if((rate/0.004615) > cachedBestReadThroughput || 0 == cachedBestReadThroughput)
+					cachedBestReadThroughput = (rate/0.004615);
+				if((rate/0.004615) < cachedWorstReadThroughput || 0 == cachedWorstReadThroughput)
+					cachedWorstReadThroughput = (rate/0.004615);
+			}
+			else
+#endif
+			{
+				if((rate/0.004615) > bestReadThroughput || 0 == bestReadThroughput)
+					bestReadThroughput = (rate/0.004615);
+				if((rate/0.004615) < worstReadThroughput || 0 == worstReadThroughput)
+					worstReadThroughput = (rate/0.004615);
+			}
+
+				timeUsedinFS = 0;
+				if(i == TIMES*5) break;
+			}
+		}
+		FS_Close(hFile);
+
+#ifdef	CACHED_TEST
+		if(KAL_TRUE == cachedTest)
+			dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestReadThroughput, cachedWorstReadThroughput);
+		else
+#endif
+		dbg_print("\r\nbest: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+
+		dbg_print("\r\n==================Read Test End(%d) ====================\r\n",count);
+		FS_Delete(full_name);
+#endif  // read test
+
+		testTimes ++;
+		if(5 == testTimes)
+			return;
+	}
+   //=======================================//
+}
+#endif
+*/
+
+typedef struct
+{
+    kal_char name[16];
+    kal_uint32 addr;
+    kal_uint32 defval;
+} REGTEST;
+
+REGTEST regbuf[] =
+{
+    {"MSDC_CFG      ", MSDC_CFG, 0x04000020},
+    {"MSDC_STA      ", MSDC_STA, 2},
+    {"MSDC_INT      ", MSDC_INTR, 0},
+    {"MSDC_PS       ", MSDC_PS, 0x01ff0008},
+
+    {"MSDC_DAT      ", MSDC_DAT, 0xffffffff},
+    {"MSDC_IOCON0   ", MSDC_IOCON, 0x010000c3},
+    {"MSDC_IOCON1   ", MSDC_IOCON1, 0x00022022},
+
+    {"SDC_CFG       ", SDC_CFG, 0x8000},
+    {"SDC_CMD       ", SDC_CMD, 0},
+    {"SDC_ARG       ", SDC_ARG, 0xffffffff},
+    {"SDC_STA       ", SDC_STA, 0x8000},
+
+    {"SDC_RESP0     ", SDC_RESP0, 0xffffffff},
+    {"SDC_RESP1     ", SDC_RESP1, 0xffffffff},
+    {"SDC_RESP2     ", SDC_RESP2, 0xffffffff},
+    {"SDC_RESP3     ", SDC_RESP3, 0xffffffff},
+
+    {"SDC_CMDSTA    ", SDC_CMDSTA, 0},
+    {"SDC_DATSTA    ", SDC_DATSTA, 0},
+    {"SDC_CSTA      ", SDC_CSTA, 0},
+    {"SDC_IRQMASK0  ", SDC_IRQMASK0, 0},
+    {"SDC_IRQMASK1  ", SDC_IRQMASK1, 0},
+
+#if defined(__MSDC_SD_SDIO__)
+    //{"SDIO_CFG      ",SDIO_CFG,0},
+    //{"SDIO_STA      ",SDIO_STA,0},
+#endif
+
+    {"BOOT_CFG      ", MSDC_BOOT_CFG, 0},
+    {"BOOT_STA      ", MSDC_BOOT_STA, 0},
+
+    {"CLKACB_CFG    ", MSDC_CLKACB_CFG, 0x00020000},
+};
+
+kal_int32 sdtestgpio(void)
+{
+    DCL_HANDLE handle;
+    int x;
+    handle = DclGPIO_Open(DCL_GPIO, 10); // GPIO10
+    DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+    DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+    DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+    DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+
+    for (x = 100; x; x--)
+    {
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+    }
+
+    DclGPIO_Close(handle);
+
+}
+
+kal_int32 sdtestgpio2(void)
+{
+    kal_uint8 buf[30], input, offset;
+    kal_int32 value, x;
+    DCL_HANDLE handle;
+
+    memset(buf, 0, sizeof(buf));
+    msdc_dbg_print("input(GPIO)(ESC:exit):");
+    offset = 0;
+
+    while (1)
+    {
+        input = U_GetUARTByte(uart_port1);
+
+        if (input >= '0' && input <= '9')
+        {
+            //input -= '0';
+        }
+        else if (input == 0x0d || input == 0x0a)
+        {
+            break;
+        }
+        else if (input == ESCKEY) //esc
+        {
+            return;
+        }
+        else
+        {
+            continue;
+        }
+
+        buf[offset++] = input;
+        dbg_print("%c", input);
+    }
+
+    buf[30 - 1] = 0;
+    value = -1;
+    dbg_print("\r\n");
+    sscanf(buf, "%d", &value);
+
+    if (value >= 0)
+    {
+        handle = DclGPIO_Open(DCL_GPIO, value); // GPIO10
+        DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+        DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+        msdc_dbg_print("[%s %d]gpio=%d \r\n", __FUNCTION__, __LINE__, value);
+
+        for (x = 1000000; x; x--)
+        {
+            DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+        }
+
+        DclGPIO_Close(handle);
+    }
+
+
+}
+
+
+
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+    kal_uint32 count, whileIndex;
+    SDC_CMD_STATUS status;
+    kal_uint32 value;
+
+    count = MSDC_SD_BLOCK_SIZE;
+
+#ifdef DRV_LSD
+    LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+
+    RESET_MSDC();
+
+    if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+        goto ERR_Exit;
+
+    whileIndex = 0;
+
+    while (1)
+    {
+        if (!MSDC_IS_FIFO_EMPTY)
+        {
+            value = MSDC_Reg32(MSDC_DAT);
+
+            if ((kal_uint32)rxbuffer % 4)
+                kal_mem_cpy(rxbuffer + whileIndex, (const void*)&value, 4);
+            else
+                *(rxbuffer + whileIndex) = value;
+
+            whileIndex++;
+
+            if (whileIndex >= count)
+                break;
+        }
+    }
+
+    if ((status = SD_WaitDatRdyOrTo()) != NO_ERROR)
+        goto ERR_Exit;
+
+    MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+    {
+        kal_uint32 cardStatus;
+        whileIndex = 0x40000;
+
+        while (SD_IS_R1B_BUSY && whileIndex)
+            whileIndex--;
+
+        whileIndex = 0x100;
+
+        do
+        {
+            status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+            if (NO_ERROR != status)
+            {
+                dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+                msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+                goto ERR_Exit;
+            }
+
+            whileIndex--;
+        }
+        while (((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) && (0 != whileIndex));
+    }
+#endif
+    MSDC_CLR_FIFO();
+    RESET_MSDC();
+    return NO_ERROR;
+ERR_Exit:
+    {
+        kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+        DisableMSDC_DMA();
+        RESET_MSDC();
+
+        // SD_StopTrans(KAL_FALSE);
+        SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+        MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+        MSDC_CLR_FIFO();
+        msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+        return status;
+    }
+
+}
+
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_datto(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+    kal_uint32 count, whileIndex;
+    SDC_CMD_STATUS status;
+    kal_uint16 sdc_datsta;
+    //    msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+    count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+    LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+    {
+        DCL_HANDLE handle;
+        handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+        DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+        DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+        DclGPIO_Close(handle);
+        guilin_sleep(10);
+    }
+
+    if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+        goto ERR_Exit;
+
+    whileIndex = 0;
+
+    while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+    {
+        sdc_datsta = MSDC_Reg(SDC_DATSTA);
+        gMSDC_Handle->dat_sta = sdc_datsta;
+
+        if (sdc_datsta & SDC_DATSTA_DATTO)
+        {
+            msdc_dbg_print("[%s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+            status = ERR_DAT_TIMEOUT;
+            goto ERR_Exit;
+        }
+        else if (sdc_datsta & SDC_DATSTA_DATCRCERR)
+        {
+            status = ERR_DAT_CRCERR;
+            goto ERR_Exit;
+        }
+
+        if (!MSDC_IS_FIFO_EMPTY )
+        {
+            *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+            whileIndex++;
+
+            if (whileIndex >= count)
+                break;
+        }
+    }
+
+    //if ((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+    //	goto ERR_Exit;
+
+    MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+    {
+        kal_uint32 cardStatus;
+        whileIndex = 0x40000;
+
+        while (SD_IS_R1B_BUSY && whileIndex)
+            whileIndex--;
+
+        whileIndex = 0x100;
+
+        do
+        {
+            status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+            if (NO_ERROR != status)
+            {
+                dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+                msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+                goto ERR_Exit;
+            }
+
+            whileIndex--;
+        }
+        while (((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) && (0 != whileIndex));
+    }
+#endif
+    MSDC_CLR_FIFO();
+    RESET_MSDC();
+    return NO_ERROR;
+ERR_Exit:
+    {
+        kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+        DisableMSDC_DMA();
+        RESET_MSDC();
+
+        // SD_StopTrans(KAL_FALSE);
+        SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+        MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+        MSDC_CLR_FIFO();
+        msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+        return status;
+    }
+
+}
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_datcrc(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+    kal_uint32 count, whileIndex;
+    SDC_CMD_STATUS status;
+    kal_uint16 sdc_datsta;
+    //    msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+    count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+    LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+
+    if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+        goto ERR_Exit;
+
+    whileIndex = 0;
+
+    while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+    {
+        sdc_datsta = MSDC_Reg(SDC_DATSTA);
+        gMSDC_Handle->dat_sta = sdc_datsta;
+
+        if (sdc_datsta & SDC_DATSTA_DATCRCERR)
+        {
+            msdc_dbg_print("[%s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+            status = ERR_DAT_CRCERR;
+            goto ERR_Exit;
+        }
+        else if (sdc_datsta & SDC_DATSTA_DATTO)
+        {
+            status = ERR_DAT_TIMEOUT;
+            goto ERR_Exit;
+        }
+
+        if (!MSDC_IS_FIFO_EMPTY)
+        {
+            *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+            whileIndex++;
+
+            if (whileIndex >= count)
+                break;
+        }
+
+        if (whileIndex == 100 )
+        {
+            DCL_HANDLE handle;
+            handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+            DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+            DclGPIO_Close(handle);
+            guilin_sleep(10);
+        }
+        else if (whileIndex == 110 )
+        {
+            DCL_HANDLE handle;
+            handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+            DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+            DclGPIO_Close(handle);
+            guilin_sleep(10);
+        }
+
+    }
+
+    //	if ((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+    //		goto ERR_Exit;
+
+    MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+    {
+        kal_uint32 cardStatus;
+        whileIndex = 0x40000;
+
+        while (SD_IS_R1B_BUSY && whileIndex)
+            whileIndex--;
+
+        whileIndex = 0x100;
+
+        do
+        {
+            status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+            if (NO_ERROR != status)
+            {
+                dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+                msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+                goto ERR_Exit;
+            }
+
+            whileIndex--;
+        }
+        while (((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) && (0 != whileIndex));
+    }
+#endif
+    MSDC_CLR_FIFO();
+    RESET_MSDC();
+    return NO_ERROR;
+ERR_Exit:
+    {
+        kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+        DisableMSDC_DMA();
+        RESET_MSDC();
+
+        // SD_StopTrans(KAL_FALSE);
+        SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+        MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+        MSDC_CLR_FIFO();
+        msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+        return status;
+    }
+
+}
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_cmdto(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+    kal_uint32 count, whileIndex;
+    SDC_CMD_STATUS status;
+    kal_uint16 sdc_datsta;
+    //    msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+    count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+    LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+    {
+        DCL_HANDLE handle;
+        handle = DclGPIO_Open(DCL_GPIO, CMDGPIO);
+        DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+        DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+        DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+        DclGPIO_Close(handle);
+        guilin_sleep(10);
+    }
+
+    if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+        goto ERR_Exit;
+
+    whileIndex = 0;
+
+    while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+    {
+        if (!MSDC_IS_FIFO_EMPTY )
+        {
+            *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+            whileIndex++;
+
+            if (whileIndex >= count)
+                break;
+        }
+
+        sdc_datsta = MSDC_Reg(SDC_DATSTA);
+        gMSDC_Handle->dat_sta = sdc_datsta;
+
+        if (sdc_datsta >> 1)
+        {
+            msdc_dbg_print("[guilin %s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+            break;
+        }
+
+    }
+
+    //	if((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+    //		goto ERR_Exit;
+
+    MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+    {
+        kal_uint32 cardStatus;
+        whileIndex = 0x40000;
+
+        while (SD_IS_R1B_BUSY && whileIndex)
+            whileIndex--;
+
+        whileIndex = 0x100;
+
+        do
+        {
+            status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+            if (NO_ERROR != status)
+            {
+                dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+                msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+                goto ERR_Exit;
+            }
+
+            whileIndex--;
+        }
+        while (((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) && (0 != whileIndex));
+    }
+#endif
+    MSDC_CLR_FIFO();
+    RESET_MSDC();
+    return NO_ERROR;
+ERR_Exit:
+    {
+        kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+        DisableMSDC_DMA();
+        RESET_MSDC();
+
+        // SD_StopTrans(KAL_FALSE);
+        SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+        MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+        MSDC_CLR_FIFO();
+        msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+        return status;
+    }
+
+}
+
+SDC_CMD_STATUS SD_WriteSingleBlock_MCU(kal_uint32 address, kal_uint32* txbuffer)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 count, whileIndex, value;
+#ifdef DRV_MSDC_FORCE_WAIT_FOR_PROG_R1B_MALFUNCTION
+    kal_uint32 cardStatus = 0;
+    kal_uint32 t1 = 0;
+#endif
+    kal_uint32 *ptr;
+#if defined(MT6225)
+    kal_bool is_aligned;
+    ECO_VERSION eco;
+    eco = INT_ecoVersion();
+#endif
+
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+    kal_uint32 triedDLTTimes = 0;
+
+retryDLT:
+#endif
+
+    RESET_MSDC();
+    MSDC_CLR_FIFO();
+
+    if (gSD->mWPEnabled)
+        return ERR_WRITE_PROTECT;
+
+    count = MSDC_SD_BLOCK_SIZE;
+
+#if defined(MT6225)
+
+    if (eco <= ECO_E3)
+    {
+        is_aligned = ((kal_uint32)txbuffer % 4 == 0);
+
+        if (is_aligned)
+        {
+            ptr = txbuffer;
+        }
+        else
+        {
+            kal_mem_cpy(MSDC_Sector, txbuffer, 512);
+            ptr = MSDC_Sector;
+        }
+    }
+    else
+    {
+        ptr = txbuffer;
+    }
+
+#else
+    ptr = txbuffer;
+#endif
+
+#ifdef DRV_LSD
+    LSD_HostSetBuffer((kal_uint8 *)txbuffer);
+#endif
+
+    if ((status = SD_Send_Cmd(SDC_CMD_CMD24, address)) != NO_ERROR)
+        goto ERR_Exit;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        goto ERR_Exit;
+
+    whileIndex = 0;
+
+    while (1)
+    {
+        if (!MSDC_IS_FIFO_FULL)
+        {
+            if ((kal_uint32)txbuffer % 4)
+                kal_mem_cpy(&value, (txbuffer + whileIndex), 4);
+            else
+                value = *(txbuffer + whileIndex);
+
+            MSDC_WriteReg32(MSDC_DAT, value);
+
+            whileIndex++;
+
+            if (whileIndex >= count)
+                break;
+        }
+    }
+
+    if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+        goto ERR_Exit;
+
+    if ((status = SD_WaitDatRdyOrTo()) != NO_ERROR)
+        goto ERR_Exit;
+
+#ifdef SD_STOP_SLOW
+    {
+        kal_uint32 cardStatus;
+        whileIndex = 0x40000;
+
+        while (SD_IS_R1B_BUSY && whileIndex)
+            whileIndex--;
+
+        whileIndex = 0x100;
+
+        do
+        {
+            status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+            if (NO_ERROR != status)
+            {
+                dbg_print("[MSDC]CMD13 fail when singleBlockWrite!");
+                msdc_dbg_print("[guilin %s %d]ERROR address=0x%x txbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, address, txbuffer, status);
+                goto ERR_Exit;
+            }
+
+            whileIndex--;
+        }
+        while (((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) && (0 != whileIndex));
+
+        if ((cardStatus & R1_CUR_STATE) >> 9 !=  TRAN_STA) //guilin
+        {
+            msdc_dbg_print("[guilin %s %d]ERROR cardStatus=0x%x", __FUNCTION__, __LINE__, cardStatus);
+            return ERR_CMD_TIMEOUT; //guilin
+        }
+    }
+#endif
+
+    MSDC_CLR_FIFO();
+    RESET_MSDC();
+
+    return NO_ERROR;
+
+ERR_Exit:
+    {
+        kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+        kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+        RESET_MSDC();
+        //SD_StopTrans(KAL_TRUE);
+        SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+        MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+        msdc_dbg_print("[guilin %s %d]address=0x%x txbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, address, txbuffer, status);
+        return status;
+    }
+
+}
+
+// ==================================================================================
+//
+// Test Case 1. Mount
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase1(void)
+{
+    kal_int32 status;
+
+    msdc_dbg_print("\r\n[%s %d]mount test...\r\n", __FUNCTION__, __LINE__);
+
+
+
+    gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+    gMSDC_Handle->mIsInitialized = KAL_FALSE;
+    gMSDC_Handle->msdc_clkTuneUpperBund = MSDC_CLOCK / 2;
+
+    DclSD_Initialize();
+
+    //status = MountDevice_NEW(&MSDC_Blk[0], 0, 0, 0);
+    status = SD_Initialize();
+
+    testsectors = gSD->mCSD.capacity / 512;
+
+    msdc_dbg_print("[%s %d]size(sectors) = %d ,%d MB\r\n", __FUNCTION__, __LINE__, testsectors, gSD->mCSD.capacity / (1024 * 1024));
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return status;
+}
+
+kal_int32 sdtestcase2(void)
+{
+    kal_int32 size, i;
+    msdc_dbg_print("\r\n[%s %d]reg default test...", __FUNCTION__, __LINE__);
+    size = sizeof(regbuf) / sizeof(REGTEST);
+
+    for (i = 0; i < size; i++)
+    {
+        msdc_dbg_print("[%s,0x%08x,0x%08x]=0x%08x", regbuf[i].name, regbuf[i].addr, regbuf[i].defval, MSDC_Reg32(regbuf[i].addr));
+    }
+}
+
+
+// ==================================================================================
+//
+// Test Case 3. Single block read test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase3(kal_int32 addr , kal_uint32 *pbufr)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2;
+
+    sdtestgpio();
+
+    do
+    {
+
+        time1 = drv_get_current_time();
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadSingleBlock(addr, pbufr);
+        else
+            status = SD_ReadSingleBlock(addr * 512, pbufr);
+
+        time2 = drv_get_current_time();
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR, SD_ReadSingleBlock, %d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        if (time2 != time1)
+            msdc_dbg_print("[%s %d]OK, SD_ReadSingleBlock, %5d KB/S,time=%d,addr=%d", __FUNCTION__, __LINE__, (1 * 32768 * 5) / ((time2 - time1) * 10), (time2 - time1), addr);
+        else
+            msdc_dbg_print("[%s %d]OK, SD_ReadSingleBlock, time=0,addr=%d", __FUNCTION__, __LINE__, addr);
+
+
+    }
+    while (0);
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+
+    return status;
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 4. Single block write test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase4(kal_int32 addr , kal_uint32 *pbufw , kal_uint32 *pbufr)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2;
+    kal_int32 i, compare_error;
+
+    for (i = 0; i < 512; i++)
+        //pbufw[i]=((i+10)<<0)|((i+11)<<8)|((i+12)<<16)|((i+13)<<24);
+        *((kal_uint8 *)pbufw + i) = rand() % 256;
+
+    sdtestgpio();
+
+    do
+    {
+
+        time1 = drv_get_current_time();
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_WriteSingleBlock(addr, pbufw);
+        else
+            status = SD_WriteSingleBlock(addr * 512, pbufw);
+
+        time2 = drv_get_current_time();
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR, SD_WriteSingleBlock, %d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        // readback compare
+        compare_error = 0;
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadSingleBlock(addr, pbufr);
+        else
+            status = SD_ReadSingleBlock(addr * 512, pbufr);
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR, SD_ReadSingleBlock, %d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        for (i = 0; i < 512; i++)
+        {
+            if (((kal_uint8 *)pbufw)[i] != ((kal_uint8 *)pbufr)[i])
+            {
+                msdc_dbg_print("[%s %d]ERROR, compare error:0x%x , 0x%x ,i=%d", __FUNCTION__, __LINE__, pbufw[i], pbufr[i], i);
+                compare_error = 1;
+                status = ERR_STATUS;
+                break;
+            }
+        }
+
+        if (compare_error == 0)
+        {
+            if (time2 != time1)
+                msdc_dbg_print("[%s %d]OK,SD_WriteSingleBlock,readback compare ok,write= %5d KB/S , time=%d ,addr=%d", __FUNCTION__, __LINE__, (1 * 32768 * 5) / ((time2 - time1) * 10) , time2 - time1 , addr);
+            else
+                msdc_dbg_print("[%s %d]OK,SD_WriteSingleBlock,readback compare ok,time=0,addr=%d", __FUNCTION__, __LINE__, addr);
+        }
+
+
+
+    }
+    while (0);
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return status;
+}
+
+
+// ==================================================================================
+//
+// Test Case 5. Multiple block read test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase5(kal_int32 addr , kal_uint32 *pbufr)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2;
+
+    sdtestgpio();
+
+    do
+    {
+
+        time1 = drv_get_current_time();
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadMultiBlock(addr, pbufr, testblnum);
+        else
+            status = SD_ReadMultiBlock(addr * 512, pbufr, testblnum);
+
+        time2 = drv_get_current_time();
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR, SD_ReadMultiBlock, %d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        if (time2 != time1)
+            msdc_dbg_print("[%s %d]OK,SD_ReadMultiBlock, %5d KB/S,addr=%d , blnum=%d", __FUNCTION__, __LINE__, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr, testblnum);
+        else
+            msdc_dbg_print("[%s %d]OK,SD_ReadMultiBlock, time=0,addr=%d , blnum=%d", __FUNCTION__, __LINE__, addr, testblnum);
+
+        gspeed = (testblnum * 32768 * 5) / ((time2 - time1) * 10);
+
+
+    }
+    while (0);
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return status;
+}
+
+kal_int32 sdtestcase6(kal_int32 addr , kal_uint32 *pbufw , kal_uint32 *pbufr)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2;
+
+    kal_int32 i, compare_error;
+
+    //srand(drv_get_current_tick());
+
+    for (i = 0; i < 512 * testblnum; i++)
+        //pbufw[i]=((i+20)<<0)|((i+21)<<8)|((i+22)<<16)|((i+23)<<24);
+        //*((kal_uint8 *)pbufw + i) = i;
+        *((kal_uint8 *)pbufw + i) = rand() % 256;
+
+    sdtestgpio();
+
+    do
+    {
+
+        time1 = drv_get_current_time();
+
+        if (SD_CARD == gMSDC_Handle->mMSDC_type)
+        {
+
+            status = SD_SetPreEraseBlk(testblnum);
+
+            if (status != NO_ERROR)
+            {
+                msdc_dbg_print("[%s %d]ERROR, pre erase fail!!, %d", __FUNCTION__, __LINE__, status);
+                break;
+            }
+        }
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_WriteMultiBlock(addr, pbufw, testblnum);
+        else
+            status = SD_WriteMultiBlock(addr * 512, pbufw, testblnum);
+
+        time2 = drv_get_current_time();
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR,SD_WriteMultiBlock,%d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        // readback compare
+        compare_error = 0;
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadMultiBlock(addr, pbufr, testblnum);
+        else
+            status = SD_ReadMultiBlock(addr * 512, pbufr, testblnum);
+
+        if (status != NO_ERROR)
+        {
+            msdc_dbg_print("[%s %d]ERROR,SD_ReadMultiBlock,%d", __FUNCTION__, __LINE__, status);
+            break;
+        }
+
+        for (i = 0; i < 128 * testblnum; i++)
+        {
+            if (pbufw[i] != pbufr[i])
+            {
+                msdc_dbg_print("[%s %d]ERROR, readback compare error:0x%x , 0x%x ,i=%d", __FUNCTION__, __LINE__, pbufw[i], pbufr[i], i);
+                compare_error = 1;
+                status = ERR_STATUS;
+                break;
+            }
+        }
+
+        if (compare_error == 0)
+        {
+            if (time2 != time1)
+                msdc_dbg_print("[%s %d]OK,SD_WriteMultiBlock,readback compare ok,write= %5d KB/S , time=%d ,addr=%d , blnum=%d", __FUNCTION__, __LINE__, (testblnum * 32768 * 5) / ((time2 - time1) * 10) , time2 - time1 , addr, testblnum);
+            else
+                msdc_dbg_print("[%s %d]OK,SD_WriteMultiBlock,readback compare ok,time=0,addr=%d , blnum=%d", __FUNCTION__, __LINE__, addr, testblnum);
+        }
+
+        gspeed = (testblnum * 32768 * 5) / ((time2 - time1) * 10);
+
+
+
+    }
+    while (0);
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return status;
+}
+
+kal_int32 SD_setclk(kal_int32 wdata)//KHZ
+{
+    msdc_clk_setting cs, cs2;
+    kal_int32 temp1, temp2;
+
+    temp1 = 0;
+    temp2 = 0x0fffffff;
+    cs2.cardClk = 0;
+
+    for (cs.sclkf = 0; cs.sclkf < 250; cs.sclkf ++)
+    {
+        for (cs.clksrc = 0; cs.clksrc < CLKSRCNUM; cs.clksrc ++)
+        {
+            cs.cardClk = gMsdcClksrcRate[cs.clksrc] / DIV_SCLKF(cs.sclkf);
+
+            if (wdata >= cs.cardClk)
+            {
+                temp1 = wdata - cs.cardClk;
+
+                if (temp1 <= temp2)
+                {
+                    temp2 = temp1;
+                    cs2.cardClk = cs.cardClk;
+                    cs2.clksrc = cs.clksrc;
+                    cs2.sclkf = cs.sclkf;
+
+                    if (temp1 == 0)
+                        goto SD_setclk_return;
+                }
+            }
+        }
+    }
+
+SD_setclk_return:
+
+    if (cs2.cardClk)
+    {
+        MSDC_LSD_ClearBits32(SDC_CFG, SDC_CFG_SIEN);
+        BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)cs2.sclkf, MSDC_CFG_SCLKF);
+        BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)cs2.clksrc, MSDC_CFG_CLKSRC);
+        MSDC_LSD_SetBits32(SDC_CFG, SDC_CFG_SIEN);
+        gMSDC_Handle->op_clock = cs2.cardClk;
+        gMSDC_Handle->msdc_clock = gMsdcClksrcRate[cs2.clksrc];
+        msdc_dbg_print("[%s %d]CLK=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, cs2.cardClk, cs2.clksrc, cs2.sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+
+        if (gMSDC_Handle->op_clock >= 25000)
+        {
+            MSDC_LSD_SetBits32(MSDC_IOCON, (1 << 10));
+            msdc_dbg_print("[%s %d]HIGH SPEED", __FUNCTION__, __LINE__);
+        }
+        else
+        {
+            MSDC_LSD_ClearBits32(MSDC_IOCON, (1 << 10));
+        }
+    }
+
+    return 0;
+}
+
+
+// ==================================================================================
+//
+// Test Case 7. Set clock/ODC
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase7(void)
+{
+    kal_uint8 buf[30], input, offset = 0;
+    kal_uint32 value = 0xFFFFFFFF, odc;
+
+    dbg_print("1. Set clock.\r\n");
+    dbg_print("2. Set ODC. \r\n");
+    dbg_print("3. Set MPLL/26M.\r\n");
+
+    dbg_print("input:");
+    input = U_GetUARTByte(uart_port1);
+    dbg_print("%c\r\n", input);
+
+    switch (input)
+    {
+
+        case '1':
+        {
+
+            memset(buf, 0, sizeof(buf));
+            msdc_dbg_print("\r\n[%s %d]clock test...", __FUNCTION__, __LINE__);
+            msdc_dbg_print("[%s %d]msdc_clock=%d,op_clock=%d,MSDC_CFG=0x%x(CLKSRC=%d,SCLKF=%d)", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clock, gMSDC_Handle->op_clock, MSDC_Reg32(MSDC_CFG), 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3), 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8));
+            msdc_dbg_print("input(KHz)(ESC:exit):");
+
+            msdc_dbg_input(&value);
+
+            if (value != 0xFFFFFFFF)
+            {
+                SD_setclk(value);
+                msdc_dbg_print("\r\n set clock=%d(%d) KHz , press any key to exit...\r\n", value, gMSDC_Handle->op_clock);
+                // enable 74 SD clk by s/w
+                MSDC_SetBits32(MSDC_CFG, 0x80);
+
+                //kal_sleep_task(2000);
+                U_GetUARTByte(uart_port1);
+
+                // stop SD clk by s/w
+                MSDC_ClearBits32(MSDC_CFG, 0x80);
+            }
+
+        }
+        break;
+
+        case '2':
+        {
+
+            msdc_dbg_print("[%s %d]MSDC_IOCON=0x%x \r\n", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON));
+            dbg_print("Choose ODC(4,8,12,16):");
+
+            msdc_dbg_input(&value);
+
+            if (value == 4)
+                odc = MSDC_ODC_4MA;
+            else if (value == 8)
+                odc = MSDC_ODC_8MA;
+            else if (value == 12)
+                odc = MSDC_ODC_12MA;
+            else if (value == 16)
+                odc = MSDC_ODC_16MA;
+            else
+            {
+                dbg_print("wrong argument\r\n");
+                return -1;
+            }
+
+            MSDC_SetData32(
+                MSDC_IOCON,
+                MSDC_IOCON_ODCCFG0 | MSDC_IOCON_ODCCFG1,
+                (odc << 3 | odc)
+            );
+
+        }
+        break;
+
+        case '3':
+        {
+
+            dbg_print("Not support\r\n");
+
+        }
+        break;
+
+        default:
+            break;
+    }
+
+
+}
+
+
+
+
+
+kal_int32 sdtestcase8(void)
+{
+    kal_uint32 input;
+
+    msdc_dbg_print("\r\n[%s %d]1-4 bit BUS test...", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[%d BIT]input(1:1bit ; 4:4bit ; ESC:exit):", (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1 );
+
+    msdc_dbg_input(&input);
+
+    if (input == 1)
+        gMSDC_Handle->trySingleLine = KAL_TRUE;
+    else if (input == 4)
+        gMSDC_Handle->trySingleLine = KAL_FALSE;
+
+
+    msdc_dbg_print("\r\n re-mount...\r\n");
+
+    kal_sleep_task(200);
+    sdtestcase1();
+
+
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 9. Stress test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase9(void)
+{
+    SDC_CMD_STATUS status = 0;
+    kal_int32 loopIndex = 0, addr = 0, addrend = 10;
+    kal_uint32 time1, time2;
+    kal_int32 result = 0;
+    kal_uint32 oknum = 0, errornum = 0;
+    kal_uint8 str[30], input, offset;
+    kal_uint32 value;
+
+    memset(str, 0, sizeof(str));
+
+
+    msdc_dbg_print("\r\n[%s %d]stress test...", __FUNCTION__, __LINE__);
+
+    msdc_dbg_print("\r\n Input test loop: ");
+
+    msdc_dbg_input(&value);
+
+    //-------------------------------------------------------------------------
+    addrend = value;
+
+    for (addr = 0; addr < addrend; addr++)
+    {
+
+        //
+        // Single read test.
+        //
+        status = sdtestcase3(addr, msdc_sector_buf1);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+    //-------------------------------------------------------------------------
+
+    for (addr = 0; addr < addrend; addr++)
+    {
+
+        //
+        // Single write with compare test.
+        //
+        status = sdtestcase4(addr, msdc_sector_buf1, msdc_sector_buf2);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+
+
+    //-------------------------------------------------------------------------
+    for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+    {
+        //
+        // Multi read test.
+        //
+        status = sdtestcase5(addr, msdc_uncachedBuf1);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+
+
+    //-------------------------------------------------------------------------
+    for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+    {
+        //
+        // Multi write with compare test.
+        //
+        status = sdtestcase6(addr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+    //-------------------------------------------------------------------------
+
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return 0;
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 0. Non-4N align test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase10(void)
+{
+    kal_int32 loopIndex, addr;
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2, result = KAL_TRUE;
+
+    msdc_dbg_print("\r\n[%s %d]non-4N read single test...", __FUNCTION__, __LINE__);
+
+    for (loopIndex = 0; loopIndex < 4; loopIndex++)
+    {
+        msdc_dbg_print("[%s %d]DMA test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+        status = sdtestcase3(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+        if (status != NO_ERROR)
+            result = 0;
+
+        guilin_sleep(200);
+
+        msdc_dbg_print("[%s %d]MCU test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+        status = SD_ReadSingleBlock_MCU(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+        if (status != NO_ERROR)
+            result = 0;
+
+        guilin_sleep(200);
+    }
+
+    //---------------------------------------------------------------------------
+    msdc_dbg_print("\r\n[%s %d]non-4N write single test...", __FUNCTION__, __LINE__);
+
+    for (loopIndex = 0; loopIndex < 4; loopIndex++)
+    {
+        msdc_dbg_print("[%s %d]DMA test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+        status = sdtestcase4(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex], (kal_uint32 *)&msdc_sector_buf2[loopIndex]);
+
+        if (status != NO_ERROR)
+            result = 0;
+
+        guilin_sleep(200);
+
+        msdc_dbg_print("[%s %d]MCU test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf2[loopIndex]);
+        status = SD_WriteSingleBlock_MCU(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+        if (status != NO_ERROR)
+            result = 0;
+
+        guilin_sleep(200);
+    }
+
+    if (result == 0)
+        msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+
+}
+
+// ==================================================================================
+//
+// Test Case 11. cache test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase11(void)
+{
+    kal_int32 loopIndex, addr, addrend;
+    SDC_CMD_STATUS status;
+    kal_uint32 time1, time2;
+    kal_uint32 value = 0;
+    kal_uint32 oknum = 0, errornum = 0;
+
+    msdc_dbg_print("\r\n[%s %d]cache stress test...", __FUNCTION__, __LINE__);
+
+    gMSDC_Handle->isCachedBuf = KAL_TRUE;
+
+    msdc_dbg_input(&value);
+
+    //-------------------------------------------------------------------------
+    addrend = value;
+
+    for (addr = 0; addr < addrend; addr++)
+    {
+        status = sdtestcase3(addr, cachemsdc_sector_buf1);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+
+
+    //-------------------------------------------------------------------------
+    //addrend = testsectors;
+    //addrend = ADDREND;
+
+    for (addr = 0; addr < addrend; addr++)
+    {
+        status = sdtestcase4(addr, cachemsdc_sector_buf1, cachemsdc_sector_buf2);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+    //-------------------------------------------------------------------------
+    //addrend = testsectors - testblnum;
+    //addrend = ADDREND2;
+
+    for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+    {
+        status = sdtestcase5(addr, cachemsdc_uncachedBuf1);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+    oknum = 0;
+    errornum = 0;
+
+    //-------------------------------------------------------------------------
+
+    for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+    {
+        status = sdtestcase6(addr, cachemsdc_uncachedBuf1, cachemsdc_uncachedBuf2);
+
+        if (status == NO_ERROR)
+            oknum++;
+        else if (status != NO_ERROR)
+        {
+            errornum++;
+            break;
+        }
+
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+    oknum = 0;
+    errornum = 0;
+
+    //-------------------------------------------------------------------------
+    gMSDC_Handle->isCachedBuf = KAL_FALSE;
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+
+    return 0;
+
+}
+
+
+kal_int32 sdtestcase12(void)
+{
+    kal_int32 loopIndex;
+    SDC_CMD_STATUS status;
+    kal_uint32 oknum = 0, errornum = 0;
+
+    msdc_dbg_print("\r\n[%s %d]mount stress test...", __FUNCTION__, __LINE__);
+
+    for (loopIndex = 0; loopIndex < TESTLOOP; loopIndex++)
+    {
+        if (U_GetUARTByte_guilin(uart_port1) == ESCKEY)
+        {
+            msdc_dbg_print("[%s %d]ESC,mount stress test...END,OK=%d,ERROR=%d", __FUNCTION__, __LINE__, oknum, errornum);
+            break;
+        }
+
+        if (sdtestcase1() == NO_ERROR)
+        {
+            oknum++;
+            msdc_dbg_print("[%s %d]OK=%d,ERROR=%d,clksrc=%d,sclkf=%d,CLK=%d \r\n", __FUNCTION__, __LINE__, oknum, errornum, test_clksrc, test_sclkf, gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf));
+        }
+        else
+        {
+            errornum++;
+            msdc_dbg_print("[%s %d]OK=%d,ERROR=%d,clksrc=%d,sclkf=%d,CLK=%d \r\n", __FUNCTION__, __LINE__, oknum, errornum, test_clksrc, test_sclkf, gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf));
+        }
+    }
+
+    msdc_dbg_print("[%s %d]mount stress test...END,OK=%d,ERROR=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+}
+
+
+// ==================================================================================
+//
+// Test Case 13. Clock test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase13(kal_uint32 count)
+{
+    SDC_CMD_STATUS status;
+    kal_int32 result = 0, oknum = 0, errornum = 0, errloop = 0, round;
+
+    msdc_dbg_print("\r\n[%s %d]clock stress test...", __FUNCTION__, __LINE__);
+    memset(test_statistic, 0, sizeof(test_statistic));
+
+    for (test_clksrc = 0; test_clksrc < CLKSRCNUM; test_clksrc++)
+    {
+
+        for (test_sclkf = 0; test_sclkf < SCLKFNUM; test_sclkf++)
+        {
+            MSDC_LSD_ClearBits32(SDC_CFG, SDC_CFG_SIEN);
+            BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)test_sclkf, MSDC_CFG_SCLKF);
+            BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)test_clksrc, MSDC_CFG_CLKSRC);
+            MSDC_LSD_SetBits32(SDC_CFG, SDC_CFG_SIEN);
+            gMSDC_Handle->op_clock = gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf);
+            gMSDC_Handle->msdc_clock = gMsdcClksrcRate[test_clksrc];
+            msdc_dbg_print("[%s %d]CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+
+            errloop = 0;
+
+            status = sdtestcase21(count);
+
+            if (status == NO_ERROR)
+            {
+                oknum++;
+                msdc_dbg_print("[%s %d]OK=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, oknum, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+            }
+            else
+            {
+                errornum++;
+                msdc_dbg_print("[%s %d]ERROR=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d\r\n", __FUNCTION__, __LINE__, errornum, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+                goto END_TEST;
+            }
+
+        }
+    }
+
+
+    msdc_dbg_print("\r\n[%s %d]clock stress test...END\r\n", __FUNCTION__, __LINE__);
+
+END_TEST:
+
+    if (status != NO_ERROR)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+    return status;
+
+}
+
+
+kal_int32 sdtestcase14(void)
+{
+    kal_uint8 input;
+    kal_uint32 value;
+
+    msdc_dbg_print("[%s %d]CLKPAD_RED test...\r\n", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[%s %d]CLKPAD_RED=%d\r\n", __FUNCTION__, __LINE__, ((MSDC_Reg32(MSDC_CLKACB_CFG) & 0x80) >> 7));
+    msdc_dbg_print("input(0:rising edge ; 1:falling edge)(ESC:exit):\r\n");
+
+    msdc_dbg_input(&value);
+    dbg_print("%c\r\n", value);
+
+    if (value == 1)
+    {
+        MSDC_SetBits32(MSDC_CLKACB_CFG, 1 << 7);
+    }
+    else
+    {
+        MSDC_ClearBits32(MSDC_CLKACB_CFG, 1 << 7);
+    }
+
+    return 0;
+}
+
+
+// ==================================================================================
+//
+// Test Case 15. Format test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase15(void)
+{
+    kal_uint32 status;
+    kal_uint32 boot_sector_offset, total_sectors;
+
+    FS_MasterBootRecord *mbr;
+    FS_BootRecord *bs;
+
+    msdc_dbg_print("\r\n[%s %d]FAT fastformat test...", __FUNCTION__, __LINE__);
+
+    do
+    {
+
+        mbr = (FS_MasterBootRecord *)msdc_sector_buf1;
+        bs = (FS_BootRecord *)msdc_sector_buf2;
+
+        total_sectors = gSD->mCSD.capacity / 512;
+
+        //
+        // 1. Create MBR.
+        //
+        boot_sector_offset = SDCreateMasterBootRecord(mbr, total_sectors);
+
+        if (boot_sector_offset > 0)
+        {
+
+            //
+            // 2. Write MBR.
+            //
+            status = WriteSectors(&MSDC_Blk[0], 0, 1, (void *)mbr);
+
+            if (status != STATUS_OK)
+            {
+                msdc_dbg_print("[%s %d]FAT fastformat test...write MBR fail,%d", __FUNCTION__, __LINE__, status);
+                break;
+            }
+
+            //
+            // 3. Create boot sector.
+            //
+            if (SDCreateBootSector(bs, total_sectors, &mbr->PTable[0]) > 0)
+            {
+
+                //
+                // 4. Write boot sector to boot_sector_offset
+                //
+                status = WriteSectors(&MSDC_Blk[0], boot_sector_offset, 1, bs);
+
+                if (status != STATUS_OK)
+                {
+                    msdc_dbg_print("[%s %d]FAT fastformat test...write BS fail,%d", __FUNCTION__, __LINE__, status);
+                    break;
+                }
+
+            }
+            else
+            {
+                msdc_dbg_print("[%s %d]FAT fastformat test...boot sector fail!!!", __FUNCTION__, __LINE__);
+            }
+        }
+        else
+        {
+            msdc_dbg_print("[%s %d]FAT fastformat test...boot sector offset is wrong!!!", __FUNCTION__, __LINE__);
+        }
+
+        //
+        // 5. Finally, perform high level format.
+        //    According to SD spec, 2G~32G card's start address is 0x2000
+        //
+        status = highlevelformat(&MSDC_Blk[0], boot_sector_offset);
+
+        if (status != STATUS_OK)
+            msdc_dbg_print("[%s %d]FAT fastformat test...highlevelformat error,%d", __FUNCTION__, __LINE__, status);
+        else
+            msdc_dbg_print("[%s %d]FAT fastformat test...END,%d", __FUNCTION__, __LINE__, status);
+
+    }
+    while (0);
+
+    if (status != STATUS_OK)
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    else
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+}
+
+
+kal_int32 sdtestcase16(void)
+{
+    kal_int32 status;
+    msdc_dbg_print("\r\n[%s %d]DMA.fix test...", __FUNCTION__, __LINE__);
+    gMSDC_Handle->MSDC_fastFormat = KAL_TRUE;
+    {
+        kal_int32 loopIndex, addr, addrend;
+        SDC_CMD_STATUS status;
+        kal_uint32 time1, time2;
+
+        msdc_dbg_print("[%s %d]write multi test...", __FUNCTION__, __LINE__);
+        addrend = testsectors - testblnum;
+        addr = 0;
+        addrend = ADDREND2;
+        //for(loopIndex = TESTLOOP; loopIndex; loopIndex--)
+        //for(addr=0;addr<addrend;addr++)
+        {
+            kal_int32 i, compare_error;
+
+            for (i = 0; i < 128 * 1; i++)
+                msdc_sector_buf1[i] = ((i + 20 + addr) << 0) | ((i + 21 + addr) << 8) | ((i + 22 + addr) << 16) | ((i + 23 + addr) << 24);
+
+            memset(msdc_uncachedBuf1, 0, sizeof(msdc_uncachedBuf1));
+            time1 = drv_get_current_time();
+
+            //status = SD_SetPreEraseBlk(testblnum);
+            if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+                status = SD_WriteMultiBlock(addr, msdc_sector_buf1, testblnum);
+            else
+                status = SD_WriteMultiBlock(addr * 512, msdc_sector_buf1, testblnum);
+
+            time2 = drv_get_current_time();
+            msdc_dbg_print("[guilin %s %d]SD_WriteMultiBlock=%d,%d KB/S,addr=%d", __FUNCTION__, __LINE__, status, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr);
+
+            if (status != NO_ERROR)
+            {
+                msdc_dbg_print("[%s %d]ERROR,SD_WriteMultiBlock,%d", __FUNCTION__, __LINE__, status);
+                return;
+            }
+
+            //guilin_sleep(400);
+            // readback compare
+            compare_error = 0;
+            time1 = drv_get_current_time();
+
+            if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+                status = SD_ReadMultiBlock(addr, msdc_uncachedBuf2, testblnum);
+            else
+                status = SD_ReadMultiBlock(addr * 512, msdc_uncachedBuf2, testblnum);
+
+            time2 = drv_get_current_time();
+            msdc_dbg_print("[guilin %s %d]SD_ReadMultiBlock=%d,%d KB/S,addr=%d", __FUNCTION__, __LINE__, status, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr);
+
+            if (status != NO_ERROR)
+            {
+                msdc_dbg_print("[%s %d]ERROR,SD_ReadMultiBlock,%d", __FUNCTION__, __LINE__, status);
+                return;
+            }
+
+            for (i = 0; i < 128 * testblnum; i++)
+            {
+                if (msdc_sector_buf1[0] != msdc_uncachedBuf2[i])
+                {
+                    msdc_dbg_print("[%s %d]SD_WriteMultiBlock,readback compare error:write=0x%x , read=0x%x ,i=%d", __FUNCTION__, __LINE__, msdc_uncachedBuf1[i], msdc_uncachedBuf2[i], i);
+                    compare_error = 1;
+                    break;
+                }
+            }
+
+            if (compare_error == 0)
+            {
+                msdc_dbg_print("[%s %d]SD_WriteMultiBlock,readback compare ok", __FUNCTION__, __LINE__);
+            }
+        }
+
+    }
+
+
+    gMSDC_Handle->MSDC_fastFormat = KAL_FALSE;
+    msdc_dbg_print("[%s %d]DMA.fix test...END,%d", __FUNCTION__, __LINE__, status);
+
+
+}
+
+kal_int32 sdtestcase17(void)
+{
+    kal_int32 status, addr, cnt = 0;
+
+    do
+    {
+
+        //--------------------------------------------------------------------
+        msdc_dbg_print("\r\n[%s %d]DAT CRC test...", __FUNCTION__, __LINE__);
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadSingleBlock_MCU_datcrc(0, msdc_sector_buf1 );
+        else
+            status = SD_ReadSingleBlock_MCU_datcrc(0 * 512, msdc_sector_buf1 );
+
+        msdc_dbg_print("[%s %d]sdc_datsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta);
+
+        if (status != ERR_DAT_CRCERR)
+            break;
+
+        cnt++;
+
+        {
+            DCL_HANDLE handle;
+            handle = DclGPIO_Open(DCL_GPIO, DATGPIO); // GPIO31-DAT0
+            DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+            DclGPIO_Close(handle);
+            guilin_sleep(100);
+        }
+
+
+        //--------------------------------------------------------------------
+        msdc_dbg_print("\r\n[%s %d]DATTO test...", __FUNCTION__, __LINE__);
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadSingleBlock_MCU_datto(0, msdc_sector_buf1 );
+        else
+            status = SD_ReadSingleBlock_MCU_datto(0 * 512, msdc_sector_buf1 );
+
+        msdc_dbg_print("[%s %d]sdc_datsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta);
+
+        if (status != ERR_DAT_TIMEOUT)
+            break;
+
+        cnt++;
+
+        {
+            DCL_HANDLE handle;
+            handle = DclGPIO_Open(DCL_GPIO, DATGPIO); // GPIO31-DAT0
+            DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+            DclGPIO_Close(handle);
+            guilin_sleep(100);
+        }
+
+
+
+        //--------------------------------------------------------------------
+        msdc_dbg_print("\r\n[%s %d]CMDTO test...", __FUNCTION__, __LINE__);
+
+        if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+            status = SD_ReadSingleBlock_MCU_cmdto(0, msdc_sector_buf1 );
+        else
+            status = SD_ReadSingleBlock_MCU_cmdto(0 * 512, msdc_sector_buf1 );
+
+        msdc_dbg_print("[%s %d]sdc_cmdsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cmd_sta);
+
+        if (status != ERR_CMD_TIMEOUT)
+            break;
+
+        cnt++;
+
+        {
+            DCL_HANDLE handle;
+            handle = DclGPIO_Open(DCL_GPIO, CMDGPIO); // GPIO32-CMD
+            DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+            DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+            DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+            DclGPIO_Close(handle);
+            guilin_sleep(100);
+        }
+
+
+
+        //--------------------------------------------------------------------
+
+        msdc_dbg_print("[%s %d]CRC,CMDTO,DATTO test...END,%d", __FUNCTION__, __LINE__, status);
+
+    }
+    while (0);
+
+    if (cnt == 3)
+        msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+    else
+        msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+
+}
+kal_int32 sdtestcase18(void)
+{
+    kal_int32 status, addr, loopIndex;
+    kal_uint8 *p81, *p82;
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n[%s %d]odd-size test...read_mcu", __FUNCTION__, __LINE__);
+    addr = gSD->mBKNum - 1;
+
+    if (addr < 0)addr = 0;
+
+    loopIndex = 1;
+    memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+    memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+    status = SD_SetBlength(512);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf1);
+    else
+        status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf1);
+
+    status = SD_SetBlength(511);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf2);
+    else
+        status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf2);
+
+    p81 = (kal_uint8 *)&msdc_sector_buf1[0];
+    p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+    for (loopIndex = 0; loopIndex < 511; loopIndex++)
+    {
+        if (p81[loopIndex] != p82[loopIndex])
+        {
+            msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+            break;
+        }
+    }
+
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n[%s %d]odd-size test...write_mcu", __FUNCTION__, __LINE__);
+    memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+    memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+    memset(msdc_sector_buf3, 0, sizeof(msdc_sector_buf3));
+    status = SD_SetBlength(512);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf1 );
+    else
+        status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf1);
+
+    for (loopIndex = 0; loopIndex < 512 / 4; loopIndex++)
+        msdc_sector_buf2[loopIndex] = msdc_sector_buf1[loopIndex] + 0x01010101;
+
+    status = SD_SetBlength(511);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_WriteSingleBlock_MCU(0, msdc_sector_buf2);
+    else
+        status = SD_WriteSingleBlock_MCU(0 * 512, msdc_sector_buf2);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf3);
+    else
+        status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf3);
+
+    p81 = (kal_uint8 *)&msdc_sector_buf3[0];
+    p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+    for (loopIndex = 0; loopIndex < 511; loopIndex++)
+    {
+        if (p81[loopIndex] != p82[loopIndex])
+        {
+            msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+            break;
+        }
+    }
+
+    //-------------------------------------------------------------------------
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n[%s %d]odd-size test...read_dma", __FUNCTION__, __LINE__);
+    memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+    memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+    status = SD_SetBlength(512);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock(0, msdc_sector_buf1);
+    else
+        status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf1);
+
+    status = SD_SetBlength(511);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock(0, msdc_sector_buf2);
+    else
+        status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf2);
+
+    p81 = (kal_uint8 *)&msdc_sector_buf1[0];
+    p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+    for (loopIndex = 0; loopIndex < 511; loopIndex++)
+    {
+        if (p81[loopIndex] != p82[loopIndex])
+        {
+            msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+            break;
+        }
+    }
+
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n[%s %d]odd-size test...write_dma", __FUNCTION__, __LINE__);
+    memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+    memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+    memset(msdc_sector_buf3, 0, sizeof(msdc_sector_buf3));
+    status = SD_SetBlength(512);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock(0, msdc_sector_buf1 );
+    else
+        status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf1);
+
+    for (loopIndex = 0; loopIndex < 512 / 4; loopIndex++)
+        msdc_sector_buf2[loopIndex] = msdc_sector_buf1[loopIndex] + 0x01010101;
+
+    status = SD_SetBlength(511);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+    loopIndex = 1;
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_WriteSingleBlock(0, msdc_sector_buf2);
+    else
+        status = SD_WriteSingleBlock(0 * 512, msdc_sector_buf2);
+
+    loopIndex = 1;
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        status = SD_ReadSingleBlock(0, msdc_sector_buf3);
+    else
+        status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf3);
+
+    p81 = (kal_uint8 *)&msdc_sector_buf3[0];
+    p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+    for (loopIndex = 0; loopIndex < 511; loopIndex++)
+    {
+        if (p81[loopIndex] != p82[loopIndex])
+        {
+            msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+            break;
+        }
+    }
+
+    //-------------------------------------------------------------------------
+    status = SD_SetBlength(512);
+    msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("[%s %d]odd-size test...END,%d", __FUNCTION__, __LINE__, status);
+
+}
+kal_int32 sdtestcase19(void)
+{
+    kal_uint8 input;
+
+    msdc_dbg_print("\r\n[%s %d]MSDC_useDMA4ByteBurst test...%d byte", __FUNCTION__, __LINE__, (MSDC_useDMA4ByteBurst == KAL_TRUE ? 4 : 1));
+    msdc_dbg_print("input(1:1byte ; 4:4byte ; ESC:exit):");
+
+    while (1)
+    {
+        input = U_GetUARTByte(uart_port1);
+
+        if (input == '1')
+        {
+            MSDC_useDMA4ByteBurst = KAL_FALSE;
+        }
+        else if (input == '4')
+        {
+            MSDC_useDMA4ByteBurst = KAL_TRUE;
+        }
+        else if (input == 0x0d || input == 0x0a)
+        {
+            break;
+        }
+        else if (input == ESCKEY) //esc
+        {
+            return;
+        }
+        else
+        {
+            continue;
+        }
+
+        dbg_print("%c", input);
+    }
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 20. Erase test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase20(kal_uint32 startSector, kal_uint32 sectorNum)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 i;
+    kal_uint32 time1, time2;
+
+    msdc_dbg_print("[%s %d]SD_FlushSectors %d, %d", __FUNCTION__, __LINE__, startSector, sectorNum);
+
+    time1 = drv_get_current_time();
+    status = SD_FlushSectors(startSector, sectorNum);
+    time2 = drv_get_current_time();
+
+    if (status == NO_ERROR)
+    {
+        msdc_dbg_print("[%s %d]OK=%d , time=%d \r\n", __FUNCTION__, __LINE__, status, time2 - time1);
+        msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]ERROR=%d , time=%d \r\n", __FUNCTION__, __LINE__, status, time2 - time1);
+        msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+    }
+
+
+    MSDC_PDNControl(KAL_FALSE);
+}
+
+
+
+kal_int32 sdtestcase21(kal_uint32 test_round)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 i, addr, addrend, loopIndex, oknum, errornum, result, offset;
+    msdc_dbg_print("[%s %d]start", __FUNCTION__, __LINE__);
+
+    memset(test_statistic, 0, sizeof(test_statistic));
+
+    oknum = 0;
+    errornum = 0;
+    offset = 0;
+
+    //-------------------------------------------------------------------------
+    for (testblnum = 1; testblnum < 1024; testblnum *= 2)
+    {
+        addrend = testblnum * test_round;
+
+        for (addr = 0; addr < addrend; addr += testblnum)
+        {
+            status = sdtestcase5(addr, msdc_uncachedBuf1);
+
+            if (status == NO_ERROR)
+            {
+                oknum++;
+                test_statistic[offset].bit14 = (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1;
+                test_statistic[offset].isread1 = 1;
+                test_statistic[offset].clksrc = 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3);
+                test_statistic[offset].sclkf = 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8);
+                test_statistic[offset].clock = gMsdcClksrcRate[test_statistic[offset].clksrc] / DIV_SCLKF(test_statistic[offset].sclkf);
+                test_statistic[offset].addr = addr;
+                test_statistic[offset].blnum = testblnum;
+                test_statistic[offset].speed = gspeed;
+                gspeed = 0;
+                offset++;
+            }
+            else
+            {
+                errornum++;
+                msdc_dbg_print("[%s %d]ERROR, ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+                return status;
+            }
+        }
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n:index      bit  RW \t clksrc  sclkf    clock \t    addr \t   blnum \t  speed ");
+
+    for (offset = 0; offset < test_round * 10; offset++)
+    {
+        msdc_dbg_print("[%3d]  %3d \t %c \t %3d \t %3d \t %6d \t %6d \t %6d \t %6d ",
+                       offset,
+                       test_statistic[offset].bit14,
+                       test_statistic[offset].isread1 == 1 ? 'R' : 'W',
+                       test_statistic[offset].clksrc,
+                       test_statistic[offset].sclkf,
+                       test_statistic[offset].clock,
+                       test_statistic[offset].addr,
+                       test_statistic[offset].blnum,
+                       test_statistic[offset].speed );
+    }
+
+    //-------------------------------------------------------------------------
+    memset(test_statistic, 0, sizeof(test_statistic));
+
+    oknum = 0;
+    errornum = 0;
+    offset = 0;
+
+WRITE_TEST:
+
+    for (testblnum = 1; testblnum < 1024; testblnum *= 2)
+    {
+        addrend = testblnum * test_round;
+
+        for (addr = 0; addr < addrend; addr += testblnum)
+        {
+            status = sdtestcase6(addr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+            if (status == NO_ERROR)
+            {
+                oknum++;
+                test_statistic[offset].bit14 = (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1;
+                test_statistic[offset].isread1 = 2;
+                test_statistic[offset].clksrc = 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3);
+                test_statistic[offset].sclkf = 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8);
+                test_statistic[offset].clock = gMsdcClksrcRate[test_statistic[offset].clksrc] / DIV_SCLKF(test_statistic[offset].sclkf);
+                test_statistic[offset].addr = addr;
+                test_statistic[offset].blnum = testblnum;
+                test_statistic[offset].speed = gspeed;
+                gspeed = 0;
+                offset++;
+            }
+            else
+            {
+                errornum++;
+                msdc_dbg_print("[%s %d]ERROR, ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+                return status;
+            }
+
+        }
+    }
+
+    msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+    oknum = 0;
+    errornum = 0;
+
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("\r\n:index      bit  RW \t clksrc  sclkf    clock \t    addr \t   blnum \t  speed ");
+
+    for (offset = 0; offset < test_round * 10; offset++)
+    {
+        msdc_dbg_print("[%3d]  %3d \t %c \t %3d \t %3d \t %6d \t %6d \t %6d \t %6d ",
+
+                       offset,
+                       test_statistic[offset].bit14,
+                       test_statistic[offset].isread1 == 1 ? 'R' : 'W',
+                       test_statistic[offset].clksrc,
+                       test_statistic[offset].sclkf,
+                       test_statistic[offset].clock,
+                       test_statistic[offset].addr,
+                       test_statistic[offset].blnum,
+                       test_statistic[offset].speed );
+    }
+
+END_TEST:
+
+    testblnum = 32;
+
+    return status;
+}
+
+kal_int32 sdtestcase22(void)
+{
+    SDC_CMD_STATUS status;
+    kal_uint8 buf[30], input, offset;
+    kal_uint32 value, cmdvalue = 0, cmdarg = 0x55;
+
+    memset(buf, 0, sizeof(buf));
+    msdc_dbg_print("\r\n[%s %d]SD CMD test...", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[%s %d]SDC_CMD=0x%x SDC_ARG=0x%x SDC_CMDSTA=0x%x SDC_RESP0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD), MSDC_Reg32(SDC_ARG), MSDC_Reg(SDC_CMDSTA), MSDC_Reg32(SDC_RESP0));
+    msdc_dbg_print("input CMD(ESC:exit):");
+
+    msdc_dbg_input(&value);
+
+    if (value >= 0)
+    {
+        switch (value)
+        {
+            case 0 :
+                cmdvalue = SDC_CMD_CMD0;
+                cmdarg = 0;
+                break;
+
+            case 1 :
+                cmdvalue = SDC_CMD_CMD1;
+                cmdarg = 0;
+                break;
+
+            case 2 :
+                cmdvalue = SDC_CMD_CMD2;
+                cmdarg = 0;
+                break;
+
+            case 3 :
+                cmdvalue = SDC_CMD_CMD3_SD;
+                cmdarg = 0;
+                break;
+
+            case 7 :
+                cmdvalue = SDC_CMD_CMD7;
+                cmdarg = gSD->mRCA;
+                break;
+
+            case 8 :
+                cmdvalue = SDC_CMD_CMD8;
+                cmdarg = 0x1aa;
+                break;
+
+            case 9 :
+                cmdvalue = SDC_CMD_CMD9;
+                cmdarg = 0;
+                break;
+
+            case 13:
+                cmdvalue = SDC_CMD_CMD13;
+                cmdarg = gSD->mRCA;
+                break;
+
+            case 16:
+                cmdvalue = SDC_CMD_CMD16;
+                cmdarg = 0;
+                break;
+
+            case 17:
+                cmdvalue = SDC_CMD_CMD17;
+                cmdarg = 0;
+                break;
+
+            case 18:
+                cmdvalue = SDC_CMD_CMD18;
+                cmdarg = 0;
+                break;
+
+            case 41:
+                cmdvalue = SDC_CMD_CMD41_SD;
+                cmdarg = 0x40ff8000;
+                break;
+
+            case 42:
+                cmdvalue = SDC_CMD_CMD42;
+                cmdarg = 0;
+                break;
+
+            case 51:
+                cmdvalue = SDC_CMD_ACMD51;
+                cmdarg = 0x40FF8000;
+                break;
+
+            case 55:
+                cmdvalue = SDC_CMD_CMD55;
+                cmdarg = 0;
+                break;
+
+            default:
+                cmdvalue = SDC_CMD_CMD0;
+                cmdarg = 0;
+                break;
+        }
+
+        status = SD_Send_Cmd(cmdvalue, cmdarg);
+        msdc_dbg_print("SD_Send_Cmd=%d cmd=0x%x cmdarg=0x%x", status, cmdvalue, cmdarg);
+        msdc_dbg_print("[%s %d]SDC_CMD=0x%x SDC_ARG=0x%x SDC_CMDSTA=0x%x SDC_RESP0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD), MSDC_Reg32(SDC_ARG), gMSDC_Handle->cmd_sta, MSDC_Reg32(SDC_RESP0));
+    }
+
+
+}
+
+
+
+
+SDC_CMD_STATUS vSDIOInitialisation_Test(void)
+{
+    static DCL_STATUS fgControl;
+    static SDIO_CTRL_SET_BLK_SIZE_T fgblksize;
+    static DCL_SDIO_function_id_enum fgfunctionid;
+    static kal_uint32 u4BlockSize;
+    static kal_char u4PrintBuff[30];
+    static SDIO_CTRL_REG_RW_T regReadWrite;
+    kal_uint32 j;
+    int tbttCount = 0;
+    kal_uint32 mcrValue;
+    SDIO_CTRL_DAT_RW_T datReadWrite;
+    SDIO_CTRL_ENABLE_T enableInterrupt;
+    kal_uint32  checkChipIdRevision;
+    SDC_CMD_STATUS status;
+
+    //fgControl = DclSDIO_Open(DCL_SDIO, DCL_SDIO_FLAGS_DEVICE_CARD1|DCL_SDIO_FLAGS_USAGE_CMD);
+
+    //fgControl = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_INIT,  (DCL_CTRL_DATA_T *)NULL);
+
+    //MSDC_Initialize();
+
+    MSDC_turnOnVMC(KAL_FALSE);
+    guilin_sleep(1000);
+    MSDC_turnOnVMC(KAL_TRUE);
+
+    status = SDIO_Initialize();
+
+    if (status != NO_ERROR)
+    {
+        msdc_dbg_print("[%s %d]sdio initialize fail!!%d\r\n", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    msdc_dbg_print("[%s %d]sdio initialize OK. %d\r\n", __FUNCTION__, __LINE__, status);
+
+    /*
+        fgblksize.function= SDIO_FUCN_1;
+        fgblksize.size = 128;
+        fgControl = DclSDIO_Control(handle_sdio,SDIO_CTRL_CMD_SET_BLK_SIZE,(DCL_CTRL_DATA_T *)&fgblksize);
+
+        if (fgControl != ((DCL_STATUS)STATUS_OK)) {
+
+            dbg_print("Error !!! SDIO Setting bulk size for function 1 Failed!\n");
+        }
+        else {
+            dbg_print("SDIO Setting bulk size for function 1 passed!\n");
+
+        }
+    */
+}
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#if 1
+char str_buf[256] = {0};
+kal_int32 str_num = 0;
+kal_semid msdc_dbg_print_semid = NULL;
+
+void msdc_dbg_print(char *fmt, ...)
+{
+    static kal_uint32 num = 0;
+
+    va_list argp;
+
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+        if (msdc_dbg_print_semid == NULL)
+            msdc_dbg_print_semid = kal_create_sem("msdc_dbg_print_semid_lock", 1);
+
+
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+    {
+        if (msdc_dbg_print_semid)
+            kal_take_sem(msdc_dbg_print_semid, 1);
+    }
+
+
+    snprintf(str_buf, 5, "%04d", str_num++);
+    va_start(argp, fmt);
+    _vsnprintf(&str_buf[4], (256 - 4), fmt, argp);
+    va_end(argp);
+
+    kal_prompt_trace(MOD_MSDC_HISR, "%s", str_buf);
+    dbg_print("%s \r\n", str_buf);
+
+    //    kal_bootup_trace
+
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+    {
+        if (msdc_dbg_print_semid)
+            kal_give_sem(msdc_dbg_print_semid);
+    }
+
+
+}
+
+kal_uint8 U_GetUARTByte(UART_PORT port)
+{
+   
+   kal_uint8 data;
+   kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value);//liming add statement
+   while(!U_GetUARTByteWithTimeOut(port,&data,0xffffffff));// for descrease code size  (U_GetUARTByte &U_GetUARTByteTimeout)
+   return data;
+}
+
+void msdc_dbg_input(kal_uint32 *value)
+{
+    kal_uint32 result = 0;
+    kal_uint8 str[30], input, offset;
+
+    offset = 0;
+
+    while (1)
+    {
+        input = U_GetUARTByte(DBG_PRINT_PORT);
+	
+        /*
+        if (input >='0' && input <= '9') {
+
+            //input -= '0';
+        }
+        else {
+
+            if(input == 0x0d || input == 0x0a) {
+
+                break;
+            }
+            else {
+
+                if(input == ESCKEY)//esc
+                    return;
+                else
+                    continue;
+
+            }
+        }
+        */
+        if (input == 0x0d || input == 0x0a)
+            break;
+
+        if (input == ESCKEY)
+            return;
+
+        str[offset++] = input;
+        dbg_print("%c", input);
+    }
+
+    str[offset] = 0;
+
+    dbg_print("\r\n");
+    sscanf(str, "%d", value);
+}
+
+
+kal_uint32 msdc_get_uart_input()
+{
+    kal_uint8 buf[30], input, offset;
+    kal_int32 value = 0;
+
+    while (1)
+    {
+
+        input = U_GetUARTByte(uart_port1);
+
+        //if(input >='0' && input <= '9')
+        //{
+        //input -= '0';
+        //}
+        //else if(input == 0x0d || input == 0x0a)
+        if (input == 0x0d || input == 0x0a)
+        {
+            break;
+        }
+        else if (input == ESCKEY) //esc
+        {
+            return;
+        }
+
+        //else
+        //{
+        //    continue;
+        //}
+
+        buf[offset++] = input;
+        dbg_print("%c", input);
+    }
+
+    buf[30 - 1] = 0;
+
+    dbg_print("\r\n");
+    sscanf(buf, "%x", &value);
+
+    return value;
+}
+
+
+void guilin_sleep(kal_uint32 x)
+{
+    if ((kal_query_systemInit() == KAL_TRUE)
+#ifdef  __TST_WRITE_TO_FILE__
+            || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+            || KAL_TRUE == FTL_isPollingMode()
+       )
+    {
+        MSDC_GPTI_BusyWait(x * 5);
+    }
+    else
+    {
+        kal_sleep_task(x);
+    }
+}
+void guilintest(void)
+{
+    msdc_dbg_print("[guilin %s %d]start", __FUNCTION__, __LINE__);
+
+    msdc_dbg_print("[guilin %s %d]gSD->mSDC_ocr  =0x%x", __FUNCTION__, __LINE__, gSD->mSDC_ocr                 ); // gSD->mSDC_ocr  =0x80FF8000
+    msdc_dbg_print("[guilin %s %d]gSD->mBKLength =0x%x", __FUNCTION__, __LINE__, gSD->mBKLength                ); // gSD->mBKLength =0x200
+    msdc_dbg_print("[guilin %s %d]gSD->mBKNum    =0x%x", __FUNCTION__, __LINE__, gSD->mBKNum                   ); // gSD->mBKNum    =0xF3400
+    msdc_dbg_print("[guilin %s %d]gSD->flags     =0x%x", __FUNCTION__, __LINE__, gSD->flags                    ); // gSD->flags     =0x3C
+    msdc_dbg_print("[guilin %s %d]gSD->mRCA      =0x%x", __FUNCTION__, __LINE__, gSD->mRCA                     ); // gSD->mRCA      =0xB368
+    msdc_dbg_print("[guilin %s %d]gSD->mState    =0x%x", __FUNCTION__, __LINE__, gSD->mState                   ); // gSD->mState    =0x3
+    msdc_dbg_print("[guilin %s %d]gSD->mInactive =0x%x", __FUNCTION__, __LINE__, gSD->mInactive                ); // gSD->mInactive =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->bus_width =0x%x", __FUNCTION__, __LINE__, gSD->bus_width                ); // gSD->bus_width =0x4
+    msdc_dbg_print("[guilin %s %d]gSD->mWPEnabled=0x%x", __FUNCTION__, __LINE__, gSD->mWPEnabled               ); // gSD->mWPEnabled=0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mIsLocked =0x%x", __FUNCTION__, __LINE__, gSD->mIsLocked                ); // gSD->mIsLocked =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCD_DAT3  =0x%x", __FUNCTION__, __LINE__, gSD->mCD_DAT3                 ); // gSD->mCD_DAT3  =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCMD8Resp =0x%x", __FUNCTION__, __LINE__, gSD->mCMD8Resp                ); // gSD->mCMD8Resp =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->sd_r      =0x%x", __FUNCTION__, __LINE__, gSD->sd_r                     ); // gSD->sd_r      =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->sd_w      =0x%x", __FUNCTION__, __LINE__, gSD->sd_w                     ); // gSD->sd_w      =0x0
+
+    msdc_dbg_print("[guilin %s %d]CSD", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.tacc              =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.tacc                ); // gSD->mCSD.tacc              =0x5E
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.nsac              =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.nsac                ); // gSD->mCSD.nsac              =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.tran_speed        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.tran_speed          ); // gSD->mCSD.tran_speed        =0x32
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.ccc               =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ccc                 ); // gSD->mCSD.ccc               =0x5F5
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_len         =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_len           ); // gSD->mCSD.w_blk_len         =0x200
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_len         =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_len           ); // gSD->mCSD.r_blk_len         =0x200
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.max_w_blk_len     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.max_w_blk_len       ); // gSD->mCSD.max_w_blk_len     =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.max_r_blk_len     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.max_r_blk_len       ); // gSD->mCSD.max_r_blk_len     =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_misali      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_misali        ); // gSD->mCSD.w_blk_misali      =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_misali      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_misali        ); // gSD->mCSD.r_blk_misali      =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_part        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_part          ); // gSD->mCSD.w_blk_part        =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_part        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_part          ); // gSD->mCSD.r_blk_part        =0x1
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_sec_size_mmc=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_sec_size_mmc  ); // gSD->mCSD.erase_sec_size_mmc=0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_grp_size_mmc=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_grp_size_mmc  ); // gSD->mCSD.erase_grp_size_mmc=0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_grp_size_mmc   =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_grp_size_mmc     ); // gSD->mCSD.wp_grp_size_mmc   =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_blk_en_sd   =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_blk_en_sd     ); // gSD->mCSD.erase_blk_en_sd   =0x1
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_sec_size_sd =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_sec_size_sd   ); // gSD->mCSD.erase_sec_size_sd =0x80
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_prg_size_sd    =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_prg_size_sd      ); // gSD->mCSD.wp_prg_size_sd    =0x800
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_grp_enable     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_grp_enable       ); // gSD->mCSD.wp_grp_enable     =0x1
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.capacity          =%d MB", __FUNCTION__, __LINE__, gSD->mCSD.capacity / (1024 * 1024)); // gSD->mCSD.capacity          =0x1E680000
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.cmd_class         =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.cmd_class           ); // gSD->mCSD.cmd_class         =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.temp_wp           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.temp_wp             ); // gSD->mCSD.temp_wp           =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.perm_wp           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.perm_wp             ); // gSD->mCSD.perm_wp           =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.dsr_imp           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.dsr_imp             ); // gSD->mCSD.dsr_imp           =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.csd_ver           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.csd_ver             ); // gSD->mCSD.csd_ver           =0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mCSD.spec_ver          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.spec_ver            ); // gSD->mCSD.spec_ver          =0x0
+    {
+        guilin_sleep(30);
+        msdc_dbg_print("[guilin %s %d]EXTCSD", __FUNCTION__, __LINE__);
+#ifndef MSDC_MMC441_SUPPORT
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev1[183]            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev1[183 - 1]           );
+#else
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev0[136]      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev0[136 - 1]     );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->enh_start_addr       =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->enh_start_addr      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->enh_size_mult[3]     =0x%x 0x%x 0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->enh_size_mult[2], gSD->mCSD.ext_csd->enh_size_mult[1], gSD->mCSD.ext_csd->enh_size_mult[0]    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[4]      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[11], gSD->mCSD.ext_csd->gp_size_mult[10], gSD->mCSD.ext_csd->gp_size_mult[9]    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[3]      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[8], gSD->mCSD.ext_csd->gp_size_mult[7], gSD->mCSD.ext_csd->gp_size_mult[6]    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[2]      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[5], gSD->mCSD.ext_csd->gp_size_mult[4], gSD->mCSD.ext_csd->gp_size_mult[3]    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[1]      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[2], gSD->mCSD.ext_csd->gp_size_mult[1], gSD->mCSD.ext_csd->gp_size_mult[0]    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_settig     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_settig    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_attr       =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_attr      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->max_enh_size_mult[3] =0x%x 0x%x 0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->max_enh_size_mult[2], gSD->mCSD.ext_csd->max_enh_size_mult[1], gSD->mCSD.ext_csd->max_enh_size_mult[0]);
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_support    =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_support   );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev1           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev1          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rst_function         =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rst_function        );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev2[5]        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev2[5 - 1]       );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rpmb_size_mul        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rpmb_size_mul       );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->fw_config            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->fw_config           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev3           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev3          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->user_wp              =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->user_wp             );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev4           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev4          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_wp              =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_wp             );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev5           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev5          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erase_grp_def        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erase_grp_def       );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev6           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev6          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_bus_width       =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_bus_width      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_config_prot     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_config_prot    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_config     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_config    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev7           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev7          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erased_mem_cont      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erased_mem_cont     );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev8           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev8          );
+#endif
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->bus_width            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->bus_width            );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev2                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev2                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->high_speed           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->high_speed           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev3                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev3                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->power_class          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->power_class          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev4                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev4                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->cmd_set_rev          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->cmd_set_rev          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev5                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev5                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->cmd_set              =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->cmd_set              );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->ext_csd_rev          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->ext_csd_rev          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev7                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev7                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->ext_csd_ver          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->ext_csd_ver          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev8                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev8                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->card_type            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->card_type            );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev9                 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev9                 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->out_of_interrupt_time=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->out_of_interrupt_time);
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_switch_time=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_switch_time);
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_52_195           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_52_195           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_26_195           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_26_195           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_52_360           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_52_360           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_26_360           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_26_360           );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev10                =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev10                );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_4_26      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_4_26      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_4_26      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_4_26      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_8_26_4_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_8_26_4_52 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_8_26_4_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_8_26_4_52 );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_8_52      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_8_52      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_8_52      =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_8_52      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->resv11               =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->resv11               );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->sec_count            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->sec_count            );
+
+        guilin_sleep(30);
+#ifndef MSDC_MMC441_SUPPORT
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev12[288]           =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev12[288 - 1]        );
+#else
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev9[5]        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev9[5 - 1]     );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->hc_wp_grp_size       =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->hc_wp_grp_size    );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rel_wr_sec_c         =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rel_wr_sec_c      );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erase_timeout_mult   =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erase_timeout_mult);
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->hc_erase_grp_size    =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->hc_erase_grp_size );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->acc_size             =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->acc_size          );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_size_mul        =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_size_mul     );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev10          =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev10       );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_info            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_info         );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev11[275]     =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev11[275 - 1]  );
+#endif
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->s_cmd_set            =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->s_cmd_set         );
+        msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev13[7]             =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev13[7 - 1]          );
+    }
+
+    msdc_dbg_print("[guilin %s %d]CID", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.mid  =0x%x", __FUNCTION__, __LINE__, gSD->mCID.mid                 ); // gSD->mCID.mid  =0x1B
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.oid  =0x%x", __FUNCTION__, __LINE__, gSD->mCID.oid                 ); // gSD->mCID.oid  =0x534D
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.pnm  =%c%c%c%c%c%c", __FUNCTION__, __LINE__, gSD->mCID.pnm[0], gSD->mCID.pnm[1], gSD->mCID.pnm[2], gSD->mCID.pnm[3], gSD->mCID.pnm[4], gSD->mCID.pnm[5]);
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.prv  =0x%x", __FUNCTION__, __LINE__, gSD->mCID.prv                 ); // gSD->mCID.prv  =0x10
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.psn  =0x%x", __FUNCTION__, __LINE__, gSD->mCID.psn                 ); // gSD->mCID.psn  =0x7940C2
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.year =0x%x", __FUNCTION__, __LINE__, gSD->mCID.year                ); // gSD->mCID.year =0x7D8
+    msdc_dbg_print("[guilin %s %d]gSD->mCID.month=0x%x", __FUNCTION__, __LINE__, gSD->mCID.month               ); // gSD->mCID.month=0x8
+
+    msdc_dbg_print("[guilin %s %d]SCR", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[guilin %s %d]gSD->mSCR.dat_after_erase=0x%x", __FUNCTION__, __LINE__, gSD->mSCR.dat_after_erase     ); // gSD->mSCR.dat_after_erase=0x0
+    msdc_dbg_print("[guilin %s %d]gSD->mSCR.security       =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.security            ); // gSD->mSCR.security       =0x2
+    msdc_dbg_print("[guilin %s %d]gSD->mSCR.bus_width      =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.bus_width           ); // gSD->mSCR.bus_width      =0x5
+    msdc_dbg_print("[guilin %s %d]gSD->mSCR.spec_ver       =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.spec_ver            ); // gSD->mSCR.spec_ver       =0x1
+
+    guilin_sleep(30);
+
+    msdc_dbg_print("[guilin %s %d]Reg", __FUNCTION__, __LINE__);
+    msdc_dbg_print("[guilin %s %d]MSDC_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_CFG));   // MSDC_CFG=0x1210031
+    msdc_dbg_print("[guilin %s %d]MSDC_STA=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_STA));   // MSDC_STA=0x2
+    msdc_dbg_print("[guilin %s %d]MSDC_PS=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_PS));     // MSDC_PS=0x1FF0008
+    msdc_dbg_print("[guilin %s %d]MSDC_IOCON=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON)); // MSDC_IOCON=0x1280036
+    msdc_dbg_print("[guilin %s %d]MSDC_IOCON1=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON1)); // MSDC_IOCON1=0x22222
+
+    msdc_dbg_print("[guilin %s %d]SDC_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CFG));       // SDC_CFG=0x50038200
+    msdc_dbg_print("[guilin %s %d]SDC_CMD=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD));       // SDC_CMD=0x97
+    msdc_dbg_print("[guilin %s %d]SDC_ARG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_ARG));       // SDC_ARG=0x20
+    msdc_dbg_print("[guilin %s %d]SDC_IRQMASK0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK0)); // SDC_IRQMASK0=0x7000F
+    msdc_dbg_print("[guilin %s %d]SDC_IRQMASK1=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK1)); // SDC_IRQMASK1=0x0
+
+    msdc_dbg_print("[guilin %s %d]SDIO_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK1 + 4)); // SDIO_CFG=0x0
+
+    //    msdc_dbg_print("[guilin %s %d]MSDC_BOOT_CFG=0x%x",__FUNCTION__,__LINE__,MSDC_Reg32(MSDC_BOOT_CFG));    // MSDC_BOOT_CFG=0x0
+    //    msdc_dbg_print("[guilin %s %d]MSDC_BOOT_IOCON=0x%x",__FUNCTION__,__LINE__,MSDC_Reg32(MSDC_BOOT_IOCON));// MSDC_BOOT_IOCON=0x0
+
+    msdc_dbg_print("[guilin %s %d]MSDC_CLKACB_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_CLKACB_CFG)); // MSDC_CLKACB_CFG=0x20000
+
+    guilin_sleep(30);
+
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_clock               =%d", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clock                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->op_clock                 =%d", __FUNCTION__, __LINE__, gMSDC_Handle->op_clock                    );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->total_count              =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->total_count                 );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->timeout_period           =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->timeout_period              );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.type          =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.type             );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.size          =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.size             );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.count         =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.count            );
+#if defined(__DMA_API_V2__)
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.fixed_pattern =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.fixed_pattern    );
+#endif
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.TMOD.burst_mode=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.TMOD.burst_mode   );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.TMOD.cycle     =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.TMOD.cycle        );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.master         =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.master            );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mMSDC_type               =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mMSDC_type                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsPresent               =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsPresent                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsInitialized           =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsInitialized              );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsChanged               =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsChanged                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_timeout               =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_timeout                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsPWDown                =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsPWDown                   );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->cmd_sta                  =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cmd_sta                     );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->dat_sta                  =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta                     );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->ins_level                =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->ins_level                   );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->timeout_count            =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->timeout_count               );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_poll                  =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_poll                     );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_aligned               =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_aligned                  );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_init_timeout          =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_init_timeout             );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->send_ilm                 =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->send_ilm                    );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_dmaport             =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_dmaport                );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->dataCrcError_count       =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dataCrcError_count          );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->trySingleLine            =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->trySingleLine               );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->isCachedBuf              =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->isCachedBuf                 );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->cachedBufCopyPtr         =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cachedBufCopyPtr            );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->tuningTopology           =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->tuningTopology              );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->MSDC_everPlugOut         =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->MSDC_everPlugOut            );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->MSDC_fastFormat          =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->MSDC_fastFormat             );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdcTimeoutDuration      =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdcTimeoutDuration         );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_clkTuneUpperBund    =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clkTuneUpperBund       );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsInitMSDC              =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsInitMSDC                 );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_int                 =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_int                    );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->LISR_Entry_Count         =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->LISR_Entry_Count            );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDCMDIRQ_Entry_Count     =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDCMDIRQ_Entry_Count        );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDMCIRQ_Entry_Count      =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDMCIRQ_Entry_Count         );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDDATIRQ_Entry_Count     =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDDATIRQ_Entry_Count        );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDR1bIRQ_Entry_count     =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDR1bIRQ_Entry_count        );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDIOIRQ_Entry_Count      =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDIOIRQ_Entry_Count         );
+    msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDPINIRQ_Entry_Count     =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDPINIRQ_Entry_Count        );
+
+    msdc_dbg_print("[guilin %s %d]end", __FUNCTION__, __LINE__);
+    guilin_sleep(30);
+
+}
+
+
+#endif
+
+
+#endif //#ifdef __MSDC_BASIC_LOAD__
+
+#ifdef __MSDC_SD_SDIO__
+
+
+DCL_HANDLE handle_sdio;
+
+#define TEST_PACKET_MIN_LENGTH 		(140)
+#define TEST_PACKET_MAX_LENGTH		(1500)
+#define MAX_TX_QUEUE_NUM 		16
+
+#pragma arm section rwdata="DYNAMICCACHEABLERW_C", zidata="DYNAMICCACHEABLEZI_C"
+static unsigned char ucDmaBuf[1500]; /*__HOTSPOT_SUPPORT__*/
+#pragma arm section
+
+typedef struct _NIC_HIF_TX_HEADER_T
+{
+    kal_uint16	u2TxByteCount;
+    kal_uint8		ucEtherTypeOffset;
+    kal_uint8		ucCSUMFlags;
+    kal_uint32	dummy[3];
+} NIC_HIF_TX_HEADER_T, *P_NIC_HIF_TX_HEADER_T;
+
+typedef enum
+{
+    RANDOM = 0,
+    DATA_FF,
+    DATA_00,
+    DATA_F0,
+    DATA_0F,
+    DATA_55,
+    DATA_99,
+    DATA_AA,
+    DATA_66,
+} Data_Pattern;
+
+// MT5931
+#define WCIR		(0x0000)
+#define WHLPCR		(0x0004)
+#define WSDIOCSR	(0x0008)
+#define WHCR		(0x000c)
+#define WHISR		(0x0010)
+#define WHIER		(0x0014)
+#define WASR		(0x0018)
+#define WSICR		(0x001c)
+#define WTSR0		(0x0020)
+#define WTSR1		(0x0024)
+#define WTDR0		(0x0028)
+#define WTDR1		(0x002c)
+#define	WRDR0		(0x0030)
+#define WRDR1		(0x0034)
+#define H2DSM0R		(0x0038)
+#define H2DSM1R		(0x003c)
+#define D2HRM0R		(0x0040)
+#define D2HRM1R		(0x0044)
+#define D2HRM2R		(0x0048)
+#define WRPLR		(0x0050)
+#define WEHTCR		(0x0054)
+
+#define FWDLDR		(0x0080)
+#define FWDLDSAR	(0x0084)
+#define FWDLSR		(0x0088)
+#define FWDLCMR0	(0x008c)
+#define FWDLCMR1	(0x0090)
+
+//4 CHIP ID Register
+#define MCR_WCIR                            0x0000
+
+//4 HIF Low Power Control  Register
+#define MCR_WHLPCR                          0x0004
+
+//4 Control  Status Register
+#define MCR_WSDIOCSR                        0x0008
+#define MCR_WSPICSR                         0x0008
+
+//4 HIF Control Register
+#define MCR_WHCR                            0x000C
+
+//4 HIF Interrupt Status  Register
+#define MCR_WHISR                           0x0010
+
+//4 HIF Interrupt Enable  Register
+#define MCR_WHIER                           0x0014
+
+//4 Abnormal Status Register
+#define MCR_WASR                            0x0018
+
+//4 WLAN Software Interrupt Control Register
+#define MCR_WSICR                           0x001C
+
+//4 WLAN TX Status Register
+#define MCR_WTSR0                           0x0020
+
+//4 WLAN TX Status Register
+#define MCR_WTSR1                           0x0024
+
+//4 WLAN TX Data Register 0
+#define MCR_WTDR0                           0x0028
+
+//4 WLAN TX Data Register 1
+#define MCR_WTDR1                           0x002C
+
+//4 WLAN RX Data Register 0
+#define MCR_WRDR0                           0x0030
+
+//4 WLAN RX Data Register 1
+#define MCR_WRDR1                           0x0034
+
+//4 Host to Device Send Mailbox 0 Register
+#define MCR_H2DSM0R                         0x0038
+
+//4 Host to Device Send Mailbox 1 Register
+#define MCR_H2DSM1R                         0x003c
+
+//4 Device to Host Receive Mailbox 0 Register
+#define MCR_D2HRM0R                         0x0040
+
+//4 Device to Host Receive Mailbox 1 Register
+#define MCR_D2HRM1R                         0x0044
+
+//4 Device to Host Receive Mailbox 2 Register
+#define MCR_D2HRM2R                         0x0048
+
+//4 WLAN RX Packet Length Register
+#define MCR_WRPLR                           0x0050
+
+//4 EHPI Transaction Count Register
+#define MCR_EHTCR                           0x0054
+
+//4 Firmware Download Data Register
+#define MCR_FWDLDR                          0x0080
+
+//4 Firmware Download Destination Starting Address Register
+#define MCR_FWDLDSAR                        0x0084
+
+//4 Firmware Download Status Register
+#define MCR_FWDLSR                          0x0088
+
+//4 WLAN MCU Control & Status Register
+#define MCR_WMCSR                           0x008c
+
+//4 WLAN Firmware Download Configuration
+#define MCR_FWCFG                           0x0090
+
+#define BIT(x) (1 << (x))
+
+//2 Definition in each register
+//3 WCIR 0x0000
+#define WCIR_WLAN_READY                  BIT(21)
+#define WCIR_POR_INDICATOR               BIT(20)
+#define WCIR_REVISION_ID                 BITS(16,19)
+#define WCIR_CHIP_ID                     BITS(0,15)
+
+#define MTK_CHIP_REV                     0x00005931
+#define MTK_CHIP_MP_REVERSION_ID         0x0
+
+//3 WHLPCR 0x0004
+#define WHLPCR_FW_OWN_REQ_CLR            BIT(9)
+#define WHLPCR_FW_OWN_REQ_SET            BIT(8)
+#define WHLPCR_IS_DRIVER_OWN             BIT(8)
+#define WHLPCR_INT_EN_CLR                BIT(1)
+#define WHLPCR_INT_EN_SET                BIT(0)
+
+//3 WSDIOCSR 0x0008
+#define WSDIOCSR_SDIO_RE_INIT_EN         BIT(0)
+
+//3 WSPICSR 0x0008
+#define WCSR_SPI_MODE_SEL                BITS(3,4)
+#define WCSR_SPI_ENDIAN_BIG              BIT(2)
+#define WCSR_SPI_INT_OUT_MODE            BIT(1)
+#define WCSR_SPI_DATA_OUT_MODE           BIT(0)
+
+//3 WHCR 0x000C
+#define WHCR_RX_ENHANCE_MODE_EN         BIT(16)
+#define WHCR_MAX_HIF_RX_LEN_NUM         BITS(4,7)
+#define WHCR_W_MAILBOX_RD_CLR_EN        BIT(2)
+#define WHCR_W_INT_CLR_CTRL             BIT(1)
+#define WHCR_MCU_DBG_EN                 BIT(0)
+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM  4
+
+//3 WHISR 0x0010
+#define WHISR_D2H_SW_INT                BITS(8,31)
+#define WHISR_D2H_SW_ASSERT_INFO_INT    BIT(31)
+#define WHISR_FW_OWN_BACK_INT           BIT(4)
+#define WHISR_ABNORMAL_INT              BIT(3)
+#define WHISR_RX1_DONE_INT              BIT(2)
+#define WHISR_RX0_DONE_INT              BIT(1)
+#define WHISR_TX_DONE_INT               BIT(0)
+
+
+//3 WHIER 0x0014
+#define WHIER_D2H_SW_INT                BITS(8,31)
+#define WHIER_FW_OWN_BACK_INT_EN        BIT(4)
+#define WHIER_ABNORMAL_INT_EN           BIT(3)
+#define WHIER_RX1_DONE_INT_EN           BIT(2)
+#define WHIER_RX0_DONE_INT_EN           BIT(1)
+#define WHIER_TX_DONE_INT_EN            BIT(0)
+#define WHIER_DEFAULT                   (WHIER_RX0_DONE_INT_EN    | \
+        WHIER_RX1_DONE_INT_EN    | \
+        WHIER_TX_DONE_INT_EN     | \
+        WHIER_ABNORMAL_INT_EN    | \
+        WHIER_D2H_SW_INT           \
+                                        )
+
+
+//3 WASR 0x0018
+#define WASR_FW_OWN_INVALID_ACCESS      BIT(4)
+#define WASR_RX1_UNDER_FLOW             BIT(3)
+#define WASR_RX0_UNDER_FLOW             BIT(2)
+#define WASR_TX1_OVER_FLOW              BIT(1)
+#define WASR_TX0_OVER_FLOW              BIT(0)
+
+
+//3 WSICR 0x001C
+#define WSICR_H2D_SW_INT_SET            BITS(16,31)
+
+
+//3 WRPLR 0x0050
+#define WRPLR_RX1_PACKET_LENGTH         BITS(16,31)
+#define WRPLR_RX0_PACKET_LENGTH         BITS(0,15)
+
+
+//3 FWDLSR 0x0088
+#define FWDLSR_FWDL_RDY                 BIT(8)
+#define FWDLSR_FWDL_MODE                BIT(0)
+
+
+//3 WMCSR 0x008c
+#define WMCSR_CHIP_RST                  BIT(15) /* write */
+#define WMCSR_DL_OK                     BIT(15) /* read */
+#define WMCSR_DL_FAIL                   BIT(14)
+#define WMCSR_PLLRDY                    BIT(13)
+#define WMCSR_WF_ON                     BIT(12)
+#define WMCSR_INI_RDY                   BIT(11)
+#define WMCSR_WF_EN                     BIT(6)
+#define WMCSR_SW_EN                     BIT(5)
+#define WMCSR_SPLLEN                    BIT(4)
+#define WMCSR_SPWREN                    BIT(3)
+#define WMCSR_HSTOPIL                   BIT(2)
+#define WMCSR_FWDLRST                   BIT(1)
+#define WMCSR_FWDLEN                    BIT(0)
+
+
+//3 FWCFG 0x0090
+#define FWCFG_KSEL                      BITS(14,15)
+#define FWCFG_FLEN                      BITS(0,13)
+
+#define CFG_RESPONSE_POLLING_TIMEOUT            512
+/* Type definition for WLAN STATUS */
+typedef kal_uint32                 WLAN_STATUS, *P_WLAN_STATUS;
+
+#define WLAN_STATUS_SUCCESS                     ((WLAN_STATUS) 0x00000000L)
+#define WLAN_STATUS_FAILURE                     ((WLAN_STATUS) 0xC0000001L)
+
+#define CFG_FW_LOAD_ADDRESS                     0xFF900000
+#define CFG_FW_START_ADDRESS                    0x00000000
+#define CMD_PKT_SIZE_FOR_IMAGE              2048 /* !< 2048 Bytes CMD payload buffer */
+
+typedef struct _HIF_HW_TX_HEADER_T
+{
+    kal_uint16     u2TxByteCount;
+    kal_uint8      ucEtherTypeOffset;
+    kal_uint8      ucCSflags;
+    kal_uint8      aucBuffer[4];
+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T;
+
+#pragma arm section rwdata="DYNAMICCACHEABLERW_C", zidata="DYNAMICCACHEABLEZI_C"
+__align(32) kal_uint8 wndrv_cmd_temp_buf[CMD_PKT_SIZE_FOR_IMAGE + 512];
+#pragma arm section
+
+#define HIF_HW_TX_HDR_SIZE                  OFFSET_OF(HIF_HW_TX_HEADER_T, aucBuffer[0])
+#define OFFSET_OF(_type, _field)    ((kal_uint32)&(((_type *)0)->_field))
+#define ALIGN_4(_value)             (((_value) + 3) & ~3u)
+#define ALIGN_32(_value)             (((_value) + 31) & ~31u)
+#define FUNC1_SDIO_BLK_SIZE (512)
+#define DMA_THRESHOLD 128
+#define SWITCH_TO_NONCACHEABLE 0
+#define SWITCH_TO_CACHEABLE 1
+kal_uint8 payload[1500];
+kal_uint8 pucTXBuf[1500];
+kal_uint8 pucRXBuf[1500];
+
+kal_uint8 const mt5931_E3_Beta_loopback_firmware_hex[] =
+{
+    0x74, 0xDB, 0x7D, 0xB4, 0x6E, 0xA7, 0x12, 0xCE, 0x3C, 0x69, 0xFF, 0xD6, 0xF3, 0x13, 0x47, 0x60
+    , 0xC7, 0x6E, 0x5C, 0xA1, 0x74, 0x29, 0x70, 0x0C, 0x6A, 0xA3, 0x42, 0x02, 0x6D, 0x1B, 0xCE, 0x6F
+    , 0x2F, 0x07, 0x8A, 0x75, 0x63, 0xF8, 0xCD, 0x46, 0x3C, 0x43, 0x7E, 0x62, 0x24, 0x58, 0x19, 0x11
+    , 0x10, 0x30, 0x84, 0x36, 0x0F, 0x06, 0x52, 0x71, 0x86, 0x5F, 0x09, 0x0F, 0x01, 0x8A, 0x51, 0x32
+    , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+    , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+    , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+    , 0xEC, 0xE6, 0x61, 0x25, 0xD2, 0x3C, 0x14, 0xDC, 0x36, 0xF3, 0x22, 0x35, 0xDF, 0xA7, 0xE7, 0x59
+    , 0xA7, 0xDD, 0x1E, 0xF2, 0x4D, 0x1D, 0x93, 0xA2, 0x22, 0xDE, 0xE5, 0x05, 0x50, 0xA5, 0xE6, 0xCA
+    , 0xC0, 0xEC, 0x76, 0x7E, 0x13, 0x8B, 0xBA, 0x3D, 0x4C, 0xC9, 0xCE, 0x6D, 0x50, 0x0F, 0x86, 0x3D
+    , 0x51, 0x52, 0xB2, 0xB5, 0xE9, 0xA2, 0x32, 0x2B, 0x9E, 0xB4, 0x65, 0x8F, 0x60, 0x18, 0xF3, 0xEB
+    , 0xE9, 0xEA, 0xD2, 0xEE, 0x81, 0xD0, 0x53, 0x44, 0x06, 0xBC, 0x43, 0x51, 0x2C, 0xA8, 0x9B, 0xEF
+    , 0xB5, 0x4C, 0x87, 0x80, 0x02, 0x94, 0xFD, 0x25, 0x6F, 0x28, 0x9E, 0x84, 0xA0, 0xDA, 0x6F, 0xA3
+    , 0x30, 0x9B, 0x68, 0xA3, 0x9E, 0x51, 0xBE, 0x1B, 0x49, 0x68, 0xBA, 0x09, 0x6E, 0xEF, 0xF9, 0x52
+    , 0x8F, 0x97, 0x31, 0x3D, 0x77, 0xFF, 0x0C, 0xF1, 0x5A, 0xE4, 0x24, 0x3A, 0xCC, 0x44, 0x9E, 0xF6
+    , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+    , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+    , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+    , 0x7B, 0x6A, 0x61, 0x39, 0xE0, 0x49, 0x0F, 0x31, 0x97, 0x1C, 0xC4, 0x20, 0xD6, 0x0B, 0xA6, 0xF4
+    , 0xA5, 0x7A, 0xCC, 0xC4, 0x1D, 0x38, 0xEC, 0x32, 0x0A, 0x83, 0xE1, 0xB2, 0x64, 0x4F, 0x9F, 0x4C
+    , 0x9A, 0x07, 0xC1, 0xC5, 0xEA, 0x1B, 0xAC, 0x14, 0x41, 0xB9, 0xEA, 0x0C, 0x3F, 0x6F, 0x27, 0xAF
+    , 0x1B, 0x87, 0x56, 0x5E, 0xAE, 0xB6, 0xB6, 0x53, 0xA9, 0xC8, 0xA4, 0xC4, 0x98, 0x97, 0xA4, 0x0F
+    , 0xAD, 0xB6, 0x89, 0x10, 0xAA, 0x99, 0xF5, 0x3C, 0xF7, 0x92, 0x09, 0x62, 0x95, 0xEC, 0x14, 0xE5
+    , 0x81, 0x20, 0xC2, 0x8F, 0xCD, 0xD0, 0x68, 0x9F, 0x9A, 0xF5, 0x7E, 0x3B, 0x13, 0x8D, 0xC9, 0x81
+    , 0x01, 0xC3, 0x39, 0xD9, 0xB5, 0x4C, 0xA4, 0x06, 0x7A, 0x76, 0xDE, 0x55, 0x53, 0x03, 0x3C, 0xA4
+    , 0xBF, 0x24, 0x19, 0x96, 0xBE, 0xD5, 0x15, 0xB5, 0xAF, 0x76, 0x9F, 0x4D, 0x75, 0x4D, 0xE3, 0xA8
+    , 0x03, 0xB0, 0x12, 0xE9, 0x45, 0x8D, 0xB3, 0x67, 0x50, 0xE5, 0xD3, 0x1C, 0xB5, 0x19, 0x32, 0x27
+    , 0x63, 0x38, 0x11, 0x64, 0x19, 0xC7, 0x4E, 0xF4, 0xEE, 0x01, 0xAF, 0xB5, 0x03, 0x97, 0x69, 0x14
+    , 0x97, 0x9E, 0x40, 0xEB, 0x04, 0xDD, 0x7C, 0xFD, 0xD0, 0xA6, 0x02, 0xD2, 0x30, 0x1B, 0x07, 0xBD
+    , 0x72, 0xC7, 0xED, 0xB5, 0x59, 0x53, 0x9B, 0x97, 0x66, 0x3B, 0x07, 0x06, 0x78, 0x51, 0xE6, 0x06
+    , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+    , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+    , 0x0A, 0x4B, 0xDE, 0x16, 0x7A, 0x80, 0x18, 0x08, 0x5B, 0x2A, 0xFA, 0x3A, 0x6B, 0x36, 0x07, 0xCF
+    , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+    , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+    , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+    , 0x7A, 0xB7, 0xD9, 0x69, 0x2E, 0xC4, 0x19, 0xE7, 0x9B, 0x85, 0x9F, 0x3F, 0x31, 0x43, 0xA7, 0xCC
+    , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+    , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+    , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+    , 0x22, 0xEE, 0x34, 0x46, 0x5A, 0x19, 0xE1, 0x1A, 0x67, 0x74, 0x7A, 0xD2, 0xA2, 0xCB, 0x69, 0x5C
+    , 0xA7, 0xDD, 0x1E, 0xF2, 0x4D, 0x1D, 0x93, 0xA2, 0x22, 0xDE, 0xE5, 0x05, 0x50, 0xA5, 0xE6, 0xCA
+    , 0xC0, 0xEC, 0x76, 0x7E, 0x13, 0x8B, 0xBA, 0x3D, 0x4C, 0xC9, 0xCE, 0x6D, 0x50, 0x0F, 0x86, 0x3D
+    , 0x83, 0x95, 0xFF, 0xA2, 0xA4, 0x31, 0xF5, 0x88, 0x38, 0x00, 0xB9, 0x27, 0xA3, 0x7B, 0xEF, 0x8A
+    , 0x5C, 0x79, 0xF1, 0x26, 0x42, 0x2C, 0x68, 0x27, 0x40, 0x02, 0x52, 0x97, 0xD6, 0x51, 0x4D, 0x3F
+    , 0xB5, 0x4C, 0x87, 0x80, 0x02, 0x94, 0xFD, 0x25, 0x6F, 0x28, 0x9E, 0x84, 0xA0, 0xDA, 0x6F, 0xA3
+    , 0x30, 0x9B, 0x68, 0xA3, 0x9E, 0x51, 0xBE, 0x1B, 0x49, 0x68, 0xBA, 0x09, 0x6E, 0xEF, 0xF9, 0x52
+    , 0x25, 0x15, 0x38, 0x2C, 0x07, 0xDB, 0x76, 0xC9, 0x7C, 0x2F, 0xC6, 0x60, 0x4F, 0xA2, 0xE3, 0xC4
+    , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+    , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+    , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+    , 0x0B, 0x7D, 0x19, 0x57, 0xB6, 0xF2, 0x8C, 0x9B, 0xCA, 0x0B, 0xDC, 0x56, 0x1C, 0x63, 0x8D, 0x1D
+    , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+    , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+    , 0x2F, 0x27, 0x25, 0x17, 0x1D, 0x25, 0x03, 0x43, 0x4B, 0x34, 0x42, 0x74, 0x45, 0x67, 0xCE, 0x68
+    , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+    , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+    , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+    , 0x3A, 0x95, 0xC8, 0x83, 0xF3, 0x0B, 0x46, 0x50, 0x95, 0xA5, 0x06, 0x15, 0xFB, 0x2B, 0x67, 0xE5
+    , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+    , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+    , 0xD3, 0xC1, 0x82, 0x91, 0x78, 0xA3, 0x12, 0x9F, 0xDD, 0xB1, 0xDE, 0x2E, 0xB5, 0x47, 0xD5, 0x51
+    , 0x01, 0xDD, 0x20, 0x23, 0x97, 0x00, 0xE9, 0x45, 0x75, 0x69, 0xE2, 0xD1, 0xD7, 0xC5, 0x43, 0x36
+    , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+    , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+    , 0xAC, 0xFB, 0x1F, 0x99, 0xF7, 0x6D, 0xAB, 0x37, 0x68, 0x2F, 0x95, 0x73, 0xE0, 0x84, 0x6E, 0x02
+    , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+    , 0xAD, 0x20, 0xFD, 0x61, 0x97, 0xF7, 0xBD, 0x96, 0xDD, 0xB9, 0x23, 0x12, 0xF9, 0xBE, 0x41, 0x58
+    , 0x55, 0x42, 0x8E, 0x49, 0x16, 0xEF, 0xCB, 0xF5, 0x8C, 0x4E, 0x1D, 0x7C, 0x3C, 0x12, 0xF8, 0xA4
+    , 0xA0, 0x08, 0xC3, 0x5F, 0x04, 0xF5, 0xAC, 0x42, 0x4F, 0x3D, 0x1D, 0x74, 0x80, 0x35, 0x6F, 0xFC
+    , 0x99, 0x53, 0x85, 0xC0, 0x07, 0x4F, 0xD3, 0xE5, 0xF9, 0x04, 0xCE, 0xE7, 0xF9, 0x76, 0x61, 0xE0
+    , 0x13, 0x6C, 0xC2, 0x84, 0x09, 0x87, 0x16, 0x13, 0x27, 0xFB, 0x15, 0x23, 0x47, 0x14, 0x82, 0x9D
+    , 0x98, 0xE3, 0x5A, 0x96, 0x9D, 0xBF, 0xB5, 0x8B, 0x58, 0x71, 0x32, 0xC2, 0xDF, 0x43, 0x79, 0x1B
+    , 0x25, 0x8B, 0x60, 0xBC, 0x49, 0x99, 0x03, 0x47, 0x37, 0xA1, 0x50, 0x44, 0x45, 0xF2, 0x2E, 0x33
+    , 0x7D, 0x7E, 0x71, 0x29, 0xDA, 0x73, 0x58, 0xF3, 0x8A, 0x9B, 0xD7, 0xF1, 0x95, 0x92, 0x24, 0xE0
+    , 0xE0, 0xA7, 0xC8, 0x5A, 0x78, 0x5C, 0xA0, 0x48, 0x8B, 0x97, 0xA0, 0x1A, 0xA1, 0xE9, 0xED, 0x5D
+    , 0x82, 0xED, 0x1B, 0x5A, 0xDA, 0x1A, 0x64, 0x0F, 0x47, 0x55, 0x21, 0x65, 0xE7, 0x80, 0x8A, 0x20
+    , 0x13, 0xA9, 0x1C, 0xE3, 0x64, 0xA4, 0xBA, 0x42, 0x06, 0x91, 0x0E, 0x57, 0x10, 0xF7, 0x04, 0x50
+    , 0x08, 0xBF, 0xEA, 0xAC, 0xDA, 0xA4, 0x1F, 0x3D, 0xFC, 0xBF, 0xD4, 0x48, 0xE5, 0x02, 0x5F, 0xFA
+    , 0x79, 0xD0, 0x2B, 0xAA, 0x45, 0xC4, 0x15, 0xB0, 0x4B, 0x2D, 0x81, 0xD0, 0xDA, 0x50, 0xDE, 0xB2
+    , 0x4F, 0xB2, 0xCB, 0x50, 0x37, 0x9E, 0xFA, 0x43, 0xEC, 0x8D, 0xE0, 0xDF, 0x5E, 0x96, 0x4E, 0xDE
+    , 0x45, 0x17, 0x77, 0xBE, 0x2C, 0x0E, 0xF1, 0x89, 0x92, 0x44, 0xDC, 0x3E, 0xC9, 0xBC, 0x9C, 0x8F
+    , 0x33, 0x36, 0xD6, 0x51, 0xE0, 0xB9, 0xE0, 0x2E, 0xB9, 0x06, 0xC6, 0xF1, 0xE5, 0xCD, 0x86, 0xDB
+    , 0x24, 0x2C, 0xFE, 0x98, 0x59, 0x63, 0x35, 0x73, 0x45, 0x54, 0xD4, 0x3C, 0x7B, 0x0E, 0x23, 0xFC
+    , 0x5D, 0x94, 0xC9, 0x02, 0xB4, 0xC6, 0xAB, 0x0C, 0xF7, 0xC7, 0x7E, 0x7D, 0x69, 0x95, 0x47, 0xF0
+    , 0x87, 0xD6, 0x7D, 0x7C, 0x2C, 0x18, 0x38, 0x0A, 0x61, 0x50, 0xD5, 0xA3, 0xEE, 0xEB, 0xBC, 0x14
+    , 0x38, 0xA0, 0x4B, 0xAE, 0xC3, 0x65, 0x24, 0x9B, 0x54, 0x23, 0x1F, 0xE1, 0xCB, 0xA9, 0xCE, 0xB5
+    , 0x8A, 0x42, 0x35, 0x7F, 0x1F, 0xED, 0xC1, 0x24, 0x9F, 0x7B, 0xB2, 0xB4, 0x8E, 0xA7, 0x44, 0x2B
+    , 0xCE, 0x92, 0x9C, 0x00, 0xA1, 0x16, 0x35, 0x00, 0x62, 0x29, 0xCF, 0xB7, 0x45, 0x27, 0x49, 0x60
+    , 0x9B, 0x61, 0x76, 0xE1, 0x2E, 0xBD, 0xE1, 0x7B, 0x12, 0x52, 0x10, 0xB9, 0xB6, 0xEB, 0x4B, 0xC1
+    , 0x35, 0x95, 0x08, 0x7B, 0xD6, 0xD3, 0x8E, 0xBF, 0xB5, 0xCF, 0xD5, 0x34, 0x62, 0xFE, 0x0C, 0x08
+    , 0xFA, 0x94, 0x18, 0x6E, 0x86, 0xB4, 0xA4, 0x2F, 0x97, 0xEB, 0xC4, 0xB3, 0x32, 0xEE, 0xEB, 0xB5
+    , 0x13, 0x86, 0xD3, 0x68, 0x8C, 0xDE, 0x8C, 0xD4, 0x8D, 0xE7, 0xEF, 0x79, 0x00, 0x7C, 0xAE, 0x36
+    , 0x79, 0xBF, 0x2E, 0x13, 0xF6, 0x58, 0x43, 0xB2, 0x3F, 0xD6, 0x2F, 0xCF, 0x51, 0x96, 0x19, 0x44
+    , 0x29, 0xF8, 0x9A, 0xEE, 0x17, 0xFD, 0xCE, 0x42, 0xD4, 0x5C, 0x8B, 0xA4, 0x2B, 0x17, 0x5E, 0x51
+    , 0xEE, 0x05, 0xC7, 0x54, 0xC9, 0xCE, 0x6E, 0x9D, 0x95, 0x8C, 0x96, 0x11, 0x9A, 0x29, 0x46, 0x21
+    , 0x85, 0x96, 0xF8, 0xBA, 0xEC, 0x6F, 0x63, 0x00, 0x3D, 0x92, 0xD9, 0x92, 0xD3, 0x38, 0xDF, 0x95
+    , 0x25, 0xBE, 0xAC, 0x59, 0x17, 0x0A, 0x9B, 0x0A, 0x5D, 0xDC, 0x4B, 0x8C, 0xF8, 0x67, 0x21, 0x5F
+    , 0xD2, 0x20, 0xF7, 0xCF, 0x50, 0x84, 0x29, 0x51, 0xE3, 0xCD, 0xFF, 0x85, 0x40, 0x5C, 0x38, 0x93
+    , 0x39, 0x6A, 0x44, 0x72, 0x32, 0x1C, 0xF9, 0xEC, 0xBB, 0x4E, 0x26, 0xF2, 0x05, 0x48, 0x79, 0x8C
+    , 0x2E, 0xAA, 0x72, 0x6B, 0xCB, 0x24, 0x9E, 0x09, 0x27, 0x43, 0xE7, 0xEA, 0x1E, 0x3A, 0xB9, 0xBE
+    , 0xA6, 0x3A, 0xBD, 0x3B, 0xD7, 0x16, 0x8A, 0x00, 0x8D, 0xF5, 0x6D, 0x91, 0x7D, 0x68, 0x91, 0x32
+    , 0x88, 0xE5, 0x82, 0xAE, 0x24, 0xAC, 0x38, 0x07, 0x9F, 0x3F, 0x47, 0x93, 0xB2, 0x41, 0x1D, 0xBF
+    , 0xD7, 0xFC, 0xF0, 0x12, 0x3F, 0xA1, 0xB5, 0xF1, 0xB4, 0x7B, 0x58, 0x94, 0x2A, 0x2F, 0xAE, 0xC2
+    , 0x4D, 0xF3, 0xA6, 0x5A, 0x4D, 0xB9, 0x3F, 0x0E, 0xA1, 0x67, 0xE9, 0xAF, 0x03, 0xA5, 0xF3, 0x7F
+    , 0x45, 0x85, 0x64, 0x3C, 0xE3, 0x2E, 0xA3, 0x31, 0x03, 0xD4, 0x3A, 0xF0, 0xB5, 0x94, 0xF9, 0x46
+    , 0xCE, 0xA4, 0x72, 0xDC, 0x65, 0xD1, 0x59, 0xBE, 0x0B, 0xAD, 0xE5, 0x5D, 0xBA, 0x55, 0xE0, 0xC1
+    , 0x82, 0x6E, 0x4A, 0x14, 0xC9, 0x55, 0xC6, 0xC0, 0x22, 0xF6, 0x57, 0x80, 0xF0, 0x02, 0xD9, 0xBD
+    , 0x4C, 0x9D, 0x3C, 0xDC, 0xC7, 0x5F, 0xCA, 0xF0, 0x3E, 0xDA, 0xFF, 0xFE, 0x69, 0xAF, 0xDA, 0x38
+    , 0x20, 0x0B, 0x14, 0x4F, 0xBB, 0x9B, 0xD0, 0xA4, 0x01, 0x63, 0x1F, 0x61, 0x24, 0x7F, 0x87, 0xB6
+    , 0x47, 0xEA, 0x7E, 0xEA, 0x74, 0xA4, 0x00, 0xDC, 0x49, 0xE3, 0x3A, 0x3C, 0xEF, 0x67, 0xF6, 0xB7
+    , 0x21, 0x09, 0x25, 0x96, 0x6F, 0xE8, 0x76, 0xEF, 0xF2, 0x6C, 0x6E, 0xF5, 0xCF, 0x06, 0x37, 0x24
+    , 0x00, 0xF2, 0xA7, 0x27, 0x4B, 0xE3, 0xC3, 0x9C, 0x9E, 0x93, 0xB5, 0xA4, 0x11, 0x65, 0x06, 0x4C
+    , 0x03, 0x97, 0x1D, 0x88, 0x3B, 0x14, 0x72, 0x5B, 0x52, 0xA5, 0xB8, 0x03, 0x68, 0xE5, 0xF1, 0x98
+    , 0x06, 0x48, 0xF7, 0x3E, 0x33, 0x29, 0xE3, 0x04, 0xEB, 0xD7, 0xCD, 0x69, 0xD9, 0x8E, 0x84, 0x15
+    , 0xBE, 0x21, 0xFC, 0x31, 0x99, 0x41, 0x58, 0x3C, 0x72, 0x6F, 0x73, 0x11, 0x43, 0x78, 0x5A, 0xF8
+    , 0x71, 0xDC, 0x02, 0x10, 0x59, 0xC8, 0xB9, 0x03, 0xB8, 0x25, 0x60, 0xDF, 0x22, 0x45, 0x4F, 0xF0
+    , 0x7E, 0x50, 0xDE, 0x54, 0x1F, 0x58, 0x8A, 0x5C, 0x93, 0xA9, 0x12, 0x2C, 0x95, 0x4C, 0x80, 0x5B
+    , 0x32, 0x8A, 0x78, 0x2C, 0x9D, 0x58, 0x2C, 0xB9, 0x40, 0xCB, 0x64, 0xFB, 0x59, 0x1E, 0xE8, 0xBD
+    , 0xBF, 0x64, 0x3F, 0x58, 0x76, 0xAE, 0xC2, 0xDF, 0x9A, 0x57, 0x69, 0xBB, 0x6C, 0xA0, 0x54, 0x0B
+    , 0xCA, 0xCA, 0x6A, 0xB6, 0xA3, 0x79, 0x54, 0x48, 0x71, 0x67, 0x40, 0x3B, 0x8E, 0x59, 0x94, 0xFB
+    , 0x31, 0xA6, 0xEE, 0xAF, 0x53, 0xC9, 0x24, 0xD6, 0x77, 0x4C, 0xE5, 0x34, 0xAD, 0x93, 0xD5, 0xCA
+    , 0x24, 0x61, 0x09, 0x66, 0x42, 0x65, 0x27, 0x7B, 0x1D, 0x3C, 0x35, 0x06, 0xB9, 0xA9, 0x13, 0xE0
+    , 0x9C, 0x08, 0xEC, 0x53, 0xB7, 0xAC, 0x71, 0x89, 0x2D, 0xEE, 0x34, 0xAE, 0x3E, 0x1D, 0x47, 0xDE
+    , 0x42, 0x17, 0xBA, 0xB8, 0x83, 0x96, 0xE5, 0x91, 0x39, 0x7D, 0xBA, 0x6E, 0x51, 0x6A, 0x48, 0xC3
+    , 0x4A, 0x9B, 0x12, 0x48, 0xA4, 0x5D, 0xD4, 0x29, 0xCA, 0x42, 0xC3, 0x75, 0xFE, 0xD9, 0xA1, 0x95
+    , 0xD6, 0xE3, 0xB9, 0x24, 0xC2, 0xD5, 0x5F, 0xF7, 0xBF, 0xB8, 0x93, 0x68, 0xCA, 0xCD, 0xF3, 0x4D
+    , 0xBA, 0x07, 0x63, 0xA6, 0x9D, 0xB1, 0x4D, 0x10, 0xF9, 0x61, 0xFB, 0x8C, 0x10, 0x27, 0x93, 0xEA
+    , 0x4A, 0x8A, 0x61, 0x87, 0x6E, 0x16, 0x46, 0xD3, 0x14, 0xD3, 0x39, 0x9E, 0x0B, 0xB4, 0xE4, 0x10
+    , 0xDE, 0x07, 0xE4, 0x69, 0x4F, 0xC2, 0x20, 0x09, 0x2B, 0x68, 0x4F, 0x9E, 0xF6, 0xD8, 0xCA, 0x9E
+    , 0x8A, 0xBD, 0x1B, 0x4B, 0xC1, 0x3C, 0x0B, 0x4D, 0xB9, 0x3A, 0x48, 0x03, 0xBA, 0xB3, 0xD4, 0xDF
+    , 0x7A, 0x93, 0x5D, 0x4D, 0x8A, 0xE7, 0x42, 0xF6, 0x73, 0x45, 0x1F, 0x36, 0xB6, 0xE0, 0xCB, 0xF6
+    , 0x22, 0xE5, 0x5B, 0x64, 0x8B, 0x51, 0xB1, 0x55, 0xC6, 0x2A, 0xD0, 0xB6, 0xAB, 0x48, 0xDA, 0x66
+    , 0xDF, 0xFD, 0xAF, 0x76, 0x47, 0x49, 0x03, 0x69, 0xB8, 0xF6, 0x05, 0x08, 0x40, 0x00, 0xFB, 0xF5
+    , 0xB7, 0x65, 0x15, 0xD1, 0xCB, 0xD0, 0x0E, 0xFB, 0x9A, 0x38, 0xAF, 0x76, 0x23, 0x2D, 0x51, 0x3A
+    , 0xFF, 0x5E, 0x56, 0xB9, 0x25, 0xD1, 0xCB, 0x94, 0xD0, 0x05, 0x92, 0x1D, 0xED, 0xCB, 0x70, 0xA6
+    , 0x6B, 0x0F, 0x41, 0x41, 0x8B, 0x3F, 0x3E, 0xA7, 0x5B, 0x73, 0xD1, 0xE8, 0x62, 0x56, 0x73, 0x64
+    , 0xB4, 0x4D, 0xF8, 0x99, 0x79, 0x39, 0xC1, 0xCD, 0xA0, 0xCA, 0x06, 0xF3, 0xF4, 0xCD, 0x66, 0x56
+    , 0x75, 0xE8, 0x21, 0xF6, 0x9A, 0xE3, 0xB1, 0x2B, 0x5B, 0x0F, 0x9F, 0xDE, 0x7A, 0xA5, 0xD1, 0x3C
+    , 0xE1, 0x11, 0x41, 0x8C, 0xCB, 0x9D, 0x25, 0x09, 0x4F, 0x2E, 0x83, 0x62, 0x9E, 0xCD, 0x77, 0x79
+    , 0x82, 0x4C, 0xB0, 0xEA, 0x02, 0xE3, 0x66, 0x9D, 0x10, 0x13, 0x75, 0x8E, 0xEF, 0x82, 0x6F, 0xDA
+    , 0xB4, 0xD6, 0x37, 0xD7, 0x6A, 0x26, 0x72, 0x62, 0x8F, 0x2D, 0xBD, 0xED, 0x23, 0xFE, 0xC4, 0xCE
+    , 0x5E, 0x1E, 0x5B, 0xDF, 0xF1, 0xFD, 0x50, 0x71, 0xD9, 0xAF, 0xE9, 0xCB, 0x07, 0xAA, 0x7C, 0xC6
+    , 0x34, 0x1A, 0x8A, 0x85, 0x25, 0x16, 0x1D, 0x55, 0x96, 0x5C, 0x8B, 0xA0, 0x6B, 0x54, 0xC5, 0x98
+    , 0x80, 0x98, 0x4D, 0x45, 0x6A, 0x96, 0x3C, 0x1A, 0x1C, 0x8D, 0x8B, 0xB8, 0x6D, 0x91, 0x6B, 0x30
+    , 0xEF, 0x11, 0x6D, 0x25, 0x84, 0x82, 0x9C, 0xD7, 0x6A, 0x18, 0x89, 0xCA, 0x88, 0xEA, 0x6F, 0x56
+    , 0xBE, 0x82, 0x03, 0xC0, 0xA3, 0xBB, 0x22, 0xAA, 0x9E, 0x99, 0x7D, 0x9D, 0x1C, 0x06, 0x8E, 0x0C
+    , 0x14, 0x0A, 0xC9, 0x18, 0x2D, 0x18, 0x8A, 0x3B, 0xC3, 0x88, 0x07, 0x19, 0x54, 0xD3, 0x2D, 0xC2
+    , 0x64, 0x2B, 0x97, 0xB5, 0xED, 0x71, 0x19, 0xAA, 0xED, 0x34, 0xEC, 0xF9, 0xEE, 0x89, 0x33, 0x19
+    , 0x2C, 0x33, 0x9D, 0xA7, 0x85, 0x98, 0x94, 0x3B, 0xE1, 0x5C, 0x5E, 0x53, 0x7F, 0x4A, 0x6B, 0xC4
+    , 0x48, 0xF4, 0xBC, 0x44, 0x93, 0x78, 0xC8, 0xC0, 0xE3, 0xD9, 0x48, 0x59, 0xDE, 0xB5, 0xE8, 0x8F
+    , 0xB1, 0x61, 0x4B, 0x67, 0xE6, 0x99, 0x47, 0x3E, 0x9A, 0xB7, 0x4D, 0x5C, 0x46, 0x0B, 0x4D, 0x5E
+    , 0xDF, 0xE8, 0xB9, 0x2B, 0xC9, 0xF8, 0xD3, 0x87, 0x4F, 0xA2, 0x3D, 0x2E, 0x2A, 0x22, 0x2B, 0x4B
+    , 0x23, 0x55, 0x7F, 0x0D, 0x0C, 0x20, 0xF4, 0x43, 0xCB, 0xF2, 0x31, 0x18, 0xD8, 0xC3, 0x0F, 0x0D
+    , 0xF5, 0xEB, 0x70, 0xCD, 0xB0, 0xD0, 0xBA, 0x2A, 0x37, 0xFD, 0x24, 0x5A, 0xF6, 0x69, 0x1A, 0x38
+    , 0x22, 0x49, 0xBC, 0xCE, 0x00, 0xCB, 0x6A, 0x2F, 0x6E, 0x98, 0x20, 0xDB, 0xE5, 0x8C, 0x0A, 0x0B
+    , 0x5E, 0x99, 0x8D, 0xAB, 0x9B, 0xD3, 0x4B, 0x12, 0xBE, 0x35, 0x75, 0x95, 0xE7, 0xA4, 0xAA, 0xC5
+    , 0x79, 0xB7, 0x9A, 0xB8, 0x3B, 0x86, 0x29, 0x15, 0xE5, 0x40, 0xE4, 0xC2, 0x85, 0xC2, 0x1B, 0xB5
+    , 0x06, 0xAF, 0x05, 0x49, 0xAD, 0x8B, 0xCE, 0xAD, 0xCD, 0x91, 0xE5, 0xA8, 0x0F, 0x97, 0x7F, 0x1C
+    , 0x42, 0x73, 0xAB, 0x1E, 0x5A, 0xEC, 0xA1, 0x31, 0x06, 0x6C, 0x80, 0x06, 0xE8, 0x03, 0x73, 0x4B
+    , 0x45, 0x48, 0x46, 0x09, 0xE0, 0x7D, 0x6F, 0xD9, 0xCD, 0x66, 0xF6, 0x0F, 0xEC, 0x01, 0xE7, 0x84
+    , 0xD9, 0xF0, 0x86, 0xF0, 0x5A, 0xE9, 0x10, 0xE4, 0xDC, 0x49, 0x03, 0xF4, 0x6C, 0x3B, 0xE4, 0xC3
+    , 0x3B, 0xAE, 0x39, 0x77, 0xB1, 0x3E, 0x9F, 0x03, 0x4A, 0x09, 0xDA, 0xD8, 0xE0, 0x60, 0x2D, 0x3C
+    , 0x77, 0x98, 0xC6, 0x36, 0xFB, 0x63, 0xD6, 0x4B, 0x99, 0xDB, 0x1F, 0x5B, 0xD2, 0x75, 0x21, 0xA2
+    , 0x8E, 0xDD, 0x8F, 0x25, 0x38, 0x1E, 0xDE, 0xBA, 0x89, 0xB9, 0x58, 0x77, 0x7F, 0x6E, 0x7C, 0xA4
+    , 0xD9, 0xA1, 0x4E, 0xF2, 0x9F, 0x77, 0x84, 0x09, 0x19, 0xEE, 0xBA, 0xB1, 0x73, 0x66, 0x35, 0xBD
+    , 0x4B, 0x2A, 0x0F, 0x21, 0x08, 0x5B, 0xF2, 0xBA, 0x7C, 0xC3, 0xE6, 0xAF, 0xF0, 0x44, 0xDF, 0x10
+    , 0x0D, 0x60, 0x16, 0x2F, 0xE6, 0x8D, 0x9D, 0x15, 0xB6, 0x05, 0x6C, 0x63, 0x6B, 0xBE, 0x9D, 0x5E
+    , 0x7F, 0xBC, 0xFF, 0x38, 0xE4, 0x9E, 0xBA, 0x7A, 0xDB, 0x36, 0x87, 0x0C, 0x7D, 0x69, 0x45, 0xD6
+    , 0xFA, 0x1B, 0xA0, 0x8D, 0xFD, 0xC4, 0xC8, 0xD6, 0x01, 0xE6, 0xB3, 0x87, 0xAC, 0xD3, 0xE5, 0xDC
+    , 0x88, 0x43, 0x81, 0x89, 0x04, 0x2B, 0x43, 0x54, 0x77, 0x5D, 0x7E, 0x27, 0xF2, 0x3E, 0x02, 0xA4
+    , 0xAC, 0x9B, 0x0F, 0xCB, 0x54, 0xD7, 0xA9, 0xE4, 0x2E, 0x08, 0x9A, 0x69, 0x28, 0x89, 0x4B, 0xF4
+    , 0x19, 0x97, 0x5A, 0xB3, 0x56, 0xCD, 0xB7, 0x2C, 0x4A, 0xD5, 0xA1, 0x52, 0xF3, 0x7A, 0xB0, 0x71
+    , 0x3A, 0xA2, 0x09, 0x01, 0x80, 0x54, 0x58, 0x61, 0x4C, 0xE5, 0x0F, 0x08, 0x1E, 0x47, 0xB6, 0x43
+    , 0xC0, 0x88, 0x4A, 0xBD, 0xAB, 0x65, 0xCB, 0x32, 0x5C, 0xAA, 0x69, 0x9A, 0x42, 0x8E, 0x46, 0xB9
+    , 0x64, 0x5C, 0x9A, 0x1F, 0xF8, 0xD6, 0x47, 0xC5, 0x49, 0x17, 0x17, 0x95, 0xAE, 0x8F, 0x9C, 0xC3
+    , 0xC6, 0x9F, 0xAE, 0x3F, 0x72, 0x13, 0x72, 0xED, 0xD9, 0x35, 0x20, 0x6E, 0xAA, 0x8E, 0xAA, 0x58
+    , 0x0A, 0xB2, 0x5C, 0x97, 0xA5, 0x44, 0xF9, 0x73, 0x43, 0x59, 0x8E, 0xD6, 0x05, 0x8A, 0x13, 0x79
+    , 0xBC, 0xAA, 0x37, 0x60, 0x7B, 0xFA, 0xA1, 0x36, 0x14, 0x5D, 0xC9, 0xB3, 0x88, 0x92, 0x80, 0x59
+    , 0xD7, 0x19, 0x6C, 0xC4, 0x4B, 0x4F, 0xC2, 0x6E, 0x1D, 0x8D, 0x8B, 0x04, 0x28, 0x28, 0x85, 0x15
+    , 0x86, 0xEB, 0xD5, 0x3E, 0x39, 0x48, 0xDE, 0xF7, 0x1D, 0x59, 0xF9, 0x06, 0x77, 0xFD, 0x57, 0x5D
+    , 0x66, 0x26, 0x10, 0x6D, 0x6B, 0xF7, 0xD5, 0x47, 0xBD, 0xCA, 0xF4, 0x3E, 0xBF, 0x01, 0x49, 0xBC
+    , 0xE7, 0xF1, 0x24, 0xAE, 0x00, 0x55, 0x9B, 0xF1, 0x49, 0xAB, 0x4C, 0x50, 0x25, 0x11, 0x0E, 0x56
+    , 0x51, 0x22, 0xD4, 0x52, 0xE2, 0x9E, 0x7F, 0x08, 0xB0, 0xD0, 0x33, 0xC1, 0x22, 0xD1, 0x54, 0xCA
+    , 0x90, 0x7A, 0x22, 0x66, 0x8C, 0x28, 0xAF, 0x2D, 0x47, 0x7B, 0x8A, 0x11, 0xC5, 0x5D, 0x96, 0x66
+    , 0x3A, 0x7B, 0x4B, 0x67, 0xA8, 0x30, 0x09, 0x5A, 0x06, 0xE0, 0xA8, 0xB3, 0xDB, 0x02, 0x21, 0x46
+    , 0xCF, 0x60, 0x27, 0x19, 0x76, 0x58, 0x35, 0xBB, 0x8E, 0x0C, 0x09, 0x63, 0xD4, 0x40, 0x49, 0xF9
+    , 0xC6, 0xA0, 0xA1, 0xFF, 0xAE, 0x36, 0xC8, 0x71, 0x7E, 0x82, 0xF9, 0xDC, 0x52, 0x10, 0x26, 0xF3
+    , 0xF7, 0x1C, 0x66, 0xAC, 0x21, 0x2C, 0x5F, 0x9E, 0x69, 0xAF, 0xEA, 0x90, 0x34, 0x44, 0x01, 0x42
+    , 0xBB, 0x7B, 0x57, 0x53, 0x2D, 0x26, 0x58, 0x60, 0x0A, 0x9E, 0xF5, 0x30, 0xF9, 0x8D, 0x08, 0x86
+    , 0x32, 0x43, 0x4D, 0x85, 0xE0, 0x07, 0x54, 0x78, 0x49, 0x00, 0x40, 0x2B, 0x60, 0x18, 0x3A, 0x2A
+    , 0xD6, 0xBE, 0x1B, 0x9E, 0x8F, 0x01, 0x92, 0x43, 0x1A, 0x1D, 0xDB, 0xB0, 0x06, 0xC4, 0x8A, 0x06
+    , 0x49, 0x10, 0x9F, 0x85, 0x42, 0x12, 0x41, 0xE8, 0xDA, 0xF5, 0x73, 0x47, 0x58, 0xCF, 0x6D, 0x14
+    , 0x0C, 0x1E, 0x9A, 0x20, 0x8B, 0x81, 0x36, 0xFD, 0x0D, 0xAC, 0x6A, 0x00, 0xAD, 0x52, 0xB7, 0x7A
+    , 0x91, 0x64, 0x78, 0xD7, 0xDB, 0x7F, 0x9B, 0x31, 0xE1, 0xCB, 0x22, 0xD1, 0xD3, 0x41, 0xF5, 0xCE
+    , 0x06, 0xCD, 0x13, 0x1E, 0x52, 0x39, 0x3B, 0xFD, 0x9F, 0x16, 0x1F, 0x7D, 0x60, 0x21, 0x28, 0x29
+    , 0x10, 0x62, 0xB0, 0xE5, 0x9F, 0x43, 0x76, 0x92, 0x38, 0x5C, 0xE9, 0x31, 0x62, 0xD2, 0x24, 0x52
+    , 0x70, 0xD4, 0xBA, 0x05, 0x6F, 0x17, 0x7A, 0x43, 0x09, 0xD9, 0x57, 0x67, 0x3C, 0x8F, 0x88, 0xE8
+    , 0x22, 0x23, 0xAD, 0x68, 0x61, 0xCC, 0x8C, 0xF3, 0x94, 0x6F, 0x1C, 0x40, 0x38, 0xA9, 0x5A, 0xA5
+    , 0xD5, 0x79, 0x2C, 0xDB, 0x21, 0x32, 0x5F, 0x11, 0xC4, 0x8F, 0xC2, 0x70, 0x41, 0x93, 0xF4, 0x91
+    , 0xF8, 0xF5, 0xC5, 0x92, 0x05, 0xAA, 0xF7, 0x82, 0xB9, 0xD9, 0x7C, 0x5F, 0xE9, 0x62, 0xAB, 0x52
+    , 0xDD, 0x98, 0xF1, 0xAE, 0x0B, 0x1C, 0x8F, 0x81, 0x22, 0xDF, 0x69, 0xBA, 0xFA, 0x51, 0xB5, 0xFC
+    , 0x46, 0x1C, 0xCC, 0xA2, 0xDD, 0xD9, 0x12, 0xC5, 0xCC, 0xB6, 0xC7, 0x03, 0x57, 0x57, 0xEE, 0x5D
+    , 0x66, 0x4A, 0xB6, 0x7B, 0x07, 0x9E, 0x2A, 0x1F, 0x06, 0x00, 0x9E, 0xC5, 0x9C, 0xC2, 0x70, 0x24
+    , 0xE0, 0x8C, 0xF7, 0x13, 0x69, 0x93, 0x91, 0x39, 0x69, 0xFC, 0x47, 0xD6, 0xA0, 0xCE, 0xAA, 0xA6
+    , 0xC9, 0x04, 0xDF, 0xA9, 0x60, 0x5A, 0x96, 0xA1, 0x2C, 0xC6, 0x2A, 0xA7, 0xE5, 0x65, 0x4D, 0xA9
+    , 0x76, 0x0C, 0x6B, 0xBB, 0xAE, 0xB9, 0x58, 0x4F, 0x48, 0xE6, 0xD5, 0xDB, 0x04, 0x02, 0x2C, 0x50
+    , 0xF6, 0xE3, 0x95, 0xCC, 0xDB, 0x4D, 0x67, 0xCB, 0xED, 0x1D, 0xEC, 0x81, 0x68, 0x69, 0x2E, 0xCD
+    , 0x9A, 0x1F, 0xF6, 0x72, 0x53, 0x86, 0xBE, 0x73, 0x5F, 0xBE, 0x0E, 0x8E, 0x51, 0x06, 0xD4, 0xA5
+    , 0x27, 0x3E, 0xEE, 0x6B, 0x3B, 0x07, 0xE6, 0xF2, 0x29, 0xA2, 0x83, 0x28, 0xA9, 0x81, 0x0C, 0xE5
+    , 0x5F, 0xB6, 0x18, 0x35, 0x70, 0x45, 0x82, 0xC2, 0xEC, 0x65, 0x88, 0xD7, 0x05, 0xEE, 0x30, 0xA8
+    , 0x3D, 0x3D, 0xAB, 0x3E, 0x7A, 0x3A, 0x1B, 0x5A, 0xC4, 0xD1, 0xF8, 0x3B, 0xB8, 0x8F, 0xB2, 0x20
+    , 0xF9, 0xB4, 0x0F, 0xED, 0xB4, 0x83, 0x62, 0x85, 0x33, 0xBF, 0xE6, 0x21, 0xE3, 0x32, 0x1B, 0x24
+    , 0xD8, 0x48, 0x62, 0x1B, 0x9C, 0xDD, 0x77, 0xFC, 0x6B, 0x4C, 0x76, 0x2A, 0x74, 0xB8, 0x9C, 0x57
+    , 0x72, 0x64, 0x47, 0xF5, 0x14, 0x45, 0xC1, 0x62, 0xD5, 0x21, 0xC4, 0x91, 0x85, 0xCC, 0x61, 0xE4
+    , 0x69, 0x92, 0x7D, 0x20, 0x9A, 0x60, 0x76, 0xEC, 0x07, 0x58, 0xD6, 0xB9, 0x0A, 0xCF, 0x64, 0x33
+    , 0x28, 0x99, 0x93, 0xDE, 0x5A, 0x94, 0x6B, 0x25, 0x82, 0x77, 0x04, 0x4F, 0xFD, 0x02, 0x87, 0xD1
+    , 0x41, 0x60, 0x3B, 0xDA, 0xF6, 0x30, 0x65, 0xE9, 0x53, 0xA8, 0xB8, 0xBB, 0xBE, 0x54, 0x97, 0x74
+    , 0x15, 0x3D, 0xAD, 0x21, 0x01, 0xA0, 0xC5, 0x1C, 0x05, 0x6B, 0x55, 0x35, 0x81, 0x25, 0xFA, 0x81
+    , 0x64, 0x94, 0xBD, 0xA5, 0xE9, 0x0F, 0xFC, 0xF2, 0x40, 0xA9, 0x20, 0xE1, 0x2C, 0xCC, 0x7A, 0xC7
+    , 0xA4, 0x18, 0x6E, 0xCD, 0xDE, 0xFD, 0x17, 0xEE, 0xF9, 0x39, 0x10, 0x04, 0x9D, 0xDF, 0xBB, 0x72
+    , 0x37, 0x5D, 0xBC, 0xF8, 0xE3, 0x59, 0x73, 0x40, 0x00, 0xC2, 0x28, 0x96, 0x41, 0x10, 0x34, 0x4D
+    , 0x9C, 0x2C, 0x75, 0x5A, 0xF8, 0x24, 0x8E, 0x75, 0x0B, 0xD3, 0x72, 0x88, 0x91, 0x70, 0x7A, 0xCA
+    , 0x74, 0x0F, 0x7F, 0xAD, 0x38, 0xE7, 0x27, 0xB9, 0x42, 0xA3, 0xA4, 0xDA, 0x7A, 0xFA, 0xE9, 0x15
+    , 0xC6, 0xA2, 0x6E, 0xFE, 0x8F, 0xD6, 0x99, 0xBC, 0x29, 0x77, 0xC5, 0x16, 0x25, 0x00, 0x2A, 0x94
+    , 0xB1, 0x6C, 0x3B, 0x59, 0xEC, 0xE9, 0x14, 0x0D, 0xD3, 0xFA, 0x50, 0xF8, 0x7C, 0x2C, 0x43, 0xA1
+    , 0x9D, 0x16, 0xCF, 0x00, 0x7E, 0xD4, 0x6E, 0xB4, 0x8E, 0xEA, 0x88, 0x37, 0x13, 0xC5, 0x84, 0xD9
+    , 0x5D, 0x77, 0xC8, 0x3C, 0x2B, 0x43, 0x04, 0x83, 0x61, 0xE8, 0x8A, 0x76, 0xAC, 0x68, 0xC4, 0xF8
+    , 0x7B, 0xB5, 0xF8, 0x02, 0x2A, 0x8A, 0xD7, 0xD2, 0x60, 0x22, 0x64, 0x5A, 0xDC, 0x0B, 0xA7, 0x49
+    , 0x18, 0x8F, 0xF5, 0x7C, 0xF5, 0x82, 0x3B, 0x6C, 0xC7, 0x2D, 0xD1, 0x4D, 0x48, 0x1B, 0x22, 0x88
+    , 0x31, 0x8A, 0x42, 0x66, 0x25, 0x67, 0x9A, 0xAF, 0xAE, 0x9C, 0x61, 0x10, 0x29, 0x9B, 0xE6, 0xB9
+    , 0xBD, 0xED, 0xD3, 0x80, 0x92, 0x2C, 0xAF, 0x19, 0x59, 0xDF, 0x54, 0x30, 0x87, 0x1A, 0x83, 0x73
+    , 0xEF, 0x86, 0x1D, 0xAC, 0xAB, 0x5A, 0x46, 0x66, 0x8B, 0xF9, 0x55, 0x79, 0xA7, 0x1F, 0x9E, 0x03
+    , 0x93, 0xF1, 0x55, 0xD0, 0x90, 0x7F, 0x46, 0x2A, 0x26, 0xD7, 0x72, 0xFF, 0x1C, 0x76, 0x45, 0x67
+    , 0x96, 0xAB, 0x75, 0xED, 0x83, 0x63, 0x17, 0x27, 0xA3, 0xB4, 0x01, 0x98, 0xE0, 0x70, 0x07, 0x4E
+    , 0xC2, 0x16, 0x0B, 0x20, 0x5B, 0xAD, 0x42, 0x31, 0xA2, 0x8A, 0x04, 0x58, 0xD5, 0x75, 0xF2, 0x2C
+    , 0x51, 0x87, 0xF3, 0xA3, 0x81, 0xD9, 0x06, 0x91, 0x7E, 0xE5, 0x13, 0x71, 0xAD, 0x61, 0x6D, 0x29
+    , 0xCB, 0xA5, 0x8A, 0x64, 0x3E, 0x92, 0xB0, 0x8C, 0x03, 0xCA, 0x2A, 0xDE, 0x36, 0x76, 0x2C, 0xB7
+    , 0x44, 0xCB, 0x8B, 0xFF, 0xCF, 0x23, 0xF3, 0xD9, 0x4F, 0xE2, 0x94, 0x2A, 0xE5, 0x69, 0x97, 0xD7
+    , 0xF2, 0xAC, 0x2D, 0x3B, 0x4C, 0xD6, 0x97, 0x72, 0xF7, 0x64, 0x13, 0x69, 0x47, 0x98, 0xE1, 0xCF
+    , 0x7A, 0xAB, 0xDF, 0x45, 0xBC, 0x0C, 0x1F, 0x56, 0x07, 0xA9, 0xD0, 0x5E, 0xF2, 0xC7, 0xDB, 0x9D
+    , 0x96, 0x16, 0x89, 0x24, 0x7D, 0xD1, 0x0A, 0x4F, 0x9D, 0x52, 0xFD, 0x87, 0x2B, 0xD9, 0x19, 0x74
+    , 0x05, 0x33, 0x53, 0xCB, 0x6F, 0x89, 0x6D, 0x41, 0x19, 0x4D, 0x24, 0xEF, 0x0A, 0xB4, 0x72, 0x6E
+    , 0xE3, 0x66, 0xE2, 0x15, 0x15, 0xDF, 0x02, 0x48, 0xCA, 0x1A, 0x0A, 0xCD, 0x1A, 0xE2, 0x3A, 0x94
+    , 0x86, 0x62, 0xBC, 0x15, 0xC1, 0xD5, 0x29, 0xC8, 0x05, 0xA5, 0x81, 0x35, 0xFA, 0x07, 0x10, 0x7B
+    , 0x13, 0xBA, 0x88, 0xD0, 0xF6, 0xDD, 0xC9, 0x0F, 0xFC, 0x0D, 0xA8, 0xB4, 0x1F, 0x45, 0x4B, 0x42
+    , 0xE8, 0x0D, 0x33, 0x3D, 0x83, 0x7E, 0x1E, 0x80, 0x3D, 0x68, 0xF9, 0xB3, 0x09, 0x08, 0x14, 0x0D
+    , 0x49, 0xBA, 0xC3, 0xEF, 0xA5, 0x8A, 0x0B, 0xF2, 0xB7, 0x4F, 0xFD, 0xB6, 0xDB, 0xB6, 0xE7, 0xC6
+    , 0xB8, 0xF1, 0x00, 0x83, 0x8A, 0xF5, 0x06, 0xB8, 0x29, 0x51, 0xAF, 0x23, 0x43, 0xA7, 0xD9, 0x71
+    , 0x13, 0x94, 0x2D, 0x90, 0xF0, 0xD4, 0xDC, 0x27, 0x89, 0xF6, 0xB0, 0x61, 0x5D, 0x0B, 0x84, 0xF8
+    , 0x53, 0x28, 0x67, 0x52, 0x3E, 0x00, 0xBB, 0x8F, 0x03, 0x8D, 0x48, 0x0F, 0xFD, 0x15, 0xEA, 0x70
+    , 0x69, 0x8A, 0xA2, 0x6B, 0xC8, 0xA3, 0xD5, 0x3A, 0xF7, 0x78, 0x60, 0x88, 0x96, 0x46, 0x1B, 0xAA
+    , 0x83, 0x92, 0x8E, 0xE6, 0xA0, 0x66, 0x83, 0x1B, 0xD5, 0x1C, 0xD4, 0xE9, 0x25, 0xA0, 0xF4, 0xE1
+    , 0x5C, 0x22, 0x7E, 0xDF, 0xFC, 0xB0, 0x9A, 0xBC, 0x25, 0x42, 0x31, 0xCE, 0xDC, 0xB7, 0xDD, 0x90
+    , 0xFE, 0x30, 0x75, 0x02, 0xBF, 0xA0, 0x24, 0x3F, 0xFB, 0xF0, 0xDA, 0x95, 0x7C, 0xCF, 0x9E, 0x0B
+    , 0xEA, 0x56, 0xD3, 0x55, 0xF8, 0x0D, 0x82, 0xCE, 0x73, 0x29, 0x0C, 0x36, 0xBF, 0xD0, 0x72, 0x0B
+    , 0x44, 0x00, 0x6C, 0x05, 0xA9, 0x31, 0xE7, 0x0C, 0xF0, 0x2E, 0x8F, 0x93, 0xAB, 0x5B, 0xCE, 0x13
+    , 0xAC, 0x4F, 0xBD, 0x14, 0x5D, 0x8B, 0x05, 0x78, 0x7E, 0x22, 0xF5, 0x22, 0xE2, 0xA8, 0x1E, 0x97
+    , 0x3D, 0xFB, 0x52, 0xB8, 0x76, 0x78, 0x8D, 0xA1, 0xFB, 0x48, 0x2D, 0xED, 0x5E, 0x08, 0xBA, 0xB7
+    , 0x83, 0x94, 0xF6, 0xC4, 0x18, 0x07, 0xD3, 0x57, 0xC8, 0xBB, 0x45, 0x28, 0xDC, 0xB4, 0x2F, 0xF8
+    , 0xC8, 0x7D, 0x48, 0xC3, 0xA0, 0x11, 0x60, 0x2F, 0x34, 0x06, 0xB0, 0xFA, 0xBC, 0xCA, 0x2C, 0x71
+    , 0x0F, 0x35, 0xF6, 0x73, 0xBF, 0x2D, 0xAF, 0x49, 0xB4, 0x45, 0x9A, 0x64, 0x32, 0xAA, 0x44, 0xA0
+    , 0x66, 0x37, 0x52, 0x0A, 0xE0, 0xB2, 0xA4, 0x1D, 0x10, 0x90, 0x08, 0x85, 0x24, 0x79, 0x3B, 0x3A
+    , 0xDD, 0x8F, 0x0C, 0x9F, 0x1E, 0xBD, 0x7F, 0xDF, 0x5E, 0xE7, 0x41, 0x73, 0x2D, 0xE5, 0xC7, 0xDC
+    , 0xD3, 0xC5, 0x8B, 0x2A, 0x76, 0x2E, 0x8F, 0x42, 0x80, 0x9E, 0xC8, 0xBA, 0x19, 0x5D, 0xC7, 0xD6
+    , 0x9E, 0x76, 0x55, 0xA0, 0x4B, 0xE3, 0x37, 0xBF, 0xE7, 0x36, 0xFC, 0xD8, 0xB4, 0xB5, 0x14, 0xA9
+    , 0xD5, 0x0D, 0xB2, 0xD6, 0x6A, 0x95, 0xD3, 0xD0, 0x35, 0x8C, 0xCA, 0x70, 0x02, 0xE4, 0x15, 0xD9
+    , 0x5C, 0x92, 0xE2, 0x6B, 0xAC, 0xED, 0xD4, 0x9E, 0x1A, 0x32, 0x59, 0x40, 0x09, 0xC4, 0xA5, 0xBF
+    , 0x04, 0xD5, 0x53, 0x56, 0x70, 0x7C, 0xAC, 0x13, 0xF4, 0xB6, 0xFB, 0xF8, 0xFE, 0x3F, 0x18, 0x69
+    , 0x2C, 0x02, 0x5E, 0xF8, 0x35, 0x94, 0xF7, 0xAE, 0x87, 0x9E, 0xB9, 0xAC, 0xE4, 0xF2, 0xFA, 0xEE
+    , 0x3E, 0x23, 0x73, 0xE1, 0x55, 0x1E, 0xBA, 0x98, 0xE9, 0xB2, 0x7D, 0x75, 0x92, 0x24, 0xAD, 0xB2
+    , 0xEB, 0x2D, 0x68, 0xDB, 0x0D, 0x5F, 0xE0, 0x3F, 0x71, 0x42, 0xFB, 0x0D, 0xD7, 0xA6, 0x2C, 0x47
+    , 0xAA, 0x5F, 0xE0, 0x32, 0x89, 0x7C, 0x59, 0xEC, 0x27, 0x45, 0xF6, 0x94, 0x84, 0x85, 0xDF, 0xE3
+    , 0x86, 0xDA, 0x08, 0x3C, 0xB9, 0x57, 0xEB, 0x62, 0x5F, 0x23, 0xC7, 0x85, 0x85, 0x5C, 0x0B, 0x34
+    , 0x60, 0x2A, 0x9B, 0x01, 0x6C, 0xD6, 0xFD, 0x61, 0x81, 0xD7, 0xB8, 0xCC, 0x61, 0xFB, 0x38, 0x9E
+    , 0xFD, 0x51, 0xA1, 0x80, 0xB8, 0xA0, 0x27, 0x9D, 0x92, 0xC2, 0xCC, 0xFC, 0x76, 0x1C, 0xF3, 0x7F
+    , 0x5A, 0xEF, 0xFA, 0x26, 0x90, 0x2A, 0xB2, 0x92, 0x48, 0xB1, 0xE5, 0x3A, 0x68, 0xF9, 0x26, 0x72
+    , 0x38, 0x2D, 0xA4, 0x23, 0xAE, 0xF7, 0x3B, 0xCC, 0x8C, 0xD3, 0xB0, 0x2E, 0xFF, 0x2C, 0xE0, 0xA1
+    , 0xF5, 0xD1, 0x37, 0x98, 0x63, 0x83, 0xF2, 0x63, 0xBA, 0x3A, 0xF8, 0x98, 0xEF, 0xF7, 0x56, 0x04
+    , 0x42, 0xB9, 0x3F, 0x06, 0xF9, 0xB7, 0x42, 0xA9, 0xB6, 0xFC, 0x1A, 0x01, 0x13, 0x12, 0x42, 0x60
+    , 0xF1, 0xE1, 0xBB, 0xBF, 0x2A, 0x29, 0x6D, 0xFA, 0x2B, 0x58, 0x7E, 0xA6, 0x36, 0x8F, 0x8E, 0xD0
+    , 0x7F, 0x56, 0xEE, 0xDF, 0x49, 0x3E, 0xD6, 0xA2, 0xF3, 0x54, 0x68, 0x7E, 0xB7, 0xD6, 0xDE, 0x90
+    , 0xA8, 0xD9, 0xB6, 0x76, 0xF9, 0x77, 0x05, 0x73, 0x80, 0x4B, 0xD0, 0xB4, 0x64, 0xE7, 0xE4, 0x6C
+    , 0x13, 0x4E, 0x21, 0x2D, 0x71, 0x5A, 0x8C, 0xDE, 0xC6, 0x3F, 0xD6, 0xDC, 0xB5, 0x41, 0x96, 0x92
+    , 0x0D, 0x99, 0x5C, 0x09, 0x92, 0x73, 0x90, 0x9F, 0xC3, 0x13, 0xD9, 0x74, 0x94, 0xF9, 0xB5, 0x92
+    , 0xFA, 0x1C, 0x8D, 0x4A, 0x69, 0x23, 0xA7, 0x16, 0x64, 0xA8, 0x11, 0x7E, 0x8B, 0x88, 0xD8, 0xD5
+    , 0xE3, 0x21, 0xDB, 0xCB, 0xE8, 0x23, 0x1A, 0xB7, 0x4C, 0x35, 0x60, 0xAF, 0xBF, 0x08, 0x82, 0x72
+    , 0x46, 0x95, 0xA7, 0x98, 0x5A, 0x3E, 0xC5, 0x69, 0x28, 0x1A, 0xD0, 0xA8, 0x77, 0x9C, 0x77, 0xC5
+    , 0xDF, 0x17, 0x76, 0x13, 0x67, 0x69, 0x9E, 0x88, 0x95, 0x28, 0x74, 0xCC, 0xEE, 0x79, 0xAF, 0x70
+    , 0x99, 0x01, 0xDC, 0xCF, 0xDB, 0xF2, 0x8B, 0xF0, 0x9F, 0x02, 0xE0, 0x3D, 0xCC, 0x19, 0x9B, 0x2A
+    , 0x20, 0x01, 0x4A, 0xAC, 0x0F, 0x77, 0xB8, 0x23, 0x00, 0x0E, 0x65, 0xCF, 0xA5, 0xCF, 0x8B, 0x27
+    , 0xDD, 0x18, 0x0A, 0x41, 0x78, 0xDE, 0x9D, 0x75, 0x21, 0xE9, 0xCF, 0x37, 0xC7, 0x53, 0x97, 0x3C
+    , 0x89, 0x09, 0x47, 0x21, 0xF1, 0x50, 0xB4, 0x2D, 0x83, 0xE7, 0xE2, 0xBB, 0x36, 0x0B, 0x2B, 0xAE
+    , 0x8C, 0xC0, 0xF9, 0x7A, 0x7D, 0x83, 0x7C, 0x9C, 0x1A, 0xB5, 0x23, 0xED, 0xC0, 0x1A, 0x51, 0x16
+    , 0xDD, 0xB3, 0xB2, 0x42, 0x11, 0x87, 0x2E, 0x2D, 0x66, 0x57, 0x6A, 0x3B, 0x96, 0x2D, 0x1C, 0x7E
+    , 0x0A, 0x73, 0x93, 0xCE, 0x9D, 0xD5, 0xB5, 0xEC, 0xC0, 0x29, 0x95, 0xD5, 0xF3, 0x36, 0x5B, 0x3A
+    , 0xA3, 0xF2, 0x3F, 0xF4, 0x22, 0x25, 0x81, 0xD5, 0x15, 0xBD, 0x04, 0xF5, 0x3B, 0x44, 0x2B, 0xFE
+    , 0x53, 0x84, 0xC6, 0xE3, 0xA1, 0x82, 0xFC, 0xC8, 0x61, 0x8C, 0x5F, 0xCC, 0x36, 0xDB, 0x90, 0x5A
+    , 0x50, 0x8A, 0x03, 0xAB, 0xBB, 0xFF, 0x27, 0x5E, 0xE9, 0x54, 0x12, 0x6F, 0x96, 0x72, 0xF8, 0xCE
+    , 0x21, 0xC5, 0xE6, 0x58, 0xA5, 0x23, 0xF8, 0x0D, 0x5E, 0x85, 0xC0, 0x6F, 0x61, 0x88, 0x3D, 0x23
+    , 0x0D, 0xAE, 0xAE, 0xCB, 0x41, 0x8F, 0x8F, 0xA1, 0xFC, 0xE6, 0x38, 0x70, 0xE6, 0xF7, 0x6E, 0x9E
+    , 0x50, 0x8A, 0x03, 0xAB, 0xBB, 0xFF, 0x27, 0x5E, 0xE9, 0x54, 0x12, 0x6F, 0x96, 0x72, 0xF8, 0xCE
+    , 0xF5, 0xD1, 0x91, 0xDF, 0x5A, 0x77, 0x10, 0xC1, 0x8C, 0xC7, 0xCB, 0x16, 0x95, 0x85, 0x26, 0x98
+    , 0x8C, 0x79, 0xD9, 0x1D, 0xB8, 0x29, 0xD4, 0xC9, 0x9C, 0x86, 0x9D, 0x5C, 0xE7, 0x72, 0x1D, 0xA0
+    , 0x9D, 0xC8, 0x25, 0x48, 0x2A, 0x19, 0x6B, 0xCD, 0xC6, 0x6A, 0xE3, 0xD4, 0x9B, 0xB3, 0x99, 0x9A
+    , 0x5E, 0xE9, 0x8E, 0x6B, 0xDD, 0x9B, 0xF1, 0x92, 0xDF, 0x39, 0x74, 0x4F, 0xDF, 0xFA, 0xA8, 0x98
+    , 0xBD, 0xA6, 0x1A, 0x4C, 0x44, 0x71, 0x39, 0x26, 0x40, 0xE0, 0xCD, 0xAA, 0xD1, 0x93, 0x36, 0x11
+    , 0xE8, 0xD8, 0x39, 0x7D, 0xF5, 0x96, 0xB6, 0x31, 0x8F, 0x0D, 0x2C, 0xD4, 0x35, 0xDA, 0x23, 0xE6
+    , 0x7A, 0x92, 0x00, 0x4B, 0xB5, 0x36, 0x1B, 0xA2, 0x4F, 0xFB, 0x41, 0xD4, 0x5E, 0x94, 0x93, 0x2F
+    , 0x6A, 0xE5, 0x36, 0xC8, 0xB0, 0x6C, 0x3E, 0xEC, 0x10, 0xA1, 0xD9, 0x0A, 0xD0, 0x1D, 0xD7, 0xAA
+    , 0x31, 0xE5, 0x00, 0xBD, 0x74, 0xBB, 0x12, 0x2D, 0x74, 0xA6, 0xAC, 0xC1, 0x2C, 0xCC, 0x7C, 0xF2
+    , 0x88, 0xAA, 0x4D, 0x3F, 0x0A, 0x22, 0xBA, 0x2E, 0x2B, 0x3B, 0x74, 0xBF, 0x53, 0xEF, 0xAE, 0x20
+    , 0xDD, 0x09, 0x5A, 0xB5, 0xDA, 0xB2, 0x1B, 0x04, 0x29, 0x5D, 0x75, 0xF4, 0x4A, 0x89, 0x70, 0xC2
+    , 0xB8, 0xF6, 0x64, 0x7A, 0x8A, 0x51, 0x5F, 0x05, 0x85, 0x52, 0x57, 0x0D, 0x7D, 0x9A, 0x0F, 0x3A
+    , 0x20, 0xD1, 0x83, 0x54, 0x38, 0x5B, 0xB5, 0x2B, 0x3B, 0x71, 0x24, 0xCE, 0x08, 0x9B, 0x4F, 0x38
+    , 0xCF, 0x92, 0x42, 0x66, 0x0C, 0x1C, 0x02, 0x29, 0x4C, 0x03, 0xF3, 0x87, 0x77, 0xB0, 0x88, 0xF7
+    , 0x2C, 0x51, 0x36, 0x3C, 0x1C, 0x2D, 0xE5, 0x6C, 0x90, 0x24, 0x2E, 0x69, 0x90, 0x6F, 0x96, 0x81
+    , 0x5B, 0x0D, 0x91, 0xBF, 0xC0, 0xFC, 0x2B, 0xBD, 0xF3, 0x77, 0x87, 0x45, 0x20, 0xB2, 0xEB, 0x56
+    , 0x87, 0x64, 0x6B, 0xA3, 0xDA, 0x7F, 0x6F, 0x2B, 0x8F, 0x72, 0xE5, 0xA2, 0xB5, 0x1B, 0xC8, 0x06
+    , 0xE1, 0xD9, 0x6C, 0xB3, 0x83, 0x2E, 0xB6, 0x25, 0xD7, 0x42, 0x7C, 0x57, 0x84, 0xA6, 0xDE, 0x3E
+    , 0xE5, 0x97, 0xCF, 0xA3, 0x60, 0x66, 0x3A, 0xB7, 0xD9, 0x0E, 0xCC, 0xB0, 0xBF, 0x56, 0x81, 0x4A
+    , 0xA4, 0x87, 0x50, 0x63, 0x1B, 0x94, 0xBE, 0x59, 0x86, 0x76, 0x20, 0xE5, 0xE4, 0x72, 0xF8, 0xCA
+    , 0xEC, 0xBD, 0x5F, 0x18, 0x4D, 0x9E, 0x25, 0xBB, 0xF0, 0xC9, 0xAA, 0x1A, 0xAF, 0xAF, 0x17, 0xAA
+    , 0x45, 0x46, 0x2F, 0xD6, 0xF2, 0xB8, 0xF5, 0x83, 0x17, 0xC6, 0xAC, 0xC6, 0x6B, 0x48, 0x49, 0xBA
+    , 0x2A, 0xB5, 0xDE, 0x4F, 0x07, 0x41, 0xD3, 0xE7, 0x03, 0x79, 0xA0, 0xCF, 0x4C, 0x6C, 0xB7, 0x4F
+    , 0x41, 0xDF, 0xEC, 0x14, 0xD0, 0x97, 0xF8, 0x93, 0x55, 0xA6, 0x2C, 0x13, 0x70, 0x5C, 0xE1, 0xDC
+    , 0x78, 0x39, 0x3C, 0x68, 0x53, 0xE6, 0x67, 0x5A, 0x57, 0xC6, 0xDE, 0x3F, 0x2D, 0x73, 0x25, 0x58
+    , 0xA8, 0x0B, 0xCA, 0xA0, 0xC9, 0xCF, 0xA2, 0x96, 0x02, 0xE4, 0x15, 0x66, 0xD1, 0x6A, 0x7C, 0x52
+    , 0xA9, 0x60, 0xAE, 0xBF, 0x06, 0xB3, 0x3E, 0xB2, 0x3E, 0x07, 0x33, 0xCC, 0xD5, 0xB3, 0xDA, 0xF1
+    , 0xB9, 0x1A, 0xD0, 0xB3, 0x1C, 0x3C, 0x28, 0xE2, 0x9B, 0x99, 0x83, 0xFF, 0xF2, 0xC3, 0xBC, 0xD1
+    , 0xB8, 0x44, 0x8E, 0xA7, 0xDC, 0x8E, 0x9D, 0x64, 0x1B, 0x15, 0x00, 0x01, 0xC2, 0x0B, 0x7A, 0x72
+    , 0x6F, 0xC5, 0xC7, 0xD1, 0x37, 0x3C, 0x23, 0x6E, 0x1F, 0x0D, 0xF2, 0xAF, 0x63, 0xBA, 0x6D, 0x3A
+    , 0x53, 0x29, 0x35, 0x3D, 0x9F, 0x76, 0x02, 0x20, 0x45, 0x73, 0x4C, 0xAA, 0x7E, 0x06, 0xD5, 0xE6
+    , 0xFC, 0x35, 0xFB, 0xC4, 0x2D, 0xEE, 0xDC, 0xD2, 0xE9, 0xAB, 0x8B, 0x73, 0x9C, 0xE1, 0xB0, 0x6D
+    , 0xD5, 0x59, 0xF2, 0xEE, 0x70, 0x3C, 0x4B, 0x93, 0x76, 0x4B, 0x64, 0x4E, 0xAA, 0x9E, 0xE4, 0x5C
+    , 0x87, 0xAC, 0x88, 0x68, 0x2A, 0x96, 0x8A, 0x18, 0xB2, 0x57, 0x31, 0x30, 0x87, 0x2F, 0x91, 0x29
+    , 0xDF, 0xA8, 0x41, 0x94, 0x3B, 0x22, 0xE8, 0x90, 0xAC, 0xC4, 0x58, 0x59, 0x9A, 0x0B, 0x51, 0x8D
+    , 0x14, 0xBE, 0xC4, 0x88, 0xD2, 0xA0, 0x6E, 0x5E, 0xDA, 0x74, 0xD7, 0x9D, 0xE5, 0xD9, 0x3B, 0x83
+    , 0x2E, 0x06, 0xB7, 0xB7, 0x98, 0x59, 0x28, 0x94, 0x1D, 0x75, 0x2A, 0x9A, 0x07, 0x07, 0xFD, 0xC1
+    , 0x2D, 0xB5, 0x29, 0x85, 0x87, 0x45, 0x06, 0xCF, 0xEE, 0x5C, 0x17, 0x65, 0x54, 0x21, 0xCE, 0x87
+    , 0x1A, 0xBF, 0x70, 0x2C, 0xFB, 0xC8, 0x9F, 0x44, 0xF3, 0xA2, 0x1D, 0xF2, 0x74, 0x85, 0x2E, 0x23
+    , 0xB8, 0x44, 0x8E, 0xA7, 0xDC, 0x8E, 0x9D, 0x64, 0x1B, 0x15, 0x00, 0x01, 0xC2, 0x0B, 0x7A, 0x72
+    , 0x20, 0xA3, 0x54, 0x5C, 0x23, 0x4D, 0xA3, 0x22, 0x82, 0x83, 0xFA, 0x09, 0xE2, 0xFD, 0x54, 0xE1
+    , 0x56, 0x74, 0xD6, 0x36, 0x45, 0xDB, 0x33, 0x2B, 0xFF, 0x5C, 0xBE, 0x4A, 0x44, 0x96, 0x9E, 0x4E
+    , 0x05, 0x8B, 0xAC, 0x07, 0x29, 0xFC, 0xBB, 0x48, 0x03, 0x2C, 0xC9, 0x95, 0x9C, 0x18, 0x10, 0x02
+    , 0x66, 0xC8, 0x8B, 0x2F, 0xA1, 0xCA, 0xB2, 0xAA, 0x3F, 0x89, 0x3A, 0xE5, 0x79, 0x7E, 0x94, 0x22
+    , 0x1E, 0xBF, 0x51, 0xBF, 0x84, 0x5D, 0x44, 0xB8, 0xFC, 0xB1, 0x8F, 0xC8, 0x2B, 0x42, 0x8F, 0xCF
+    , 0xFC, 0x35, 0xFB, 0xC4, 0x2D, 0xEE, 0xDC, 0xD2, 0xE9, 0xAB, 0x8B, 0x73, 0x9C, 0xE1, 0xB0, 0x6D
+    , 0xD9, 0x33, 0xA4, 0x6D, 0xC6, 0xF5, 0xB3, 0xA5, 0xE2, 0xD3, 0x52, 0xB6, 0x80, 0x83, 0xBF, 0xA7
+    , 0x87, 0x6A, 0xAB, 0xF9, 0xF8, 0x19, 0xB5, 0x54, 0x7B, 0xA5, 0x37, 0x80, 0xF5, 0x2C, 0x78, 0xF2
+    , 0xEA, 0x7E, 0x85, 0x88, 0x6B, 0x2C, 0x5D, 0x9F, 0xBC, 0x8E, 0xE2, 0x4B, 0x2D, 0x78, 0xC9, 0x60
+    , 0xA2, 0x84, 0x3B, 0x38, 0x8B, 0xEF, 0x34, 0x34, 0xBC, 0x62, 0x80, 0x38, 0x0B, 0xA6, 0x8C, 0x26
+    , 0x87, 0xAC, 0x88, 0x68, 0x2A, 0x96, 0x8A, 0x18, 0xB2, 0x57, 0x31, 0x30, 0x87, 0x2F, 0x91, 0x29
+    , 0xDF, 0xA8, 0x41, 0x94, 0x3B, 0x22, 0xE8, 0x90, 0xAC, 0xC4, 0x58, 0x59, 0x9A, 0x0B, 0x51, 0x8D
+    , 0x2E, 0x4F, 0x10, 0x15, 0x2C, 0xF3, 0xE7, 0x07, 0xF5, 0xA7, 0x21, 0xC5, 0xFC, 0x7D, 0x20, 0x76
+    , 0x73, 0x97, 0xB8, 0x79, 0x93, 0xA8, 0x89, 0xF0, 0xAD, 0x2B, 0x97, 0xD2, 0x2A, 0xA4, 0x2A, 0xCE
+    , 0xCE, 0xB8, 0x2C, 0x87, 0x3C, 0x37, 0x6A, 0xDB, 0xB0, 0x38, 0x2D, 0x67, 0xC2, 0x3C, 0x42, 0x7F
+    , 0xA3, 0x30, 0x9C, 0x98, 0x0D, 0xD8, 0x79, 0xF7, 0x34, 0x53, 0x9D, 0x97, 0xE3, 0x87, 0x62, 0x12
+    , 0xF5, 0x4E, 0xC4, 0xDF, 0xA5, 0x64, 0xFB, 0xC2, 0xDA, 0xAE, 0xEA, 0x26, 0x44, 0xC4, 0xCE, 0x39
+    , 0x36, 0x6C, 0x44, 0xD6, 0xE5, 0x73, 0x9D, 0x34, 0x48, 0xEB, 0x76, 0x0A, 0x19, 0x84, 0xD2, 0xD7
+    , 0x33, 0xC1, 0x17, 0x3E, 0xC7, 0xCB, 0xDF, 0x55, 0xEC, 0x41, 0x2E, 0x92, 0xC2, 0xE9, 0x20, 0xD8
+    , 0x63, 0xED, 0x96, 0xD8, 0x43, 0x7A, 0x9A, 0xE3, 0xFC, 0x4E, 0xD3, 0x5F, 0xD7, 0xBF, 0x46, 0x59
+    , 0x1F, 0x9E, 0xEB, 0xF7, 0x49, 0x9F, 0x50, 0x8B, 0xF1, 0x4E, 0x83, 0x30, 0x0F, 0x3D, 0x63, 0x5B
+    , 0x74, 0x8E, 0xCE, 0x94, 0xFB, 0x06, 0x54, 0x1B, 0x0B, 0x68, 0x7D, 0x13, 0xC8, 0x74, 0x89, 0xF7
+    , 0x68, 0xB8, 0x39, 0x73, 0x7F, 0xC1, 0x78, 0xA0, 0xB5, 0xC8, 0x4D, 0x65, 0xE1, 0x87, 0x3D, 0xF4
+    , 0x53, 0x3E, 0xA2, 0x35, 0xC7, 0x55, 0x99, 0x5A, 0xAB, 0xA2, 0x5E, 0xA8, 0x13, 0xE2, 0x9F, 0x12
+    , 0x4F, 0x76, 0xCE, 0xF4, 0x85, 0x10, 0xC7, 0xB8, 0xEB, 0xF9, 0xDD, 0x66, 0x31, 0x33, 0x38, 0x1C
+    , 0xE6, 0x87, 0x00, 0x44, 0x7E, 0x22, 0xF1, 0x8F, 0xF8, 0x8C, 0x73, 0xAF, 0x0C, 0x14, 0x3C, 0x54
+    , 0xB2, 0x97, 0x10, 0xEA, 0xBC, 0xD0, 0x7B, 0x1C, 0x33, 0x6B, 0x64, 0x56, 0x1C, 0xE5, 0x6D, 0xBE
+    , 0x3D, 0xA8, 0x8E, 0xA3, 0xCB, 0x20, 0xF0, 0xDA, 0xFB, 0xEE, 0xB8, 0x28, 0xDF, 0xB8, 0x35, 0xB7
+    , 0x62, 0x4F, 0xF1, 0xFE, 0xB6, 0xE2, 0x4D, 0xFD, 0x43, 0x32, 0xCC, 0x11, 0x8B, 0x9A, 0x21, 0x2C
+    , 0x8D, 0xBC, 0x6D, 0x91, 0xDB, 0x1B, 0x2E, 0x03, 0x41, 0xE6, 0xBA, 0x0B, 0x46, 0xD1, 0xE9, 0x9B
+    , 0xF6, 0x73, 0x0B, 0x2A, 0x6A, 0xA4, 0xAC, 0x90, 0x97, 0xEA, 0x7D, 0x35, 0xD8, 0x21, 0x9C, 0xCD
+    , 0x17, 0x2E, 0x17, 0x58, 0x97, 0x1B, 0x2C, 0xB4, 0x7E, 0x83, 0xB1, 0xDA, 0x49, 0x4D, 0x07, 0x6D
+    , 0x1E, 0x48, 0xC2, 0xDA, 0xF2, 0x06, 0x2A, 0x76, 0xE8, 0xD9, 0x37, 0x69, 0x17, 0x65, 0x74, 0x83
+    , 0xB8, 0xEA, 0x25, 0x53, 0xE1, 0xD2, 0x74, 0x81, 0x35, 0xD4, 0x71, 0x33, 0x2A, 0x6D, 0x57, 0x7E
+    , 0xF6, 0xE4, 0x13, 0xA2, 0x03, 0xF8, 0x97, 0x76, 0xE6, 0xBF, 0xB0, 0x97, 0xD3, 0xF6, 0x33, 0x34
+    , 0x8B, 0xB6, 0xD5, 0x29, 0xA4, 0x4E, 0xA5, 0xF9, 0xA6, 0x19, 0x42, 0x31, 0x56, 0x6E, 0x30, 0xC3
+    , 0xF7, 0x66, 0x70, 0x44, 0x0A, 0xC1, 0xF5, 0xF7, 0x18, 0xA9, 0xB6, 0xAB, 0x7A, 0x01, 0x6D, 0x3D
+    , 0xCF, 0xC1, 0x20, 0xD4, 0x50, 0x3D, 0xFB, 0xCB, 0x87, 0x53, 0x9D, 0x82, 0x38, 0x57, 0xE2, 0x8D
+    , 0x68, 0xDF, 0x78, 0xE5, 0x62, 0x58, 0x62, 0x92, 0x3E, 0xFD, 0x5E, 0xA8, 0x35, 0x80, 0x93, 0xC6
+    , 0x35, 0xF0, 0xA2, 0xA4, 0xBA, 0xAD, 0x7B, 0x72, 0x65, 0x75, 0xDA, 0x6F, 0x48, 0x91, 0x07, 0x70
+    , 0x0C, 0x19, 0x5E, 0xA5, 0x8B, 0x0C, 0x9C, 0x84, 0xB5, 0xBA, 0x2D, 0x22, 0x2D, 0xAD, 0xB7, 0x0D
+    , 0x56, 0xF0, 0x78, 0xA9, 0x75, 0x8E, 0x80, 0x96, 0x38, 0x9B, 0x30, 0xB8, 0xF0, 0xAE, 0xB2, 0xFD
+    , 0xA6, 0x82, 0x47, 0x13, 0x4C, 0xB5, 0xC5, 0x99, 0xFF, 0xF9, 0x49, 0xB2, 0x09, 0x92, 0xCC, 0xA1
+    , 0x3E, 0x3A, 0x17, 0x93, 0x4A, 0x45, 0x9A, 0xC0, 0x02, 0x52, 0x6A, 0x02, 0x19, 0x45, 0x94, 0x1C
+    , 0x73, 0xD6, 0x1E, 0x52, 0xFF, 0x66, 0x12, 0x56, 0x05, 0xA9, 0xBC, 0xC5, 0x10, 0x14, 0x8F, 0x95
+    , 0x08, 0x2D, 0x58, 0xC1, 0x34, 0x13, 0xDD, 0x93, 0x49, 0xC5, 0x73, 0x9D, 0x62, 0xC1, 0x4F, 0x24
+    , 0x20, 0x34, 0x7A, 0x6E, 0x82, 0xE9, 0xAA, 0x96, 0x6E, 0x90, 0xA1, 0x8E, 0xB8, 0x03, 0x8D, 0x68
+    , 0xFF, 0xA7, 0x47, 0xAB, 0xD0, 0x8D, 0x0C, 0xBF, 0xE0, 0x99, 0x40, 0xB8, 0x0C, 0xE7, 0x36, 0x94
+    , 0xA1, 0x55, 0x0C, 0x97, 0xBD, 0xCD, 0x28, 0x99, 0xB6, 0x99, 0xD4, 0x69, 0x2E, 0x62, 0x4B, 0x41
+    , 0x78, 0x57, 0x86, 0x16, 0xC4, 0xBC, 0x32, 0x8B, 0x02, 0xB1, 0x80, 0x7B, 0x27, 0x4A, 0x05, 0x43
+    , 0xC7, 0x94, 0x1F, 0xED, 0x07, 0xB0, 0x1C, 0x9E, 0x64, 0xEF, 0xED, 0x16, 0x1C, 0xC8, 0xB3, 0x55
+    , 0xF6, 0x78, 0x34, 0x9E, 0x6F, 0x37, 0x14, 0x1B, 0x4F, 0xE2, 0xDC, 0x1B, 0x77, 0xCE, 0x74, 0x1A
+    , 0x2E, 0x3C, 0x0F, 0xCF, 0x0A, 0xDC, 0x31, 0x92, 0x23, 0x5C, 0x4E, 0x46, 0xFC, 0x42, 0xF1, 0xA7
+    , 0x05, 0xFD, 0xB0, 0xFF, 0x32, 0xF6, 0xFB, 0xA6, 0x1F, 0x3D, 0x8C, 0x18, 0x38, 0x0F, 0x83, 0xFC
+    , 0xEB, 0xFD, 0x51, 0xB8, 0x73, 0x39, 0x7A, 0x88, 0x0F, 0x2E, 0xFA, 0xF7, 0x78, 0xA3, 0x1B, 0x39
+    , 0x49, 0xF6, 0xFB, 0xC4, 0xA6, 0x0C, 0x90, 0x31, 0x95, 0x06, 0x6F, 0x4F, 0x32, 0x0B, 0x85, 0xB2
+    , 0xF6, 0x40, 0x15, 0x1D, 0x96, 0xB6, 0x10, 0x93, 0x10, 0xFC, 0x84, 0x5D, 0xB1, 0xBA, 0xEE, 0x4A
+    , 0xBC, 0x25, 0x0B, 0xC7, 0x49, 0x42, 0x00, 0xF2, 0x74, 0xD6, 0x55, 0x82, 0x13, 0xF5, 0x3B, 0x03
+    , 0x0D, 0x7C, 0x51, 0xBF, 0xEA, 0xB7, 0x32, 0x4C, 0x46, 0xA3, 0x33, 0xE6, 0x5F, 0x12, 0x74, 0x78
+    , 0xBE, 0x61, 0xFE, 0x0E, 0x17, 0x00, 0x86, 0xDE, 0x57, 0x48, 0x29, 0xBB, 0xEF, 0xEE, 0x13, 0x0F
+    , 0xEE, 0xA0, 0x19, 0xB1, 0xD1, 0x22, 0xBB, 0x36, 0x5E, 0x49, 0x2A, 0x58, 0x4D, 0x05, 0x2B, 0x27
+    , 0xE0, 0x92, 0xE3, 0xDC, 0x58, 0x00, 0x29, 0x93, 0x78, 0xD8, 0xC6, 0xD3, 0xC7, 0x1B, 0x91, 0xFE
+    , 0x43, 0xC5, 0x61, 0x19, 0x94, 0x6A, 0xD2, 0x37, 0xF9, 0xFF, 0xF8, 0x5D, 0x6E, 0x94, 0x03, 0x2F
+    , 0x2F, 0xF9, 0xF8, 0xCA, 0xE5, 0x1C, 0xE8, 0xA8, 0x22, 0x33, 0xE7, 0xE1, 0x7F, 0xF0, 0x88, 0x34
+    , 0x45, 0x0C, 0x72, 0x27, 0xB4, 0x6F, 0x7B, 0x7D, 0x7E, 0xC6, 0xC2, 0x05, 0xD6, 0xBB, 0x81, 0xB6
+    , 0x8F, 0xFF, 0x25, 0xA5, 0x75, 0x13, 0x28, 0x2C, 0x13, 0x3C, 0x49, 0x59, 0x57, 0xF9, 0x04, 0x3A
+    , 0x65, 0x04, 0x28, 0x16, 0xF1, 0x19, 0x32, 0x08, 0x32, 0xDA, 0x35, 0x2C, 0xEC, 0x52, 0x31, 0x6F
+    , 0x67, 0xCD, 0xAF, 0xDB, 0x2E, 0xB1, 0xEA, 0x9A, 0x18, 0x59, 0x12, 0x0B, 0x46, 0xB6, 0x06, 0xDA
+    , 0x85, 0x89, 0xE6, 0xE9, 0x7A, 0xA7, 0x14, 0xBE, 0x0D, 0x0D, 0xA8, 0xAF, 0x21, 0x86, 0x64, 0x09
+    , 0xD4, 0xCE, 0x84, 0x93, 0xB8, 0x93, 0x55, 0x62, 0xB3, 0xA3, 0xA2, 0x0A, 0xCE, 0x23, 0x5F, 0xE4
+    , 0x45, 0xF7, 0xDA, 0x0F, 0x8A, 0x7A, 0x8D, 0x28, 0x02, 0xDB, 0xED, 0x5C, 0x1C, 0x49, 0xF9, 0x72
+    , 0x2A, 0xE3, 0x16, 0x61, 0xFF, 0xF4, 0xD7, 0x54, 0x50, 0x19, 0x50, 0xA8, 0x61, 0xFF, 0x59, 0xA9
+    , 0x96, 0x93, 0x75, 0x89, 0xA4, 0x0E, 0x8E, 0x67, 0x08, 0xC6, 0x98, 0x4C, 0xF9, 0xFF, 0x84, 0x7D
+    , 0x21, 0xD6, 0x48, 0xFA, 0x33, 0xF1, 0x52, 0x0C, 0x62, 0xEA, 0x80, 0xCB, 0xE1, 0xA0, 0x78, 0x04
+    , 0x2D, 0xF0, 0xEB, 0x20, 0xC9, 0x65, 0xDD, 0xB3, 0xAC, 0x8A, 0x14, 0x0F, 0xCB, 0x37, 0xF0, 0x4A
+    , 0xED, 0xCD, 0xA0, 0xA9, 0x9D, 0x28, 0x8C, 0xB8, 0xC7, 0x4A, 0xA5, 0x79, 0xE7, 0x3B, 0xC9, 0xBF
+    , 0x59, 0xA2, 0xFE, 0xD7, 0x71, 0x37, 0x71, 0x20, 0x90, 0xB6, 0xC2, 0x19, 0x1C, 0x9C, 0x5F, 0x69
+    , 0xF1, 0xF0, 0xE8, 0x64, 0x0F, 0x61, 0x53, 0x67, 0x49, 0x95, 0xEA, 0x76, 0x89, 0xED, 0x3D, 0x4F
+    , 0xC1, 0xE1, 0x77, 0x77, 0xEB, 0xAF, 0x7A, 0xFA, 0xBB, 0x15, 0xFB, 0xFA, 0xE5, 0x0B, 0xD6, 0xC4
+    , 0xB4, 0x7B, 0xC3, 0xA9, 0xE4, 0xDB, 0xEA, 0x40, 0xAC, 0x77, 0x08, 0xBB, 0xBD, 0xAC, 0x3D, 0x4C
+    , 0x3A, 0x92, 0x39, 0x27, 0xD1, 0xF0, 0xB0, 0x4A, 0xF3, 0xAC, 0x34, 0x4E, 0x4E, 0x45, 0xD8, 0x58
+    , 0x52, 0x7F, 0x1E, 0xFF, 0xAC, 0x36, 0xD3, 0x9C, 0xD0, 0xB3, 0x69, 0x89, 0x7E, 0x09, 0x72, 0xF6
+    , 0x67, 0xB4, 0x2C, 0xB6, 0xD3, 0xD5, 0x9A, 0xCF, 0x02, 0xBB, 0x7C, 0xFE, 0x31, 0xCF, 0xF6, 0x16
+    , 0x1B, 0xEC, 0xC7, 0x21, 0x0B, 0xA9, 0x2C, 0x09, 0xD6, 0x55, 0xEE, 0xF7, 0x0C, 0x57, 0x34, 0x04
+    , 0xE3, 0x7C, 0x5B, 0x0D, 0x09, 0x61, 0xEE, 0x5B, 0x71, 0xFB, 0xC9, 0x07, 0xB0, 0x02, 0xB0, 0xF7
+    , 0xA8, 0xD5, 0x23, 0x27, 0x5B, 0xB0, 0xC1, 0x14, 0x95, 0xA6, 0xB3, 0x9B, 0xDB, 0x20, 0xCD, 0xDE
+    , 0x21, 0x36, 0x22, 0xAE, 0xE5, 0x4F, 0x49, 0x02, 0xD2, 0x4E, 0xDC, 0x90, 0x7A, 0x5E, 0xF4, 0xAD
+    , 0xB6, 0xE7, 0xB3, 0x67, 0xDB, 0x26, 0x8C, 0xFF, 0x2F, 0x21, 0x59, 0xBF, 0x79, 0xDC, 0xAD, 0xD1
+    , 0xEE, 0xD6, 0xB2, 0x5F, 0x6C, 0x17, 0x48, 0x06, 0xFC, 0xC2, 0x0B, 0x0C, 0x26, 0x0A, 0x82, 0x1B
+    , 0xD3, 0xCC, 0x41, 0xAA, 0xA2, 0x8B, 0xCB, 0xB9, 0x91, 0x55, 0x3F, 0x5D, 0xA9, 0x69, 0xD0, 0xEC
+    , 0x50, 0xE7, 0x97, 0x71, 0x00, 0xD7, 0xC3, 0xF3, 0xBF, 0x24, 0x71, 0xEB, 0x53, 0x4E, 0x5F, 0xD1
+    , 0x66, 0x65, 0x0A, 0x61, 0xD5, 0x05, 0x91, 0xF8, 0x42, 0xC6, 0x90, 0x7F, 0xD9, 0xC2, 0xC3, 0x3E
+    , 0xEC, 0x9F, 0x27, 0xB9, 0xB2, 0xE3, 0xBD, 0xC9, 0x8A, 0x7A, 0x5D, 0x10, 0x7D, 0x98, 0xF5, 0x3D
+    , 0xAC, 0x69, 0x9E, 0x67, 0x79, 0xDA, 0xA9, 0x53, 0x8B, 0xDD, 0x18, 0xCD, 0xC5, 0x0F, 0x47, 0x71
+    , 0x22, 0x26, 0xFB, 0xB1, 0xB7, 0xB9, 0x87, 0x78, 0x00, 0x09, 0x90, 0x7C, 0x6A, 0x64, 0xD2, 0x2D
+    , 0x3D, 0x10, 0x4C, 0xA4, 0xF8, 0x8F, 0x61, 0x8F, 0xC8, 0x5F, 0x2E, 0xF8, 0x07, 0x17, 0x36, 0xC4
+    , 0xB2, 0x5D, 0xEE, 0x93, 0x54, 0x53, 0x52, 0x31, 0xC0, 0x7E, 0xDA, 0xFA, 0x79, 0x95, 0x49, 0xED
+    , 0x66, 0x6D, 0x31, 0xD5, 0x2C, 0xE9, 0xA1, 0x26, 0x0C, 0x47, 0x23, 0x42, 0x91, 0x3F, 0x14, 0x49
+    , 0x1A, 0xC5, 0xEF, 0x7D, 0x9E, 0x8D, 0x37, 0x53, 0x06, 0xA7, 0xF2, 0x88, 0x5B, 0x64, 0xD5, 0xD7
+    , 0xBD, 0x6A, 0x54, 0x2F, 0xA4, 0x56, 0x58, 0x0B, 0xCF, 0x65, 0x40, 0xBA, 0x37, 0x99, 0xCE, 0x88
+    , 0x64, 0x91, 0xCC, 0x8A, 0x7E, 0x4C, 0x8C, 0x47, 0xA2, 0xBD, 0x04, 0x05, 0xB8, 0xCC, 0x62, 0xCD
+    , 0x86, 0x15, 0x54, 0x83, 0x45, 0xC8, 0x07, 0xED, 0x69, 0xD3, 0xB4, 0x90, 0x6A, 0xCE, 0x1C, 0xAC
+    , 0x1C, 0x82, 0x93, 0xDF, 0xEC, 0xCB, 0x61, 0xBC, 0x83, 0xA5, 0x54, 0xB9, 0x35, 0xC3, 0x88, 0xE4
+    , 0x9F, 0xA8, 0x9F, 0xF1, 0x3C, 0x4F, 0x01, 0xED, 0xC9, 0x71, 0xF6, 0x7F, 0xD6, 0x8C, 0x4B, 0xBC
+    , 0x2A, 0x9F, 0x28, 0xF7, 0x9A, 0x16, 0x8A, 0x00, 0xD1, 0x8F, 0x2A, 0x22, 0x3D, 0xD6, 0x7B, 0xB8
+    , 0x3B, 0xA3, 0xAD, 0x71, 0x35, 0x1D, 0x72, 0xD3, 0xB7, 0xF1, 0x9A, 0x67, 0x19, 0x23, 0x1E, 0x1B
+    , 0x2C, 0x27, 0xEE, 0x34, 0xF9, 0x45, 0x67, 0xB5, 0x1D, 0x2A, 0x9C, 0xA6, 0x5E, 0x66, 0x8D, 0x62
+    , 0xB1, 0xEF, 0xB1, 0xD6, 0x5E, 0x2B, 0x91, 0x42, 0xB2, 0x8A, 0x74, 0x7B, 0x8B, 0xEF, 0xE2, 0x02
+    , 0x38, 0x82, 0x34, 0x5B, 0xBF, 0x95, 0x4F, 0xBB, 0x70, 0xDC, 0x49, 0x17, 0xAC, 0x73, 0xD0, 0x65
+    , 0x45, 0xA6, 0x22, 0xAF, 0x99, 0x76, 0x7A, 0xA8, 0x62, 0x40, 0x2F, 0xCF, 0x31, 0xCE, 0xDD, 0x74
+    , 0x4F, 0x8A, 0x36, 0x6F, 0xB3, 0x9B, 0xBA, 0x51, 0x41, 0x2F, 0x85, 0x50, 0x74, 0xD5, 0x66, 0x01
+    , 0x90, 0xED, 0x78, 0x4C, 0xC2, 0x03, 0x99, 0x59, 0x4B, 0x08, 0x26, 0x20, 0xC1, 0x6E, 0xF8, 0x41
+    , 0x94, 0x73, 0x22, 0xEF, 0xD6, 0xB6, 0x1F, 0x64, 0x72, 0xB4, 0xEA, 0x7A, 0xFE, 0xEB, 0xB8, 0x21
+    , 0xE5, 0x16, 0x43, 0xD8, 0x4B, 0xF9, 0x58, 0x8A, 0x50, 0x6E, 0x66, 0xF5, 0x60, 0x42, 0x4E, 0x74
+    , 0x49, 0xC3, 0xE5, 0xBB, 0xF8, 0x82, 0x35, 0xAE, 0x61, 0x03, 0xAF, 0x5A, 0xA3, 0x06, 0xDE, 0x60
+    , 0x66, 0xB3, 0xBC, 0x87, 0x98, 0xD3, 0xCF, 0x98, 0xF9, 0x34, 0x38, 0xC5, 0xF0, 0x52, 0xED, 0xA5
+    , 0x01, 0x66, 0xFF, 0x80, 0x40, 0x88, 0xE9, 0x10, 0x38, 0x5F, 0xDF, 0xB3, 0x95, 0x38, 0xFF, 0x40
+    , 0x22, 0xE5, 0x9B, 0xD8, 0xEA, 0xB5, 0x0B, 0x7C, 0x28, 0x18, 0xA1, 0x6B, 0xF7, 0x32, 0x7E, 0x20
+    , 0xDD, 0xFB, 0xA3, 0xCA, 0xE4, 0x2F, 0xB0, 0x3D, 0x7F, 0x7A, 0x46, 0xBF, 0x5D, 0x93, 0x54, 0xCD
+    , 0xC3, 0xFA, 0x1C, 0x3B, 0x19, 0xFC, 0xE9, 0xD8, 0xFB, 0xB2, 0xB4, 0x0C, 0xF6, 0x4F, 0xB6, 0x42
+    , 0x61, 0xD5, 0x99, 0xEC, 0x56, 0xCF, 0xF3, 0x74, 0xD6, 0xC5, 0x10, 0x65, 0x27, 0x81, 0xD0, 0x42
+    , 0x9D, 0xFC, 0x87, 0x07, 0xEA, 0x0C, 0x55, 0x8D, 0xBA, 0xE1, 0x72, 0x13, 0xBF, 0x4B, 0x4B, 0x26
+    , 0xE0, 0xE7, 0xEC, 0xD1, 0xDA, 0x7F, 0xFC, 0xF1, 0x06, 0x6A, 0x56, 0xC4, 0xDC, 0xB2, 0x63, 0xB5
+    , 0x75, 0xEE, 0xEC, 0xAC, 0x8C, 0xDC, 0x35, 0xE6, 0x73, 0x91, 0x36, 0x30, 0x76, 0x9C, 0x50, 0x30
+    , 0xF7, 0x63, 0xE1, 0xFC, 0xE1, 0x15, 0x85, 0x42, 0xDD, 0x19, 0xA2, 0x1B, 0x3D, 0xF7, 0x8A, 0xB9
+    , 0x93, 0x9F, 0x88, 0x07, 0x00, 0x09, 0x6B, 0xD9, 0x9B, 0xC1, 0x9C, 0x09, 0x45, 0xA9, 0x3C, 0x3E
+    , 0x4C, 0xC4, 0x4D, 0x24, 0x79, 0x1A, 0xE1, 0xAA, 0x9E, 0x46, 0x46, 0xF4, 0xA5, 0xF0, 0x74, 0xFE
+    , 0xB3, 0x3D, 0xF7, 0x3B, 0x02, 0xBA, 0x7C, 0x1C, 0x4D, 0xFB, 0x02, 0x0E, 0xFF, 0x89, 0xF9, 0xD9
+    , 0xEB, 0x4D, 0x53, 0x19, 0x32, 0x37, 0xBD, 0x75, 0x2E, 0xBC, 0x4A, 0x4C, 0x03, 0xB4, 0xE6, 0xE3
+    , 0x9A, 0xBE, 0xBD, 0x89, 0xEC, 0x0D, 0x38, 0xDA, 0x51, 0xC0, 0xC3, 0x5F, 0xFA, 0xEE, 0x2B, 0x35
+    , 0x49, 0xF2, 0x15, 0x2D, 0x93, 0x14, 0x59, 0xB6, 0x8E, 0x23, 0x80, 0xD7, 0xBF, 0x4B, 0xF2, 0xDD
+    , 0x44, 0x6A, 0x5F, 0x48, 0xA5, 0xC1, 0x6D, 0x4C, 0x2C, 0xB4, 0xF5, 0x02, 0x5C, 0x98, 0xE5, 0xD0
+    , 0x11, 0xF8, 0xEA, 0xB5, 0xC3, 0x47, 0x39, 0xAC, 0x68, 0xC0, 0x98, 0x3F, 0x1E, 0x51, 0xCB, 0xE1
+    , 0x88, 0x32, 0x45, 0x83, 0xD1, 0x62, 0x4D, 0xA3, 0x3F, 0x4A, 0xC7, 0xD6, 0x93, 0x6F, 0xE6, 0x47
+    , 0x4A, 0x82, 0x34, 0x6D, 0xE4, 0x67, 0x9E, 0xB0, 0x83, 0x36, 0x84, 0x4A, 0xE2, 0x7C, 0xD2, 0x6A
+    , 0x93, 0x9F, 0x88, 0x07, 0x00, 0x09, 0x6B, 0xD9, 0x9B, 0xC1, 0x9C, 0x09, 0x45, 0xA9, 0x3C, 0x3E
+    , 0x98, 0x67, 0xCC, 0x9D, 0xD4, 0x01, 0x40, 0x25, 0x02, 0x17, 0xC0, 0xCF, 0x51, 0xD1, 0x24, 0x31
+    , 0xAD, 0xAC, 0x92, 0x10, 0x75, 0xCB, 0x97, 0x05, 0x6C, 0xFE, 0x45, 0x4A, 0x03, 0xEA, 0xC6, 0x3C
+    , 0xB1, 0xBA, 0x46, 0x61, 0xB4, 0x59, 0x5D, 0x12, 0x89, 0xA6, 0x43, 0x2C, 0xEE, 0x2A, 0x15, 0x63
+    , 0x32, 0xC3, 0xEF, 0xBC, 0xAA, 0x12, 0x41, 0xC0, 0xD9, 0x3E, 0x18, 0x6D, 0x9B, 0x47, 0xE3, 0xEA
+    , 0x4F, 0x12, 0x6F, 0xCB, 0x7F, 0x03, 0x5B, 0x48, 0x19, 0x52, 0x7A, 0xE6, 0xAD, 0x16, 0xFD, 0xCA
+    , 0x79, 0x29, 0x4F, 0xC1, 0x3B, 0x78, 0x16, 0x66, 0x1A, 0x22, 0x92, 0x06, 0x23, 0xEC, 0x27, 0xDC
+    , 0x60, 0x61, 0x42, 0x6E, 0x9C, 0x63, 0x75, 0x17, 0x9A, 0x97, 0xC3, 0x09, 0x60, 0x59, 0xFC, 0x81
+    , 0x83, 0x96, 0xAA, 0x21, 0xD2, 0xF7, 0x26, 0x2E, 0xAF, 0xF4, 0xAA, 0x27, 0x82, 0x65, 0xD6, 0x44
+    , 0xD8, 0x73, 0x04, 0x9C, 0xF1, 0xFD, 0x5C, 0xD0, 0x38, 0xB5, 0xB0, 0xAF, 0xA7, 0x54, 0xD6, 0xC3
+    , 0xD0, 0xF8, 0xB8, 0x67, 0x19, 0xD3, 0x75, 0x91, 0x7B, 0x38, 0x3A, 0xD5, 0xF4, 0x38, 0x27, 0xBA
+    , 0x09, 0xEA, 0x44, 0xF6, 0x4E, 0xB0, 0xA1, 0xD0, 0x2D, 0x5D, 0x65, 0x80, 0x92, 0x86, 0x2F, 0x30
+    , 0x2B, 0x05, 0xC7, 0xDF, 0xB8, 0x13, 0x8C, 0xC2, 0x29, 0xF9, 0x18, 0x9B, 0x85, 0x1D, 0x29, 0xD3
+    , 0x4B, 0xF5, 0x05, 0xAA, 0x17, 0x72, 0x13, 0xEE, 0x32, 0x80, 0x1C, 0xF3, 0x07, 0x5A, 0x39, 0x9F
+    , 0xF4, 0xC6, 0x6A, 0xB6, 0x1F, 0xB4, 0x85, 0xF4, 0x7B, 0xE6, 0x18, 0xF5, 0x45, 0x10, 0x1B, 0x52
+    , 0xF3, 0xD2, 0x35, 0xD8, 0xFF, 0xE4, 0x48, 0x50, 0xA1, 0xA0, 0x4E, 0x06, 0xEA, 0x84, 0xCF, 0xF4
+    , 0xC7, 0x48, 0x64, 0xFF, 0x61, 0xFA, 0xDD, 0xA4, 0xAB, 0x25, 0xED, 0xCE, 0xF2, 0x0A, 0xE8, 0xAC
+    , 0xF7, 0xCE, 0x2B, 0x09, 0x1F, 0xF3, 0xF6, 0xE2, 0xA2, 0xB7, 0x9E, 0xED, 0xDF, 0x93, 0x0D, 0x23
+    , 0xEF, 0xCB, 0xA4, 0x16, 0x80, 0x22, 0x9B, 0x09, 0xAC, 0xDE, 0xE2, 0xD7, 0x93, 0x3E, 0x2D, 0x2F
+    , 0x2D, 0x3B, 0xA6, 0x9D, 0x37, 0x51, 0xAB, 0x90, 0x07, 0xF1, 0x1B, 0xD9, 0x5F, 0xDD, 0x16, 0x47
+    , 0x15, 0xFA, 0x3D, 0x2F, 0x05, 0x90, 0x07, 0xDD, 0x9C, 0xC2, 0x5D, 0x52, 0x60, 0xA4, 0x52, 0x21
+    , 0x6E, 0x16, 0xBF, 0x26, 0x9F, 0x37, 0xE0, 0x3E, 0xF9, 0x98, 0x45, 0x00, 0x44, 0x37, 0x3E, 0xB7
+    , 0x41, 0xED, 0x1A, 0xDF, 0xEF, 0x15, 0xDB, 0x54, 0xB4, 0x26, 0x61, 0x87, 0x48, 0x9F, 0x8B, 0xD3
+    , 0x5E, 0x26, 0x59, 0xF4, 0x75, 0xCC, 0x47, 0xD0, 0xDA, 0xB8, 0x29, 0xDD, 0x15, 0xBE, 0x31, 0x34
+    , 0x8A, 0x7F, 0xDC, 0x29, 0x76, 0x94, 0x8C, 0x65, 0xC8, 0xD8, 0x4A, 0x28, 0x4E, 0x90, 0xFA, 0xB4
+    , 0x3E, 0x48, 0xD5, 0xA6, 0xCB, 0x36, 0x02, 0x30, 0xBB, 0xCA, 0xD2, 0xD0, 0x98, 0x2D, 0x6F, 0xD3
+    , 0x3F, 0xE6, 0x2B, 0x40, 0x08, 0xE3, 0x28, 0x02, 0xA3, 0x3D, 0x3F, 0xDE, 0xCB, 0xE6, 0xF9, 0xC1
+    , 0xA4, 0x7F, 0x75, 0x63, 0x48, 0x1C, 0xCA, 0xF0, 0x2D, 0x4A, 0xEF, 0x6E, 0xCE, 0x45, 0x40, 0xD2
+    , 0xC5, 0x6A, 0x0C, 0x47, 0x11, 0x02, 0x8B, 0xBC, 0xD8, 0x34, 0x80, 0x23, 0xA9, 0xD3, 0x23, 0x9B
+    , 0x72, 0xAA, 0x17, 0xAA, 0xB1, 0x56, 0x22, 0x21, 0xA3, 0xDD, 0xBB, 0x37, 0x81, 0x84, 0x39, 0xC7
+    , 0x3F, 0xEC, 0x7D, 0xB0, 0xB2, 0x79, 0x70, 0x14, 0x9A, 0xF4, 0xD2, 0x9F, 0x10, 0x01, 0xF3, 0x25
+    , 0xD5, 0x70, 0x3B, 0xD5, 0x38, 0x0C, 0x96, 0x57, 0xB4, 0x05, 0xB1, 0xD8, 0x04, 0xD7, 0x16, 0xB7
+    , 0xFA, 0x69, 0xE8, 0x44, 0x1C, 0xF5, 0xE2, 0x6C, 0x97, 0xE4, 0x51, 0xD5, 0x3D, 0x51, 0xC3, 0x07
+    , 0xF8, 0x4B, 0xD7, 0x7A, 0x4B, 0xC1, 0x27, 0x61, 0xBB, 0x46, 0xDE, 0xCE, 0x23, 0x37, 0xE7, 0x5E
+    , 0xFF, 0xEE, 0x5F, 0x35, 0x52, 0x2C, 0x43, 0xDE, 0x83, 0xC9, 0x15, 0xC2, 0x11, 0x86, 0xA9, 0x67
+    , 0x28, 0xBC, 0xB4, 0x29, 0xF9, 0x9F, 0x8D, 0x2D, 0x0B, 0xF5, 0x2A, 0x60, 0xBB, 0x48, 0x80, 0x54
+    , 0x5F, 0x95, 0xE4, 0xFC, 0x5E, 0xFA, 0x24, 0xB3, 0xCC, 0xCF, 0x1D, 0xBF, 0x2F, 0x1C, 0x47, 0x13
+    , 0x2F, 0xDE, 0xB2, 0x41, 0x1F, 0xB4, 0x40, 0xAB, 0x4B, 0xCB, 0x13, 0x13, 0x7F, 0xB2, 0x4A, 0xF3
+    , 0x77, 0x9C, 0xF4, 0x07, 0xE1, 0x1D, 0x65, 0x1D, 0xB0, 0xCE, 0x48, 0xB0, 0x38, 0xEE, 0x20, 0x95
+    , 0x2F, 0xCB, 0xFE, 0xAA, 0x88, 0xCF, 0xAF, 0x80, 0x85, 0x4F, 0xC9, 0xAD, 0x59, 0xBA, 0x0E, 0x94
+    , 0xBF, 0x64, 0xEF, 0x2D, 0x10, 0xFF, 0x9F, 0x4C, 0x82, 0x00, 0x92, 0xB9, 0x96, 0xDE, 0x1E, 0x1A
+    , 0xD0, 0x6E, 0x70, 0x07, 0x27, 0x76, 0x98, 0x11, 0xAA, 0x7E, 0x5F, 0xAC, 0x2C, 0x24, 0xA7, 0x89
+    , 0xF0, 0xF6, 0xFA, 0xE4, 0x19, 0xA3, 0xB9, 0x34, 0x8C, 0xD1, 0xA5, 0x5A, 0xFE, 0x40, 0xE5, 0xBE
+    , 0xE9, 0x21, 0x5A, 0x0F, 0x96, 0x87, 0x10, 0x73, 0xBC, 0x76, 0x92, 0x4B, 0xBB, 0xEB, 0x82, 0x3C
+    , 0xBF, 0x8B, 0xF1, 0xE9, 0xB3, 0x87, 0xDC, 0x46, 0xD5, 0x06, 0x93, 0xF9, 0xA9, 0x5C, 0xDE, 0x39
+    , 0x85, 0xA3, 0x02, 0x7C, 0x9D, 0x89, 0xC9, 0x83, 0xDB, 0x4C, 0x8F, 0x40, 0xA4, 0x2C, 0x9B, 0xE2
+    , 0xD0, 0xFD, 0x4E, 0x0B, 0xE3, 0x58, 0x40, 0x3F, 0x97, 0x0D, 0x25, 0x8F, 0x3F, 0xF6, 0x64, 0xBB
+    , 0x19, 0xBF, 0xE3, 0xF0, 0x29, 0x2F, 0xC3, 0x16, 0x75, 0x0E, 0x98, 0x8F, 0x30, 0x11, 0xF8, 0x92
+    , 0xA2, 0x2A, 0x41, 0xD5, 0x16, 0xBC, 0x3C, 0x24, 0x16, 0x8D, 0x47, 0xC9, 0x06, 0xC6, 0x70, 0x16
+    , 0x39, 0x37, 0xE2, 0x25, 0xF8, 0x98, 0xA1, 0xFB, 0x86, 0xB9, 0xD1, 0x86, 0x17, 0x49, 0xFD, 0x6F
+    , 0x8A, 0x83, 0x92, 0xB2, 0xF3, 0xDE, 0xBC, 0x44, 0x0F, 0x9F, 0x08, 0xE9, 0x88, 0x40, 0x4E, 0xD2
+    , 0x58, 0x68, 0x77, 0x89, 0xA9, 0x78, 0xBB, 0xEC, 0xA9, 0x07, 0x23, 0x3C, 0xA3, 0x12, 0x28, 0x71
+    , 0x87, 0x05, 0x86, 0x8B, 0xC7, 0x6B, 0x7E, 0x9A, 0x2D, 0xE0, 0x6D, 0x95, 0x2F, 0xDA, 0x2E, 0x33
+    , 0x42, 0x47, 0xFF, 0x41, 0x51, 0x1E, 0xB2, 0xB0, 0x07, 0xD9, 0x4D, 0x5D, 0x4F, 0xDC, 0x2F, 0xEB
+    , 0xFA, 0x56, 0xB9, 0xDA, 0x53, 0x7D, 0x75, 0x40, 0xD6, 0xA7, 0x32, 0x66, 0xFF, 0x7A, 0xB8, 0xBF
+    , 0x16, 0xB2, 0x51, 0x3D, 0x4D, 0x80, 0xFD, 0x1D, 0x11, 0x32, 0x57, 0xC9, 0x95, 0x4E, 0xAF, 0xC6
+    , 0xB0, 0x19, 0xF8, 0xC0, 0x0B, 0x1F, 0xD3, 0x92, 0xAA, 0xF0, 0xA3, 0xEE, 0x7D, 0x2D, 0xA7, 0xA4
+    , 0xB5, 0xC9, 0x45, 0x2E, 0x95, 0xF2, 0x38, 0x36, 0x49, 0x80, 0x9D, 0x9E, 0x95, 0x1D, 0x94, 0x57
+    , 0x97, 0x55, 0x0B, 0xDC, 0x03, 0xC5, 0x57, 0xB2, 0x13, 0x39, 0xB2, 0x98, 0x5B, 0xAD, 0xF6, 0xF5
+    , 0x51, 0xCD, 0xCB, 0x44, 0x54, 0xE8, 0xF7, 0xB5, 0xA4, 0xD6, 0x0F, 0xA1, 0x55, 0xB3, 0x40, 0x93
+    , 0xC6, 0xF8, 0xE1, 0x45, 0x74, 0xDA, 0x65, 0xF3, 0x8A, 0xE9, 0x57, 0xEE, 0x9E, 0x82, 0xEE, 0xEA
+    , 0x9B, 0x27, 0xE8, 0x34, 0x4E, 0x40, 0xE9, 0x99, 0x29, 0x22, 0x74, 0x92, 0x7E, 0x03, 0x8D, 0x08
+    , 0x41, 0x8E, 0x7B, 0xA4, 0xBE, 0x17, 0x2F, 0x7F, 0xC1, 0xD4, 0xED, 0x45, 0x5A, 0xB3, 0x31, 0x67
+    , 0x6D, 0x51, 0x39, 0xF4, 0x30, 0xD9, 0xFB, 0xB7, 0x87, 0xD8, 0x21, 0xB6, 0x2B, 0xAE, 0xBB, 0x76
+    , 0xBD, 0xC3, 0x4F, 0x31, 0x65, 0x63, 0x89, 0x5C, 0xFD, 0xDE, 0x36, 0xB7, 0xD3, 0xD6, 0x65, 0xC5
+    , 0xE7, 0x16, 0x1B, 0xEC, 0xF0, 0x3D, 0x47, 0x54, 0x66, 0x5E, 0xF0, 0x61, 0xB4, 0x00, 0x66, 0x13
+    , 0xD6, 0x5E, 0xBD, 0xC7, 0xC8, 0x11, 0xE1, 0x80, 0x82, 0x7C, 0x3D, 0x00, 0x23, 0xC2, 0x34, 0xA9
+    , 0x71, 0x66, 0xD7, 0x7E, 0x52, 0x45, 0x8E, 0xF2, 0xE7, 0x4B, 0x2C, 0x4A, 0x00, 0x8C, 0x28, 0xFD
+    , 0xA2, 0xFC, 0xC8, 0x72, 0xAC, 0x55, 0x25, 0xAD, 0xE6, 0x85, 0x86, 0x78, 0x8D, 0xA2, 0x47, 0xF7
+    , 0xA0, 0xCC, 0x03, 0xC0, 0xA3, 0x38, 0x7B, 0xD4, 0x7F, 0xD7, 0xE5, 0x58, 0xB4, 0x4D, 0x7B, 0xB8
+    , 0x10, 0x53, 0x0D, 0x5F, 0x15, 0x14, 0xAC, 0x4E, 0x3D, 0x80, 0x45, 0x92, 0x34, 0xDF, 0x82, 0xF2
+    , 0xCE, 0x2A, 0x25, 0x7B, 0xB7, 0x48, 0x36, 0xCF, 0xCE, 0x14, 0xCF, 0xB1, 0x82, 0xDE, 0x85, 0xAD
+    , 0x51, 0x5E, 0x0C, 0x3F, 0xE6, 0xD2, 0x4C, 0x6E, 0x40, 0x35, 0xB9, 0x07, 0x45, 0x3F, 0x23, 0x44
+    , 0x60, 0xD7, 0x78, 0x51, 0x44, 0x08, 0x43, 0x74, 0x17, 0xDD, 0x21, 0x7E, 0x04, 0xE9, 0x58, 0xF2
+    , 0x0F, 0xBB, 0x1D, 0xDB, 0xA6, 0xE6, 0x3C, 0x72, 0xF1, 0x02, 0x1A, 0x66, 0x63, 0xAF, 0x4A, 0x0A
+    , 0x7F, 0x46, 0x7C, 0x2C, 0x5B, 0xA9, 0x3A, 0x3A, 0xB3, 0x7A, 0x5F, 0xDF, 0x60, 0x49, 0xE8, 0xC0
+    , 0xC2, 0x4B, 0x81, 0xAE, 0xD6, 0xDD, 0x4A, 0x46, 0x8C, 0xEB, 0xF3, 0x10, 0x5C, 0x90, 0x9B, 0x6F
+    , 0x23, 0x1C, 0xD7, 0xAB, 0xB2, 0x70, 0x87, 0xA8, 0x80, 0xAB, 0xFF, 0xB0, 0x04, 0xAD, 0x40, 0xFE
+    , 0x41, 0x29, 0xAE, 0xE6, 0xDD, 0xF1, 0xA8, 0x69, 0xA6, 0xA4, 0xF1, 0x67, 0x65, 0x8F, 0x7F, 0xC1
+    , 0x41, 0x7E, 0xA2, 0xA0, 0xB1, 0x5D, 0x28, 0xC6, 0x04, 0x3B, 0x90, 0x0A, 0x22, 0x53, 0x16, 0x17
+    , 0x0A, 0xEF, 0xDB, 0x63, 0xEA, 0xDB, 0x40, 0x1B, 0xF9, 0x14, 0xBC, 0xCB, 0x84, 0x98, 0x3E, 0xF7
+    , 0x33, 0xEA, 0x14, 0x67, 0x52, 0x32, 0x6B, 0xAD, 0x6D, 0xE4, 0x0F, 0x62, 0x58, 0x6D, 0x8A, 0x3D
+    , 0x6C, 0x55, 0xCB, 0x30, 0xD9, 0x36, 0xE9, 0x96, 0x18, 0x4E, 0x37, 0x69, 0xC9, 0x5A, 0xCD, 0xCB
+    , 0x83, 0x22, 0x9D, 0xD5, 0xFA, 0xDC, 0xA7, 0xB7, 0x4D, 0xFC, 0x4D, 0x56, 0x70, 0xF6, 0x0F, 0xE9
+    , 0x29, 0x4C, 0xC8, 0x19, 0xA1, 0x48, 0x8A, 0x03, 0x84, 0xA4, 0x08, 0xE9, 0xA8, 0x2C, 0x48, 0xAA
+    , 0x04, 0x66, 0xCF, 0x46, 0x54, 0xC0, 0x20, 0xEA, 0x49, 0x70, 0x35, 0x7D, 0xDF, 0xA5, 0x55, 0x66
+    , 0x76, 0xE9, 0x5A, 0xE1, 0xBA, 0x24, 0xF8, 0x99, 0x46, 0x51, 0x13, 0xD9, 0x28, 0xCD, 0xC8, 0x7D
+    , 0xC5, 0x01, 0x33, 0x02, 0x9F, 0xA4, 0xFA, 0xAC, 0xB3, 0xCA, 0x79, 0xFE, 0x72, 0x40, 0x95, 0xA3
+    , 0x7D, 0x03, 0x07, 0xC9, 0x0D, 0xE2, 0x5C, 0xB1, 0xCA, 0x18, 0x12, 0x33, 0x0B, 0x95, 0x98, 0x27
+    , 0x1E, 0x55, 0x9B, 0x73, 0x8C, 0x21, 0xF1, 0x7B, 0xF5, 0x58, 0x3F, 0x9C, 0x16, 0xCB, 0xB6, 0x9D
+    , 0x60, 0xC7, 0x06, 0x78, 0x07, 0x98, 0xBF, 0xE0, 0x1D, 0x05, 0x83, 0x0D, 0xFC, 0xDA, 0xA8, 0x1A
+    , 0xAA, 0x20, 0x83, 0x65, 0xD7, 0x4E, 0x06, 0x21, 0x5B, 0x85, 0x31, 0xE1, 0x52, 0x60, 0xF9, 0xD9
+    , 0xD9, 0x25, 0x9E, 0xFE, 0xE4, 0x90, 0x89, 0x2A, 0x2B, 0x7F, 0xB8, 0xAE, 0x23, 0xB7, 0xE1, 0x7A
+    , 0x92, 0x70, 0x93, 0xC1, 0xDE, 0xF1, 0x87, 0x5B, 0x41, 0x18, 0xEA, 0xCF, 0x78, 0x2F, 0xDC, 0x3D
+    , 0xD4, 0x59, 0xFA, 0xA6, 0xD9, 0xC3, 0x58, 0x5B, 0xF0, 0x45, 0xC2, 0x18, 0xD8, 0x98, 0x83, 0x47
+    , 0x99, 0xDF, 0x12, 0x0F, 0x93, 0x4E, 0x95, 0x8B, 0x13, 0xDD, 0x16, 0x0E, 0xD4, 0x83, 0x1A, 0x14
+    , 0x07, 0x3C, 0xC9, 0x93, 0x29, 0xF2, 0xA6, 0x58, 0x87, 0xE5, 0x31, 0x78, 0x8F, 0x8A, 0x4A, 0xFF
+    , 0xF6, 0xA4, 0x4E, 0x9D, 0xA6, 0x6D, 0xC0, 0xAA, 0x54, 0xE1, 0x11, 0x73, 0x8F, 0xB0, 0x6B, 0xEF
+    , 0x39, 0xD9, 0x14, 0xA2, 0xFD, 0xBE, 0x40, 0x29, 0x00, 0x39, 0x3B, 0xEF, 0xA7, 0xA3, 0x92, 0x64
+    , 0xF4, 0x67, 0xF2, 0xA3, 0xF5, 0x8C, 0x36, 0x21, 0x8E, 0x3F, 0xA6, 0x29, 0xE8, 0x92, 0xC5, 0x55
+    , 0xFF, 0x36, 0x7D, 0x05, 0x6E, 0x4A, 0x0C, 0x51, 0x30, 0x94, 0x2C, 0x74, 0xE9, 0xB9, 0xD2, 0x34
+    , 0x36, 0xAC, 0x88, 0xF3, 0x4B, 0xBD, 0x31, 0xCF, 0xB1, 0x9D, 0x0F, 0x85, 0xC6, 0x5A, 0xAD, 0xB1
+    , 0xD2, 0xCB, 0x87, 0x6C, 0x52, 0x87, 0x77, 0x17, 0x1E, 0xEE, 0x6E, 0x11, 0xE9, 0xA6, 0x24, 0x36
+    , 0xD4, 0x60, 0x14, 0xD7, 0xCD, 0xAE, 0x07, 0xAA, 0xAE, 0xB0, 0x0C, 0xF0, 0x6C, 0x83, 0xEF, 0xEB
+    , 0xA2, 0xD1, 0xF1, 0x19, 0x4C, 0x21, 0xA3, 0x17, 0x10, 0xCB, 0x59, 0x49, 0x91, 0x0F, 0x30, 0x09
+    , 0x4F, 0xC5, 0x5C, 0x11, 0x53, 0x87, 0x69, 0xC4, 0x06, 0x5D, 0xA8, 0x06, 0x55, 0xD0, 0x84, 0xA3
+    , 0x19, 0xBC, 0x86, 0x4B, 0xE5, 0xF2, 0x81, 0xF0, 0x74, 0x2B, 0x79, 0xB2, 0xCD, 0x1B, 0xA3, 0xBF
+    , 0x5D, 0xDC, 0x71, 0xFC, 0xF3, 0xEC, 0x8B, 0x11, 0x94, 0xD3, 0x93, 0x6D, 0xE3, 0x27, 0xF8, 0x31
+    , 0xCE, 0x1A, 0xBE, 0x2E, 0xE6, 0x2D, 0x8A, 0xFC, 0x85, 0x82, 0xE9, 0xEC, 0xF5, 0xD8, 0xE4, 0x7F
+    , 0x3C, 0x87, 0x51, 0x97, 0x9F, 0x29, 0xD2, 0xE3, 0x24, 0x14, 0x87, 0x3B, 0x7F, 0x4D, 0x24, 0xB7
+    , 0x44, 0xEC, 0x1E, 0x2D, 0xAD, 0x87, 0x0D, 0x73, 0xB2, 0x68, 0x20, 0x09, 0xAF, 0x02, 0xF1, 0x58
+    , 0x49, 0x77, 0x23, 0xBA, 0xD4, 0xB3, 0x72, 0xA9, 0xED, 0x95, 0x36, 0xEC, 0x32, 0x79, 0xA8, 0x70
+    , 0x27, 0x8A, 0x3B, 0x1C, 0x68, 0x07, 0x8E, 0xA5, 0xB8, 0xE3, 0x81, 0x57, 0xA4, 0x0A, 0x07, 0xEA
+    , 0x4E, 0x44, 0x5F, 0x5E, 0x9D, 0xDF, 0x20, 0xA8, 0x5D, 0xD5, 0xBE, 0xED, 0xEA, 0xF9, 0x23, 0x31
+    , 0x93, 0xF6, 0x34, 0xC8, 0x5B, 0xA5, 0x46, 0x25, 0xCD, 0xDD, 0x31, 0xCB, 0x9A, 0xAA, 0x0C, 0xD1
+    , 0x6D, 0x5A, 0xB3, 0x65, 0x3C, 0xE0, 0x80, 0x67, 0xE8, 0x5C, 0x76, 0xCF, 0x36, 0x7F, 0xF0, 0x3B
+    , 0xB9, 0x0F, 0xE8, 0x56, 0xCA, 0xDA, 0xDE, 0x47, 0xD2, 0x88, 0x90, 0xAC, 0xE8, 0x92, 0x22, 0x8A
+    , 0x61, 0x1A, 0xFE, 0x21, 0x41, 0x6C, 0x25, 0x69, 0xDE, 0xD8, 0x33, 0xDF, 0x2A, 0xC4, 0xB4, 0xFC
+    , 0x50, 0x56, 0x78, 0xCE, 0xE9, 0x6C, 0xEA, 0xBF, 0xEE, 0x50, 0xED, 0xC7, 0x96, 0xD9, 0x88, 0xD4
+    , 0x83, 0xCB, 0x93, 0xFB, 0x7D, 0x3B, 0x04, 0xAC, 0x96, 0x7A, 0xAB, 0xFC, 0x2F, 0xCE, 0xD1, 0x68
+    , 0xF0, 0x91, 0x87, 0xE0, 0x15, 0x93, 0xF7, 0x3A, 0x8D, 0xAB, 0xAD, 0xD8, 0x7F, 0x42, 0x76, 0xA4
+    , 0x12, 0xD2, 0x54, 0x31, 0xB5, 0x79, 0xC1, 0xA1, 0xED, 0x6A, 0x38, 0x65, 0x8B, 0xDF, 0x6D, 0xD7
+    , 0x48, 0x2C, 0xA4, 0x62, 0x9E, 0x1F, 0x0A, 0x3F, 0xB2, 0xB4, 0x1F, 0x92, 0xB7, 0xF9, 0x5A, 0x93
+    , 0xF0, 0x1B, 0x67, 0x04, 0x60, 0x3A, 0x79, 0x01, 0x76, 0x40, 0xEE, 0x80, 0xF5, 0x19, 0x52, 0x2D
+    , 0xA3, 0xE4, 0xCA, 0xEC, 0x4F, 0x4B, 0x09, 0x2C, 0xE2, 0x86, 0xD7, 0x6F, 0x35, 0x07, 0xC9, 0x77
+    , 0xE6, 0x94, 0x65, 0xA4, 0x3A, 0xC1, 0xDD, 0xAF, 0x14, 0x80, 0x2D, 0xAD, 0x6B, 0xBC, 0x33, 0x5E
+    , 0xE9, 0x80, 0x3B, 0xF3, 0xCA, 0x89, 0xCD, 0x39, 0xA9, 0xC4, 0xA7, 0x50, 0xE9, 0x40, 0x10, 0x12
+    , 0x63, 0x17, 0xD0, 0xD0, 0x17, 0x9E, 0x7B, 0x7C, 0x50, 0x56, 0x27, 0x7B, 0x87, 0xEC, 0x90, 0x67
+    , 0xF2, 0xF2, 0x67, 0x5F, 0x49, 0x5A, 0xAB, 0x2E, 0x80, 0xC1, 0xC9, 0x32, 0x19, 0xA4, 0xFC, 0x19
+    , 0x59, 0x32, 0xFA, 0xE9, 0xA8, 0x99, 0xD7, 0x8C, 0x7A, 0x4E, 0x07, 0xCE, 0x7F, 0x16, 0x59, 0x47
+    , 0x90, 0x4E, 0xEE, 0x8B, 0xFF, 0xBA, 0xE3, 0xB8, 0x3F, 0x02, 0xE8, 0xC4, 0x4A, 0x50, 0xBC, 0x2F
+    , 0xC0, 0x95, 0x8D, 0xFE, 0xAF, 0xEB, 0x74, 0xF1, 0x42, 0x59, 0x20, 0x51, 0xA6, 0xAC, 0x49, 0xFF
+    , 0x68, 0x47, 0x00, 0x04, 0x55, 0x93, 0xCD, 0x85, 0x7B, 0xE5, 0xD6, 0x8C, 0x3B, 0xEB, 0x66, 0x62
+    , 0xB4, 0xD8, 0x67, 0x20, 0xCA, 0x11, 0x60, 0xE7, 0x71, 0xFC, 0xB4, 0x4E, 0x84, 0x94, 0x49, 0xE8
+    , 0x4E, 0xE5, 0x84, 0x9F, 0x2A, 0x70, 0x1D, 0xF1, 0xD1, 0x4A, 0x9C, 0x5E, 0xDF, 0xF3, 0xA7, 0x50
+    , 0x0B, 0x35, 0xF2, 0xC4, 0x1E, 0x8A, 0x9F, 0xD5, 0x7B, 0x16, 0xFA, 0x98, 0x71, 0x55, 0x6C, 0xC4
+    , 0x4C, 0x17, 0x5E, 0xD4, 0x73, 0x2C, 0xA0, 0x4C, 0x14, 0xB8, 0x48, 0x51, 0x3F, 0xBF, 0x57, 0x30
+    , 0x9D, 0x96, 0x11, 0x80, 0x40, 0x71, 0x3D, 0x17, 0x7D, 0x7E, 0xF3, 0xE6, 0xF3, 0x1D, 0x00, 0x73
+    , 0x70, 0x35, 0x5B, 0x98, 0x02, 0xF0, 0x90, 0x9A, 0x20, 0x2D, 0x15, 0xE9, 0x14, 0x0E, 0x5A, 0x12
+    , 0x00, 0x08, 0x27, 0xDF, 0x4D, 0x10, 0x52, 0xF2, 0x08, 0xF5, 0x94, 0x28, 0xED, 0x2E, 0x97, 0x07
+    , 0x0D, 0xAE, 0xED, 0x83, 0xBC, 0x58, 0x6A, 0xFA, 0x54, 0xEA, 0x48, 0xDB, 0x97, 0xB8, 0xAA, 0x22
+    , 0xA2, 0x07, 0xC6, 0x01, 0x7D, 0x55, 0x76, 0x1F, 0x9D, 0x21, 0x20, 0xF4, 0xF8, 0xF0, 0xA5, 0xF0
+    , 0x5F, 0xB9, 0xAF, 0x7A, 0x79, 0xEB, 0x3E, 0x28, 0xCC, 0xD2, 0x20, 0x04, 0x2E, 0x1D, 0xF4, 0xD4
+    , 0x1F, 0xFB, 0xC0, 0x93, 0xF9, 0x53, 0x32, 0xD0, 0x2F, 0x91, 0x78, 0x37, 0x59, 0x2E, 0x52, 0x2F
+    , 0x50, 0x9B, 0xAE, 0x03, 0xC3, 0xEE, 0x80, 0xEE, 0xB2, 0x09, 0x86, 0x3D, 0x9C, 0xCF, 0xC4, 0xC3
+    , 0xC9, 0x22, 0x41, 0x39, 0xC8, 0x8E, 0xA6, 0x48, 0x1E, 0x68, 0xD1, 0xC7, 0xB3, 0xA4, 0xCE, 0x3E
+    , 0xC4, 0xEB, 0xAF, 0x09, 0xDD, 0x5B, 0xD0, 0xAC, 0x89, 0xE8, 0x8C, 0x66, 0x8C, 0x98, 0x23, 0xF6
+    , 0x68, 0x36, 0xDB, 0x19, 0x86, 0x01, 0x70, 0x25, 0x7E, 0x70, 0x99, 0xF1, 0x62, 0x2D, 0x95, 0x4D
+    , 0x36, 0x5E, 0x06, 0x2F, 0xBE, 0x3F, 0xAC, 0xC7, 0x35, 0x0A, 0xBE, 0x1A, 0x59, 0x6C, 0x81, 0x5F
+    , 0xE5, 0x4D, 0xAA, 0x28, 0xC8, 0x69, 0x1F, 0x87, 0x52, 0xF3, 0x38, 0x99, 0x3D, 0x58, 0xCE, 0xD8
+    , 0xF2, 0x19, 0xA8, 0xE0, 0x8B, 0xD4, 0xF5, 0xD3, 0x67, 0x6B, 0xF4, 0x3A, 0x19, 0x24, 0xB4, 0xAD
+    , 0x0C, 0x1D, 0xC2, 0x89, 0x33, 0xC7, 0x6E, 0x6F, 0x07, 0x06, 0xAB, 0xB5, 0x28, 0x36, 0xDA, 0xE0
+    , 0x02, 0x7B, 0xCE, 0x66, 0x1D, 0xB8, 0x83, 0xBD, 0x80, 0x9B, 0xEA, 0x11, 0x7E, 0x68, 0x2A, 0x51
+    , 0xA8, 0x1F, 0x14, 0x2D, 0x04, 0xE1, 0x77, 0x2A, 0xB6, 0x98, 0xF0, 0x8C, 0xD0, 0x5F, 0x9C, 0x00
+    , 0x80, 0x8E, 0x46, 0x85, 0x17, 0x27, 0x89, 0x63, 0xB2, 0x1E, 0xB2, 0xEB, 0x01, 0x5A, 0x75, 0xDE
+    , 0x9F, 0x3F, 0xEC, 0x77, 0x70, 0x71, 0xA1, 0xE5, 0xC4, 0xC1, 0xFB, 0x89, 0x2E, 0x92, 0x29, 0xF2
+    , 0x2A, 0x6D, 0x48, 0x8B, 0x17, 0x4B, 0xAA, 0x4D, 0x23, 0x1D, 0x38, 0x3A, 0xD5, 0x41, 0x62, 0xBF
+    , 0xA9, 0x7B, 0x3E, 0x73, 0x08, 0xC2, 0x87, 0x00, 0xD5, 0x0F, 0x2A, 0x34, 0xCA, 0xA3, 0x59, 0x9B
+    , 0x7C, 0x46, 0x1D, 0x59, 0xFB, 0xAC, 0x86, 0x2D, 0x6A, 0x77, 0x05, 0x9A, 0xD7, 0x28, 0xB6, 0xD5
+    , 0xC3, 0xFA, 0x0E, 0x46, 0x91, 0xE7, 0xEF, 0xD6, 0xCC, 0x1B, 0x72, 0x94, 0x05, 0x00, 0xB9, 0x8D
+    , 0xE6, 0x85, 0x22, 0x99, 0xB5, 0x94, 0x0C, 0x05, 0x6A, 0xEC, 0x82, 0x02, 0x0B, 0xE4, 0x44, 0xB9
+    , 0xDF, 0x10, 0x95, 0xC7, 0x5C, 0xF9, 0x8B, 0x35, 0xF1, 0x87, 0xF6, 0xDA, 0x3E, 0xD6, 0x83, 0x64
+    , 0xDE, 0x57, 0x7C, 0xF3, 0xDB, 0xF1, 0xE5, 0xE8, 0xD6, 0x43, 0xF3, 0x6E, 0xED, 0x3F, 0xC0, 0x13
+    , 0x9F, 0x1D, 0x8E, 0x71, 0x20, 0xD1, 0x22, 0x99, 0x0B, 0x3E, 0x6A, 0x69, 0x1B, 0xFF, 0x3F, 0xD3
+    , 0x31, 0xA9, 0x24, 0xBA, 0xAA, 0xA1, 0x0B, 0x68, 0xE1, 0x42, 0x04, 0xED, 0x9B, 0x6B, 0x0D, 0xD1
+    , 0xCF, 0xC0, 0x79, 0x99, 0xCE, 0x8C, 0x42, 0x9E, 0x22, 0x32, 0xAF, 0x72, 0x65, 0x76, 0xDC, 0xA5
+    , 0x3F, 0xE1, 0xC7, 0x39, 0xCB, 0xAF, 0xE2, 0xC8, 0x14, 0x3C, 0x41, 0xFE, 0x6F, 0x47, 0xE7, 0x0E
+    , 0x85, 0xD9, 0x3A, 0x09, 0x7E, 0x6B, 0x53, 0x6A, 0xD7, 0xB2, 0xDF, 0x5D, 0xE2, 0x81, 0x29, 0x1A
+    , 0xCF, 0x10, 0x86, 0xE2, 0x53, 0x3C, 0x7A, 0x69, 0xE5, 0x62, 0x38, 0x2B, 0x0F, 0x9E, 0x79, 0x40
+    , 0x99, 0x3A, 0x16, 0x8E, 0xE6, 0x68, 0xF0, 0x61, 0xAC, 0x11, 0x45, 0xC2, 0x1D, 0x9E, 0x53, 0x79
+    , 0x07, 0xD9, 0xCD, 0x58, 0xDF, 0x76, 0xAD, 0xA5, 0xF4, 0xB7, 0xEE, 0x3E, 0x7A, 0xB2, 0xC2, 0x32
+    , 0x76, 0xDB, 0x15, 0xD6, 0x6B, 0x20, 0xF1, 0xA2, 0xDB, 0x00, 0x0C, 0xC8, 0xA7, 0xA5, 0xD9, 0x9A
+    , 0x68, 0xF5, 0xF7, 0x7F, 0x47, 0xB4, 0x73, 0x0D, 0x37, 0x05, 0xA5, 0x77, 0xE3, 0x69, 0x5F, 0x0A
+    , 0xFA, 0x94, 0x3D, 0xCD, 0x33, 0xBF, 0x55, 0xDE, 0xAD, 0x03, 0x6E, 0x3E, 0x13, 0x8E, 0x95, 0x71
+    , 0xD4, 0xCC, 0xC2, 0x30, 0x85, 0x64, 0xED, 0x96, 0xFC, 0xF0, 0x4E, 0x11, 0x3E, 0x74, 0xA9, 0xD8
+    , 0x2C, 0xBB, 0x5D, 0xAD, 0x49, 0xE1, 0x10, 0x31, 0xD1, 0x95, 0xFC, 0x77, 0x27, 0x8A, 0x4F, 0x51
+    , 0x5F, 0x61, 0x5D, 0x45, 0x2D, 0xE3, 0x98, 0x64, 0x43, 0xA3, 0x51, 0xBB, 0x48, 0x1F, 0x42, 0xFF
+    , 0xFB, 0x3A, 0x6A, 0x52, 0xE5, 0x90, 0xD0, 0x32, 0xC8, 0x56, 0x5B, 0x50, 0xC5, 0x94, 0x9E, 0xF4
+    , 0x80, 0xAA, 0x5B, 0x6D, 0x52, 0x79, 0x65, 0x87, 0x42, 0x69, 0x22, 0xE2, 0x13, 0x44, 0x6C, 0x07
+    , 0xC0, 0x13, 0xC7, 0xE2, 0xC9, 0xD6, 0x7C, 0x68, 0xB2, 0xCC, 0x12, 0x7D, 0x19, 0xC6, 0x69, 0xCC
+    , 0x8C, 0x96, 0xF7, 0x49, 0x4C, 0x34, 0x9F, 0xBA, 0x46, 0x5D, 0xDF, 0x17, 0xA5, 0x6A, 0x42, 0xA2
+    , 0xD1, 0x17, 0x04, 0xD6, 0x66, 0x39, 0xAD, 0x0D, 0x64, 0xD9, 0x21, 0xDD, 0x3B, 0x0E, 0xEA, 0x43
+    , 0xA9, 0x02, 0x29, 0x15, 0x7E, 0xC3, 0x11, 0xA9, 0xC4, 0x0A, 0x55, 0x8E, 0x0B, 0xEF, 0xAE, 0x1E
+    , 0x54, 0x56, 0x82, 0x3D, 0x88, 0xFB, 0x60, 0x1A, 0x6C, 0xF4, 0x98, 0x82, 0xD6, 0xAF, 0xBB, 0x39
+    , 0x65, 0xDC, 0x9D, 0xD6, 0x4B, 0xA1, 0xE3, 0xFB, 0x49, 0x58, 0x41, 0x33, 0x25, 0x52, 0x9F, 0x84
+    , 0xA1, 0x43, 0x1C, 0x48, 0x87, 0x09, 0xFF, 0x7E, 0x89, 0x25, 0x54, 0x9E, 0x30, 0x68, 0x26, 0x4C
+    , 0xC7, 0xCE, 0x5F, 0xB5, 0xFB, 0x7F, 0x9B, 0xEB, 0xB0, 0xCF, 0x25, 0x78, 0x97, 0x96, 0x9D, 0xB9
+    , 0x00, 0xD4, 0x29, 0x6E, 0x92, 0x3D, 0x18, 0xE5, 0x56, 0xE9, 0x55, 0x14, 0x6B, 0xFA, 0xD8, 0xF2
+    , 0xE8, 0x4A, 0x8D, 0x5C, 0xBD, 0x27, 0x1D, 0x02, 0x78, 0x64, 0xE7, 0x85, 0x4A, 0x10, 0x0C, 0x27
+    , 0xC0, 0xCE, 0xF6, 0xF3, 0x74, 0x57, 0x5C, 0x83, 0xA3, 0x27, 0x46, 0xE6, 0xB3, 0x00, 0x04, 0xCF
+    , 0xBE, 0x64, 0x0A, 0xDE, 0xD0, 0xFB, 0xB6, 0x11, 0x71, 0x54, 0xCB, 0x7D, 0x30, 0x2F, 0x25, 0xBD
+    , 0xD9, 0x7B, 0x00, 0xB4, 0x75, 0x5D, 0xEC, 0xA9, 0x81, 0xC3, 0x75, 0x16, 0x6C, 0xC6, 0xDD, 0xA2
+    , 0x30, 0xF6, 0xD7, 0x64, 0xB4, 0x87, 0x09, 0x0E, 0x7C, 0xEF, 0x9C, 0xB9, 0xF4, 0xCE, 0x35, 0xF5
+    , 0xB8, 0x4D, 0x06, 0x18, 0x5D, 0x2A, 0xBB, 0x67, 0xC2, 0xCB, 0xA6, 0x40, 0xD3, 0xFE, 0x7B, 0xCD
+    , 0x19, 0x33, 0x08, 0x75, 0x38, 0xE5, 0x77, 0x09, 0x36, 0xAF, 0x85, 0x4D, 0xAC, 0xB7, 0xE0, 0xFC
+    , 0x04, 0x16, 0xE6, 0x86, 0x2E, 0x49, 0x3E, 0x9F, 0x70, 0xC0, 0x35, 0xF8, 0x86, 0x88, 0x7F, 0xA8
+    , 0x10, 0x36, 0x7D, 0xB0, 0xA2, 0xC7, 0x61, 0x81, 0xAA, 0x28, 0x48, 0x1D, 0xBF, 0xD3, 0x13, 0x29
+    , 0x73, 0x8F, 0x5B, 0x4E, 0x5D, 0x71, 0x62, 0xAC, 0xD3, 0x8D, 0x41, 0xE5, 0x90, 0x7A, 0xFE, 0x83
+    , 0x06, 0x6C, 0x38, 0x51, 0xEE, 0x5E, 0xBE, 0x9B, 0x97, 0xF2, 0x0A, 0xCC, 0xAD, 0xBD, 0x37, 0x53
+    , 0x1C, 0x9F, 0x28, 0x87, 0xF8, 0x89, 0x5C, 0xB0, 0x23, 0x41, 0xA8, 0x59, 0x97, 0xC9, 0x01, 0x88
+    , 0x5B, 0xA4, 0x7B, 0xBA, 0xAC, 0x33, 0xFC, 0x55, 0xC7, 0x24, 0x12, 0xB8, 0xFC, 0x5C, 0x9F, 0xE3
+    , 0xFD, 0x14, 0x41, 0x6B, 0x9F, 0x49, 0x3C, 0x5D, 0xE5, 0x8E, 0xBD, 0x8D, 0x9E, 0x38, 0x1F, 0x34
+    , 0xEA, 0xAB, 0x88, 0x13, 0xA0, 0x53, 0x4B, 0xB1, 0x91, 0xE7, 0x12, 0x9C, 0x56, 0x1E, 0xD9, 0x47
+    , 0x92, 0x9C, 0x44, 0xE9, 0xC6, 0x82, 0xDC, 0x77, 0xB7, 0xC9, 0x7E, 0xF7, 0xF1, 0x23, 0xF2, 0xCE
+    , 0xA8, 0x7B, 0x4A, 0x3B, 0x55, 0x29, 0x79, 0xBA, 0xBD, 0x1E, 0x9A, 0x22, 0x8F, 0xB1, 0x11, 0xDB
+    , 0x81, 0x70, 0x7D, 0xCC, 0xA3, 0x06, 0x6B, 0x75, 0xF9, 0xDE, 0xBB, 0xD7, 0xF2, 0x45, 0x9C, 0x94
+    , 0x32, 0xB2, 0xA4, 0x83, 0x3C, 0xCA, 0x8B, 0xEC, 0xB0, 0xD1, 0xDE, 0x93, 0x35, 0xDF, 0xD0, 0xFC
+    , 0xDC, 0x0A, 0x4E, 0x08, 0x31, 0x10, 0x9E, 0x12, 0x4F, 0x78, 0xED, 0x47, 0x8C, 0x94, 0x11, 0x29
+    , 0x76, 0x7F, 0x72, 0x50, 0x25, 0xE6, 0xAB, 0x73, 0x6B, 0xCC, 0x26, 0x46, 0xD7, 0xCA, 0x56, 0x48
+    , 0x54, 0xCF, 0xD8, 0xE4, 0x93, 0x4A, 0x89, 0xCD, 0x13, 0xCB, 0x95, 0x9B, 0x3F, 0x32, 0x54, 0x18
+    , 0xB7, 0x0D, 0xA1, 0x44, 0x97, 0x1D, 0x66, 0x22, 0x4E, 0x91, 0xE2, 0xB0, 0x6C, 0x76, 0x2C, 0x5F
+    , 0xA0, 0xDB, 0x00, 0x56, 0x0E, 0x9D, 0x6E, 0xDC, 0x92, 0xA9, 0x79, 0x06, 0x04, 0x2E, 0xC8, 0x3C
+    , 0x7D, 0x63, 0xA0, 0x0E, 0xFF, 0x3C, 0x96, 0x9D, 0x36, 0x74, 0x0F, 0x5A, 0xA2, 0xFD, 0x8B, 0xBE
+    , 0x50, 0x76, 0xB1, 0x48, 0x77, 0x2B, 0xE1, 0xAE, 0x0E, 0xBB, 0x0F, 0x92, 0x3D, 0xBC, 0xD8, 0x97
+    , 0x9D, 0x0B, 0x99, 0x8E, 0x04, 0x9E, 0x0A, 0x85, 0x3A, 0xCA, 0x05, 0xE8, 0xF6, 0xC2, 0x24, 0x70
+    , 0xCF, 0x5C, 0xAD, 0x11, 0x19, 0xC6, 0xCA, 0x70, 0xAF, 0x38, 0x1D, 0x2B, 0xD0, 0x27, 0xC4, 0x44
+    , 0xE9, 0xB9, 0x9B, 0x41, 0xBA, 0x9E, 0x72, 0x63, 0x67, 0x3D, 0xD5, 0xB4, 0xEC, 0x86, 0xED, 0xF5
+    , 0x77, 0xFA, 0xCB, 0xDB, 0xAB, 0xAD, 0xCA, 0x1E, 0x19, 0xFD, 0x03, 0xA2, 0x81, 0x59, 0x26, 0x2B
+    , 0xA8, 0x9B, 0x20, 0xAF, 0x66, 0x95, 0xDC, 0x67, 0x11, 0xF8, 0xB5, 0x85, 0x05, 0x26, 0x11, 0x53
+    , 0x05, 0x90, 0x71, 0x27, 0xA1, 0x52, 0xAF, 0x0D, 0x00, 0x60, 0xFB, 0x20, 0x85, 0x6D, 0x54, 0xF1
+    , 0x99, 0xF7, 0xF8, 0x03, 0x40, 0xE7, 0xF5, 0xE3, 0x2B, 0x4E, 0x18, 0x56, 0x81, 0x2C, 0xD9, 0x34
+    , 0x17, 0x5A, 0x61, 0xF2, 0x9F, 0xE2, 0x2C, 0xAA, 0xA6, 0x9F, 0x08, 0xF6, 0xCD, 0xE7, 0x62, 0x7C
+    , 0xEC, 0xA6, 0x86, 0x6F, 0x85, 0xBF, 0xAD, 0xB1, 0x7A, 0xBF, 0x0C, 0xC4, 0xBE, 0x13, 0x06, 0x1A
+    , 0x0D, 0xE7, 0x55, 0xE7, 0xCF, 0xF1, 0xB1, 0x16, 0xDE, 0x8B, 0xCE, 0x55, 0x69, 0x8E, 0x50, 0x1B
+    , 0x34, 0x01, 0x06, 0xA1, 0xD2, 0x5B, 0xE8, 0x8B, 0x37, 0x40, 0x2D, 0x3D, 0x0A, 0x86, 0x28, 0x53
+    , 0x19, 0x75, 0xB3, 0x86, 0x10, 0x84, 0x91, 0x7C, 0xC0, 0x91, 0x98, 0x08, 0x18, 0xE8, 0x01, 0x53
+    , 0xBD, 0xE2, 0xAD, 0xC5, 0x02, 0xE1, 0xF7, 0x2A, 0x9C, 0xE5, 0x8A, 0xCC, 0x80, 0xBD, 0x26, 0x63
+    , 0x02, 0x62, 0xEE, 0x36, 0xD2, 0x47, 0x81, 0xFB, 0x1D, 0x79, 0xD2, 0xDF, 0x53, 0xDA, 0xD0, 0xC7
+    , 0x5A, 0xDC, 0xE1, 0x18, 0x80, 0x00, 0x09, 0xE0, 0xAA, 0x85, 0xAE, 0x54, 0xA1, 0xB3, 0x22, 0x96
+    , 0x0C, 0x79, 0x4E, 0xA1, 0xD8, 0x95, 0x94, 0xA4, 0xD8, 0x49, 0x55, 0x81, 0x41, 0xA4, 0x86, 0x6D
+    , 0x3E, 0x32, 0x3E, 0x50, 0xFD, 0xDD, 0x74, 0x1F, 0x4E, 0xB6, 0xF6, 0x6C, 0x56, 0x1A, 0x8D, 0xCC
+    , 0x81, 0xA0, 0xC7, 0x1C, 0x52, 0xF8, 0x50, 0x9C, 0x0D, 0xC4, 0x70, 0xE3, 0x0E, 0xC5, 0x9C, 0xDC
+    , 0x3B, 0x92, 0xFA, 0xD1, 0x60, 0x83, 0xD4, 0xE2, 0xB0, 0x84, 0x84, 0xF6, 0xDD, 0xAC, 0x44, 0x4A
+    , 0x98, 0xD9, 0x30, 0x95, 0x7A, 0xEF, 0x6B, 0x47, 0x51, 0x0C, 0x44, 0x54, 0x3D, 0x83, 0x26, 0x9A
+    , 0x99, 0x19, 0x0A, 0x2C, 0xF9, 0xFE, 0xD7, 0x8F, 0x6C, 0xE9, 0x79, 0xAD, 0x7A, 0x1B, 0x2F, 0x92
+    , 0x20, 0xA0, 0xCA, 0x11, 0x61, 0x18, 0x94, 0x4E, 0x4C, 0xD2, 0x05, 0x3D, 0x65, 0x08, 0xDE, 0xF2
+    , 0x5D, 0x49, 0x61, 0xDE, 0x13, 0x71, 0x11, 0xCF, 0x89, 0x27, 0xD1, 0xCD, 0x2D, 0xE7, 0x4A, 0x70
+    , 0x0F, 0x89, 0x56, 0x08, 0x93, 0xA1, 0x1C, 0x0B, 0xE1, 0x2A, 0xBD, 0xF6, 0x7E, 0xEF, 0x9F, 0xD8
+    , 0x19, 0xB1, 0x78, 0x87, 0x88, 0xE8, 0x91, 0xCC, 0xB5, 0x73, 0x8F, 0x48, 0xDC, 0x91, 0xA1, 0xD0
+    , 0xEB, 0xCC, 0x36, 0xBA, 0x3D, 0x7E, 0x3F, 0xC2, 0xF7, 0x7F, 0xB1, 0x54, 0x4D, 0xA9, 0x9E, 0xD9
+    , 0xC1, 0xB8, 0x61, 0x2D, 0x35, 0x6C, 0x05, 0x12, 0x26, 0xBF, 0x71, 0x90, 0xAF, 0x0D, 0xF2, 0x42
+    , 0x95, 0x67, 0x8D, 0x84, 0x95, 0x8D, 0x88, 0x47, 0xF2, 0x9A, 0x80, 0xAF, 0x27, 0x71, 0x7A, 0x14
+    , 0x47, 0x41, 0xF8, 0xD9, 0xD2, 0x76, 0x4A, 0x6D, 0x3B, 0x90, 0xF8, 0x95, 0x5E, 0xBC, 0x81, 0x66
+    , 0x17, 0x74, 0x03, 0xBD, 0x1B, 0x56, 0x81, 0x8E, 0x58, 0x75, 0x5E, 0x96, 0x3E, 0xCC, 0x97, 0x87
+    , 0xD2, 0x84, 0x65, 0x76, 0xC7, 0xE1, 0x0D, 0xCB, 0xF5, 0x25, 0x18, 0xB7, 0xC2, 0x70, 0x03, 0xA0
+    , 0xA9, 0xC5, 0x86, 0x79, 0x17, 0x2C, 0xB6, 0x45, 0xC4, 0xF7, 0x3F, 0x08, 0x70, 0xD7, 0x46, 0xDF
+    , 0x1A, 0xED, 0xAC, 0xAE, 0x2E, 0xA7, 0x31, 0x9E, 0xD4, 0x56, 0xC0, 0x98, 0x23, 0x95, 0xDA, 0x61
+    , 0x28, 0x05, 0x0F, 0xF7, 0xB5, 0x62, 0x44, 0x81, 0x3B, 0x7D, 0xAB, 0x73, 0x83, 0xDB, 0xF1, 0xED
+    , 0x3D, 0x26, 0xB1, 0x22, 0x4A, 0x98, 0x08, 0xBB, 0xD2, 0x21, 0x5A, 0x5B, 0x7B, 0xA1, 0xEB, 0xEF
+    , 0x47, 0xD9, 0x92, 0x65, 0x45, 0x97, 0xE7, 0xE4, 0x89, 0x02, 0xFD, 0x62, 0x75, 0x08, 0x32, 0x2E
+    , 0x45, 0xE9, 0x8B, 0x17, 0xFD, 0x43, 0xC8, 0x6B, 0x5C, 0x12, 0x38, 0x0F, 0x5A, 0x55, 0x84, 0x85
+    , 0x42, 0xD4, 0x71, 0xE1, 0xFF, 0xAF, 0x59, 0xC4, 0xED, 0xB2, 0xCD, 0x1A, 0xD9, 0x45, 0x7C, 0x94
+    , 0x8A, 0x5B, 0x89, 0x31, 0x25, 0x41, 0xC5, 0x54, 0xE2, 0xE2, 0xCD, 0x99, 0xFF, 0x38, 0x89, 0xDF
+    , 0xDD, 0x1B, 0xC1, 0xFC, 0xB8, 0x06, 0x4C, 0xFA, 0x8C, 0xF2, 0xDA, 0xE4, 0x22, 0x73, 0x1A, 0xA3
+    , 0x53, 0x1D, 0x97, 0xCF, 0x21, 0x90, 0x42, 0xA4, 0x56, 0x17, 0x07, 0xF3, 0x3F, 0xA3, 0x1F, 0x10
+    , 0x8A, 0x28, 0x57, 0x1C, 0x81, 0xC0, 0xEC, 0x2C, 0x7B, 0x1C, 0xFC, 0xE8, 0x13, 0xF1, 0xAB, 0x59
+    , 0xA3, 0x6D, 0x0F, 0x65, 0xBD, 0x20, 0x01, 0x23, 0xA1, 0x08, 0x5E, 0x50, 0x37, 0xE0, 0x8B, 0x7D
+    , 0x16, 0x26, 0x36, 0xE9, 0x7D, 0xC0, 0x08, 0xA1, 0xDB, 0xBF, 0xB4, 0x85, 0x4B, 0xF8, 0xE8, 0x6A
+    , 0x73, 0xBD, 0x9C, 0x16, 0x47, 0xC0, 0x5A, 0x1C, 0x9E, 0xAD, 0x4F, 0xB2, 0x7C, 0x1B, 0x72, 0x12
+    , 0xB0, 0xB5, 0x41, 0x5F, 0xAB, 0x93, 0x5B, 0xF5, 0x1A, 0x23, 0xEE, 0x9B, 0x1A, 0x1E, 0x43, 0x39
+    , 0xC2, 0xBD, 0x9B, 0xAA, 0xEF, 0xE9, 0x26, 0xA6, 0xFE, 0xC1, 0x24, 0x24, 0xBF, 0xFB, 0xFC, 0x30
+    , 0x32, 0x51, 0x30, 0x7C, 0x17, 0x3B, 0xC0, 0x81, 0xA6, 0xB3, 0x38, 0x03, 0xD9, 0x6B, 0x49, 0x43
+    , 0xFB, 0x2E, 0x13, 0x99, 0x47, 0x19, 0xD8, 0x89, 0x59, 0xEB, 0x00, 0x44, 0x04, 0xA4, 0xC3, 0xA5
+    , 0x34, 0x00, 0x6B, 0x7F, 0x91, 0x09, 0xB8, 0x2C, 0xCE, 0x09, 0xF0, 0xE1, 0x5A, 0x3F, 0x3A, 0xE2
+    , 0x61, 0xE3, 0x67, 0x36, 0x80, 0xB5, 0x47, 0x35, 0x8E, 0x27, 0x1E, 0x71, 0x5E, 0xE9, 0x59, 0xE6
+    , 0x6B, 0x4A, 0x88, 0xDA, 0x1B, 0x2F, 0x4B, 0x2C, 0x31, 0xEA, 0x5D, 0x58, 0x08, 0x87, 0x67, 0x3F
+    , 0x59, 0x12, 0x0C, 0x39, 0xD3, 0x84, 0x5F, 0x3B, 0xB5, 0x29, 0x95, 0xC6, 0x58, 0xD7, 0xEA, 0x36
+    , 0x0B, 0x0F, 0x31, 0x9B, 0xDE, 0xB6, 0xDD, 0xFE, 0x40, 0x4A, 0x90, 0x07, 0x6B, 0xC5, 0x7B, 0xF5
+    , 0xA9, 0xDA, 0x7A, 0x5C, 0x15, 0x70, 0xA1, 0xBF, 0x56, 0x5D, 0x16, 0x69, 0x7E, 0x82, 0x60, 0xD6
+    , 0xB9, 0xF8, 0x67, 0x03, 0x37, 0x4E, 0xB7, 0xD1, 0x8D, 0x7D, 0x27, 0x8F, 0xFE, 0x53, 0xC6, 0x03
+    , 0x0E, 0xBE, 0x8D, 0x13, 0x08, 0xBE, 0x5A, 0xBD, 0x74, 0x67, 0xB6, 0xF8, 0x59, 0x02, 0xA6, 0x29
+    , 0x6A, 0x51, 0x65, 0xA0, 0xE1, 0x7B, 0xDC, 0x87, 0x19, 0x3C, 0x85, 0x44, 0xB9, 0xAD, 0x36, 0xD0
+    , 0xFC, 0xDC, 0x30, 0x26, 0xF9, 0x8C, 0x79, 0xCC, 0x2D, 0xC2, 0x73, 0x53, 0x0C, 0x54, 0x07, 0xF1
+    , 0x6F, 0xAA, 0x9E, 0x80, 0x30, 0x79, 0xC1, 0xDF, 0xEF, 0x12, 0x29, 0x83, 0xAB, 0xCF, 0x9E, 0x7A
+    , 0x95, 0x16, 0xDA, 0xCF, 0xBA, 0x31, 0x0D, 0xF1, 0xF5, 0x58, 0xA7, 0x49, 0x43, 0x73, 0x9E, 0x24
+    , 0xAC, 0xF8, 0x85, 0x10, 0xD1, 0x7D, 0x7F, 0x1A, 0x41, 0x06, 0x75, 0xE0, 0xF5, 0x10, 0x84, 0x39
+    , 0x2C, 0x1E, 0xB1, 0xDA, 0x15, 0x29, 0x66, 0x5F, 0x55, 0x7C, 0x5E, 0xF5, 0x14, 0xAF, 0x9D, 0x55
+    , 0x50, 0x94, 0xB7, 0x11, 0xAD, 0xC6, 0x7D, 0x79, 0xFF, 0x12, 0xD5, 0x19, 0x8A, 0x54, 0x00, 0x19
+    , 0x69, 0xAF, 0xD1, 0x76, 0xE9, 0x85, 0x8B, 0x24, 0xB0, 0xF7, 0x31, 0x1B, 0xEF, 0xC2, 0xD3, 0xA5
+    , 0x7F, 0xC7, 0xC5, 0x76, 0x84, 0x8B, 0x54, 0xA4, 0x93, 0x98, 0x86, 0xB3, 0x26, 0x1C, 0x76, 0xD4
+    , 0x8B, 0xDE, 0x2A, 0x49, 0xF1, 0xE2, 0x21, 0xC8, 0x8A, 0xE8, 0xB2, 0x3A, 0xE7, 0x67, 0x5E, 0x63
+    , 0x26, 0x27, 0xF4, 0x03, 0x8C, 0xFC, 0xFE, 0x9C, 0x13, 0xF9, 0x51, 0x9C, 0xED, 0xDA, 0x19, 0x08
+    , 0x6A, 0x14, 0x3A, 0xF0, 0x25, 0x92, 0xDF, 0x7E, 0x7A, 0xDC, 0x9E, 0x06, 0x7A, 0x1F, 0xCA, 0x5B
+    , 0x4D, 0xB1, 0x57, 0x3A, 0x2E, 0x13, 0xB8, 0xD0, 0x42, 0x1E, 0xC9, 0xE2, 0xF4, 0x4C, 0x84, 0x4F
+    , 0x5C, 0x04, 0xE4, 0xC6, 0xC2, 0x01, 0x99, 0x24, 0xA9, 0x53, 0xC3, 0x21, 0x24, 0x3C, 0x32, 0x0C
+    , 0x64, 0xA3, 0x65, 0xD5, 0xB9, 0x76, 0x0C, 0x0A, 0x96, 0x09, 0x5F, 0x57, 0x3E, 0x68, 0xBB, 0x8B
+    , 0x88, 0x34, 0xA7, 0xEE, 0xCC, 0x32, 0xEE, 0x63, 0x40, 0x77, 0x68, 0x6D, 0x0C, 0x6A, 0x9E, 0x1E
+    , 0x9A, 0x57, 0x77, 0x66, 0xCB, 0x63, 0x45, 0x99, 0xD6, 0x4E, 0x90, 0xF9, 0x14, 0xA8, 0xAE, 0x41
+    , 0xA3, 0x8C, 0x5E, 0xE2, 0xA0, 0x85, 0x25, 0xFF, 0x33, 0x7B, 0x6F, 0x1E, 0xAF, 0xAD, 0xE3, 0x37
+    , 0xBE, 0x76, 0xD3, 0x82, 0x19, 0x39, 0x4A, 0x7F, 0xF7, 0x58, 0xFC, 0xF5, 0x07, 0xE9, 0x08, 0x90
+    , 0xB9, 0x92, 0x55, 0x35, 0xD9, 0xC7, 0x8A, 0x1A, 0x38, 0x8A, 0xB5, 0xD5, 0xE5, 0x54, 0x84, 0x08
+    , 0x53, 0x93, 0xBB, 0x15, 0x9B, 0x55, 0x9F, 0x53, 0x11, 0x3B, 0xC1, 0xA7, 0xC3, 0x1B, 0x87, 0xD3
+    , 0x7B, 0xB7, 0x5E, 0x54, 0xC5, 0x00, 0xFB, 0x32, 0x95, 0x91, 0x6D, 0x32, 0x1C, 0xB3, 0x94, 0xB5
+    , 0x0D, 0x8F, 0xA2, 0x84, 0x4F, 0x77, 0xF6, 0x0F, 0x57, 0x12, 0x8F, 0x51, 0xB2, 0x05, 0xC6, 0x86
+    , 0x4B, 0x0E, 0x55, 0xCC, 0x39, 0xC1, 0x56, 0xF7, 0xB8, 0x90, 0xF5, 0x21, 0x45, 0x58, 0x5A, 0x3E
+    , 0xE1, 0xAF, 0x85, 0xC6, 0x2E, 0x4B, 0x9D, 0x01, 0xF4, 0x76, 0x99, 0xD5, 0x5F, 0x83, 0x38, 0x2B
+    , 0x6F, 0x44, 0xDE, 0x7D, 0x61, 0xF8, 0x70, 0x32, 0xE9, 0x6C, 0xC0, 0xBD, 0xA9, 0xC0, 0xA8, 0x5A
+    , 0x1B, 0xE2, 0xA5, 0xF0, 0xF9, 0x25, 0xA3, 0x5C, 0x7E, 0xEC, 0x78, 0xFE, 0x67, 0x14, 0x31, 0x4F
+    , 0x42, 0xFB, 0x61, 0x8B, 0x0C, 0x7A, 0xB4, 0xED, 0x65, 0x34, 0xE4, 0x2C, 0x01, 0x81, 0x46, 0xEF
+    , 0x6D, 0xE0, 0x49, 0x25, 0xAA, 0x6F, 0xD1, 0x8E, 0x82, 0xC7, 0x9B, 0xEB, 0xEB, 0x54, 0x25, 0x7E
+    , 0x4F, 0x5E, 0xE3, 0x11, 0x7C, 0xF7, 0x72, 0x18, 0x99, 0xD7, 0xCE, 0x83, 0x99, 0x24, 0x1D, 0x19
+    , 0x8B, 0xCE, 0xAD, 0x44, 0xDE, 0xCE, 0x34, 0x65, 0xA1, 0x5D, 0x1F, 0x0F, 0x3E, 0x50, 0x3E, 0x9B
+    , 0x8A, 0x82, 0xD2, 0x00, 0xC8, 0x84, 0x62, 0x9A, 0x66, 0xB1, 0x62, 0xCD, 0x01, 0x7A, 0x3B, 0xC6
+    , 0xB2, 0x82, 0x3E, 0x93, 0xDF, 0xB4, 0xC0, 0x13, 0xAC, 0x7D, 0x6D, 0x57, 0xFB, 0x40, 0xD2, 0xD8
+    , 0xCD, 0xE0, 0x88, 0x34, 0xF6, 0xC8, 0x4C, 0xE8, 0xA5, 0x0C, 0xA3, 0x1A, 0x5F, 0x61, 0x18, 0x72
+    , 0x48, 0x17, 0xCD, 0x7A, 0x5E, 0xD8, 0x77, 0x58, 0x43, 0x92, 0x1E, 0x9F, 0xD4, 0x57, 0x74, 0x89
+    , 0xF6, 0xDD, 0x5E, 0x7B, 0xFD, 0xA5, 0xE3, 0xC2, 0x3D, 0x53, 0xBF, 0x86, 0x75, 0x24, 0x32, 0x1A
+    , 0x74, 0xF7, 0xEB, 0x3B, 0xC8, 0x6E, 0x77, 0xA6, 0x93, 0x61, 0xD4, 0x95, 0x81, 0xDC, 0x2A, 0xAC
+    , 0xD5, 0x90, 0x9F, 0xBA, 0x64, 0x62, 0xBD, 0x70, 0x54, 0x3F, 0x87, 0xA8, 0xB2, 0x6C, 0x1F, 0xF0
+    , 0x81, 0x43, 0x47, 0x17, 0x90, 0x4E, 0xE6, 0x73, 0x24, 0x86, 0x6A, 0x5B, 0xC0, 0xF6, 0xDF, 0x28
+    , 0xF5, 0x25, 0x40, 0xF8, 0xB2, 0x2E, 0x96, 0xBF, 0xAA, 0xAA, 0xB1, 0x6D, 0xF6, 0xFC, 0xC9, 0x0E
+    , 0xDF, 0x8D, 0x89, 0xF8, 0xD1, 0x4B, 0xAE, 0x01, 0xAF, 0x15, 0xCE, 0xC2, 0x50, 0x60, 0x37, 0x16
+    , 0xE1, 0x35, 0xA2, 0xD4, 0xB8, 0xD6, 0x3B, 0x0F, 0xEF, 0x9C, 0x9B, 0xA0, 0x0D, 0xCE, 0x1E, 0xE7
+    , 0x6C, 0x16, 0x85, 0xB0, 0xC9, 0xB5, 0xBB, 0x27, 0xB3, 0x14, 0x53, 0x93, 0x2F, 0x65, 0xE9, 0x24
+    , 0xDA, 0x7B, 0x34, 0x09, 0x50, 0x88, 0x1A, 0xDF, 0x50, 0xBB, 0x1B, 0x35, 0xB4, 0xA5, 0x30, 0x20
+    , 0x74, 0x31, 0x52, 0xA2, 0x1D, 0x59, 0x78, 0xBD, 0x1B, 0x0C, 0xB1, 0x29, 0xE6, 0xE3, 0x31, 0x3C
+    , 0xF8, 0x22, 0xBE, 0xBF, 0x57, 0xE0, 0x02, 0xA8, 0xAC, 0xE6, 0x7D, 0x46, 0x6C, 0x96, 0x04, 0x97
+    , 0x53, 0x68, 0x46, 0x2B, 0xD8, 0xE0, 0x04, 0xA4, 0xA9, 0x78, 0xCF, 0xB7, 0x77, 0xB5, 0xD6, 0x6E
+    , 0x68, 0xDF, 0x7E, 0x3A, 0x68, 0x79, 0x0A, 0x13, 0x2E, 0x09, 0x89, 0xCB, 0x90, 0xC4, 0x1B, 0x4A
+    , 0x0F, 0x89, 0x9E, 0xD8, 0xC9, 0xE5, 0xF3, 0x2C, 0x16, 0x27, 0xE3, 0xE2, 0xA5, 0xC4, 0x23, 0x86
+    , 0x83, 0x65, 0x79, 0x1A, 0x06, 0x12, 0x3E, 0x84, 0x44, 0x42, 0x83, 0xA5, 0x14, 0x67, 0x47, 0x0B
+    , 0x60, 0x34, 0x8D, 0x54, 0x75, 0x6B, 0xE9, 0xDD, 0x58, 0xEB, 0x09, 0x8C, 0x07, 0x80, 0x26, 0x52
+    , 0x02, 0x43, 0xC8, 0x6B, 0x9E, 0xDF, 0xE4, 0x8B, 0xE1, 0xBF, 0x47, 0x1C, 0xCE, 0x27, 0x96, 0xAC
+    , 0x90, 0xB8, 0x29, 0xC6, 0x34, 0x18, 0x67, 0x8C, 0x05, 0xEC, 0xBE, 0x04, 0x6E, 0x85, 0xE9, 0x04
+    , 0x0C, 0x31, 0xB8, 0xD9, 0x09, 0x15, 0xAF, 0xAE, 0x0D, 0x6B, 0x96, 0x49, 0x88, 0x2C, 0x5F, 0xAD
+    , 0x73, 0xA4, 0x6A, 0xAF, 0x22, 0xF7, 0xF3, 0xC5, 0x80, 0x38, 0xEE, 0x4D, 0xB8, 0x28, 0xA1, 0x20
+    , 0x8D, 0xB8, 0x5B, 0x0A, 0x0D, 0xF5, 0x0A, 0x8C, 0xBE, 0x25, 0x80, 0xB2, 0x9F, 0xD3, 0x27, 0x85
+    , 0x57, 0x75, 0x39, 0x2F, 0xC5, 0x04, 0x31, 0x96, 0x67, 0xFC, 0x9C, 0x00, 0xB9, 0xCC, 0x74, 0x51
+    , 0x2B, 0x2E, 0x1E, 0x85, 0xF3, 0x5C, 0x7C, 0x8E, 0xA3, 0x5F, 0x26, 0xA3, 0xC3, 0xCC, 0x09, 0x04
+    , 0xA1, 0xD0, 0x51, 0x2F, 0x96, 0x53, 0xB1, 0x50, 0xD8, 0x7F, 0x7E, 0x10, 0x0F, 0x75, 0xA0, 0x54
+    , 0xF2, 0xC5, 0x99, 0xEA, 0x20, 0x87, 0x91, 0x0F, 0x60, 0x35, 0x88, 0xFE, 0xDF, 0xC1, 0xF1, 0xB1
+    , 0x76, 0x5F, 0x1A, 0xAE, 0xCE, 0x8A, 0x69, 0xE0, 0x1F, 0xA5, 0x37, 0x1D, 0xC5, 0x30, 0x0E, 0xFB
+    , 0x13, 0xC6, 0xC0, 0xDE, 0xD6, 0x92, 0xDF, 0x5B, 0x2E, 0x07, 0x42, 0xBE, 0xC9, 0x42, 0x76, 0x4D
+    , 0xC4, 0x98, 0xB4, 0x21, 0x9D, 0x14, 0x73, 0xF3, 0x44, 0x80, 0x83, 0x67, 0x6D, 0x42, 0x21, 0xD5
+    , 0x7E, 0xF1, 0xAC, 0x68, 0x4B, 0xF3, 0x5B, 0x0E, 0xCD, 0xBC, 0x40, 0xC5, 0xDD, 0x1F, 0xA6, 0x10
+    , 0x2C, 0x4B, 0xC1, 0xA5, 0xFA, 0xAC, 0xCA, 0xED, 0xD2, 0x6B, 0xEA, 0x44, 0xAA, 0xFF, 0x91, 0x7F
+    , 0x36, 0xDE, 0x4D, 0xA5, 0x0D, 0x16, 0x40, 0x4D, 0x29, 0xE6, 0xDD, 0xA6, 0x06, 0x37, 0xB6, 0x81
+    , 0x09, 0x34, 0x05, 0xF1, 0x5C, 0x8B, 0x8B, 0x45, 0x5F, 0xC1, 0xA0, 0xF7, 0x48, 0x35, 0x27, 0x64
+    , 0x2D, 0xC5, 0x58, 0x8B, 0xE1, 0xE3, 0x0C, 0x43, 0x65, 0x5E, 0x74, 0xF6, 0x34, 0x4F, 0xE2, 0x7D
+    , 0x13, 0x30, 0x99, 0x67, 0xA3, 0x24, 0xE3, 0xA9, 0xAD, 0x5D, 0x89, 0xCA, 0xA6, 0x32, 0xCF, 0xF4
+    , 0xAB, 0xC3, 0x36, 0xA5, 0x8E, 0xAE, 0xD6, 0x0D, 0x93, 0xFF, 0x22, 0xCD, 0x8F, 0xCA, 0xE6, 0x4E
+    , 0xC8, 0xCC, 0x0C, 0xEC, 0x5B, 0x49, 0x41, 0xA0, 0xFE, 0x74, 0xC9, 0x2F, 0x27, 0xE6, 0x0B, 0x9E
+    , 0xDB, 0xA6, 0x14, 0x44, 0x82, 0x97, 0x1D, 0xAA, 0xC3, 0x44, 0xC1, 0x1A, 0x16, 0xB4, 0xD9, 0xD4
+    , 0x93, 0x00, 0xF1, 0x83, 0x46, 0x07, 0xAA, 0xD3, 0x0D, 0x9E, 0x01, 0xD2, 0xE2, 0x2B, 0xB7, 0x1E
+    , 0xCC, 0x91, 0xDF, 0xF0, 0x41, 0x67, 0x82, 0x38, 0x05, 0x37, 0xC1, 0xE6, 0x15, 0xFA, 0x9E, 0x07
+    , 0x66, 0x6A, 0x18, 0x37, 0x53, 0x16, 0xA3, 0x5C, 0xC3, 0x2C, 0x35, 0xDC, 0x57, 0xF4, 0xEB, 0xC8
+    , 0x7F, 0xC8, 0xEB, 0x3F, 0x77, 0x13, 0xB3, 0x3F, 0x7A, 0x7A, 0x79, 0x65, 0x73, 0xA5, 0xA3, 0x72
+    , 0xA4, 0x4B, 0x3C, 0x04, 0x05, 0x24, 0x5B, 0xDC, 0x0D, 0x5F, 0x91, 0xAE, 0xA6, 0xA5, 0x6E, 0x15
+    , 0x06, 0x29, 0xD7, 0x28, 0x42, 0x42, 0xCA, 0xAC, 0xA0, 0x79, 0xF6, 0x68, 0x2B, 0xD2, 0x5E, 0xF9
+    , 0x36, 0x1C, 0x65, 0xD6, 0x75, 0x78, 0xB9, 0xC2, 0x9C, 0xDF, 0x0A, 0xD0, 0xD1, 0x55, 0xA0, 0xA2
+    , 0x74, 0xE0, 0x45, 0x0D, 0x66, 0x8C, 0x2B, 0xF3, 0x9B, 0x78, 0xD8, 0xCF, 0x48, 0xDC, 0x1C, 0x1F
+    , 0x9A, 0xD8, 0xD8, 0xD9, 0xC4, 0x03, 0xE8, 0x15, 0x6E, 0x85, 0xB7, 0x4A, 0x6A, 0x73, 0xB3, 0xAF
+    , 0x86, 0x0C, 0xD0, 0x5F, 0x06, 0xDE, 0x07, 0xF9, 0x95, 0x2A, 0x40, 0x7A, 0x5A, 0x96, 0x9F, 0x9B
+    , 0xFA, 0x0F, 0xAD, 0x71, 0x52, 0x56, 0x89, 0xC0, 0x90, 0xA7, 0x3E, 0x1C, 0xA1, 0x61, 0x63, 0xE9
+    , 0x99, 0x98, 0x63, 0x80, 0xF0, 0x7B, 0xD7, 0xDB, 0xEF, 0xC4, 0x62, 0x05, 0x43, 0xF5, 0xDF, 0xEF
+    , 0xD0, 0xD3, 0x7D, 0x28, 0x02, 0xB9, 0x26, 0xB0, 0xA0, 0x90, 0xF8, 0x80, 0x98, 0xD6, 0xFA, 0xD4
+    , 0x89, 0x79, 0xF2, 0x01, 0x90, 0x0B, 0xB8, 0x56, 0x44, 0xE7, 0x20, 0x5C, 0x70, 0x7C, 0x34, 0xF2
+    , 0xD0, 0x7C, 0xF7, 0x00, 0xD6, 0x3C, 0x46, 0x5F, 0xBE, 0xF3, 0xC9, 0x5D, 0x5F, 0x6A, 0xB3, 0x6D
+    , 0xC4, 0x90, 0x49, 0x5E, 0xF0, 0xD6, 0x04, 0x99, 0xDC, 0x76, 0xC8, 0xEE, 0x7F, 0x63, 0x26, 0x3F
+    , 0x98, 0xE1, 0xFB, 0x5C, 0x76, 0x14, 0x20, 0x0E, 0x6D, 0xE5, 0xF7, 0xD5, 0x8C, 0x72, 0x9D, 0x9B
+    , 0xF9, 0xEA, 0xD6, 0x0C, 0x1F, 0xD5, 0x31, 0x22, 0xDC, 0x9A, 0xA3, 0x56, 0x5B, 0xD6, 0xFD, 0x11
+    , 0xB7, 0x7E, 0x13, 0x74, 0xAF, 0xAC, 0x28, 0xAA, 0x3F, 0xDF, 0x5F, 0x35, 0x02, 0xD3, 0x4F, 0x7B
+    , 0x50, 0xB5, 0x80, 0xD8, 0x4E, 0xD9, 0x8D, 0x63, 0x1B, 0x69, 0xCF, 0x2E, 0xB2, 0xC5, 0x9D, 0x07
+    , 0xBA, 0x65, 0xB9, 0x1E, 0x56, 0xAC, 0x5F, 0x56, 0x54, 0x1A, 0x4B, 0x47, 0xD0, 0xE3, 0x99, 0xA7
+    , 0x7C, 0x29, 0x81, 0x11, 0x8D, 0xE1, 0xBC, 0x4D, 0x0F, 0x7F, 0x37, 0xFA, 0x69, 0x5B, 0x03, 0x47
+    , 0x53, 0x1C, 0x2A, 0x8A, 0x6B, 0xA8, 0xF0, 0xCB, 0xDF, 0x3A, 0x8E, 0x72, 0x05, 0xBF, 0x60, 0x24
+    , 0x0E, 0xFF, 0xF6, 0x90, 0xA0, 0xDC, 0xF1, 0x17, 0x20, 0xF2, 0x98, 0xF0, 0xA5, 0xDC, 0x50, 0x13
+    , 0xD8, 0x5C, 0x7A, 0x2D, 0xC2, 0xC1, 0xFF, 0xF2, 0x11, 0x10, 0x09, 0xAB, 0xF3, 0xF0, 0xC3, 0x5C
+    , 0x0A, 0x0B, 0xC8, 0x32, 0x19, 0x34, 0x93, 0xE4, 0x21, 0x57, 0x78, 0x32, 0xED, 0x51, 0x0A, 0xAC
+    , 0x33, 0x02, 0x97, 0x83, 0xD7, 0x7B, 0x26, 0xD9, 0xB7, 0xBC, 0xCA, 0xCE, 0xE3, 0x0F, 0x38, 0xD5
+    , 0xE2, 0x26, 0x4F, 0xAC, 0x0D, 0x77, 0x25, 0xF7, 0x68, 0x31, 0x70, 0x41, 0xE6, 0xCA, 0x1D, 0xDC
+    , 0x9D, 0xD8, 0x83, 0x22, 0xFF, 0xB9, 0xC9, 0x27, 0xEB, 0xC6, 0x82, 0x6D, 0xFC, 0x45, 0x3D, 0x5C
+    , 0x6D, 0x6B, 0x99, 0x9B, 0x46, 0x16, 0x96, 0x72, 0x5C, 0x2C, 0x5C, 0x24, 0x2D, 0xEC, 0xB5, 0x86
+    , 0x29, 0x8A, 0x3A, 0x94, 0x69, 0x28, 0xD5, 0x5C, 0x0C, 0x0C, 0x20, 0x0D, 0x65, 0x02, 0x6E, 0x0F
+    , 0xEF, 0xBA, 0x64, 0x88, 0x5C, 0x32, 0x9F, 0x45, 0xA3, 0xB1, 0x39, 0xB5, 0x72, 0x42, 0x94, 0x62
+    , 0x72, 0xF0, 0x34, 0xDC, 0x37, 0xD9, 0x28, 0xEE, 0xE5, 0xB2, 0xF7, 0xA8, 0xEE, 0x22, 0x46, 0xD0
+    , 0x59, 0x24, 0x4A, 0x97, 0x98, 0x00, 0x6D, 0x83, 0xC3, 0xE2, 0x38, 0x4E, 0x04, 0x4B, 0x08, 0x67
+    , 0x06, 0xFB, 0xD3, 0xE0, 0x5A, 0xFB, 0x8A, 0xC8, 0x72, 0xB3, 0xE4, 0xBB, 0x7C, 0x59, 0xA0, 0x66
+    , 0x9B, 0xB7, 0x0F, 0x16, 0xE3, 0xFC, 0xFC, 0x55, 0xDC, 0xE3, 0x98, 0x10, 0x66, 0xC3, 0x9B, 0x55
+    , 0xBA, 0xA1, 0xC4, 0x00, 0x58, 0x30, 0xDD, 0x96, 0x48, 0x82, 0x58, 0xED, 0x56, 0x77, 0xE3, 0xFA
+    , 0xF1, 0x3D, 0x09, 0xB7, 0x1A, 0x8F, 0xF2, 0xA2, 0x05, 0x2D, 0x1C, 0xAB, 0xA6, 0xE1, 0x5F, 0x44
+    , 0xD8, 0x4A, 0x56, 0x16, 0xD4, 0xE7, 0x42, 0x35, 0x6F, 0x62, 0x09, 0xA9, 0x63, 0x99, 0xD9, 0x62
+    , 0xE6, 0x65, 0x3F, 0xFA, 0xAF, 0x61, 0x83, 0x5C, 0x52, 0x5F, 0x51, 0x57, 0x82, 0x1B, 0xC9, 0xB0
+    , 0xE1, 0x3C, 0x06, 0x90, 0xEE, 0xF8, 0x17, 0x85, 0x73, 0xC4, 0x6E, 0x9C, 0xA6, 0x23, 0x27, 0x43
+    , 0x1B, 0x25, 0xC7, 0x6E, 0xD0, 0x6D, 0x68, 0x82, 0x92, 0x03, 0xA2, 0xEF, 0x3D, 0x6B, 0x50, 0x5A
+    , 0x3A, 0x1D, 0xD3, 0x0F, 0x1C, 0x82, 0x92, 0x8B, 0x6A, 0x30, 0xD4, 0xF7, 0x8C, 0x7C, 0xE1, 0x3E
+    , 0x83, 0xE3, 0xAB, 0x60, 0xB2, 0x5D, 0x06, 0xDA, 0x75, 0xB8, 0x0C, 0x31, 0x52, 0x6E, 0xD3, 0x0A
+    , 0xFD, 0x08, 0x4D, 0x2C, 0x87, 0x4E, 0x1D, 0x5E, 0x5B, 0x46, 0x8A, 0xDA, 0x29, 0x0D, 0xD8, 0xE6
+    , 0x75, 0x75, 0xF4, 0xA0, 0x79, 0xDC, 0xB9, 0xF8, 0xCE, 0xB0, 0x61, 0xF9, 0x45, 0x45, 0xE4, 0xFD
+    , 0x56, 0x3F, 0xF7, 0x2E, 0xA7, 0xC6, 0x69, 0x12, 0xBB, 0xAF, 0x0A, 0x2A, 0x44, 0xEE, 0x5E, 0x9A
+    , 0x65, 0x80, 0x4E, 0x68, 0x98, 0x54, 0xEB, 0x8B, 0x81, 0x3F, 0x41, 0x94, 0x13, 0x6B, 0x0F, 0x35
+    , 0x13, 0x60, 0x0F, 0x6D, 0x7D, 0xB9, 0x40, 0x2E, 0xC4, 0x0C, 0xBD, 0x89, 0x8F, 0xB5, 0x23, 0xBB
+    , 0x19, 0x63, 0x5F, 0x37, 0xB5, 0x70, 0xFE, 0x54, 0x8A, 0x73, 0x7E, 0x67, 0x50, 0x58, 0x81, 0x08
+    , 0x5F, 0x13, 0xA7, 0x12, 0xC3, 0x60, 0x2A, 0x7E, 0x8E, 0x3B, 0x32, 0x21, 0xEF, 0xA8, 0xE0, 0xDE
+    , 0xDA, 0x62, 0x73, 0x7F, 0xAE, 0xE5, 0xC4, 0x46, 0x9C, 0x54, 0x73, 0x15, 0x28, 0xD4, 0x14, 0x4A
+    , 0x7B, 0x1B, 0xE3, 0xEB, 0x18, 0x65, 0xE8, 0x9C, 0x36, 0xFA, 0xA8, 0x97, 0xB2, 0x36, 0xB5, 0xDD
+    , 0x49, 0x56, 0x4D, 0x81, 0x4A, 0x81, 0x32, 0x25, 0x50, 0xA4, 0x36, 0xE0, 0x36, 0x1C, 0x55, 0xE4
+    , 0x8F, 0x03, 0x7F, 0x61, 0xD9, 0xDE, 0x64, 0x7E, 0xE4, 0x2E, 0xF2, 0xF3, 0xFC, 0x66, 0x4E, 0x30
+    , 0x06, 0x9F, 0x4B, 0x9E, 0x0B, 0xE2, 0xBA, 0x93, 0xFD, 0x0F, 0xDD, 0xCE, 0xC9, 0x93, 0xE9, 0x3D
+    , 0x17, 0x3F, 0xB7, 0x45, 0x51, 0x3F, 0x0A, 0x12, 0x30, 0xFE, 0xB4, 0xF3, 0x59, 0x8D, 0x67, 0x3B
+    , 0x1B, 0x76, 0x6C, 0x08, 0x3C, 0x04, 0xC6, 0xCE, 0x48, 0x9C, 0x73, 0x5B, 0x80, 0xAA, 0x01, 0xB6
+    , 0x45, 0x16, 0xDF, 0x8A, 0x39, 0x5A, 0xF1, 0x98, 0xE4, 0xD4, 0xC5, 0x9C, 0x59, 0xC3, 0xDC, 0x4C
+    , 0x24, 0xC8, 0xFF, 0x1C, 0x63, 0x00, 0xBC, 0x7B, 0xC5, 0x4D, 0xA3, 0x11, 0xB7, 0x04, 0x49, 0xF7
+    , 0x34, 0x68, 0x4D, 0xAF, 0x84, 0xDF, 0xCF, 0xDB, 0xCC, 0x79, 0xF7, 0x72, 0x35, 0xBA, 0x57, 0x78
+    , 0x83, 0xBE, 0x82, 0x37, 0x3B, 0xC2, 0x6A, 0xE4, 0x3D, 0xFA, 0x6D, 0x21, 0xC7, 0x8C, 0x61, 0x7C
+    , 0x9A, 0x69, 0xD6, 0x6C, 0xEA, 0x34, 0x36, 0x37, 0x1F, 0x1F, 0xE3, 0x3F, 0xD0, 0x34, 0xFE, 0x20
+    , 0x87, 0xFD, 0xD1, 0x0A, 0x01, 0x1D, 0xB2, 0x27, 0x3E, 0x7B, 0x1C, 0x5B, 0xAE, 0x28, 0x18, 0x99
+    , 0xB9, 0x94, 0x8E, 0xF7, 0xD7, 0x6A, 0x53, 0x5E, 0x15, 0xB9, 0x48, 0xA0, 0x0E, 0xAF, 0xEB, 0xAE
+    , 0xEE, 0xBE, 0xE4, 0x55, 0x3A, 0x6C, 0xD9, 0xB9, 0xB8, 0x4D, 0xD0, 0x0E, 0x40, 0x45, 0x22, 0x7D
+    , 0x24, 0xDB, 0x32, 0xEB, 0x77, 0xC7, 0x21, 0x1D, 0x6C, 0xDF, 0xEF, 0xEA, 0x0F, 0xD9, 0x2C, 0x7A
+    , 0xA4, 0xA0, 0x2C, 0x8F, 0x03, 0x33, 0xE8, 0xB3, 0x6F, 0xF2, 0xC3, 0xA3, 0xC6, 0x08, 0x29, 0x38
+    , 0xFA, 0x30, 0x35, 0xA1, 0x38, 0x39, 0x1F, 0xE3, 0xB9, 0xA1, 0x58, 0x12, 0x91, 0x18, 0x4A, 0x1C
+    , 0xCC, 0x3D, 0xEA, 0xE6, 0xAA, 0x42, 0x5B, 0x28, 0x17, 0x15, 0xCE, 0x66, 0x09, 0xCA, 0x3F, 0x40
+    , 0x86, 0x2E, 0x6F, 0x95, 0xA9, 0x62, 0xCB, 0x8B, 0x81, 0xBC, 0x57, 0x59, 0xF5, 0xA7, 0x13, 0x30
+    , 0xF9, 0x5A, 0xF0, 0xA8, 0xEB, 0xFA, 0x90, 0x8D, 0x84, 0x15, 0xD7, 0xE2, 0x8C, 0xEB, 0x05, 0xFB
+    , 0xF8, 0xCE, 0x59, 0xFE, 0x1F, 0x1D, 0x19, 0x04, 0x2B, 0x72, 0xEB, 0x24, 0x45, 0x50, 0x5D, 0x56
+    , 0xCC, 0x97, 0xB4, 0x75, 0x2D, 0x31, 0x1F, 0xF4, 0x30, 0x7B, 0xF7, 0x27, 0x4A, 0x97, 0x65, 0x2D
+    , 0xE6, 0xDE, 0xDB, 0xEE, 0x7A, 0x0E, 0x2B, 0x26, 0xD1, 0xEE, 0x0F, 0x61, 0x81, 0xAA, 0x10, 0x71
+    , 0x72, 0xC0, 0xF4, 0xF5, 0x60, 0x81, 0xC2, 0xDE, 0x4D, 0xA8, 0xC7, 0x33, 0xEC, 0x6D, 0xE7, 0xC7
+    , 0x6E, 0x46, 0xAD, 0x9C, 0x6B, 0x6F, 0x20, 0x1E, 0xE0, 0x77, 0x1F, 0x71, 0x94, 0x7A, 0x15, 0x05
+    , 0xF0, 0xD7, 0xF0, 0x33, 0x70, 0x97, 0x0D, 0xB4, 0xB6, 0xD3, 0xBC, 0xA4, 0x50, 0x7A, 0x3C, 0x49
+    , 0xE2, 0xE8, 0x0F, 0x3E, 0x21, 0xB7, 0x17, 0x95, 0x9E, 0x31, 0x62, 0xB2, 0x49, 0xE8, 0x4F, 0x1E
+    , 0x86, 0xD4, 0xF9, 0xD5, 0x22, 0x89, 0x5B, 0x67, 0xE6, 0xDA, 0xFC, 0xA3, 0x3C, 0xFE, 0x5E, 0x8E
+    , 0xF9, 0x4D, 0xF5, 0x24, 0x3C, 0x56, 0xE5, 0x26, 0xFD, 0x3D, 0xA1, 0xAA, 0x86, 0x99, 0x54, 0x87
+    , 0x12, 0x85, 0x4D, 0x89, 0x64, 0x67, 0xD6, 0xCB, 0x8D, 0x40, 0xB7, 0xBA, 0x4A, 0x60, 0x8A, 0xE4
+    , 0xCC, 0x01, 0x04, 0x11, 0xE2, 0x38, 0x9F, 0x7F, 0xD1, 0xB5, 0x82, 0xCF, 0xD8, 0x50, 0x02, 0xF6
+    , 0x42, 0x2D, 0x63, 0x1B, 0x0D, 0x1A, 0xF9, 0xE5, 0x2A, 0x54, 0xCC, 0x7E, 0xDE, 0x43, 0x7B, 0xC9
+    , 0xF0, 0xF5, 0xBD, 0x64, 0xA2, 0x79, 0x55, 0x90, 0x8E, 0x19, 0x44, 0xE9, 0x85, 0x18, 0x6C, 0x58
+    , 0x9D, 0xA5, 0xCE, 0xF1, 0x38, 0xF0, 0xDD, 0x87, 0x4E, 0x72, 0xF0, 0x17, 0x09, 0xAC, 0xF6, 0x1B
+    , 0xD0, 0x8B, 0x1B, 0x78, 0xBF, 0x63, 0xA4, 0x33, 0xF9, 0x44, 0x5D, 0xD9, 0x97, 0x28, 0x06, 0x5B
+    , 0x4A, 0x26, 0xEB, 0xC0, 0x97, 0x1C, 0x67, 0x10, 0x65, 0x47, 0x7D, 0x52, 0x50, 0xE5, 0x55, 0x0F
+    , 0x68, 0xC6, 0x93, 0x37, 0x44, 0xB1, 0xB3, 0x4A, 0xF4, 0x0D, 0xBE, 0x15, 0x27, 0x6C, 0xE5, 0xEC
+    , 0x25, 0xDC, 0x65, 0xE9, 0x07, 0x1A, 0x6C, 0xA6, 0x0E, 0xB2, 0xDB, 0xDE, 0x75, 0xD0, 0xC3, 0x67
+    , 0x41, 0xCB, 0x4F, 0x5F, 0x00, 0xF5, 0x1E, 0x94, 0x45, 0x7D, 0xCA, 0x0F, 0xBF, 0xC4, 0x04, 0x83
+    , 0x9E, 0xBE, 0x25, 0xB1, 0x5E, 0x32, 0xBF, 0x4F, 0x28, 0x9B, 0x68, 0x2E, 0x5A, 0xE0, 0xD1, 0x4A
+    , 0xF3, 0xB2, 0x9E, 0xA9, 0x27, 0xD6, 0x6D, 0x58, 0x2E, 0x34, 0x67, 0x6B, 0xB8, 0x39, 0x15, 0x3A
+    , 0x10, 0xE3, 0xD8, 0x74, 0x28, 0x83, 0x5C, 0x2F, 0x7C, 0xF0, 0x3B, 0x76, 0xA6, 0xEE, 0x4E, 0xE4
+    , 0x38, 0x70, 0xBA, 0x20, 0x17, 0x9D, 0x28, 0x03, 0x87, 0x67, 0x6F, 0x90, 0x6F, 0x78, 0xA1, 0xFF
+    , 0x98, 0xD3, 0x82, 0xB6, 0x11, 0x4D, 0xFB, 0xF7, 0x8B, 0x85, 0x79, 0x01, 0x6B, 0x42, 0x68, 0x77
+    , 0x01, 0x51, 0xA4, 0x69, 0x2C, 0x11, 0x91, 0x1E, 0xBD, 0x64, 0xD3, 0x80, 0x68, 0x95, 0xFC, 0x1B
+    , 0x85, 0xA1, 0xD9, 0xEB, 0xD2, 0x63, 0xA5, 0x61, 0x2A, 0x40, 0x98, 0x2D, 0xB8, 0x44, 0xB6, 0x04
+    , 0xED, 0x00, 0xDB, 0xA1, 0xDB, 0xE4, 0x6A, 0x62, 0xC9, 0x8C, 0xA6, 0xFF, 0xA2, 0xBA, 0xE7, 0x3E
+    , 0x12, 0x58, 0x01, 0x37, 0xB0, 0xFA, 0xBB, 0xBB, 0x13, 0xAC, 0x10, 0x60, 0x2B, 0x4E, 0x8F, 0xCF
+    , 0x22, 0xD5, 0xC9, 0xA8, 0x59, 0x7A, 0xC9, 0xEE, 0xC4, 0xA6, 0xAE, 0x51, 0xE0, 0xD8, 0x4C, 0xF2
+    , 0xA0, 0xAA, 0x6B, 0xA0, 0x20, 0xE8, 0x99, 0xFF, 0xF6, 0xBF, 0x15, 0x3C, 0x6C, 0x23, 0xCC, 0x0B
+    , 0xC8, 0xF2, 0xD2, 0x3F, 0x43, 0x97, 0x74, 0x03, 0x6C, 0x3E, 0xA7, 0xF8, 0xE5, 0xD2, 0x04, 0x04
+    , 0x40, 0x37, 0xBE, 0x49, 0xD1, 0xAA, 0xCF, 0xA0, 0xAF, 0x0A, 0xDA, 0x75, 0x7E, 0x2B, 0x66, 0xE1
+    , 0x35, 0x72, 0x2A, 0xAF, 0x5F, 0x72, 0x11, 0x12, 0xEB, 0x67, 0xC0, 0x35, 0xAC, 0xAB, 0x03, 0x09
+    , 0xA4, 0x9A, 0x1C, 0x97, 0xC7, 0x76, 0xD2, 0x66, 0x5D, 0x4B, 0x70, 0xD2, 0x9C, 0xDF, 0x0D, 0xBE
+    , 0x74, 0x46, 0x9D, 0x1B, 0xC2, 0xA8, 0x33, 0xF7, 0x7A, 0xAB, 0xE0, 0xB0, 0xC2, 0x5D, 0xDE, 0x80
+    , 0xCA, 0xD3, 0x28, 0xC1, 0xEB, 0x64, 0xCE, 0xEB, 0x93, 0xB1, 0x9C, 0xE9, 0x58, 0x97, 0xB2, 0x57
+    , 0x7C, 0xB2, 0xD4, 0xCC, 0xFE, 0xEF, 0x0B, 0x10, 0x11, 0xAF, 0x0B, 0x55, 0x22, 0x30, 0xFA, 0xC1
+    , 0x17, 0x48, 0xBC, 0x14, 0x25, 0x12, 0x83, 0xD1, 0xB0, 0x08, 0x11, 0x1C, 0x41, 0x07, 0xF1, 0xA5
+    , 0x7D, 0x04, 0x51, 0x9C, 0x2B, 0x85, 0x49, 0xAD, 0x67, 0x78, 0xD9, 0x9B, 0x3C, 0xB7, 0x54, 0xD8
+    , 0xB3, 0xB5, 0x2B, 0x0B, 0xC1, 0xE9, 0xCF, 0xD7, 0xAF, 0x5E, 0x5D, 0x99, 0xED, 0x45, 0x79, 0xBD
+    , 0x3D, 0x37, 0xE6, 0x6B, 0x08, 0xA4, 0x96, 0x05, 0x51, 0xB8, 0x8A, 0xA6, 0xE9, 0x40, 0x7B, 0x25
+    , 0xF7, 0xE2, 0x8F, 0x0F, 0x8D, 0xF0, 0xC3, 0x9F, 0x7B, 0x26, 0xA3, 0xA3, 0x45, 0x0F, 0x30, 0x27
+    , 0xBF, 0xB0, 0xB3, 0xA9, 0xF1, 0xA5, 0xC4, 0xF3, 0xDD, 0xCD, 0x24, 0xF5, 0x5C, 0xC3, 0xFE, 0x4F
+    , 0xA2, 0xFD, 0xF1, 0x15, 0x4F, 0x3F, 0x50, 0xAF, 0xB8, 0x95, 0x72, 0x7A, 0x95, 0xCE, 0x1D, 0xFD
+    , 0xA7, 0x85, 0xD0, 0x92, 0x05, 0xEE, 0x42, 0x7B, 0xD8, 0x3D, 0xEE, 0x9C, 0xDB, 0x81, 0xF6, 0x7F
+    , 0x1D, 0x1F, 0xA8, 0xA9, 0x0A, 0xDB, 0xA8, 0xC3, 0xE2, 0x08, 0x7E, 0x49, 0x00, 0xFF, 0xC2, 0x11
+    , 0x32, 0xF8, 0x90, 0xE4, 0x40, 0x93, 0x34, 0x3A, 0x17, 0x4A, 0xAB, 0x67, 0x76, 0x36, 0x62, 0x1D
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xDB, 0xD2, 0xFC, 0x49, 0xEA, 0x27, 0x1B, 0xDD, 0x5C, 0x12, 0x14, 0x16, 0x4F, 0x54, 0xD2, 0x53
+    , 0x77, 0xC1, 0x2F, 0xEF, 0x0D, 0x4D, 0x10, 0x08, 0x69, 0xA6, 0xB9, 0x9B, 0xE4, 0xDF, 0xC1, 0x47
+    , 0xC2, 0x1E, 0x6F, 0xC7, 0xAF, 0x94, 0x9E, 0xF5, 0xEE, 0xAB, 0x07, 0x52, 0x02, 0x76, 0xB6, 0x0C
+    , 0x1E, 0x74, 0x26, 0x19, 0x75, 0x0E, 0x23, 0x6F, 0x7B, 0x10, 0x64, 0x45, 0x31, 0xF6, 0xAA, 0xA6
+    , 0x53, 0x78, 0x9D, 0xB0, 0xBC, 0xB2, 0xC7, 0x95, 0xAD, 0x87, 0x6D, 0x00, 0x86, 0x3C, 0x51, 0x34
+    , 0x8F, 0x74, 0x0F, 0x1E, 0x34, 0x71, 0x59, 0x06, 0x4B, 0x07, 0xA6, 0xCB, 0x5C, 0x30, 0x5E, 0xA6
+    , 0xA8, 0x2A, 0xBB, 0x4C, 0x5C, 0xD6, 0xAB, 0x38, 0xD0, 0xE7, 0x17, 0x94, 0x68, 0x90, 0xF1, 0x8B
+    , 0x43, 0x6B, 0x93, 0xC3, 0x3E, 0xD7, 0x8B, 0x25, 0x51, 0x49, 0x97, 0x2A, 0x07, 0x79, 0xA6, 0x44
+    , 0x65, 0x9D, 0x8C, 0x50, 0xA6, 0xC7, 0x7E, 0x17, 0xE7, 0x4D, 0x28, 0x81, 0x03, 0x69, 0x9C, 0xF7
+    , 0x31, 0xAB, 0xEB, 0x8C, 0x5E, 0x6F, 0x01, 0x10, 0x01, 0xB2, 0x0F, 0x16, 0x8B, 0xD4, 0x0A, 0x4F
+    , 0x3F, 0x27, 0xA1, 0xB1, 0x08, 0x74, 0x74, 0x26, 0x16, 0x35, 0x6E, 0x0D, 0x43, 0x64, 0xEA, 0xAA
+    , 0x83, 0x07, 0xB0, 0x47, 0x44, 0xDF, 0x80, 0x0D, 0x20, 0x4D, 0x0A, 0x97, 0x2D, 0x28, 0xE1, 0xF4
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+    , 0xCF, 0x97, 0x8D, 0xF4, 0xFE, 0x97, 0xB7, 0xEF, 0x1B, 0xE7, 0xA4, 0x45, 0xD1, 0x58, 0xBB, 0xB1
+};
+
+
+
+#pragma arm section zidata="NONCACHEDZI", rwdata="NONCACHEDRW"
+__align(4) kal_uint8 sdiobuf[2048] = {0xff,};
+#pragma arm section zidata, rwdata
+kal_uint8 sdiobuf2[2048] = {0xff,};
+
+
+void test_hisr(void)
+{
+    kal_uint32 sdc_intsta;
+    dbg_print("interrupt callback\r\n");
+    msdc_dbg_print("[%s %d]SDIO EINT12 \r\n", __FUNCTION__, __LINE__);
+
+    //EINT_Set_Polarity(MT5931_EINT_NUM, KAL_FALSE);
+    //call = 1;
+    //SDIO_HISR_Entry();
+}
+
+kal_int32
+kalDevReadWithSdioCmd52(
+    kal_uint32          u4Register,
+    kal_uint8 *         pucValue
+)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+    Data.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+    Data.rSDIOCMD52.addr = u4Register;
+    Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &Data);
+
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevReadWithSdioCmd52() reports error: %d", Status);
+        return -1;
+    }
+    else
+    {
+        *pucValue = Data.rSDIOCMD52.rdata;
+        return 0;
+    }
+}
+
+kal_int32
+kalDevWriteWithSdioCmd52(
+    kal_uint32          u4Register,
+    kal_uint8         ucValue
+)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+    Data.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+    Data.rSDIOCMD52.addr = u4Register;
+    Data.rSDIOCMD52.wdata = ucValue;
+    Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD52_WRITE, &Data);
+
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevWriteWithSdioCmd52() reports error: %x", Status);
+        return -1;
+    }
+    else
+        return 0;
+}
+
+#pragma arm section zidata = "NONCACHEDZI",  rwdata = "NONCACHEDRW"
+__align(4) kal_uint8 uvalue[4] = {0xff,};
+#pragma arm section zidata, rwdata
+
+kal_int32
+kalDevRegRead (
+    //IN  P_GLUE_INFO_T    prGlueInfo,
+    kal_uint32          u4Register,
+    kal_uint32 *        pu4Value
+)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+
+    //Setup and Excute CMD53
+    Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+    Data.rSDIOCMD53.block = KAL_FALSE;
+    Data.rSDIOCMD53.addr = u4Register;
+    Data.rSDIOCMD53.buffer = (kal_uint32)&uvalue[0];
+    Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+    Data.rSDIOCMD53.count = 4; //4*8 Bits
+    /*Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT,NULL);
+    if (Status == FALSE) {
+        ERRORLOG(("kalDevRegRead() CMD Init fail: %x", Status));
+    }*/
+
+    Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevRegRead() reports error: %d", Status);
+        return -1;
+    }
+    else
+    {
+        *pu4Value = ((kal_uint32)uvalue[3] << 24) + ((kal_uint32)uvalue[2] << 16) + ((kal_uint32)uvalue[1] << 8) + uvalue[0];
+        return 0;
+    }
+}
+kal_int32
+kalDevRegWrite (
+    //IN P_GLUE_INFO_T    prGlueInfo,
+    kal_uint32          u4Register,
+    kal_uint32          u4Value)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+
+    uvalue[0] = (kal_uint8)u4Value & 0xFF;
+    uvalue[1] = (kal_uint8)((u4Value >> 8) & 0xFF);
+    uvalue[2] = (kal_uint8)((u4Value >> 16) & 0xFF);
+    uvalue[3] = (kal_uint8)((u4Value >> 24) & 0xFF);
+    //Setup and Excute CMD53
+    Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+    Data.rSDIOCMD53.block = KAL_FALSE;
+    Data.rSDIOCMD53.addr = u4Register;
+    Data.rSDIOCMD53.buffer = (kal_uint32)&uvalue[0];
+    Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+    Data.rSDIOCMD53.count = 4; //4*8 Bits
+    /*Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT,NULL);
+    if (Status == FALSE) {
+        ERRORLOG(("kalDevRegRead() CMD Init fail: %x", Status));
+    }*/
+
+    Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevRegWrite() reports error: %d", Status);
+        return -1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+int kalDevPortRead (
+    //IN  P_GLUE_INFO_T   prGlueInfo,
+    kal_uint16         u2Port,
+    kal_uint16         u2Len,
+    kal_uint8 *         pucBuf
+    //IN  UINT_16         u2ValidOutBufSize
+)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+    kal_uint8 bNum = 0;
+    kal_uint16 i;
+    kal_uint32 u4TotalLen, u4Len;
+
+#if 1
+    u4Len = u2Len;
+
+    while (u2Len >= FUNC1_SDIO_BLK_SIZE)
+    {
+        u2Len -= FUNC1_SDIO_BLK_SIZE;
+        bNum++;
+    }
+
+    if (u2Len > 0 && bNum > 0)
+    {
+        bNum++;
+    }
+
+    if (bNum > 0)   // block mode
+    {
+        Data.rSDIOCMD53.block = KAL_TRUE;
+        u4TotalLen = ALIGN_32(bNum * FUNC1_SDIO_BLK_SIZE);
+        Data.rSDIOCMD53.count = bNum;
+    }
+    else if (u2Len > DMA_THRESHOLD)  //byte mode with DMA
+    {
+        Data.rSDIOCMD53.block = KAL_FALSE;
+        u4TotalLen = ALIGN_32(u2Len);
+        Data.rSDIOCMD53.count = u4TotalLen;
+    }
+    else   //byte mode wit MCU
+    {
+        u4TotalLen = ALIGN_32(u2Len);
+        Data.rSDIOCMD53.block = KAL_FALSE;
+        Data.rSDIOCMD53.count = u2Len;
+    }
+
+    if (u4TotalLen >= DMA_THRESHOLD
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+            && is_predef_dyna_c_region((kal_uint32)pucBuf, u4TotalLen)
+#endif /* __ARM9_DCACHEABLE__ */
+       )
+    {
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+        dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_NONCACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+        Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+        Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+        Data.rSDIOCMD53.addr = u2Port;
+        Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+        Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+        dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_CACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+    }
+    else
+    {
+        if (u4TotalLen >= DMA_THRESHOLD)
+        {
+            Data.rSDIOCMDREG.data = 1;
+
+            if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_READ, &Data))
+            {
+                msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_READ failed %s %d!!", __FUNCTION__, __LINE__);
+            }
+        }
+
+        Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+        Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+        Data.rSDIOCMD53.addr = u2Port;
+        Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+        Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+
+        if (u4TotalLen >= DMA_THRESHOLD)
+        {
+            Data.rSDIOCMDREG.data = 0;
+
+            if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_READ, &Data))
+            {
+                msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_READ failed %s %d!!", __FUNCTION__, __LINE__);
+            }
+        }
+    }
+
+    //printk(KERN_INFO DRV_NAME"-- kalDevPortWrite-- ret=%d\n", ret);
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevPortRead() reports error: %x", Status);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif /*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif /*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif/*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+} /* end of kalDevPortRead() */
+
+int
+kalDevPortWrite (
+    //IN P_GLUE_INFO_T  prGlueInfo,
+    kal_uint16        u2Port,
+    kal_uint16        u2Len,
+    kal_uint8 *        pucBuf
+    //IN UINT_16        u2ValidInBufSize
+)
+{
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS Status;
+    kal_uint8 bNum = 0;
+    kal_uint32 u4TotalLen, u4Len;
+
+    u4Len = u2Len;
+
+    //Setup and Excute CMD53
+    /* Split buffer into multiple single block to workaround hifsys */
+    while (u2Len >= FUNC1_SDIO_BLK_SIZE)
+    {
+        u2Len -= FUNC1_SDIO_BLK_SIZE;
+        bNum++;
+    }
+
+    if (u2Len > 0 && bNum > 0)
+    {
+        bNum++;
+    }
+
+    if (bNum > 0)   // block mode
+    {
+        Data.rSDIOCMD53.block = KAL_TRUE;
+        u4TotalLen = ALIGN_32(bNum * FUNC1_SDIO_BLK_SIZE);
+        Data.rSDIOCMD53.count = bNum;
+    }
+    else   //byte mode
+    {
+        Data.rSDIOCMD53.block = KAL_FALSE;
+        u4TotalLen = ALIGN_32(u4Len);
+        Data.rSDIOCMD53.count = u4TotalLen;
+    }
+
+    if ((u4TotalLen - u4Len) >= sizeof(kal_uint32))
+    {
+        /* fill with single dword of zero as TX-aggregation termination */
+        *(kal_uint32 *) (&((pucBuf)[ALIGN_4(u4Len)])) = 0;
+    }
+
+    if (u4TotalLen >= DMA_THRESHOLD
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+            && is_predef_dyna_c_region((kal_uint32)pucBuf, u4TotalLen)
+#endif /* __ARM9_DCACHEABLE__ */
+       )
+    {
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+        dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_NONCACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+        Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+        Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+        Data.rSDIOCMD53.addr = u2Port;
+        Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+        Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+        dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_CACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+    }
+    else
+    {
+        if (u4TotalLen >= DMA_THRESHOLD)
+        {
+            Data.rSDIOCMDREG.data = 1;
+
+            if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_WRITE, &Data))
+            {
+                msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_WRITE failed %s %d!!", __FUNCTION__, __LINE__);
+            }
+        }
+
+        Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+        Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+        Data.rSDIOCMD53.addr = u2Port;
+        Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+        Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+
+        if (u4TotalLen >= DMA_THRESHOLD)
+        {
+            Data.rSDIOCMDREG.data = 0;
+
+            if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_WRITE, &Data))
+            {
+                msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_WRITE failed %s %d!!", __FUNCTION__, __LINE__);
+            }
+        }
+    }
+
+    //printk(KERN_INFO DRV_NAME"-- kalDevPortWrite-- ret=%d\n", ret);
+    if (Status != STATUS_OK)
+    {
+        msdc_dbg_print("kalDevPortWrite() reports error: %d", Status);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+} /* end of kalDevPortWrite() */
+
+
+kal_int32
+wlanImageSectionDownload (
+    // P_ADAPTER_T  prAdapter,
+    kal_int32      u4DestAddr,
+    kal_int32      u4ImgSecSize,
+    kal_int8      *pucImgSecBuf
+)
+{
+
+
+    kal_uint32 i, u4Value;
+    P_HIF_HW_TX_HEADER_T prHifTxHeader;
+
+    WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+    kal_uint8 * pucDmaBuf;
+    kal_uint32 u4TotalLen;
+    kal_uint32 u4DmaLen;
+    kal_uint32 u4DmaOffset;
+
+    //ASSERT(prAdapter);
+    //ASSERT(pucImgSecBuf);
+    //ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE);
+
+    msdc_dbg_print("wlanImageSectionDownload");
+    //DBGLOG(INIT, TRACE, ("Destination: 0x%08x / Length: 0x%08x\n", u4DestAddr, u4ImgSecSize));
+    msdc_dbg_print("Destination: 0x%08x / Length: 0x%08x", u4DestAddr, u4ImgSecSize);
+
+    if (u4ImgSecSize == 0)
+    {
+        return WLAN_STATUS_SUCCESS;
+    }
+
+    // 1. Use TX coalescing buffer
+    prHifTxHeader = (P_HIF_HW_TX_HEADER_T)(&wndrv_cmd_temp_buf[0]);
+
+    // 2. Setup HIF_TX_HEADER
+    //prHifTxHeader->u2TxByteCount = (UINT_16)(ALIGN_4(sizeof(HIF_HW_TX_HEADER_T) + u4ImgSecSize));
+    prHifTxHeader->u2TxByteCount = (kal_uint16)(ALIGN_4(HIF_HW_TX_HDR_SIZE + u4ImgSecSize));
+    prHifTxHeader->ucEtherTypeOffset = 0;
+    prHifTxHeader->ucCSflags = 0;
+
+    // 3. Copy payload
+    memcpy((void *)prHifTxHeader->aucBuffer, (void *)pucImgSecBuf, u4ImgSecSize);
+
+    // 3.1 add 4-bytes zero tail
+    //kalMemZero(&(prHifTxHeader->aucBuffer[ALIGN_4(u4ImgSecSize)]), sizeof(HIF_HW_TX_HEADER_T));
+    memset(&(prHifTxHeader->aucBuffer[ALIGN_4(u4ImgSecSize)]), 0, HIF_HW_TX_HDR_SIZE);
+
+    // 4. Poll til FWDL_RDY = 1
+    i = 0;
+
+    while (1)
+    {
+        kalDevRegRead(MCR_FWDLSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_FWDLSR, &u4Value);
+
+        if (u4Value & FWDLSR_FWDL_RDY)
+        {
+            //DBGLOG(INIT, TRACE, ("FWDL_RDY detected\n"));
+            msdc_dbg_print("FWDL_RDY detected", u4DestAddr, u4ImgSecSize);
+            break;
+        }
+        else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+        {
+            //DBGLOG(INIT, ERROR, ("Waiting for FWDL_RDY: Timeout (0x%08X)\n", u4Value));
+            msdc_dbg_print("Waiting for FWDL_RDY: Timeout (0x%x)", u4Value);
+            u4Status = WLAN_STATUS_FAILURE;
+            break;
+        }
+        else
+        {
+            i++;
+            kal_sleep_task(10);
+        }
+    }
+
+    // 5. Send firmware
+    kalDevRegWrite(WEHTCR, ALIGN_4(prHifTxHeader->u2TxByteCount));//HAL_MCR_WR(prAdapter, WEHTCR, ALIGN_4(prHifTxHeader->u2TxByteCount));
+    u4TotalLen = ALIGN_4(prHifTxHeader->u2TxByteCount);
+
+    //HAL_PORT_WR(prAdapter,MCR_FWDLDR,u4TotalLen,(PUINT_8)prHifTxHeader,prAdapter->u4CoalescingBufCachedSize);
+    if (u4TotalLen > 4)
+    {
+        kalDevRegWrite(WEHTCR, ALIGN_4(u4TotalLen));//HAL_MCR_WR(_prAdapter, WEHTCR, ALIGN_4(u4TotalLen));
+    }
+
+    if (kalDevPortWrite(MCR_FWDLDR, u4TotalLen, (kal_uint8 *)prHifTxHeader) == KAL_FALSE)
+    {
+        //HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR);
+        //fgIsBusAccessFailed = TRUE;
+        msdc_dbg_print("HAL_PORT_WR access fail! 0x%x\n", MCR_FWDLDR);
+    }
+
+    kalDevRegWrite(WEHTCR, 4);//HAL_MCR_WR(prAdapter, WEHTCR, 4);
+
+    return u4Status;
+
+}
+void  wndrv_wifi_hifsys_init( void )
+{
+    //    P_ADAPTER_T prAdapter = wndrv_context.adpt_p;
+    kal_uint32     u4Value;
+    kal_uint32  counter = 0;
+
+    do
+    {
+        kalDevRegWrite(WHLPCR, 0x00000200);//HAL_MCR_WR( prAdapter, WHLPCR, 0x00000200 );
+        kalDevRegRead(WHLPCR, &u4Value);//HAL_MCR_RD(prAdapter, WHLPCR, &u4Value);
+
+        //kal_sleep_task(10);
+        if ( counter++ > 512 )
+        {
+            msdc_dbg_print("[eHPI test]Request FW-Own back failed! (times=%d)", counter );
+            break;
+            //ASSERT(0);
+        }
+    }
+    while ( !(u4Value & 0x00000100) );
+
+    kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+}
+int  wndrv_prepare_test( int test_number )
+{
+    unsigned int response = 0;
+    //P_ADAPTER_T prAdapter = wndrv_context.adpt_p;
+    kal_uint32 reg_value = 0;
+    kal_uint32 ret;
+    kal_uint32 loop_count = 0;
+
+    msdc_dbg_print("wndrv_prepare_test():#%d", test_number);
+
+    /* write test number */
+    ret = kalDevRegWrite(H2DSM0R, (unsigned int)test_number);//HAL_MCR_WR( prAdapter, H2DSM0R, (unsigned int)test_number );
+
+    if (ret == -1)
+    {
+        msdc_dbg_print("Reg write error\r\n");
+    }
+
+
+    /* interrupt firmware: H2D[31] */
+    //    HAL_MCR_WR( prAdapter, WSICR, 1 << 31 );
+    ret = kalDevRegWrite(WSICR, 0x80000000);//HAL_MCR_WR( prAdapter, WSICR, 0x80000000 );
+
+    if (ret == -1)
+    {
+        msdc_dbg_print("Reg write error\r\n");
+    }
+
+
+    /* wait for response */
+    while (1)
+    {
+        kalDevRegRead(WHISR, &reg_value);//HAL_MCR_RD( prAdapter, WHISR, &reg_value );
+
+        if ( reg_value & (0x80000000) ) /* check bit_31 of WHISR */
+        {
+            kalDevRegRead(D2HRM0R, &response);//HAL_MCR_RD( prAdapter, D2HRM0R, &response );
+            msdc_dbg_print("WHISR = [%x]", reg_value);
+            msdc_dbg_print("response = [%x]", response);
+            break;
+        }
+        else
+        {
+            kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 ); /* enable interrupt */
+            kal_sleep_task(1);//kalUdelay(10);
+
+            //if ( loop_count++ > 500000 )
+            if ( loop_count++ > 5120 )
+            {
+                msdc_dbg_print("Pollin WHISR fail");
+                return -1;
+            }
+
+            msdc_dbg_print("Pollin WHISR...");
+        }
+    }
+
+    if ( response == test_number + 1 )
+    {
+        return 0;
+    }
+    else if ( response == test_number - 1 )
+    {
+        return -1;
+    }
+    else /* unexpected response */
+    {
+        return -1;
+    }
+}
+
+kal_int32 wndrv_generate_random_payload(unsigned char *buf, int len)
+{
+    int i;
+
+    //randomize();
+
+    for (i = 0 ; i < len ; i++)
+        buf[i] = (unsigned char)(rand() & 0xff);
+
+    return 0;
+}
+
+kal_int32 wndrv_generate_test_frame(unsigned char *buf,	int len, Data_Pattern type)
+{
+    // controls pattern (initialization included)
+    //unsigned char test_cnt = 5;
+    //unsigned char i;
+    //    unsigned char *payload = NULL;
+    unsigned short payload_s = 0;
+    unsigned char *dst = buf;
+    int offset = 0;
+    NIC_HIF_TX_HEADER_T txHeader;
+    //    payload = get_ctrl_buffer(1500);
+    payload_s = len - sizeof(NIC_HIF_TX_HEADER_T);
+
+
+    // attach NIC_HIF_TX_HEADER_T in the head
+
+    txHeader.u2TxByteCount      = len;
+    txHeader.ucEtherTypeOffset  = 0x0;//(sizeof(NIC_HIF_TX_HEADER_T) + 12) / 2;
+    txHeader.ucCSUMFlags        = 0x0; // [UT = 0 / I = 0]
+    txHeader.dummy[0]       = 0x0;
+    txHeader.dummy[1]       = 0x0;
+    txHeader.dummy[2]       = 0x0;
+
+    kal_mem_cpy(&dst[offset], &txHeader, sizeof(NIC_HIF_TX_HEADER_T));
+    offset += sizeof(NIC_HIF_TX_HEADER_T);
+
+    // payload generation
+    switch (type)
+    {
+        case RANDOM:
+            if (payload_s > 0)
+            {
+                wndrv_generate_random_payload(&payload[0], payload_s);
+            }
+
+            break;
+
+        case DATA_FF:
+            memset (payload, 0xFF , payload_s);
+            break;
+
+        case DATA_00:
+            memset (payload, 0x00 , payload_s);
+            break;
+
+        case DATA_F0:
+            memset (payload, 0xF0 , payload_s);
+            break;
+
+        case DATA_0F:
+            memset (payload, 0x0F , payload_s);
+            break;
+
+        case DATA_55:
+            memset (payload, 0x55 , payload_s);
+            break;
+
+        case DATA_99:
+            memset (payload, 0x99 , payload_s);
+            break;
+
+        case DATA_AA:
+            memset (payload, 0xAA , payload_s);
+            break;
+
+        case DATA_66:
+            memset (payload, 0x66 , payload_s);
+            break;
+
+        default:
+            memset (payload, 0x11 , payload_s);
+            break;
+    }
+
+    // memcpy for generated frame
+    kal_mem_cpy(&dst[offset], &payload[0], payload_s);
+    //    free_ctrl_buffer(payload);
+    return 0;
+}
+
+void HAL_PORT_WR(kal_uint16 _u4Port, kal_uint16 _u4Len, kal_uint8 * _pucBuf)
+{
+    if (_u4Len > 4)
+    {
+        kalDevRegWrite( WEHTCR, ALIGN_4(_u4Len));
+    }
+
+    if (kalDevPortWrite(_u4Port, _u4Len, _pucBuf) == KAL_FALSE)
+    {
+        msdc_dbg_print("HAL_PORT_WR access fail! 0x%x\n", _u4Port);
+    }
+    else
+    {
+        /*fgResult = TRUE;*/
+    }
+
+    kalDevRegWrite( WEHTCR, 4);
+}
+void HAL_PORT_RD(kal_uint16 _u4Port, kal_uint16 _u4Len, kal_uint8 * _pucBuf)
+{
+    if (_u4Len > 4)
+    {
+        kalDevRegWrite(WEHTCR, ALIGN_4(_u4Len));
+    }
+
+    if (kalDevPortRead(_u4Port, _u4Len, _pucBuf) == KAL_FALSE)
+    {
+        msdc_dbg_print(" access fail! 0x%x\n", _u4Port);
+    }
+    else
+    {
+        /*fgResult = TRUE;*/
+    }
+
+    kalDevRegWrite( WEHTCR, 4);
+}
+
+
+
+kal_int32 SDIO_test_main_MT5931_SDIOISR( SD_BITWIDTH bus )
+{
+    DCL_CTRL_DATA_T sdiodata;
+    DCL_CTRL_DATA_T Data;
+    DCL_SDC_CMD_STATUS status = STATUS_OK;
+    kal_uint32      counter, u4Status, u4Value, u4Pass = 0, u4FileSize, wndrv_firmware_loopback_size, u4Actual_length, reg_value, u4FwLoadAddr, i;
+    kal_uint8 const *wndrv_firmware_loopback_p;
+    kal_uint8  fgIsPass = 0;
+    kal_uint16 u2Packet_Len;
+    kal_uint8   TX_DMA = 0; //MCU
+    kal_uint8   RX_DMA = 0; //MCU
+    kal_uint8   data_type = 0;
+    kal_uint32	u4DmaLen, u4DmaOffset1, u4DmaOffset2;
+    kal_int32 ret;
+    //    unsigned char *pucTXBuf = NULL;
+    //    unsigned char *pucRXBuf = NULL;
+    kal_uint32  loopback_times = 10;
+    //    pucTXBuf = get_ctrl_buffer(1500);
+    //    pucRXBuf = get_ctrl_buffer(1500);
+
+POWER_ON_AGAIN:
+
+
+    msdc_dbg_print("[%s %d]start,bus=%d", __FUNCTION__, __LINE__, bus);
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+    //-------------------------------------------------------------------------
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+
+    //-------------------------------------------------------------------------
+    DclSDIO_Initialize();
+    handle_sdio = DclSDIO_Open(DCL_SDIO, DCL_SDIO_FLAGS_DEVICE_CARD1 | DCL_SDIO_FLAGS_USAGE_CMD | DCL_SDIO_FLAGS_SDIO1);
+    msdc_dbg_print( "[%s %d]The SDIO handle_sdio is 0x%x", __FUNCTION__, __LINE__, handle_sdio);
+
+    if ( handle_sdio  == DCL_HANDLE_INVALID )
+    {
+        msdc_dbg_print("[%s %d]ERROR \r\n", __FUNCTION__, __LINE__);
+        return -1;
+    }
+
+    //-------------------------------------------------------------------------
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT, NULL);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    //-------------------------------------------------------------------------
+    status = SDIO_configure_bus(bus);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,bus=%d(0:1bit; 2:4bit)", __FUNCTION__, __LINE__, bus);
+    }
+
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMDREG.data = 128;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_MCUDMA_WRITE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_MCUDMA_READ, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,mcudma=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+    }
+
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMDREG.data = 20000; // 20000KHZ
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SETCLK, &sdiodata);
+
+    if (STATUS_OK == status)
+    {
+        sdiodata.rSDIOCMDREG.data = 0;
+        status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GETCLK, &sdiodata);
+
+        if (STATUS_OK != status)
+        {
+            kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]ERROR", __FUNCTION__, __LINE__);
+            return ;
+        }
+        else
+        {
+            kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]OK,SDIO_CTRL_CMD_GETCLK=%d", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+        }
+    }
+    else
+    {
+        kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]ERROR", __FUNCTION__, __LINE__);
+        return ;
+    }
+
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMDREG.data = 0;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CLKSRC_READ, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,clksrc=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+    }
+
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMDREG.data = 0;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SCLKF_READ, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,sclkf=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+    }
+
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMDREG.data = 0;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CLKPADRED_READ, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,msdc_iocon.clkpadred=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+    }
+
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("[%s %d]CCCR TEST \r\n", __FUNCTION__, __LINE__);
+    {
+        kal_int32 i;
+
+        for (i = 0; i < 0x14; i++)
+        {
+            sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+            sdiodata.rSDIOCMD52.addr = i;
+            sdiodata.rSDIOCMD52.rdata = 0;
+            status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &sdiodata);
+
+            if (STATUS_OK != status)
+            {
+                msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+                return;
+            }
+            else
+            {
+                msdc_dbg_print("[%s %d]OK,CCCR[0x%x]=0x%x,R5=0x%x \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMD52.addr, sdiodata.rSDIOCMD52.rdata, sdiodata.rSDIOCMD52.r5_resp);
+            }
+        }
+    }
+    //-------------------------------------------------------------------------
+    sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+    sdiodata.rSDIOCMD52.addr = 4;
+    sdiodata.rSDIOCMD52.wdata = 3;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_WRITE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+        sdiodata.rSDIOCMD52.addr = 4;
+        sdiodata.rSDIOCMD52.rdata = 0;
+        status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &sdiodata);
+
+        if (STATUS_OK != status)
+        {
+            msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+            return;
+        }
+        else
+            msdc_dbg_print("[%s %d]OK,CCCR[0x%x]=0x%x,R5=0x%x \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMD52.addr, sdiodata.rSDIOCMD52.rdata, sdiodata.rSDIOCMD52.r5_resp);
+    }
+
+    //-------------------------------------------------------------------------
+    msdc_dbg_print("[%s %d]SET BLOCKSIZE=512 \r\n", __FUNCTION__, __LINE__);
+    sdiodata.rSDIOSetBlkSize.function = DCL_SDIO_FUCN_0;
+    sdiodata.rSDIOSetBlkSize.size = 512;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SET_BLK_SIZE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    sdiodata.rSDIOSetBlkSize.size = 0;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GET_BLK_SIZE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,blocksize=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOSetBlkSize.size);
+    }
+
+    sdiodata.rSDIOSetBlkSize.function = DCL_SDIO_FUCN_1;
+    sdiodata.rSDIOSetBlkSize.size = 512;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SET_BLK_SIZE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    sdiodata.rSDIOSetBlkSize.size = 0;
+    status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GET_BLK_SIZE, &sdiodata);
+
+    if (STATUS_OK != status)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[%s %d]OK,blocksize=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOSetBlkSize.size);
+    }
+
+    //guilin
+    status = kalDevWriteWithSdioCmd52(4, 3); // enable sdio interrupt
+
+    if (status != STATUS_OK)
+    {
+        msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+        return;
+    }
+
+    //-------------------------------------------------------------------------
+
+    //-------------------------------------------------------------------------
+    /* 0. Read Chip ID */
+    if (STATUS_OK != kalDevRegRead(WCIR, &u4Value)) //HAL_MCR_RD( prAdapter, WCIR, &u4Value );
+    {
+        msdc_dbg_print("[%s %d]Error", __FUNCTION__, __LINE__);
+        return;
+    }
+    else
+    {
+        msdc_dbg_print("[eHPI test]Chip ID = %x", u4Value & 0xfffff );
+    }
+
+    /* 1.1 wait for INIT_RDY */
+    i = 0;
+
+    while (1)
+    {
+        kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+
+        if (u4Value & WMCSR_INI_RDY)
+        {
+            msdc_dbg_print("INIT-RDY detected");
+            break;
+        }
+        else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+        {
+            msdc_dbg_print("Waiting for Init Ready bit: Timeout");
+            u4Status = WLAN_STATUS_FAILURE;
+            //ASSERT(u4Status == WLAN_STATUS_SUCCESS);
+            return;
+        }
+        else
+        {
+            i++;
+            kal_sleep_task(10);
+        }
+    }
+
+    wndrv_firmware_loopback_size = sizeof(mt5931_E3_Beta_loopback_firmware_hex);
+    u4FileSize = wndrv_firmware_loopback_size;
+    /* 1.2 set KSEL/FLEN */
+    msdc_dbg_print("1.2 set KSEL/FLEN = %d", u4FileSize);
+    kalDevRegWrite(MCR_FWCFG, u4FileSize >> 6);//    HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FileSize >> 6);
+    /* 1.3 enable FWDL_EN */
+    msdc_dbg_print("1.3 enable FWDL_EN");
+    kalDevRegWrite(FWDLCMR0, WMCSR_FWDLEN | WMCSR_FWDLRST); //HAL_MCR_WR( prAdapter, FWDLCMR0, WMCSR_FWDLEN|WMCSR_FWDLRST);
+    kalDevRegWrite(FWDLCMR0, WMCSR_FWDLEN);//HAL_MCR_WR( prAdapter, FWDLCMR0, WMCSR_FWDLEN);
+    /* 1.4 wait for PLL_RDY */
+    msdc_dbg_print("1.4 wait for PLL_RDY");
+    i = 0;
+
+    while (1)
+    {
+        kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+        msdc_dbg_print("[%s %d]MCR_WMCSR=0x%x ", __FUNCTION__, __LINE__, u4Value);
+
+        if (u4Value & WMCSR_PLLRDY)
+        {
+            msdc_dbg_print("PLL-RDY detected\n");
+            break;
+        }
+        else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+        {
+            msdc_dbg_print("Waiting for PLL Ready bit: Timeout\n");
+            u4Status = WLAN_STATUS_FAILURE;
+            //kal_sleep_task(1000);
+            //goto POWER_ON_AGAIN;
+            return;
+        }
+        else
+        {
+            i++;
+            kal_sleep_task(10);
+        }
+    }
+
+    /* 2.1 turn on HIFSYS firmware download mode */
+    msdc_dbg_print("2.1 turn on HIFSYS firmware download mode");
+    kalDevRegWrite(MCR_FWDLSR, FWDLSR_FWDL_MODE);//HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE);
+    /* 2.2 set starting address */
+    wndrv_firmware_loopback_p = mt5931_E3_Beta_loopback_firmware_hex;
+    u4FwLoadAddr = CFG_FW_LOAD_ADDRESS;
+    kalDevRegWrite(MCR_FWDLDSAR, u4FwLoadAddr);//HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr);
+    msdc_dbg_print("[eHPI test]0. Firmware Download" );
+
+    for (i = 0; i < u4FileSize ; i += CMD_PKT_SIZE_FOR_IMAGE)
+    {
+        if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FileSize)
+            u4Actual_length = CMD_PKT_SIZE_FOR_IMAGE;
+        else
+            u4Actual_length = u4FileSize - i;
+
+        //if(wlanImageSectionDownload(prAdapter,u4FwLoadAddr + i,u4Actual_length,(kal_uint8 *)wndrv_firmware_loopback_p + i) != WLAN_STATUS_SUCCESS)
+        if (wlanImageSectionDownload(u4FwLoadAddr + i, u4Actual_length, (kal_uint8 *)wndrv_firmware_loopback_p + i) != WLAN_STATUS_SUCCESS)
+        {
+            msdc_dbg_print("Firmware scatter download failed!");
+            return;
+        }
+    }
+
+    /* 4.1 poll FWDL_OK & FWDL_FAIL bits */
+    i = 0;
+
+    while (1)
+    {
+        kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+        msdc_dbg_print("[%s %d]MCR_WMCSR=0x%x ", __FUNCTION__, __LINE__, u4Value);
+
+        if (u4Value & WMCSR_DL_OK)
+        {
+            msdc_dbg_print("DL_OK detected\n");
+            break;
+        }
+        else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+        {
+            msdc_dbg_print("Waiting for DL_OK/DL_FAIL bit: Timeout\n");
+            u4Status = WLAN_STATUS_FAILURE;
+            //ASSERT(u4Status == WLAN_STATUS_SUCCESS); //TODO(Nelson): error handling for this
+            return;
+        }
+        else
+        {
+            i++;
+            kal_sleep_task(10);
+        }
+    }
+
+    /* 4.2 turn off HIFSYS download mode */
+    kalDevRegWrite(MCR_FWDLSR, 0);//HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0);
+
+    /* 5. disable interrupt */
+    kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_CLR);//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);//nicDisableInterrupt(prAdapter);
+
+    msdc_dbg_print("wlanAdapterStart(): Waiting for Ready bit..\n");
+    /* 6. check Wi-Fi FW asserts ready bit */
+    i = 0;
+
+    while (1)
+    {
+        kalDevRegRead(MCR_WCIR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+        if (u4Value & WCIR_WLAN_READY)
+        {
+            msdc_dbg_print("Ready bit asserted\n");
+            break;
+        }
+        else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+        {
+            msdc_dbg_print("Waiting for Ready bit: Timeout\n");
+            u4Status = WLAN_STATUS_FAILURE;
+            //ASSERT(u4Status == WLAN_STATUS_SUCCESS); //TODO(Nelson): error handling for this
+            return;
+        }
+        else
+        {
+            i++;
+            kal_sleep_task(10);
+        }
+    }
+
+    msdc_dbg_print("[eHPI test]1. Chip ID/Revision ID" );
+    kalDevRegRead(WCIR, &reg_value );//HAL_MCR_RD( prAdapter, WCIR, &reg_value );
+    msdc_dbg_print("[eHPI test]Chip ID/Revision ID = %x", reg_value );
+
+    msdc_dbg_print("[eHPI test]2. Request FW-Own back" );
+    kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_SET);//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+
+#if 1
+    {
+        DCL_HANDLE handle_eint1;
+
+        //handle_eint1 = DclGPIO_Open(DCL_GPIO,MT5931_EINT); // MT5931,WIFI_EINT
+        //DclGPIO_Control(handle_eint1,GPIO_CMD_SET_MODE_6,0);
+        //DclGPIO_Control(handle_eint1,GPIO_CMD_SET_MODE_3,0);
+        //DclGPIO_Close(handle_eint1);
+
+        EINT_Registration( MT5931_EINT_NUM,
+                           KAL_FALSE,     /* DbounceEn */
+                           KAL_TRUE,    /* ACTPolarity */
+                           test_hisr,
+                           KAL_FALSE/* AutoUnmask */ );
+        /* set new debounce value */
+        EINTaddr(MT5931_EINT_NUM) |= 2;
+        /* Set Software debounce time 0 */
+        EINT_SW_Debounce_Modify(MT5931_EINT_NUM, 0);
+
+        // James modify for setting GPIO52 enable
+        kal_sleep_task(10);
+
+
+    }
+#endif
+    msdc_dbg_print("[%s %d]", __FUNCTION__, __LINE__);
+    wndrv_wifi_hifsys_init();
+    ret = kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+    if ( wndrv_prepare_test( 3 ) == -1 )    /* item 3 for intr loopback test */
+    {
+        msdc_dbg_print("Test #1: FW cannot do the test.\n");
+        //ASSERT(0);
+    }
+
+#if 1
+    /* Loopback test TXRX*/
+    fgIsPass = 1;
+    kalDevRegRead(WHCR, &reg_value);//HAL_MCR_RD( prAdapter, WHCR, &reg_value );
+    kalDevRegWrite(WHCR, reg_value | 0x00010000);//HAL_MCR_WR( prAdapter, WHCR, reg_value | 0x00010000 ); //Enable RX_Enhance_Mode
+    kalDevRegRead(WHCR, &reg_value);//HAL_MCR_RD( prAdapter, WHCR, &reg_value );
+    msdc_dbg_print("WHCR: %x\n", reg_value);
+    msdc_dbg_print("[eHPI test]>>WIFI HIFSYS Loopback test");
+
+    u2Packet_Len = TEST_PACKET_MIN_LENGTH;
+
+    do
+    {
+        u2Packet_Len = u2Packet_Len < TEST_PACKET_MAX_LENGTH ? u2Packet_Len += 4 : TEST_PACKET_MIN_LENGTH;
+        data_type = u4Pass % 10;
+        TX_DMA = (u4Pass + 3) % 3;
+        RX_DMA = (u4Pass + 2) % 2;
+        TX_DMA = 1;
+        RX_DMA = 1;
+
+        //TX with DMA or MCU Start
+        if (TX_DMA)
+        {
+            u4DmaLen = u2Packet_Len;
+            u4DmaOffset1 = CPU_CACHE_LINE_SIZE - ((kal_uint32)ucDmaBuf & CPU_CACHE_LINE_SIZE_MASK);
+
+            //1. 32byte non-ailgn block
+            if ( (u4DmaOffset1 != 0) && (u4DmaOffset1 != CPU_CACHE_LINE_SIZE) )
+            {
+                u4DmaLen -= u4DmaOffset1;
+            }
+
+            //2. 32byte-align block, Only 32byte-align block will be TX
+            u4DmaOffset2 = u4DmaLen & CPU_CACHE_LINE_SIZE_MASK;
+            //u4DmaLen -=u4DmaOffset2;
+            // generate test frame
+            wndrv_generate_test_frame(ucDmaBuf + u4DmaOffset1, u4DmaLen, (Data_Pattern) data_type);
+            kalDevRegWrite(WEHTCR, ALIGN_32(u4DmaLen));//HAL_MCR_WR(prAdapter, WEHTCR, ALIGN_32(u4DmaLen));
+            //kalDevPortWriteData( WTDR0, ALIGN_4(u4DmaLen), &ucDmaBuf[u4DmaOffset1] );
+            HAL_PORT_WR( WTDR0, u4DmaLen, ucDmaBuf + u4DmaOffset1);
+            kal_mem_cpy(pucTXBuf, ucDmaBuf + u4DmaOffset1, u4DmaLen);
+            //3. remain 32byte non-align block
+            /*pucTXBuf += u4DmaLen;
+            u4DmaLen = u4DmaOffset2;
+
+            if( u4DmaLen != 0)
+            {
+                kalDevPortWriteData(MCR_WTDR0, u4DmaLen, pucTXBuf);
+            }*/
+        }
+        else
+        {
+            u4DmaLen = u2Packet_Len;
+            u4DmaOffset1 = 0;
+            wndrv_generate_test_frame(pucTXBuf, u4DmaLen, (Data_Pattern) data_type);
+            kalDevRegWrite(WEHTCR, u4DmaLen);//HAL_MCR_WR( prAdapter, WEHTCR, u4DmaLen );
+            HAL_PORT_WR( WTDR0, u4DmaLen, pucTXBuf);
+        }
+
+        //TX with DMA or MCU END
+
+        counter = 0;
+
+        while (1)
+        {
+            kalDevRegRead(WHISR, &reg_value);//HAL_MCR_RD( prAdapter, WHISR, &reg_value );
+
+            if ( reg_value & 0x1 ) /* check TX0 TX1 done */
+            {
+                kalDevRegRead(WTSR0, &reg_value);//HAL_MCR_RD( prAdapter, WTSR0, &reg_value );
+                //WNDRV_PROMPT_TRACE0( TRACE_INFO, "[eHPI test]>> TX Done");
+            }
+            else if ( reg_value & 0x2 ) /* check RX0 RX1 done */
+            {
+                kalDevRegRead(WTSR0, &reg_value);//HAL_MCR_RD( prAdapter, WTSR0, &reg_value );
+                kal_sleep_task(10);
+                kalDevRegRead(WRPLR, &reg_value);//HAL_MCR_RD( prAdapter, WRPLR, &reg_value );
+                kalDevRegWrite(WEHTCR, reg_value);//HAL_MCR_WR( prAdapter, WEHTCR, reg_value );
+
+                if (RX_DMA)
+                {
+                    u4DmaOffset1 = CPU_CACHE_LINE_SIZE - ((kal_uint32)ucDmaBuf & CPU_CACHE_LINE_SIZE_MASK);
+                    reg_value = (reg_value + 31) & ~31u;
+                    HAL_PORT_RD(WRDR0, reg_value, ucDmaBuf + u4DmaOffset1);
+                    kal_mem_cpy(pucRXBuf, ucDmaBuf + u4DmaOffset1, u4DmaLen);
+                }
+                else
+                {
+                    HAL_PORT_RD(WRDR0, reg_value, &pucRXBuf[0]);
+                }
+
+                break;
+            }
+            else
+            {
+                kal_sleep_task(10);
+                kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+
+                if ( counter++ > 1024 )
+                {
+                    msdc_dbg_print("[eHPI test]>> loopback test fail");
+                    fgIsPass = 0;
+                    DclSDIO_Close(handle_sdio);//wlanAdapterStop(prAdapter);
+                    return;
+                }
+            }
+        }
+
+        counter = 0;
+        reg_value = 0;
+
+        for (i = 0; i < (u4DmaLen - 16); i++)
+        {
+            u4Value = pucTXBuf[i + 16] - pucRXBuf[i + 12];
+
+            if (u4Value == 0)
+            {
+                counter++;
+            }
+            else
+            {
+                reg_value ++;
+                msdc_dbg_print("[eHPI test] Data Compare error, TX Mode: %x, RX Mode\n", TX_DMA, RX_DMA);
+                return;//ASSERT(0);
+            }
+        }
+
+        msdc_dbg_print("[eHPI test] Data Compare OK, TX Mode: %x, RX Mode\n", TX_DMA, RX_DMA);
+        kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+        kal_sleep_task(100);
+        u4Pass++ ;
+        msdc_dbg_print("[eHPI test]packets pass: %x", u4Pass );
+    }
+    while (u4Pass < loopback_times);
+
+    if ( fgIsPass == 1 )
+    {
+        msdc_dbg_print("[eHPI test]Total packets pass: 0x%x", u4Pass );
+        msdc_dbg_print("[eHPI test]Each Test Patern pass: 0x%x", u4Pass);
+        msdc_dbg_print("[eHPI test]TX DMA->RX DMA pass: 0x%x", u4Pass );
+        msdc_dbg_print("[eHPI test]TX DMA->RX MCU pass: 0x%x", u4Pass );
+        msdc_dbg_print("[eHPI test]TX MCU->RX DMA pass: 0x%x", u4Pass );
+        msdc_dbg_print("[eHPI test]TX MCU->RX MCU pass: 0x%x", u4Pass );
+        msdc_dbg_print("[eHPI test]Packet size 200 - 1500 loop count: 0x%x", u4Pass);
+    }
+
+    DclSDIO_Close(handle_sdio);//wlanAdapterStop(prAdapter);
+    //    free_ctrl_buffer(pucTXBuf);
+    //    free_ctrl_buffer(pucRXBuf);
+#endif
+
+    msdc_dbg_print("[%s %d]END", __FUNCTION__, __LINE__);
+}
+
+
+#endif
+
+#ifdef DRV_MSDC_BT
+
+#define MSC_CFG		(MSDC_ADRS+0x60)
+#define MSC_CMD	(MSDC_ADRS+0x64)
+
+#define MSC_CFG_SIEN			0x0001
+#define MSC_CFG_PMODE		0x8000
+
+kal_uint8 msdc_dmaport, msdc_dmaport2;
+DMA_INPUT msdc_input, msdc_input2;
+DMA_HWMENU msdc_menu, msdc_menu2;
+kal_uint32 tempReg;
+
+#pragma arm section zidata = "NONCACHEDZI",  rwdata = "NONCACHEDRW"
+kal_uint32 msdc_bt_buffer[128];
+#pragma arm section zidata, rwdata
+
+msdc_bt()
+{
+    kal_uint32 loopIndex2;
+    kal_uint32 baseAddrSpace;
+    dbg_print("MSDC_bt start\n\r");
+
+    //baseAddrSpace = MSDC2_base - MSDC_base;
+
+    /*turn on MSDC power gating*/
+#ifdef __OLD_PDN_ARCH__
+    DRVPDN_Disable(DRVPDN_CON1, DRVPDN_CON1_MSDC, PDN_MSDC);
+#else
+    DRVPDN_Disable(PDN_MSDC);
+#endif
+
+    //DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+
+    if (NULL == msdc_dmaport)
+    {
+        msdc_dmaport = DMA_GetChannel(DMA_MSDC);
+        msdc_menu.TMOD.burst_mode = KAL_TRUE;
+        msdc_menu.TMOD.cycle = 0x4;
+        msdc_menu.master = DMA_MSDC;
+        msdc_menu.addr = (kal_uint32)msdc_bt_buffer;
+        msdc_input.type = DMA_HWRX;
+        msdc_input.size = DMA_LONG;
+        msdc_input.count = 128;
+        msdc_input.menu = &msdc_menu;
+
+
+        //msdc_dmaport2 = DMA_GetChannel(DMA_MSDC2);
+        //msdc_menu2.TMOD.burst_mode = KAL_TRUE;
+        //msdc_menu2.TMOD.cycle = 0x4;
+        //msdc_menu2.master = DMA_MSDC2;
+        //msdc_menu2.addr = (kal_uint32)msdc_bt_buffer;
+        //msdc_input2.type = DMA_HWRX;
+        //msdc_input2.size = DMA_LONG;
+        //msdc_input2.count = 128;
+        //msdc_input2.menu = &msdc_menu2;
+
+    }
+
+
+
+    /*
+    	0x81110000 = 0x1aa20021
+    	0x81110004 = 0x2
+    	0x81110010 = 0x010F0008
+    	0x81110014 = 0x01000036
+    	0x81110020 = 0x28038200
+    	0x81110028 = 0x00048200
+    	write 0x02898 to 0x81110024 to write single block in 4bit SD mode
+    */
+
+    /*
+    	0x81110000 = 0x1aa20021
+    	0x81110004 = 0x2
+    	0x81110010 = 0x010F0008
+    	0x81110014 = 0x01000036
+    	0x81110020 = 0x28038200
+    	0x81110028 = 0x0
+    	write 0x0891 to 0x81110024 to read single block in 4bit SD mode
+    */
+
+    /*MSDC 1*/
+
+    /*configure DMA*/
+    msdc_input.type = DMA_HWTX;
+    DMA_Config_B2W(msdc_dmaport, &msdc_input, KAL_TRUE, KAL_FALSE);
+    DRV_WriteReg32(MSDC_CFG, 0x1aa20021);
+    DRV_WriteReg32(MSDC_STA, 0x2);
+    DRV_WriteReg32(MSDC_PS, 0x010F0008);
+    DRV_WriteReg32(MSDC_IOCON, 0x01000036);
+    DRV_WriteReg32(SDC_CFG, 0x28038200);
+    DRV_WriteReg32(SDC_ARG, 0x00048200);
+    DRV_WriteReg32(SDC_CMD, 0x02898);
+
+    /*wait data transfer*/
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    /*read out CMDSTA and DATSTA*/
+    tempReg = DRV_Reg32(SDC_CMDSTA);
+    tempReg = DRV_Reg32(SDC_DATSTA);
+
+    DMA_Stop(msdc_dmaport);
+    /*stop MSDC DMA and reset MSDC*/
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_DRQEN);
+    DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+    msdc_input.type = DMA_HWRX;
+    DMA_Config_B2W(msdc_dmaport, &msdc_input, KAL_TRUE, KAL_FALSE);
+    DRV_WriteReg32(MSDC_CFG, 0x1aa20021);
+    DRV_WriteReg32(MSDC_STA, 0x2);
+    DRV_WriteReg32(MSDC_PS, 0x010F0008);
+    DRV_WriteReg32(MSDC_IOCON, 0x01000036);
+    DRV_WriteReg32(SDC_CFG, 0x28038200);
+    DRV_WriteReg32(SDC_ARG, 0x0);
+    DRV_WriteReg32(SDC_CMD, 0x0891);
+
+    /*wait data transfer*/
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    /*read out CMDSTA and DATSTA*/
+    tempReg = DRV_Reg32(SDC_CMDSTA);
+    tempReg = DRV_Reg32(SDC_DATSTA);
+
+    DMA_Stop(msdc_dmaport);
+    /*stop MSDC DMA and reset MSDC*/
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_DRQEN);
+    DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+    /*MS test*/
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_MSDC);
+    DRV_SetBits(MSC_CFG, (MSC_CFG_PMODE | MSC_CFG_SIEN));
+    DRV_WriteReg(MSC_CMD, 0x20200);
+
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+    for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+    DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+
+    /*MSDC 2*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+    dbg_print("msdc_bt end\n\r");
+
+
+
+
+}
+#endif
+
+#ifdef MSDC_SDIO_DVT
+extern void test_sdio_ini(void );
+
+void MSDC_DVT_SDIO_test(void)
+{
+    test_sdio_ini();
+}
+#endif
+
+#ifdef MSDC2_SDIO_DVT
+extern void test_sdio_ini(void );
+
+void MSDC2_DVT_SDIO_test(void)
+{
+    test_sdio_ini();
+}
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+
+
+
+void ssdbg1_main_msdc(task_entry_struct *task_entry_ptr)
+{
+    SDC_CMD_STATUS status;
+    ilm_struct current_ilm;
+    ssdbg1_localpara_struct *paraptr;
+    kal_uint32 my_index;
+
+    kal_uint32 i = 0;
+    double	bestReadThroughput4Bit, worstReadThroughput4Bit, bestWriteThroughput4Bit, worstWriteThroughput4Bit;
+    kal_uint32 offset = 0, blkaddr, idx, loop;
+    char str[30];
+
+    /*
+    #ifdef MSDC_SDIO_DVT
+    MSDC_DVT_SDIO_test();
+    gMSDC_Handle->mIsInitialized = KAL_FALSE;
+    waitingSDIOTest = KAL_FALSE;
+    #endif
+
+    if(waitingSDIOTest){
+    kal_sleep_task(20);
+    }
+    */
+
+    kal_get_my_task_index (&my_index);
+    stack_set_active_module_id ( my_index, MOD_SSDBG1 );
+
+    //
+    // Initialize ILM, and timer
+    //
+    stack_init_timer(&ssdbg1_context.ssdbg1_timer0, "SSDBG1 Timer0", MOD_SSDBG1);
+
+    stack_start_timer(&ssdbg1_context.ssdbg1_timer0, 0, 10);
+
+    while (1)
+    {
+        kal_uint32 input, input2;
+        kal_uint32 addr;
+
+        MSDC_PDNControl(KAL_FALSE);
+
+        dbg_print("\r\n");
+        dbg_print("*********************************************************\r\n");
+        dbg_print("*                                                       *\r\n");
+        dbg_print("*                MT6280 MSDC Basicload                  *\r\n");
+        dbg_print("*                                                       *\r\n");
+        dbg_print("*********************************************************\r\n");
+
+        dbg_print("============================\r\n");
+        dbg_print(" 1  mount test...\r\n");
+        dbg_print(" 2  reg default test...\r\n");
+        dbg_print(" 3  read single test...\r\n");
+        dbg_print(" 4  write single test...\r\n");
+        dbg_print(" 5  read multi test...\r\n");
+        dbg_print(" 6  write multi test...\r\n");
+        dbg_print(" 7  set clock/odc...\r\n");
+        dbg_print(" 8  1-4 bit BUS test...\r\n");
+        dbg_print(" 9  read/write stress test...\r\n");
+        dbg_print("10  non-4N test...\r\n");
+        dbg_print("11  cache test...\r\n");
+        dbg_print("12  mount stress test...\r\n");
+        dbg_print("13  clock stress test...\r\n");
+        dbg_print("14  CLKPAD_RED test...\r\n");
+        dbg_print("15  FAT fastformat test...\r\n");
+        dbg_print("16  DMA.fix test...\r\n");
+        dbg_print("17  error test...\r\n");
+        dbg_print("18  odd-size test...\r\n");
+        dbg_print("19  burst type test...\r\n");
+        dbg_print("20  erase test...\r\n");
+        dbg_print("21  gpio test...\r\n");
+        dbg_print("22  \r\n");
+        dbg_print("23  throughput test...\r\n");
+        dbg_print("24  SD CMD test...\r\n");
+        dbg_print("25  MSDC initialize...\r\n");
+        dbg_print("26  dump register...\r\n");
+        dbg_print("27  set block number...\r\n");
+        dbg_print("28  edit script...\r\n");
+        dbg_print("29  sdio initialize test...\r\n");
+        dbg_print("30  sdio read/write test...\r\n");
+        dbg_print("31  sdio interrupt test...\r\n");
+        dbg_print("32  sdio MT5931 1-bit test...\r\n");
+        dbg_print("33  sdio MT5931 4-bit test...\r\n");
+        dbg_print("34  memory card sequential read...\r\n");
+        dbg_print("35  memory card sequential write...\r\n");
+        dbg_print("36  memory card random read...\r\n");
+        dbg_print("37  memory card random write...\r\n");
+        dbg_print("============================\r\n");
+
+        dbg_print("input:");
+        //input = U_GetUARTByte(uart_port1);
+        msdc_dbg_input(&input);
+        dbg_print("%d\r\n", input);
+
+        switch (input)
+        {
+            case 1:
+                sdtestcase1();
+                break;
+
+            case 2:
+                sdtestcase2();
+                break;
+
+            case 3:
+                sdtestcase3(rand()%gSD->mCSD.capacity / 512 - 1, msdc_sector_buf1);;
+                break;
+
+            case 4:
+                sdtestcase4(0, msdc_sector_buf1, msdc_sector_buf2);
+                break;
+
+            case 5:
+                sdtestcase5(0, msdc_uncachedBuf1);
+                break;
+
+            case 6:
+                sdtestcase6(0, msdc_uncachedBuf1, msdc_uncachedBuf2);
+                break;
+
+            case 7:
+                sdtestcase7();
+                break;
+
+            case 8:
+                sdtestcase8();
+                break;
+
+            case 9:
+                sdtestcase9();
+                break;
+
+            case 10:
+                sdtestcase10();
+                break;
+
+            case 11:
+                sdtestcase11();
+                break;
+
+            case 12:
+                sdtestcase12();
+                break;
+
+            case 13:
+                dbg_print("Input a test round:");
+                msdc_dbg_input(&input);
+                dbg_print("%c\r\n", input);
+
+                dbg_print("Input a count of one round:");
+                msdc_dbg_input(&input2);
+                dbg_print("%c\r\n", input2);
+
+                for (i = 0; i < input; i++)
+                {
+                    status = sdtestcase13(input2);
+
+                    if (status != NO_ERROR)
+                        break;
+                }
+
+                break;
+
+            case 14:
+                sdtestcase14();
+                break;
+
+            case 15:
+                sdtestcase15();
+                break;
+
+            case 16:
+                sdtestcase16();
+                break;
+
+            case 17:
+                sdtestcase17();
+                break;
+
+            case 18:
+                sdtestcase18();
+                break;
+
+            case 19:
+                sdtestcase19();
+                break;
+
+            case 20:
+                sdtestcase20(0, testsectors);
+                break;
+
+            case 21:
+                sdtestgpio2();
+                break;
+
+            case 22:
+
+                break;
+
+            case 23:
+                dbg_print("Input a test round:");
+                msdc_dbg_input(&input);
+                dbg_print("%c\r\n", input);
+
+                sdtestcase21(input);
+                break;
+
+            case 24:
+                sdtestcase22();
+                break;
+
+            case 25:
+                i = 0;
+                gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+                gMSDC_Handle->mIsInitialized = KAL_FALSE;
+                gMSDC_Handle->msdc_clkTuneUpperBund = MSDC_CLOCK / 2;
+                MSDC_PDNControl(KAL_FALSE);
+                kal_sleep_task(1);
+
+
+
+                MSDC_LSD_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+                while (MSDC_Reg32(MSDC_CFG) & 0x02)
+                {
+                    i++;
+                }
+
+                dbg_print("%d\r\n", i);
+
+                DclSD_Initialize();
+                break;
+
+            case 26:
+
+                dbg_print("\r\n0x");
+
+                while (1)
+                {
+                    input = U_GetUARTByte(uart_port1);
+
+                    if (input == 0x0d || input == 0x0a)
+                        break;
+
+                    if (input == ESCKEY)
+                        return;
+
+                    str[offset++] = input;
+                    dbg_print("%c", input);
+                }
+
+                str[offset] = 0;
+
+                dbg_print("\r\n");
+                sscanf(str, "%x", &input2);
+
+                dbg_print("\r\n %x", MSDC_Reg32(input2));
+                break;
+
+            case 27:
+                dbg_print("input a block number:\r\n");
+                msdc_dbg_input(&testblnum);
+                dbg_print("%c\r\n", testblnum);
+                break;
+
+            case 28:
+                dbg_print("input test case number:(ESC to cancel)\r\n");
+
+                while (1)
+                {
+
+                    msdc_dbg_input(&input);
+
+
+
+                }
+
+                break;
+
+            case 29:
+
+                status = vSDIOInitialisation_Test();
+                break;
+
+            case 30:
+                break;
+
+            case 31:
+                //status = vSDIOInterrupt_Test();
+                break;
+
+            case 32:
+#ifdef __MSDC_SD_SDIO__
+                gMSDC_Handle->trySingleLine = KAL_TRUE;
+                SDIO_test_main_MT5931_SDIOISR(BIT_1W);
+                dbg_print("\r\n\r\n");
+
+                //gMSDC_Handle->trySingleLine = KAL_FALSE;
+                //SDIO_test_main_MT5931_SDIOISR(BIT_4W);
+                //dbg_print("\r\n\r\n");
+#endif
+                break;
+
+            case 33:
+#ifdef __MSDC_SD_SDIO__
+                gMSDC_Handle->trySingleLine = KAL_FALSE;
+                SDIO_test_main_MT5931_SDIOISR(BIT_4W);
+                dbg_print("\r\n\r\n");
+#endif
+
+                break;
+
+                //
+                // sequential read.
+                //
+            case 34:
+
+                dbg_print("\r\nStart address:");
+                msdc_dbg_input(&input);
+                dbg_print("%c\r\n", input);
+
+                dbg_print("\r\nTransfer length:");
+                msdc_dbg_input(&input2);
+                dbg_print("%c\r\n", input2);
+
+
+
+                break;
+
+            case 35:
+
+                break;
+
+            case 36:
+
+                break;
+
+                //
+                // random read/write.
+                //
+            case 37:
+
+                while (1)
+                {
+
+                    idx = rand() % 4;
+                    blkaddr = rand() % gSD->mCSD.capacity / 512 - 1;
+
+                    testblnum = 1;
+                    loop = rand() % 10;
+
+                    for (i = 0; i < loop; i++)
+                        testblnum *= 2;
+
+                    if (blkaddr < 0)
+                        blkaddr = 0;
+
+                    if (blkaddr + testblnum >= gSD->mCSD.capacity / 512)
+                        blkaddr = gSD->mCSD.capacity / 512 - testblnum - 1;
+
+                    switch (idx)
+                    {
+
+                        case 0:
+                            status = sdtestcase3(blkaddr, msdc_sector_buf1);
+
+                            if (status != NO_ERROR)
+                                goto EXIT;
+
+                            break;
+
+                        case 1:
+                            status = sdtestcase4(blkaddr, msdc_sector_buf1, msdc_sector_buf2);
+
+                            if (status != NO_ERROR)
+                                goto EXIT;
+
+                            break;
+
+                        case 2:
+                            status = sdtestcase5(blkaddr, msdc_uncachedBuf1);
+
+                            if (status != NO_ERROR)
+                                goto EXIT;
+
+                            break;
+
+                        case 3:
+                            status = sdtestcase6(blkaddr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+                            if (status != NO_ERROR)
+                                goto EXIT;
+
+                            break;
+
+                        default:
+                            dbg_print("\r\nswitch error\r\n");
+                            break;
+                    }
+                }
+
+            EXIT:
+
+                if (status != NO_ERROR)
+                    msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+                else
+                    msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+
+                break;
+
+            default:
+                break;
+        }
+
+    }
+
+    while (1)
+    {
+
+        //MSDC_DVT_sleepModeCardDetectionTestMT6268A();
+        //receive_msg_ext_q(task_info_g[task_entry_ptr->task_indx].task_ext_qid, &current_ilm );
+        //msg_receive_extq(task_info_g[task_entry_ptr->task_indx].task_ext_qid, &current_ilm );
+        msg_receive_extq(&current_ilm);
+
+        switch (current_ilm.msg_id)
+        {
+
+            case MSG_ID_MSDC_CARD_DETECT_IND:
+                MSDC_GetCardStatus(&MSDC_Blk[0], 0);
+                bestReadThroughput = 0;
+                worstReadThroughput = 0;
+                bestWriteThroughput = 0;
+                worstWriteThroughput = 0;
+                dbg_print("card plug in/out");
+                MSDC_Blk[0].trySingleLine = KAL_FALSE;
+                MSDC_DVT_readWrite();
+                bestReadThroughput4Bit = bestReadThroughput;
+                bestReadThroughput = 0;
+                worstReadThroughput4Bit = worstReadThroughput;
+                worstReadThroughput = 0;
+                bestWriteThroughput4Bit = bestWriteThroughput;
+                bestWriteThroughput = 0;
+                worstWriteThroughput4Bit = worstWriteThroughput;
+                worstWriteThroughput = 0;
+                MSDC_Blk[0].trySingleLine = KAL_TRUE;
+                MSDC_Blk[0].mIsInitialized = KAL_FALSE;
+                MSDC_DVT_readWrite();
+
+                dbg_print("4 bit mode:");
+                dbg_print("\r\nwrite best: %f, worst:%f\r\n", bestWriteThroughput4Bit, worstWriteThroughput4Bit);
+                dbg_print("\r\nread best: %f, worst:%f\r\n", bestReadThroughput4Bit, worstReadThroughput4Bit);
+                dbg_print("1 bit mode:");
+                dbg_print("\r\nwrite best: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+                dbg_print("\r\nread best: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+                break;
+
+            default:
+                break;
+        }
+
+        free_ilm(&current_ilm);
+    }
+}
+
+
+#ifdef DRV_MSDC_MT6238_SERIES
+void MSDC2_DVT_readWrite(void);
+
+
+void
+ssdbg2_main_msdc( task_entry_struct * task_entry_ptr )
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#ifdef MSDC2_SDIO_DVT
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+void MSDC2_DVT_readWrite(void)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(NOT_4BYTES_ALIGN)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if 0 // read & write testing
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+#if 1//write 
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(NOT_4BYTES_ALIGN)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif //write
+/* under construction !*/
+#if 1 // read test
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif  // read test
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+}
+#else
+void ssdbg2_main_msdc ( task_entry_struct * task_entry_ptr )
+{
+}
+#endif
+#endif
+
+#else //this is the original MSDC test code full set
+
+void ssdbg1_main_msdc ( task_entry_struct * task_entry_ptr )
+
+{
+
+
+
+#ifdef MULTIPLE_WRITE_TEST
+    gMSDC_Handle->mIsPresent = KAL_TRUE;
+    simple_multi_write_test();
+    return;
+#endif
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+    //MSDC_Initialize();
+    //SD_Initialize();
+
+
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+
+    {
+        kal_int32 i, j, result = 0, count = 0;
+        kal_uint32 access = 17893;
+        FS_HANDLE hFile = 0, wFile = 0;
+        kal_wchar full_name[100];
+        kal_uint32  file_size, len, total_len;
+        kal_uint32 time_1, time_2;
+        double rate;
+        volatile kal_bool format = 0;
+        kal_uint8 offset1 = 0, offset2 = 0;
+        kal_uint32 timeUsedinFS;
+        int card;
+        kal_uint8 path[10];
+        FS_DiskInfo info;
+
+#if 0 //defined(MTK_FORMAT)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#ifdef TRANSCEND_CARD_ISSUE
+        j = 0;
+
+        if (gMSDC_Handle->mIsInitialized)
+        {
+            while (1)
+            {
+                result = FS_SdDrv.ReadSectors(gMSDC_Handle, 0x200, 4, w);
+                //result = FS_SdDrv.ReadSectors(gMSDC_Handle,0x100000,4,w);
+                //result = FS_SdDrv.ReadSectors(gMSDC_Handle,0x700000,4,w);
+                result = FS_SdDrv.ReadSectors(gMSDC_Handle, 0xf02c80, 4, w);
+
+                /*
+                for(i = 0; i<10; i++){
+                	w[i] = w[i]+1;
+                }
+                result = FS_SdDrv.WriteSectors(gMSDC_Handle,0xf04c80,4,w);
+                result = FS_SdDrv.ReadSectors(gMSDC_Handle,0xf04c80,4,r);
+                */
+                for (i = 0; i < 10; i++)
+                {
+                    if (w[i] !=  x[i])
+                    {
+                        dbg_print("%d-th byte has different in %d-th turn,%d, %d\r\n", i, j + 1, result, clkNeedB4Data);
+                    }
+                }
+
+                if (w[0] != x[0])
+                {
+                    errorCount ++;
+                    dbg_print("error rate %d/%d\r\n", errorCount, j);
+                }
+
+                j++;
+
+                if ((j & 0xff) == 0)
+                {
+                    dbg_print("finish %d-th turns\r\n", j);
+                }
+
+            }
+
+        }
+        else
+        {
+            while (1);
+        }
+
+#endif
+
+#ifdef WRITE_ALL_ZERO_DATA
+        j = 0;
+        //if(gMSDC_Handle->mIsInitialized){
+        DumpDiskInfo("d:\\");
+        /*make all zero data*/
+        kal_mem_set(allZeroDataArray, 0, 512);
+        i = min(gSD->mCSD.capacity / 512, 50);
+
+        for (j = 0; j < i; j++)
+        {
+            result = FS_SdDrv.WriteSectors(gMSDC_Handle, j, 1, allZeroDataArray);
+
+            if (0 != result)
+            {
+                dbg_print("write %d-th sector fail \r\n", j);
+                break;
+            }
+        }
+
+        if (0 == result)
+        {
+            dbg_print("clear all sector to zero doen\r\n");
+        }
+
+        while (1);
+
+        //}
+        //else{
+        //	while(1);
+        //}
+#endif
+
+
+        result = FS_TestMSDC(gMSDC_Handle);
+
+        if (result < FS_NO_ERROR)
+        {
+            dbg_print("memory card card not present %d !!\r\n", result);
+
+            while (1)
+                kal_sleep_task(1000);
+        }
+
+        card = FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
+
+        if (card >= FS_NO_ERROR)
+        {
+            kal_wsprintf((WCHAR*) path, "%c:\\", card);
+
+            result = FS_GetDiskInfo((WCHAR*) path, &info, FS_DI_BASIC_INFO | FS_DI_FREE_SPACE);
+
+            if (result < RTF_NO_ERROR)
+            {
+                ASSERT(0);
+            }
+
+
+        }
+        else
+        {
+            dbg_print("memory card card not present!!\r\n");
+
+            while (1)
+                kal_sleep_task(1000);
+        }
+
+#ifdef HW_FAST_FORMAT_TEST
+
+        while (1)
+        {
+            time_1 = drv_get_current_time();
+            result = FS_GeneralFormat((WCHAR*) path, FS_FORMAT_HIGH, NULL);
+
+            if (FS_NO_ERROR == result)
+            {
+                time_2 = drv_get_current_time();
+                dbg_print("format done %d, %f\n\r", time_2 - time_1, (double)(0.0005 * writeSectorsCount * 32000) / (double)(writeTimeCount));
+                writeSectorsCount = writeTimeCount = 0;
+                kal_sleep_task(1500);
+            }
+            else
+            {
+                dbg_print("format failed: %d \n\r", result);
+
+                while (1)
+                    kal_sleep_task(1000);
+
+            }
+        }
+
+#endif
+        //DumpDiskInfo("d:\\");
+        kal_wsprintf(full_name, "%c:\\Write.bin", card);
+
+        for (i = 0; i < LEN + 3; i++)
+        {
+            w[i + offset1] = i % 256;
+            r[i + offset2] = 0;
+
+#ifdef	CACHED_TEST
+            cached_w[i + offset1] = i % 256;
+            cached_r[i + offset2] = 0;
+#endif
+
+        }
+
+#if defined(NOT_4BYTES_ALIGN)
+        // test W to B or B to W(DMA)
+        offset1 = (kal_uint32)w % 4;
+
+        if (offset1 == 0)
+            offset1 = 1;
+        else
+            offset1 = 0;
+
+        offset2 = (kal_uint32)r % 4;
+
+        if (offset2 == 0)
+            offset2 = 1;
+        else
+            offset2 = 0;
+
+        for (i = 0; i < LEN + 3; i++)
+        {
+            w[i + offset1] = i % 256;
+            r[i + offset2] = 0;
+        }
+
+#endif
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+        while (1)
+        {
+
+#if 0 // read & write testing
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#if 1//write 
+
+            count++;
+            //Search_Dir(L"C:\\");
+            FS_Delete(full_name);
+#ifdef	CACHED_TEST
+
+            if (KAL_TRUE == cachedTest)
+                cachedTest = KAL_FALSE;
+            else
+                cachedTest = KAL_TRUE;
+
+            if (KAL_TRUE == cachedTest)
+                dbg_print("\r\n===========Cached Write Test Start(%d) ====================\r\n", count);
+            else
+#endif
+                dbg_print("\r\n==================Write Test Start(%d) ====================\r\n", count);
+
+            hFile = FS_Open(full_name, FS_CREATE | FS_READ_WRITE);
+
+            if (hFile <= 0)
+                continue;
+
+            //ASSERT(hFile>0);
+
+#if defined(NOT_4BYTES_ALIGN)
+            // test W to B or B to W(DMA)
+            offset1 = (kal_uint32)w % 4;
+
+            if (offset1 == 0)
+                offset1 = 1;
+            else
+                offset1 = 0;
+
+            offset2 = (kal_uint32)r % 4;
+
+            if (offset2 == 0)
+                offset2 = 1;
+            else
+                offset2 = 0;
+
+            for (i = 0; i < LEN + 3; i++)
+            {
+                w[i + offset1] = i % 256;
+                r[i + offset2] = 0;
+            }
+
+#endif
+            i = 0;
+            total_len = 0;
+
+            kal_get_time(&time_1);
+
+            //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2 = 0;
+            //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+            while (1)
+            {
+
+#ifdef	CACHED_TEST
+
+                if (KAL_TRUE == cachedTest)
+                    result = FS_Write(hFile, cached_w + offset1, LEN, &len);
+                else
+#endif
+                    result = FS_Write(hFile, w + offset1, LEN, &len);
+
+                total_len += len;
+                i++;
+
+                if (result < 0 )
+                {
+                    if (result == RTF_DISK_FULL)
+                        dbg_print("Disk Full %d\r\n", total_len);
+                    else
+                        dbg_print("write fail %d at: %d \r\n", result, total_len);
+
+                    break;
+                }
+
+                if (len != LEN)
+                    break;
+
+                if (i % TIMES == 0)
+                {
+                    kal_get_time(&time_2);
+                    rate = (double)(LEN * TIMES) / (double)(time_2 - time_1);
+                    dbg_print("write[%d], total: %d, rate %f \r\n", i, total_len, rate / 0.004615);
+                    //dbg_print("%d, %d, %d , %d\r\n", writeTime3 , writeTime4 , writeTime5,writeTime6);
+                    //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2= 0;
+                    //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+#ifdef	CACHED_TEST
+
+                    if (KAL_TRUE == cachedTest)
+                    {
+                        if ((rate / 0.004615) > cachedBestWriteThroughput || 0 == cachedBestWriteThroughput)
+                            cachedBestWriteThroughput = (rate / 0.004615);
+
+                        if ((rate / 0.004615) < cachedWorstWriteThroughput || 0 == cachedWorstWriteThroughput)
+                            cachedWorstWriteThroughput = (rate / 0.004615);
+                    }
+                    else
+#endif
+                    {
+                        if ((rate / 0.004615) > bestWriteThroughput || 0 == bestWriteThroughput)
+                            bestWriteThroughput = (rate / 0.004615);
+
+                        if ((rate / 0.004615) < worstWriteThroughput || 0 == worstWriteThroughput)
+                            worstWriteThroughput = (rate / 0.004615);
+                    }
+
+                    kal_get_time(&time_1);
+
+
+                    if (i == TIMES * 5) break;
+                }
+            }
+
+            FS_Close(hFile);
+
+#ifdef	CACHED_TEST
+
+            if (KAL_TRUE == cachedTest)
+                dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestWriteThroughput, cachedWorstWriteThroughput);
+            else
+#endif
+                dbg_print("\r\nbest: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+
+            dbg_print("\r\n==================Write Test End(%d) ====================\r\n", count);
+#endif //write
+
+#if 1 // read test
+
+#ifdef	CACHED_TEST
+
+            if (KAL_TRUE == cachedTest)
+                dbg_print("\r\n==========Cached Read Test Start(%d) ====================\r\n", count);
+            else
+#endif
+                dbg_print("\r\n==================Read Test Start(%d) ====================\r\n", count);
+
+            timeUsedinFS = 0;
+            i = 0;
+            total_len = 0;
+            hFile = FS_Open(full_name, FS_READ_WRITE);
+
+            if (hFile <= 0)
+                continue;
+
+            ASSERT(hFile > 0);
+
+            while (1)
+            {
+                kal_get_time(&time_1);
+
+#ifdef	CACHED_TEST
+
+                if (KAL_TRUE == cachedTest)
+                    result = FS_Read(hFile, cached_r + offset1, LEN, &len);
+                else
+#endif
+                    result = FS_Read(hFile, r + offset2, LEN, &len);
+
+                kal_get_time(&time_2);
+                timeUsedinFS += (time_2 - time_1);
+                i++;
+                total_len += len;
+
+                if (check_read_content)
+                {
+#ifdef	CACHED_TEST
+
+                    if (KAL_TRUE == cachedTest)
+                    {
+                        for (j = 0; j < len; j++)
+                        {
+                            if (cached_r[j + offset2] != cached_w[j + offset1])
+                            {
+                                dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+
+                                while (1);
+                            }
+
+                        }
+                    }
+                    else
+#endif
+                    {
+                        for (j = 0; j < len; j++)
+                        {
+                            if (r[j + offset2] != w[j + offset1])
+                            {
+                                dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+
+                                while (1);
+                            }
+
+                        }
+                    }
+
+                    dbg_print(".");
+#ifdef	CACHED_TEST
+
+                    if (KAL_TRUE == cachedTest)
+                        memset(cached_r, 0, sizeof(cached_r));
+                    else
+#endif
+                        memset(r, 0, sizeof(r));
+                }
+
+                if (result < 0)
+                {
+                    if (result != RTF_DISK_FULL)
+                        dbg_print("read fail %d, at: %d \r\n", result, total_len);
+                    else
+                        dbg_print("Disk Full \r\n");
+                }
+
+                if (len != LEN)
+                    break;
+
+                if (i % TIMES == 0)
+                {
+
+                    rate = (double)(LEN * TIMES) / (double)timeUsedinFS;
+                    dbg_print("read[%d], total: %d, rate: %f \r\n", i, total_len, rate / 0.004615);
+
+#ifdef	CACHED_TEST
+
+                    if (KAL_TRUE == cachedTest)
+                    {
+                        if ((rate / 0.004615) > cachedBestReadThroughput || 0 == cachedBestReadThroughput)
+                            cachedBestReadThroughput = (rate / 0.004615);
+
+                        if ((rate / 0.004615) < cachedWorstReadThroughput || 0 == cachedWorstReadThroughput)
+                            cachedWorstReadThroughput = (rate / 0.004615);
+                    }
+                    else
+#endif
+                    {
+                        if ((rate / 0.004615) > bestReadThroughput || 0 == bestReadThroughput)
+                            bestReadThroughput = (rate / 0.004615);
+
+                        if ((rate / 0.004615) < worstReadThroughput || 0 == worstReadThroughput)
+                            worstReadThroughput = (rate / 0.004615);
+                    }
+
+                    timeUsedinFS = 0;
+
+                    if (i == TIMES * 5) break;
+                }
+            }
+
+            FS_Close(hFile);
+
+#ifdef	CACHED_TEST
+
+            if (KAL_TRUE == cachedTest)
+                dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestReadThroughput, cachedWorstReadThroughput);
+            else
+#endif
+                dbg_print("\r\nbest: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+
+            dbg_print("\r\n==================Read Test End(%d) ====================\r\n", count);
+            FS_Delete(full_name);
+#endif  // read test
+        }
+
+        //=======================================//
+
+    }
+#endif
+
+}
+
+#endif//MSDC_DVT
+#endif//__MSDC_BASIC_LOAD__
diff --git a/mcu/driver/storage/mc/src/sd.c b/mcu/driver/storage/mc/src/sd.c
new file mode 100644
index 0000000..a35e6be
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd.c
@@ -0,0 +1,6853 @@
+ /*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sd.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   driver functons for SD/MMC
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+//#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "kal_debug.h"
+#include "init.h"
+
+#include "kal_trace.h"
+#include "dcl.h"
+#include "drv_comm.h"
+#include "drv_features.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "us_timer.h"
+#include "msdc_reg_adap.h"
+#include "reg_base.h"
+#include "msdc_api.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "upll_ctrl.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#if defined(__EMMC_BOOTING__)
+#include "FTL.h"
+#endif
+
+#ifdef DRV_LSD
+#include "msdc_lsd.h"
+
+
+
+extern void LSD_Host74TCMDHigh(void);
+extern kal_bool LSD_HostDetectBusy(void);
+#endif
+
+#if defined(__MSDC_SD_MMC__)
+//global variables
+T_SDC_HANDLE	gSD_blk[SD_NUM];
+T_SDC_HANDLE	*gSD = gSD_blk;
+
+/*global veriable ,operation by DMA ,alloc in uncached memory*/
+#ifdef MSDC_GPD_BD_BUF_CACHED
+msdc_gpd_t MSDC_gpd[SD_NUM];
+msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+msdc_bd_t  MSDC_bd[SD_NUM][MSDC_BD_MAX];
+#else
+__attribute__ ( (section ("NONCACHEDRW")))msdc_gpd_t MSDC_gpd[SD_NUM];
+__attribute__ ( (section ("NONCACHEDRW")))msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+__attribute__ ( (section ("NONCACHEDRW")))msdc_bd_t  MSDC_bd[SD_NUM][MSDC_BD_MAX];
+#endif
+
+//static SDC_CMD_STATUS gblSDsta;
+
+extern MSDC_Custom_Handle msdc_custom_handle;
+void SD_Sleep4Wait(kal_int32 sleep_tick);
+void SD_Use13M_Clock(void);
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_bool INT_USBBoot(void);
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+extern void MSDC_SetLatchTuning(void);
+#else
+extern void MSDC_SetIOCONRegDLT(void);
+#endif//#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+//kal_uint32 sd_writeFailReason; // fix Lint warning
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+void SD_SetRedDlt(kal_uint32 redDlt);
+#endif//#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+extern void SLA_CustomLogging(kal_char *customJob, kal_int32 saAction); 
+
+/*#ifdef DRV_MSDC_SDC_V3
+static kal_uint32 sd_cmd_extra = ((64) << 24);	// CTOC = 64
+#else
+static kal_uint32 sd_cmd_extra = 0;
+#endif*/
+
+#if defined(__SIM_PLUS__)
+#if !defined(__CUST_NEW__)
+kal_char MSDC_GetClockWithoutSIMPlus(void);
+#endif
+#endif
+
+
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+
+SDC_CMD_STATUS SD_SetCallBack(MSDC_CALLBACK callback1, MSDC_CALLBACK callback2, MSDC_CALLBACK callback3, MSDC_CALLBACK callback4, MSDC_CALLBACK callback5, MSDC_CALLBACK callback6);
+SDC_CMD_STATUS SD_SetReadTestFlag(kal_uint32 readTestFlag);
+SDC_CMD_STATUS SD_readTest(void);
+SDC_CMD_STATUS SD_SetUpllClock(void);
+
+#ifdef __MEUT__
+SDDriver_t sd_driver_MTK1 =
+{
+    (DCL_SINGLE_BLK_RD)SD_ReadSingleBlock,
+    (DCL_MUL_BLK_RD)SD_ReadMultiBlock,
+    (DCL_SINGLE_BLK_WR)SD_WriteSingleBlock,
+    (DCL_MUL_BLK_WR)SD_WriteMultiBlock,
+    (DCL_SD_INITITALIZE)SD_Initialize,
+    (DCL_SET_PRE_ERASE_CNT)SD_SetPreEraseBlk,
+    (DCL_SD_SET_CALLBACK)SD_SetCallBack,
+    (DCL_SET_READ_TEST_FLAG)SD_SetReadTestFlag,
+    (DCL_SD_READ_TEST)SD_readTest,
+    (DCL_SD_SET_UPLL_CLOCK_TEST)SD_SetUpllClock,
+    (DCL_SD_ERASE_BLK)SD_FlushSectors,
+};
+#else
+SDDriver_t sd_driver_MTK1 =
+{
+    (DCL_SINGLE_BLK_RD)SD_ReadSingleBlock,
+    (DCL_MUL_BLK_RD)SD_ReadMultiBlock,
+    (DCL_SINGLE_BLK_WR)SD_WriteSingleBlock,
+    (DCL_MUL_BLK_WR)SD_WriteMultiBlock,
+    (DCL_SD_INITITALIZE)SD_Initialize,
+    (DCL_SET_PRE_ERASE_CNT)SD_SetPreEraseBlk,
+    (DCL_SD_SET_CALLBACK)NULL,
+    (DCL_SET_READ_TEST_FLAG)NULL,
+    (DCL_SD_READ_TEST)NULL,
+    (DCL_SD_SET_UPLL_CLOCK_TEST)NULL,
+    (DCL_SD_ERASE_BLK)SD_FlushSectors,
+    (DCL_GPD_MUL_BLK_RD)SD_GpdReadMultiBlock,
+    (DCL_GPD_MUL_BLK_WR)SD_GpdWriteMultiBlock,
+};
+#endif
+
+#endif
+
+#if defined( __MSDC_BASIC_LOAD__) || defined( __MEUT__)
+#define MSDC_TESTBUFFER_SIZE	512
+kal_uint32	msdc_testBuffer[(MSDC_TESTBUFFER_SIZE / 4)];
+kal_uint32	msdc_writeBuffer[(MSDC_TESTBUFFER_SIZE / 4)];
+
+#define CMD_DVT_TEST_STATUS 7
+kal_uint32 msdc_ReadTestFlag;
+MSDC_CALLBACK msdc_TestCallBack1;
+MSDC_CALLBACK msdc_TestCallBack2;
+MSDC_CALLBACK msdc_TestCallBack3;
+MSDC_CALLBACK msdc_TestCallBack4;
+MSDC_CALLBACK msdc_TestCallBack5;
+MSDC_CALLBACK msdc_TestCallBack6;
+static kal_uint32 sendCmdTimes = 0;
+#endif
+
+#ifdef __CARD_DOWNLOAD__
+extern kal_bool MSDC_QueryIsPowerControllable(void);
+extern void MSDC_SetPower(kal_bool enable);
+#endif
+
+
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_Acmd42
+*
+* DESCRIPTION
+*	connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_Acmd42(kal_bool connect)
+{
+    SDC_CMD_STATUS status;
+    MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+    
+    MSDC_DEBUG("[SD][%s %d]send acmd42\r\n",__FUNCTION__,__LINE__);
+
+    // send cmd6
+    if ((status = SD_SendCmd(SDC_CMD_ACMD42, connect,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    gSD->mCD_DAT3 = KAL_FALSE;	// pull-up resistor is disconnected for data trnasfer
+    return NO_ERROR;
+}
+
+
+#if defined(MSDC_MMC441_SUPPORT)
+
+kal_bool SD_eMMC_ECSD_setValue(kal_uint8 addr, kal_uint8 value)
+{
+    //kal_uint32 r0; // [TODO]: eMMC
+    //kal_bool status = KAL_FALSE;
+    kal_uint8 *pData;
+
+    if (192 <= addr) //addr above 192 is information registers, we can't write these registers
+        ASSERT(0);
+
+    MSDC_PDNControl(KAL_FALSE);
+
+    if (NO_ERROR != SD_Switch_MMC40(SET_BYTE, addr, value, 0))
+        ASSERT(0);
+
+    //if(NO_ERROR != SD_GetStatus(gSD->mRCA,(kal_uint32*)&r0))
+    //	ASSERT(0);
+    if (NO_ERROR != SD_SendEXTCSD_MMC40(MSDC_Sector))
+        ASSERT(0);
+
+    pData = (kal_uint8 *)MSDC_Sector;
+
+    if (value !=  *(pData + addr))
+        ASSERT(0);
+
+    //status = KAL_TRUE;
+    MSDC_PDNControl(KAL_TRUE);
+    return KAL_TRUE;
+}
+
+/*
+	This API is to ask eMMC to start the partition.
+	That is, this API should be called after configuring partition settings.
+*/
+kal_bool SD_eMMC_ECSD_StartPartition()
+{
+    kal_bool status;
+
+    /*if this is not eMMC 4.4, assert it */
+    //EMMC44_CHECK_AND_ASSERT;
+
+    /*the device has been partitioned*/
+    if (EMMC_MASK_PARTITION_SETTING & gSD->mCSD.ext_csd->partition_settig)
+    {
+        ASSERT(0);
+    }
+
+    status = SD_eMMC_ECSD_setValue(EXT_CSD_PARTITION_CONFIG_INDEX, 1);
+
+    return status;
+}
+
+// unit: 512-byte
+kal_uint32 SD_eMMC_getWpgSize()
+{
+     if ((1 & gSD->mCSD.ext_csd->erase_grp_def) && (gSD->mCSD.ext_csd->hc_wp_grp_size > 0))
+        return 1024 * gSD->mCSD.ext_csd->hc_erase_grp_size * gSD->mCSD.ext_csd->hc_wp_grp_size;
+    else
+        return (gSD->mCSD.wp_grp_size_mmc >> 9);
+}
+
+/*
+	This API is called to configure partition settings. Size unit is 512-byte.
+*/
+kal_bool SD_eMMC_ECSD_configPartition(eMMC_partitions partition, kal_uint32 startAddr, kal_uint32 size, kal_bool isEnhanced)
+{
+    
+	kal_bool status;
+	kal_uint32 maxEnhSizeMult;
+	kal_uint32 wpgSize;
+	kal_uint32 wpgNum;
+	kal_uint32 partitionSize[5];
+	kal_uint8	regIndex;
+	kal_uint8 value[3];
+
+	if (eMMC_GP_partition1 > partition || eMMC_user_Area < partition)
+		ASSERT(0);
+
+	/*if this is not eMMC 4.4, assert it */
+	//EMMC44_CHECK_AND_ASSERT;
+
+	/*1st, if this card does not support enhanced feature or does not support partition feature, we can not do this function*/
+
+	/*	2nd, there is a limitation for the total size of enhanced memory area.
+		we have to know the total size of other existed enhanced area and check whether the setting violet the limitation.
+	*/
+	maxEnhSizeMult = gSD->mCSD.ext_csd->max_enh_size_mult[0] | ( gSD->mCSD.ext_csd->max_enh_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->max_enh_size_mult[2] << 16);
+
+	/*get current all partition size*/
+	partitionSize[eMMC_GP_partition1 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[0] | ( gSD->mCSD.ext_csd->gp_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[2] << 16);
+	partitionSize[eMMC_GP_partition2 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[3] | ( gSD->mCSD.ext_csd->gp_size_mult[4] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[5] << 16);
+	partitionSize[eMMC_GP_partition3 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[6] | ( gSD->mCSD.ext_csd->gp_size_mult[7] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[8] << 16);
+	partitionSize[eMMC_GP_partition4 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[9] | ( gSD->mCSD.ext_csd->gp_size_mult[10] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[11] << 16);
+	partitionSize[eMMC_user_Area - eMMC_GP_partition1] = gSD->mCSD.ext_csd->enh_size_mult[0] | ( gSD->mCSD.ext_csd->enh_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->enh_size_mult[2] << 16);
+
+	/*calculate how many wpg we need to set*/
+	wpgSize = SD_eMMC_getWpgSize();
+	wpgNum = (size / wpgSize) + ((size % wpgSize) > 0 ? 1 : 0);
+
+	/*replace old size with the new size we want to set*/
+	partitionSize [partition - eMMC_GP_partition1] = wpgNum;
+
+	if ((partitionSize[0] + partitionSize[1] + partitionSize[2] + partitionSize[3] + partitionSize[4]) > maxEnhSizeMult)
+		return KAL_FALSE;
+
+	/*everything check passed, now we can set the value*/
+	if (eMMC_user_Area > partition)
+		regIndex = EXT_CSD_GP_SIZE_MULT_GP0_INDEX + 3 * (partition - eMMC_GP_partition1);
+	else
+		regIndex = EXT_CSD_ENH_SIZE_MULT_INDEX;
+
+	value[2] = wpgNum / 64;
+	value[1] = (wpgNum - (value[2] * 64)) / 8;
+	value[0] = wpgNum - (value[2] * 64) - (value[1] * 8);
+	status = SD_eMMC_ECSD_setValue(regIndex, value[0]);
+
+	if (KAL_TRUE != status)
+		goto err_exit;
+
+	status = SD_eMMC_ECSD_setValue(regIndex + 1, value[1]);
+
+	if (KAL_TRUE != status)
+		goto err_exit;
+
+	status = SD_eMMC_ECSD_setValue(regIndex + 2, value[2]);
+
+	if (KAL_TRUE != status)
+		goto err_exit;
+
+err_exit:
+	return status;
+    
+}
+
+/*
+	This API is to configure to boot from specified partition.
+	By this API, DA can decide from wich partition, will card output the boot code in boot mode.
+*/
+kal_bool SD_eMMC_ECSD_setCurrentPart(eMMC_partitions partition)
+{
+    kal_uint8 regValue;
+    kal_bool status;
+    eMMC_partitions pt;
+
+  	if (0 == partition || eMMC_user_Area < partition)
+        ASSERT(0);
+
+    /*if this is not eMMC 4.4, assert it */
+    //EMMC44_CHECK_AND_ASSERT;
+
+    pt = (partition == eMMC_user_Area) ? 0 : partition;
+
+    regValue = gSD->mCSD.ext_csd->partition_config;
+
+    /*currently it uses the setting DA want, no need to change*/
+    if (pt == (EMMC_MASK_PARTITION_CONFIG & regValue))
+        return KAL_TRUE;
+
+    regValue &= ~EMMC_MASK_PARTITION_CONFIG;
+    regValue |= pt;
+    status = SD_eMMC_ECSD_setValue(EXT_CSD_PARTITION_CONFIG_INDEX, regValue);
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(__EMMC_BOOTING__)
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+    return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_IsEMMC
+*
+* DESCRIPTION
+*	Check inserted card is e-MMC 4.4
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_IsEmmcV44()
+{
+    /*	from eMMC 4.3, EXT_CSD_REV has maximum value 3, and from eMMC 4.4, EXT_CSD_REV new value 4, 5
+    */
+    if (3 < gSD->mCSD.ext_csd->ext_csd_rev)
+    {
+        if (0 != gSD->mCSD.ext_csd->boot_size_mul) //has boot partition, this is eMMC
+        {
+            gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_TRUE;
+            gSD->emmc_info.bootPartitionSize = 2 * 128 * gSD->mCSD.ext_csd->boot_size_mul;
+            gSD->emmc_info.gp1PartitionSize = SD_eMMC_getWpgSize() *
+                                              (gSD->mCSD.ext_csd->gp_size_mult[0]
+                                               + ( gSD->mCSD.ext_csd->gp_size_mult[1] * 256)
+                                               + ( gSD->mCSD.ext_csd->gp_size_mult[2] * 65536));
+
+            /*from spec, alternated boot method is mandatory for eMMC4.4*/
+            if ( 0 == (0x1 & gSD->mCSD.ext_csd->boot_info))
+                ASSERT(0);
+
+            /*we can't use the card that don't have RST signal support*/
+            if ( 0x2 == (0x3 & gSD->mCSD.ext_csd->rst_function))
+                ASSERT(0);
+
+            if ( 0x1 == (0x1 & gSD->mCSD.ext_csd->partition_support))
+                gSD->emmc_info.supportPartition = (kal_bool)KAL_TRUE;
+            else
+                gSD->emmc_info.supportPartition = (kal_bool)KAL_FALSE;
+
+            if ( 0x2 == (0x2 & gSD->mCSD.ext_csd->partition_support))
+                gSD->emmc_info.supportEnhancedPart = (kal_bool)KAL_TRUE;
+            else
+                gSD->emmc_info.supportEnhancedPart = (kal_bool)KAL_FALSE;
+        }
+        else   //normal mmc card without boot support
+        {
+            gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_FALSE;
+        }
+    }
+    else   //spec version below or equals to eMMC 4.3
+    {
+        gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_FALSE;
+    }
+}
+
+#endif//defined(MSDC_MMC441_SUPPORT)
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetMMC40_4bit_high_speed
+*
+* DESCRIPTION
+*	Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetMMC40_bus_high_speed(void)
+{
+	kal_uint32 clock, hs;
+    //    kal_uint8 *pData;
+
+    #if !defined(__EMMC_BOOTING__)
+
+    if (SD_SetBlength(512) != NO_ERROR)
+        goto err;
+
+    #endif
+
+    #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+    // read the EXT_CSD
+    if (SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
+        goto err;
+
+    #endif
+
+    /*calculate size*/
+    if (MMC42_CARD == gMSDC_Handle->mMSDC_type)
+    {
+        gSD->mCSD.capacity = (kal_uint64)gSD->mCSD.ext_csd->sec_count * 512;
+    }
+
+    #if defined(MSDC_MMC441_SUPPORT)
+        SD_IsEmmcV44();
+    #endif
+
+    // set high speed
+    #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+    if (gSD->mCSD.ext_csd->card_type & HS_52M)
+    #endif
+    {
+        // should be 52000
+        clock = 52000000;
+        //clock = gMSDC_Handle->msdc_clock / 2;
+
+        //if (52000000 < clock)
+        //    clock = clock / 2;
+
+        hs = 1;
+        //MSDC_LSD_WriteReg32(MSDC_IOCON,0x010002FF)
+        
+	    MSDC_DEBUG("[MSDC][%s %d]1.Set clock to %d \r\n",__FUNCTION__,__LINE__,clock);
+    }
+
+    #ifndef MSDC_SPECIAL_MMC_41_CARD
+    else if (gSD->mCSD.ext_csd->card_type & HS_26M)
+    {
+        // should be 26000
+        clock = 26000000;
+        hs = 1;
+    }
+    else
+    {
+        clock = 13000000;
+        hs = 0;
+    }
+
+    #endif
+    
+    if (hs)
+    {
+        //! [TODO]: eMMC
+        /* select proper power class
+        if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
+        	(gSD->mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
+        	goto err;
+        */
+
+
+       
+        /* enable high speed (26M or 52M)*/
+        if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
+        	goto err;
+        
+
+        // latch data at falling edge to cover the card driving capability
+        // MSDC_LSD_SetBits32(MSDC_CFG,MSDC_CFG_RED);
+    }
+
+    #ifndef DRV_LSD
+
+    //#ifndef DRV_MSDC_CLK_SEARCH
+    //gMSDC_Handle->msdc_clock = MSDC_CLOCK;
+    MSDC_SetClock(clock,KAL_FALSE);
+    //#endif
+    #else
+    LSD_HostSetClock(LSD_SPEED_52M);
+    #endif
+
+
+
+    if (NO_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+    {
+        // select bus width
+        #if defined(MMC40_USE_4BIT_BUS)
+        // enable 4-bit bus width
+        if (SD_Switch_MMC40(SET_BYTE, EXT_CSD_BUS_WIDTH_INDEX, BIT_4_MMC40, 0) != NO_ERROR)
+            goto err;
+
+        #ifdef MSDC_SPECIAL_MMC_41_CARD
+
+        if (KAL_TRUE == kal_query_systemInit()
+            || KAL_TRUE == FTL_isPollingMode()
+           )
+        {
+            MSDC_GPTI_BusyWait(2);
+        }
+        else
+        {
+            kal_sleep_task(4);
+        }
+
+        #endif
+
+        MSDC_SetBusWidth(BIT_4W);
+        gSD->bus_width = 4;
+        #elif defined(MMC40_USE_8BIT_BUS)
+
+        // enable 8-bit bus width
+        if (SD_Switch_MMC40(SET_BYTE, EXT_CSD_BUS_WIDTH_INDEX, BIT_8_MMC40, 0) != NO_ERROR)
+            goto err;
+        MSDC_SetBusWidth(BIT_8W);
+        gSD->bus_width = 8;
+        #endif
+    }
+    else
+    {
+        gMSDC_Handle->trySingleLine&=(~TEMP_SINGLE_LINE);
+    }
+
+    #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+    if (SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
+        goto err;;
+
+    #endif
+    
+    return NO_ERROR;
+err:
+
+    return ERR_MMC_BUS_HS_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_CheckSDorMMC
+*
+* DESCRIPTION
+*	Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+T_MSDC_CARD SD_CheckSDorMMC()
+{
+    SDC_CMD_STATUS status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+    SD_Cmd8();
+#endif
+    status = SD_Acmd41_SD();
+
+    if (status == NO_ERROR)
+        return gMSDC_Handle->mMSDC_type;	// SD_CARD
+    else
+        MSDC_ERR("[SD]SD_Acmd41_SD returns error code: %d\r\n", status);
+
+    status = SD_Cmd1_MMC();
+
+    if (status == NO_ERROR)
+        return gMSDC_Handle->mMSDC_type;	// MMC_CARD
+    else
+        MSDC_ERR("[SD]SD_Cmd1_MMC returns error code: %d\r\n", status);
+
+    return UNKNOWN_CARD;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetDefault
+*
+* DESCRIPTION
+*	set default values to gSD
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_SetDefault(void)
+{
+     MSDC_LOCK_TAG tempLock;
+    kal_mem_cpy(&tempLock, &gSD->mSDdrv_lock, sizeof(MSDC_LOCK_TAG));
+    kal_mem_set(gSD, 0, sizeof(T_SDC_HANDLE));
+
+    gSD->mBKLength = 0;
+    gSD->mRCA = 0;
+    gSD->mInactive = KAL_FALSE;
+    gSD->mState = IDLE_STA;
+    gSD->bus_width = 1;
+    //gSD->mCD_DAT3 = KAL_TRUE;
+
+    kal_mem_cpy(&gSD->mSDdrv_lock, &tempLock, sizeof(MSDC_LOCK_TAG));
+}
+
+void SD_Use24M_Clock(void)
+{
+
+}
+
+void SD_Use13M_Clock(void)
+{
+
+}
+
+#ifdef	DRV_MSDC_CLK_MT6268_SERIES
+void SD_Use30M_Clock(void)
+{
+    
+}
+
+void SD_Use45M_Clock(void)
+{
+   
+}
+#endif
+
+#ifdef DRV_MSDC_CLK_SEARCH
+
+kal_uint32 whenToStop;
+kal_uint32 stopTimeout = 300;
+
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+void SD_SetRedDlt(kal_uint32 redDlt)
+{
+    
+}
+#endif//#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool sd_DltTestWithClkStopped(kal_uint32 data_adrs)
+{
+	return 0;
+    
+}
+
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool SD_setCLKAndTest(kal_uint32 targetCLK)
+{
+   return 0;
+}
+
+
+kal_uint32 SD_tuneCLK2()
+{
+    return 0;
+}
+
+#else//!defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool SD_IsClkInRange(kal_uint32 clk)
+{
+     return 0;
+}
+
+kal_bool SD_CanCmdBeLatched(void)
+{
+     return 0;
+}
+
+/*kal_bool SD_CanDataBeLatched(msdc_clk_setting cs)
+{
+   
+}*/
+
+/*SDC_CMD_STATUS MSDC_AutoCalibrate(
+    msdc_acb_mode		mode,
+    msdc_acb_scan_mode	scanMode,
+    msdc_acb_tun_scheme	tunScheme,
+    kal_uint8			tunBlockNum
+)
+{
+   
+}*/
+
+/*kal_uint32 MSDC_ManuCalibrate(
+    msdc_clk_setting	cs,
+    msdc_acb_mode 		mode
+)
+{
+    
+}*/
+
+#define MAX_NUM_MULTI_PHASE	32
+SDC_CMD_STATUS FindMostConsecutiveBits(
+    kal_uint32 word,
+    kal_uint8 wordLen,
+    kal_uint8 threshold,
+    kal_uint8 *pos
+)
+{
+    return 0;
+}
+
+/*SDC_CMD_STATUS MSDC_AutoCalibrate_FindBestLatchWindow(
+    msdc_acb_scan_mode scanMode,
+    kal_uint8 *pos
+)
+{
+    
+}*/
+
+/*SDC_CMD_STATUS MSDC_ManuCali_FindBestLatchWindow(
+    msdc_clk_setting cs,
+    kal_uint32 phaseArraySeamless,
+    kal_uint8 *pos
+)
+{
+    
+}*/
+
+/*kal_uint32 SD_ClkTuning_AutoCalibrate(msdc_clk_setting cs)
+{
+
+}*/
+
+/*kal_uint32 SD_ClkTuning_ManualCalibrate(msdc_clk_setting cs)
+{
+   
+}*/
+
+/*kal_uint32 SD_ClkTuning_FeedbackClk(msdc_clk_setting cs)
+{
+    
+}*/
+
+kal_uint32 SD_tuneCLK2()
+{
+    return 0;
+}
+
+#endif//!defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+#endif//#ifdef DRV_MSDC_CLK_SEARCH
+
+#ifdef __MEUT__
+kal_bool	msdcOddNumberSizeTestByDMA;
+kal_bool	msdcDoNotRST;
+SDC_CMD_STATUS msdcReadTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs)
+{
+	
+    return 0;
+}
+
+#endif
+
+
+#ifdef __MSDC_BASIC_LOAD__
+
+kal_bool	msdcOddNumberSizeTestByDMA;
+kal_bool	msdcDoNotRST;
+SDC_CMD_STATUS msdcTransferLengthTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs)
+{
+	 return 0;
+   }
+
+SDC_CMD_STATUS msdcWriteLengthTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs, kal_bool notChange)
+{
+	 return 0;
+    
+}
+#endif
+
+#if defined(MSDC_QMU_ENABLE)
+#define MSDC_QBM_BPS_NUM        1
+#define MSDC_QBM_BPS_BUF_SZ		QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TGPD_BPS, MSDC_QBM_BPS_NUM)
+kal_uint8 msdc_bps_buf[MSDC_QBM_BPS_BUF_SZ];
+void *g_p_msdc_bps[MSDC_QBM_BPS_NUM];
+
+/* Initialize the QUM buffer for MSDC queue transfer */
+kal_bool SD_QMU_Init(void)
+{
+    kal_bool ret = KAL_TRUE;
+    unsigned char idx = 0;
+    bm_queue_config conf;
+    qbm_gpd *p_cur_gpd = NULL ,*p_head_gpd = NULL , *p_tail_gpd = NULL;
+
+    /* Init the BPS pointer */
+    for (idx = 0; idx < MSDC_QBM_BPS_NUM; idx++)
+        g_p_msdc_bps[idx] = NULL;
+
+    /*initial non-free bypass GPD buffer pool*/
+    qbm_init_q_config(&conf);
+    conf.buff_num = MSDC_QBM_BPS_NUM;
+    conf.p_mem_pool_str = msdc_bps_buf;
+    conf.p_mem_pool_end = msdc_bps_buf + MSDC_QBM_BPS_BUF_SZ;
+
+    /*user must flush the GPD after this non-free init queue*/
+    if (QBM_ERROR_OK != qbm_init_queue_non_free(QBM_TYPE_TGPD_BPS, &conf , (void **)&p_head_gpd, (void **)&p_tail_gpd)) {
+        return KAL_FALSE;
+    }
+
+    idx = 0;
+    p_cur_gpd = p_head_gpd;
+
+    do {
+        qbm_set_non_free(p_cur_gpd);
+		qbm_set_used(p_cur_gpd);
+		QBM_DES_CLR_HWO(p_cur_gpd);
+		QBM_DES_SET_NEXT(p_cur_gpd, NULL);
+
+		g_p_msdc_bps[idx] = p_cur_gpd;
+		
+        /*flush GPD here because qbm_init_queue_non_free don't flush GPD*/
+        QBM_CACHE_FLUSH(p_cur_gpd, sizeof(qbm_gpd));
+        idx ++;
+
+        /*should consider the bps_ptr array count*/
+        if ((p_cur_gpd == p_tail_gpd) || (idx >= MSDC_QBM_BPS_NUM)) {
+            break;
+        }
+
+        p_cur_gpd = p_cur_gpd->p_next;
+    } while(1);
+
+    return ret;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+*  SD_Initialize
+*
+* DESCRIPTION
+*	Initial SD controller and card
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Initialize(void)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 cid[4], csd[4], scr[4];
+    kal_uint32 sd_status[16];
+    kal_uint16 rca;
+    
+    /*check if init or not*/
+    if (gMSDC_Handle->mIsInitialized==KAL_TRUE)
+    {
+    	return NO_ERROR;
+    }
+
+#if defined(MSDC_MMC441_SUPPORT)
+    gSD->emmc_info.isEmmcV44 = KAL_FALSE;
+#endif
+
+    /* Re-Init gSD */
+	kal_mem_set(&gSD->mSCR, 0, sizeof(T_SCR));
+
+    /*reset event*/
+    kal_set_eg_events(gMSDC_Handle->MSDC_Events,0,KAL_AND);
+
+    /*reset MSDC*/
+    MSDC_RESET();
+
+    /*may switch to 1.8 last time,we should set signal volt to 3.3v and power cycle*/
+    gMSDC_Handle->signal_volt=3300;
+    MSDC_SetSignalPower(KAL_TRUE, gMSDC_Handle->signal_volt);
+    power_cycle(20);
+
+    /* Set INIT clock */
+    MSDC_SetClock(MSDC_INIT_CLOCK,KAL_FALSE);
+    /*set to 1 bit data line*/
+    MSDC_SetBusWidth(BIT_1W);
+    /*SD_SetDefault*/
+    SD_SetDefault();					//need check the function !!!!!!
+    /*set latch tuning*/
+
+    /*set IOCON1  */
+    /*set CARD_CK_PWDN=0 */
+    MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_CKPDN);
+    /*enable bus clk*/
+    MSDC_SetBits32(MSDC_CFG,MSDC_CFG_CKDRV_EN);
+
+    /*reset cmd0*/
+    status=SD_Reset();
+    SD_INITIALIZE_STATUS_CHECK();                   /*need check this function !!!!!!!!!!!!*/
+    /*checkSDorMMC cmd8 acmd41 cmd1*/
+    if (SD_CheckSDorMMC() == UNKNOWN_CARD)
+    {
+        MSDC_ERR("[SD][%s %d]unknow card\r\n",__FUNCTION__,__LINE__);
+        SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
+        status = ERR_STATUS;
+        goto err;
+    }
+    /*getCID cmd2*/
+    status = SD_GetCID(cid);
+    SD_INITIALIZE_STATUS_CHECK();
+    /*validateRCA cmd3*/
+    status = SD_ValidateRCA(&rca);
+    SD_INITIALIZE_STATUS_CHECK();
+    /*GetCSD cmd9*/
+    status = SD_GetCSD(gSD->mRCA, csd);
+    SD_INITIALIZE_STATUS_CHECK();
+    MSDC_DEBUG("[SD][%s %d]send cmd4\r\n",__FUNCTION__,__LINE__);
+    /*setSDR cmd4*/
+    if (gSD->mCSD.dsr_imp){
+        if ((status = SD_SetDSR()) != NO_ERROR)
+        {
+            //dbg_print("6\r\n");
+            SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
+            goto err;
+        }
+    }
+    /*check Write Protected*/
+#if defined(MSDC_WR_PROT_EN)
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+    if(!(MSDC_Reg32(MSDC_PS)&MSDC_PS_WP))
+    {
+        //gSD->mWPEnabled=KAL_TRUE;
+        if (gSD->mWPEnabled!=KAL_TRUE)
+            gSD->mWPEnabled=KAL_FALSE;
+    }
+    else
+    {
+        //gSD->mWPEnabled=KAL_FALSE;
+        gSD->mWPEnabled=KAL_TRUE;
+    }
+#else
+    {
+    DCL_HANDLE handle;
+
+    GPIO_CTRL_READ_T data;
+
+    /* when use EINT for card detect,get the status */
+    handle = DclGPIO_Open(DCL_GPIO, MSDC_WP_GPIO);
+    DclGPIO_Control(handle, GPIO_CMD_READ, (DCL_CTRL_DATA_T *)&data);
+
+    if (data.u1IOData)
+        gSD->mWPEnabled = KAL_TRUE;
+    else
+        gSD->mWPEnabled = KAL_FALSE;
+        
+    DclGPIO_Close(handle);
+    }
+#endif
+#else       /* MSDC_WR_PROT_EN */
+    gSD->mWPEnabled = KAL_FALSE;
+#endif
+
+    MSDC_CRIT("[SD][%s %d]Card is %s\r\n",__FUNCTION__,__LINE__,
+        gSD->mWPEnabled ? "WP-ed" : "Not WP-ed");
+        
+    /*select Card cmd7*/
+    status = SD_SelectCard(gSD->mRCA);
+    if (status == CARD_IS_LOCKED)
+        gSD->mIsLocked = KAL_TRUE;
+    SD_INITIALIZE_STATUS_CHECK();
+
+
+    /*read SCR cmd16 acmd51*/
+    if (gMSDC_Handle->mMSDC_type==SD_CARD\
+        ||gMSDC_Handle->mMSDC_type==SD20_HCS_CARD ||gMSDC_Handle->mMSDC_type==SD20_LCS_CARD\
+        ||gMSDC_Handle->mMSDC_type==SD30_CARD)
+    {
+        status = SD_ReadSCR(scr);
+        SD_INITIALIZE_STATUS_CHECK();
+
+        status = SD_ReadSDStatus(sd_status);
+        SD_INITIALIZE_STATUS_CHECK();
+        
+    	/*set bus width acmd6*/
+        if (NO_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+        {
+            status = SD_SetBusWidth(BIT_4W);
+            SD_INITIALIZE_STATUS_CHECK();
+        }
+        else
+        {
+            gMSDC_Handle->trySingleLine&=~(TEMP_SINGLE_LINE);
+        }
+     
+    	/*acmd42*/
+    	#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+        status = SD_Acmd42(KAL_FALSE);
+        SD_INITIALIZE_STATUS_CHECK();
+    	#endif
+
+        status=SD_SwitchSpeedMode();
+        SD_INITIALIZE_STATUS_CHECK();
+        
+#if defined(MSDC_CONFIG_SD30_SUPPORT)
+        if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+        {
+         
+            switch (gSD->function_set.function1)
+            {
+                case FUN1_SET_SDR104:
+                    MSDC_SetClock(208000000,KAL_FALSE);
+                    gMSDC_Handle->msdc_clkTuneUpperBund = 100000000;
+                    break;
+                case FUN1_SET_SDR50:
+                    MSDC_SetClock(100000000,KAL_FALSE);
+                    gMSDC_Handle->msdc_clkTuneUpperBund = 50000000;
+                    break;
+                case FUN1_SET_SDR25_HS:
+                    MSDC_SetClock(50000000,KAL_FALSE);
+                    gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+                    break;
+                case FUN1_SET_SDR12_DS:
+                    MSDC_SetClock(25000000,KAL_FALSE);
+                    gMSDC_Handle->msdc_clkTuneUpperBund = 12500000;
+                    break;
+                case FUN1_SET_DDR50:
+                    MSDC_SetClock(50000000,KAL_TRUE);
+                    gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+                    break;
+            }
+        }
+        else
+#endif
+        {
+            if (gSD->function_set.function1==1)
+            {
+                MSDC_CRIT("[SD][%s %d]set Bus Clock to 50M(HS)\r\n",__FUNCTION__,__LINE__);
+                MSDC_SetClock(50000000,KAL_FALSE);
+                gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+            }
+            else
+            {
+                MSDC_CRIT("[SD][%s %d]set Bus Clock to 25M(DS)\r\n",__FUNCTION__,__LINE__);
+                MSDC_SetClock(25000000,KAL_FALSE);
+                gMSDC_Handle->msdc_clkTuneUpperBund = 12500000;
+            }
+        }
+
+        /* For SDA compliance test */
+        if (((gSD->mSCR.spec_ver==SD_SPEC_101)||(gSD->mSCR.spec_ver==SD_SPEC_110)||(gSD->mCSD.csd_ver==CSD_VER_1_0))&&
+             ((kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)) > 2048)&&(status==NO_ERROR)) {
+            status = ERR_STATUS;
+            MSDC_ERR("[SD] We would not mount >2G Card which is compliant to SD1.x\r\n");
+            goto err;
+        }
+        if (((gSD->mSCR.spec_ver<=SD_SPEC_200))&&
+             ((kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)) > 32768)&&(status==NO_ERROR)) {
+            status = ERR_STATUS;
+            MSDC_ERR("[SD] We would not mount >32GB Card which is compliant to SD2.0\r\n");
+            goto err;
+        }
+    }
+    else
+    {
+    	MSDC_CRIT("[SD][%s %d]init mmc \r\n",__FUNCTION__,__LINE__);
+        //mmc card
+        if ((gMSDC_Handle->mMSDC_type == MMC_CARD || gMSDC_Handle->mMSDC_type == MMC42_CARD) && gSD->mCSD.spec_ver >= 4)
+        {
+            if (gMSDC_Handle->mMSDC_type == MMC_CARD) /*we don't need to change MMC42_CARD to MMC40_CARD*/
+                gMSDC_Handle->mMSDC_type = MMC40_CARD;
+            status = SD_SetMMC40_bus_high_speed();
+            SD_INITIALIZE_STATUS_CHECK();
+            #if defined(MSDC_MMC441_SUPPORT)
+            if ( gSD->mCSD.ext_csd->ext_csd_rev >= 5 )
+            {
+                // set ERASE_GROUP_DEF[175] before issuing read, write, erase, write protect
+                status = SD_Switch_MMC40(SET_BYTE, EXT_CSD_ERASE_GRP_DEF, 1 , 0);
+                SD_INITIALIZE_STATUS_CHECK();
+            }
+            #endif
+        }
+        else
+        {
+            MSDC_SetClock(13000000,KAL_FALSE);
+        }
+       
+    }
+    
+    /* Set block length cmd16 */
+    status = SD_SetBlength(512);
+    SD_INITIALIZE_STATUS_CHECK();
+    
+err:
+
+    if (status != NO_ERROR)
+    {
+    	MSDC_ERR("[SD][%s %d]mount fail %x\r\n",__FUNCTION__,__LINE__,status);
+        SD_SetDefault();
+        gMSDC_Handle->mIsInitialized = KAL_FALSE;
+        gMSDC_Handle->mIsPresent = KAL_FALSE;
+        MSDC_turnOnVMC(gMSDC_Handle->mIsPresent);
+        MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+    	MSDC_PDNControl(KAL_TRUE);
+     }
+     else
+     {
+    	MSDC_CRIT("[SD][%s %d]mount ok %x\r\n",__FUNCTION__,__LINE__,status);
+        gMSDC_Handle->mIsInitialized = KAL_TRUE;
+     }
+     
+    /*reset event*/
+     kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+    return status;
+
+}
+
+#ifdef __MEUT__
+SDC_CMD_STATUS SD_SetCallBack(MSDC_CALLBACK callback1, MSDC_CALLBACK callback2, MSDC_CALLBACK callback3, MSDC_CALLBACK callback4, MSDC_CALLBACK callback5, MSDC_CALLBACK callback6)
+{
+     return 0;
+}
+SDC_CMD_STATUS SD_SetReadTestFlag(kal_uint32 readTestFlag)
+{
+     return 0;
+}
+SDC_CMD_STATUS SD_readTest(void)
+{
+
+     return 0;
+}
+
+SDC_CMD_STATUS SD_SetUpllClock(void)
+{
+
+    return 0;
+}
+#endif
+
+
+void SD_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
+{
+    int i;
+
+    for (i = 0; i < len; i++)
+        *(dest + len - 1 - i) = *(src + i);
+
+}
+/*************************************************************************
+* FUNCTION
+*  power2
+*
+* DESCRIPTION
+*	Calculate the power of 2
+*
+* PARAMETERS
+*	num:
+*
+* RETURNS
+*  2^num
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+static kal_uint32 power2(kal_uint32 num)
+{
+    return 1 << num;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisCSD
+*
+* DESCRIPTION
+*	Analysis Card Specific Data and store in the member of gSD
+*
+* PARAMETERS
+*	csd: input csd for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_AnalysisCSD(kal_uint32* csd)
+{
+    kal_uint8 *ptr;
+    kal_uint32 c_mult, c_size;
+
+    ptr = (kal_uint8*)csd;
+    c_mult = c_size = 0;
+    // these offsets refer to the spec. of SD and MMC
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.csd_ver, ptr, 126, 2);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.tacc, ptr, 112, 8);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.nsac, ptr, 104, 8);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.tran_speed, ptr, 96, 8);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.ccc, ptr, 84, 12);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_len, ptr, 80, 4);
+    gSD->mCSD.r_blk_len = power2(gSD->mCSD.r_blk_len);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_part, ptr, 79, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_misali, ptr, 78, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_misali, ptr, 77, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.dsr_imp, ptr, 76, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_part, ptr, 21, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_len, ptr, 22, 4);
+    gSD->mCSD.w_blk_len = power2(gSD->mCSD.w_blk_len);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_grp_enable, ptr, 31, 1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.temp_wp,ptr,12,1);
+    GetBitFieldN((kal_uint8*)&gSD->mCSD.perm_wp,ptr,13,1);
+    if (gSD->mCSD.temp_wp || gSD->mCSD.perm_wp)
+        gSD->mWPEnabled = KAL_TRUE;
+
+    // there are some difference of CSD between SD and MMC
+    if (gMSDC_Handle->mMSDC_type == MMC_CARD || gMSDC_Handle->mMSDC_type == MMC42_CARD)
+    {
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.spec_ver, ptr, 122, 4);
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_sec_size_mmc, ptr, 42, 5);
+        gSD->mCSD.erase_sec_size_mmc = (gSD->mCSD.erase_sec_size_mmc + 1) * gSD->mCSD.w_blk_len;
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_grp_size_mmc, ptr, 37, 5);
+        gSD->mCSD.erase_grp_size_mmc = (gSD->mCSD.erase_grp_size_mmc + 1) * gSD->mCSD.erase_sec_size_mmc;
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_grp_size_mmc, ptr, 32, 5);
+        gSD->mCSD.wp_grp_size_mmc = (gSD->mCSD.wp_grp_size_mmc + 1) * gSD->mCSD.erase_grp_size_mmc;
+    }
+    else // SD_CARD
+    {
+        if (gSD->mCSD.csd_ver == CSD_VER_2_0)
+            gSD->mIsBlkAddr = 1;
+        else
+            gSD->mIsBlkAddr = 0;
+            
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_sec_size_sd, ptr, 39, 7);
+        gSD->mCSD.erase_sec_size_sd += 1;
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_prg_size_sd, ptr, 32, 7);
+        gSD->mCSD.wp_prg_size_sd = (gSD->mCSD.wp_prg_size_sd + 1) * gSD->mCSD.erase_sec_size_sd;
+        GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_blk_en_sd, ptr, 46, 1);
+    }
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+    if ((gMSDC_Handle->mMSDC_type == SD20_HCS_CARD||\
+        gMSDC_Handle->mMSDC_type == SD30_CARD) && gSD->mCSD.csd_ver >= SD_CSD_VER_20)
+    {
+        GetBitFieldN((kal_uint8*)&c_size, ptr, 48, 22);
+        gSD->mBKNum = (c_size + 1);
+        gSD->mCSD.capacity = (kal_uint64)gSD->mBKNum * 512 * 1024;
+    }
+    else
+#endif
+    {
+        GetBitFieldN((kal_uint8*)&c_mult, ptr, 47, 3);
+        c_mult = power2(c_mult + 2);
+        GetBitFieldN((kal_uint8*)&c_size, ptr, 62, 12);
+        gSD->mBKNum = (c_size + 1) * c_mult;
+        gSD->mCSD.capacity = (kal_uint64)(c_size + 1) * (kal_uint64)c_mult * (kal_uint64)gSD->mCSD.r_blk_len;
+    }
+    if (!(gSD->mCSD.ccc &CCC_BLOCK_WRITE))
+        gSD->mWPEnabled = KAL_TRUE;  //unsupport write command
+
+    MSDC_CRIT("[SD][%s %d]The capacity is %d MB, BLK_ADDR(%d)\r\n", __FUNCTION__, __LINE__,
+        (kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)), gSD->mIsBlkAddr);
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisCID
+*
+* DESCRIPTION
+*	Analysis Card Identificaton and store in the member of gSD
+*
+* PARAMETERS
+*	cid: input of card ID for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_AnalysisCID(kal_uint32* cid)
+{
+    kal_uint8	i;
+    kal_uint8* pcid;
+    pcid = (kal_uint8*)cid;
+
+    if (gMSDC_Handle->mMSDC_type == MMC_CARD || MMC42_CARD == gMSDC_Handle->mMSDC_type)
+    {
+        GetBitFieldN((kal_uint8*)&gSD->mCID.year, pcid, 8, 4);
+        gSD->mCID.year += 1997;
+        GetBitFieldN((kal_uint8*)&gSD->mCID.month, pcid, 12, 4);
+        GetBitFieldN((kal_uint8*)&gSD->mCID.psn, pcid, 16, 32);
+        GetBitFieldN((kal_uint8*)&gSD->mCID.prv, pcid, 48, 8);
+
+        for (i = 0; i < 6; i++)
+            gSD->mCID.pnm[i] = *(pcid + 7 + i);
+
+        GetBitFieldN((kal_uint8*)&gSD->mCID.oid, pcid, 104, 16);
+        GetBitFieldN((kal_uint8*)&gSD->mCID.mid, pcid, 120, 8);
+
+        // special case handling
+        {
+            kal_uint8 pnm[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0x31};
+
+            if (gSD->mCID.mid == 6 && gSD->mCID.oid == 0 &&
+                !kal_mem_cmp(gSD->mCID.pnm, pnm, 6))
+            {
+                gSD->flags |= SD_FLAG_MMC_MRSW_FAIL;
+            }
+        }
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+        {
+            kal_uint8 fullCardPnm[] = {0x55, 0x59, 0x4E, 0x41, 0x49, 0x54};
+
+            if (!kal_mem_cmp(gSD->mCID.pnm, fullCardPnm, 6)) /*Tianyu does not provide MID and OID*/
+            {
+                SD_setFullCard(KAL_TRUE);
+                gMSDC_Handle->msdc_clkTuneUpperBund = 15000;
+            }
+            else
+                SD_setFullCard(KAL_FALSE);
+        }
+#endif
+
+    }
+    else // SD_CARD
+    {
+        gSD->mCID.mid = *(pcid + 15);
+        gSD->mCID.oid = *(pcid + 13) + 256 * (*(pcid + 14));
+
+        for (i = 0; i < 5; i++)
+            gSD->mCID.pnm[i] = *(pcid + 8 + i);
+
+        gSD->mCID.prv = *(pcid + 7);
+        //gSD->mCID.psn = *(kal_uint32*)(pcid+3);
+        gSD->mCID.psn = (*(kal_uint32*)(pcid + 4) << 8) | *(pcid + 3);
+        gSD->mCID.month = (kal_uint8)GET_BIT(*(pcid + 1), 0, BIT_MASK_4);
+        gSD->mCID.year = GET_BIT(*(pcid + 1), 4, BIT_MASK_4) + 16 * GET_BIT(*(pcid + 2), 0, BIT_MASK_4) + 2000;
+    }
+
+#ifdef MSDC_TRACE_LEVEL1
+    MD_TRC_MSDC_INFORM_CID(gSD->mCID.mid, gSD->mCID.oid);
+#endif
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisSCR
+*
+* DESCRIPTION
+*	Analysis SD Card Configuration Register and store in the member of gSD
+*
+* PARAMETERS
+*	scr: input of scr for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	Only for SD card.
+*
+*************************************************************************/
+void SD_AnalysisSCR(kal_uint32* scr)
+{
+    kal_uint8 *pscr;
+
+    pscr = (kal_uint8*)scr;
+    gSD->mSCR.spec_ver = (SD_SPEC)((kal_uint8)GET_BIT(*(pscr), 0, BIT_MASK_4));
+
+    if (gSD->mSCR.spec_ver > SD_SPEC_101)
+        gSD->flags |= SD_FLAG_CMD6_SUPPORT;
+
+    gSD->mSCR.dat_after_erase = (kal_uint8)GET_BIT(*(pscr + 1), 7, BIT_MASK_1);
+    gSD->mSCR.security = (kal_uint8)GET_BIT(*(pscr + 1), 4, BIT_MASK_3);
+    gSD->mSCR.bus_width = (kal_uint8)GET_BIT(*(pscr + 1), 0, BIT_MASK_4);
+    gSD->mSCR.cmd_support = (kal_uint8)GET_BIT(*(pscr + 3), 0, BIT_MASK_2);
+    
+    gSD->mSCR.sd_spec3 = (kal_uint8)GET_BIT(*(pscr + 2), 7, BIT_MASK_1);
+    if ((gSD->mSCR.spec_ver == SD_SPEC_200) && (gSD->mSCR.sd_spec3))
+        gSD->mSCR.spec_ver = SD_SPEC_30X;
+    else
+        gSD->mSCR.spec_ver = SD_SPEC_200;
+
+    MSDC_CRIT("[SD] SD_SPEC(%d) SD_SPEC3(%d) SD_BUS_WIDTH=%d\r\n", 
+            gSD->mSCR.spec_ver, gSD->mSCR.sd_spec3, gSD->mSCR.bus_width);
+    MSDC_CRIT("[SD] SD_SECU(%d) CMD_SUPP(%d): CMD23(%d), CMD20(%d)\r\n", 
+            gSD->mSCR.security, gSD->mSCR.cmd_support,
+            (gSD->mSCR.cmd_support >> 1) & 0x1, gSD->mSCR.cmd_support & 0x1);
+}
+
+kal_uint32  SD_CmdPollResp(kal_uint32 * error,kal_uint32 pollTime_ms)
+{
+	kal_uint32 status;
+	
+	if (!MSDC_TIMEOUT_WAIT(MSDC_Reg32(MSDC_INT)&MSDC_CMD_INTS,pollTime_ms))
+	{
+		status=MSDC_Reg32(MSDC_INT);
+		MSDC_WriteReg32(MSDC_INT,(status&MSDC_CMD_INTS));
+		if (status & MSDC_INT_CMDTMO)
+		{
+			MSDC_ERR("[SD][%s %d]CMDTMO(%d)\r\n",__FUNCTION__,
+			    __LINE__, gMSDC_Handle->cmd);
+			*error=ERR_CMD_TIMEOUT;
+		}
+		else if (status & MSDC_INT_RSPCRCERR)
+		{
+			MSDC_ERR("[SD][%s %d]CMDCRC(%d)\r\n",__FUNCTION__,
+			    __LINE__, gMSDC_Handle->cmd);
+			*error=ERR_CMD_RSPCRCERR;
+		}
+		else if (status & MSDC_INT_CMDRDY)
+		{
+			*error=NO_ERROR;
+		}
+		/*we get the interrupt information*/
+		return 0;
+	}
+	/*polling  timeout ,so we need sleep and  try wait interrupt*/
+	return 1;	//tiemeout
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo
+*
+* DESCRIPTION
+*	Wait until command ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo(void)
+{
+	kal_uint32 ret;
+	kal_uint32 status;
+	kal_uint32 flag;
+	/*poll 5 ms first to check response*/
+	ret=SD_CmdPollResp(&(gMSDC_Handle->error),5);
+	if (ret)
+	{
+		MSDC_START_TIMER(MSDC_CMD_TIMEOUT/10);
+		/*enable interrupt*/
+		MSDC_SetBits32(MSDC_INTEN,MSDC_CMD_INTS|MSDC_INT_CDSC);
+		/*use interrupt handler*/
+		kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,EVENT_CMD_DONE,KAL_OR_CONSUME,&flag,KAL_SUSPEND);	
+		/*disable interrupt*/
+		MSDC_ClearBits32(MSDC_INTEN, MSDC_CMD_INTS);
+		MSDC_STOP_TIMER();
+        if (gMSDC_Handle->is_timeout)
+        {
+            gMSDC_Handle->error=MSDC_GPT_TIMEOUT_ERR;
+        }
+        else
+        {
+    		status=gMSDC_Handle->msdc_int&MSDC_CMD_INTS;
+    		
+    		if (status &MSDC_INT_CMDRDY)
+    		{
+    			gMSDC_Handle->error=NO_ERROR;
+    		}
+    		else if (status& MSDC_INT_CMDTMO)
+    		{
+    			MSDC_ERR("[SD][%s %d]CMDTMO(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+    			    __LINE__, gMSDC_Handle->cmd, status);
+    			gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+    		}
+    		else if (status & MSDC_INT_RSPCRCERR)
+    		{
+    			MSDC_ERR("[SD][%s %d]CMDCRC(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+    			    __LINE__, gMSDC_Handle->cmd, status);
+    			gMSDC_Handle->error=ERR_CMD_RSPCRCERR;
+    		}
+    		else
+    		{
+    			MSDC_ERR("[SD][%s %d]ERR(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+    			    __LINE__, gMSDC_Handle->cmd, status);
+    			gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+    		}
+    		ret=status;
+        }
+	}
+	return gMSDC_Handle->error;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WaitDatRdyOrTo
+*
+* DESCRIPTION
+*	Wait until data ready or timeout ,just for pio read and write
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	just polling 
+*
+*************************************************************************/
+	SDC_CMD_STATUS SD_WaitDatRdyOrTo(kal_uint32 *buffer,kal_uint32 byte_len,kal_bool isWrite)
+	{
+		kal_uint32 intsts;
+		kal_uint8 * u8ptr;
+		kal_uint32 * ptr;
+        ptr=buffer;
+        
+		gMSDC_Handle->abort=0;
+		MSDC_SetBits32(MSDC_INTEN,MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+		if(!isWrite)
+		{
+			/*poll to read data from FIFO*/
+			while(byte_len)
+			{
+			   
+				if ((byte_len>=MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=MSDC_FIFO_THD)){
+					int count =MSDC_FIFO_THD>>2;	
+					do{
+						*ptr++=MSDC_FIFO_READ32();
+					}while(--count);
+					byte_len-=MSDC_FIFO_THD;
+					
+				}
+				else if  ((byte_len<MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=byte_len))
+				{
+					while(byte_len>3){
+						*ptr++=MSDC_FIFO_READ32();
+						byte_len-=4;
+					}
+					u8ptr=(kal_uint8 *)ptr;
+					while(byte_len){
+						*u8ptr++=MSDC_FIFO_READ8();
+						byte_len--;
+					}
+				}
+				if (gMSDC_Handle->abort){
+				   	gMSDC_Handle->abort=0;
+					MSDC_ERR("[SD][%s %d]pio read abort ,byte_len=%d \r\n",__FUNCTION__,__LINE__,byte_len);
+					break;
+				}
+			}
+		}
+		else
+		{
+			/*poll to write data into FIFO*/
+			while(byte_len){
+				if (byte_len >= MSDC_FIFO_SZ){
+					if (MSDC_TXFIFOCNT()==0){
+						int count =MSDC_FIFO_SZ>>2;
+						do {
+							MSDC_FIFO_WRITE32(*ptr);
+							ptr++;
+						}while(--count);
+						byte_len-=MSDC_FIFO_SZ;
+					}
+				}
+				else if ((byte_len<MSDC_FIFO_SZ)&&(MSDC_TXFIFOCNT()==0)){
+					while(byte_len){
+						while(byte_len>3){
+							MSDC_FIFO_WRITE32(*ptr);
+							ptr++;
+							byte_len-=4;
+						}
+						u8ptr=(kal_uint8 *)ptr;
+						while(byte_len){
+							MSDC_FIFO_WRITE8(*u8ptr);
+							u8ptr++;
+							byte_len--;
+						}
+					}
+				}
+				if (gMSDC_Handle->abort)
+				{
+					gMSDC_Handle->abort=0;
+					MSDC_ERR("[SD][%s %d]pio write abort ,byte_len=%d \r\n",__FUNCTION__,__LINE__,byte_len);
+					break;
+				}
+			}
+			
+		}
+		
+		MSDC_ClearBits32(MSDC_INTEN, MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+		if (byte_len)
+			goto end;
+		intsts =MSDC_PollInts(MSDC_INT_XFER_COMPL|MSDC_INT_DATTMO|MSDC_INT_DATCRCERR,100);
+		MSDC_DEBUG("[SD][%s %d]intsts =%x \r\n",__FUNCTION__,__LINE__,intsts);
+		MSDC_CLR_FIFO();
+		if (intsts&MSDC_INT_XFER_COMPL)
+		{
+			gMSDC_Handle->error=NO_ERROR;
+		}
+		else if (intsts&MSDC_INT_DATCRCERR){
+			gMSDC_Handle->error=ERR_DAT_CRCERR;
+		}
+		else if (intsts&MSDC_INT_DATTMO)
+		{
+			gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+		}
+end:
+		if (gMSDC_Handle->error)
+		{
+			MSDC_FatalErrorHandle();
+		}
+		
+		/*wait busy for write operation*/
+		if (isWrite)
+		{
+		    dbg_print("isWrite=%x ,go to MSDC_CheckCardBusy",isWrite);
+			MSDC_CheckCardBusy(KAL_FALSE,30*1000);
+		}
+		return gMSDC_Handle->error;
+	}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCardNotBusy
+*
+* DESCRIPTION
+*	Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+*	void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+kal_uint32 direct_msdc_entry = 0;
+
+SDC_CMD_STATUS SD_WaitCardNotBusy(kal_uint32 timeout_ms)
+{
+    	if(MSDC_TIMEOUT_WAIT((!SD_IS_R1B_BUSY())&&MSDC_Check_Card_Present(),timeout_ms))
+    	{
+    		gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+    		MSDC_ERR("[SD][%s %d]R1B busy timeout ,wait %d ms\r\n",__FUNCTION__,__LINE__,timeout_ms);
+    		return ERR_CMD_TIMEOUT;
+    	}
+	return  NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_CheckStatus
+*
+* DESCRIPTION
+*	Check command status
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_CheckStatus(void)
+{
+	     kal_uint32 status;
+
+	    status= MSDC_Reg32(SDC_RESP0);
+	    if ((status & SDC_CSTA_MASK) == 0 )
+	        return NO_ERROR;
+
+	    MSDC_ERR("[SD][%s %d]check status<%x>\r\n",__FUNCTION__,__LINE__,status);
+	    if (status & SDC_CARD_IS_LOCKED)
+	    {
+	    	
+	        return CARD_IS_LOCKED;
+	    }
+	    return ERR_STATUS;
+    
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_Send_Cmd
+*
+* DESCRIPTION
+*	to launch the command packet to the card
+*
+* PARAMETERS
+*	1. cmd: the content of SDC_CMD register
+*	2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	1. Check if controller is available  before launch any commands
+*	2. Maybe add check if card is busy (R1b)
+*************************************************************************/
+SDC_CMD_STATUS SD_SendCmdOnly( kal_uint32 cmd, kal_uint32 arg,kal_uint32 timeout_ms)
+{
+	kal_uint32 retry_count=0;
+check_busy:
+	/*wait CMD busy and SDC busy*/
+   	if (cmd == SDC_CMD_CMD12||cmd==SDC_CMD_CMD13)
+   	{
+		if (MSDC_TIMEOUT_WAIT((!SD_IS_CMD_BUSY()),timeout_ms))
+   		{
+			gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+			MSDC_FatalErrorHandle();
+			MSDC_ERR("[SD][%s %d]wait cmd busy timeout !!,retry %d times\r\n",__FUNCTION__,__LINE__,retry_count);
+		}
+   	}
+   	else
+   	{
+		if (MSDC_TIMEOUT_WAIT((!SD_IS_SDC_BUSY()), timeout_ms))
+		{
+			gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+			MSDC_FatalErrorHandle();
+			MSDC_ERR("[SD][%s %d]wait SDC busy %d ms timeout!!,retry %d times\r\n",__FUNCTION__,__LINE__,timeout_ms,retry_count);
+			goto retry;
+		}
+   	}
+	if (gSD->mBKLength&&(gSD->mBKLength <= 0xfff))
+	{
+		cmd|=(gSD->mBKLength<<16);
+	}
+
+    /* If the card supports CMD23, enable AUTOCMD23 function of MSDC */
+    if (((cmd & 0x3F) == 18) || ((cmd & 0x3F) == 25)) {
+        if ((gSD->mSCR.cmd_support >> 1) & 0x1)
+            cmd |= (2 << 28);
+    }
+
+    MSDC_DEBUG("[SD]CMD=%d, arg=%X\r\n", cmd & 0x3F, arg);
+	
+	/*set argument*/
+	MSDC_WriteReg32(SDC_ARG,arg);
+	/*set command*/
+	MSDC_WriteReg32(SDC_CMD,cmd);
+	gMSDC_Handle->cmd = (kal_uint8)(cmd & 0x3F);
+    gMSDC_Handle->error=NO_ERROR;
+	return gMSDC_Handle->error;
+	
+retry:
+	if ((!SD_IS_SDC_BUSY())&&(retry_count<3)){
+		retry_count++;
+		goto check_busy;
+	}
+	return gMSDC_Handle->error;
+	
+}
+
+#define MSDC_TUNE_CMD_RESP_TA_MAX           (8)
+#define MSDC_TUNE_INT_DAT_LATCH_CK_MAX      (8)
+#define MSDC_TUNE_WCRC_TA_MAX               (8)
+
+static kal_uint8 fgCMDTuneLargeScale = 1;
+static kal_uint32 times_large = 0;
+static kal_uint32 times_small = 0;
+
+static kal_uint8 fgWrTuneLargeScale = 1;
+static kal_uint32 times_large_w = 0;
+static kal_uint32 times_small_w = 0;
+
+static kal_uint8 fgReadTuneLargeScale = 1;
+static kal_uint32 times_large_r = 0;
+static kal_uint32 times_small_r = 0;
+    
+static kal_uint32 msdc_tune_cmd_retry(kal_uint32 cmd, kal_uint32 arg, kal_uint32 timeout_ms)
+{
+    kal_uint32 result = ERR_CMD_RSPCRCERR;
+
+    /* CMD12 CRCERR should not tune */
+    if ((cmd & 0x3F) == 12) {
+        result = NO_ERROR;
+        goto done;
+    }
+    
+    /* Send 'STOP' command to complete 'TRANS' state */
+    if (MSDC_Reg32(SDC_CMD)&0x1800)
+    {
+        /*check if has data phase*/
+        result=SD_SendCmdOnly(SDC_CMD_CMD12,SDC_NO_ARG,1000);
+        result=SD_WaitCmdRdyOrTo();
+        if (result!=NO_ERROR)
+            goto err;
+    }
+    
+    if (gMSDC_Handle->app_cmd)
+    {
+        /*for acmd ,we should send cmd55 again*/
+        result=SD_SendCmdOnly(SDC_CMD_CMD55,gSD->mRCA,1000);
+        if (result!=NO_ERROR)
+            goto err;
+        result=SD_WaitCmdRdyOrTo();
+        if (result!=NO_ERROR)
+            goto err;
+    }
+    
+    result=SD_SendCmdOnly(cmd,arg,timeout_ms);
+
+    if (result!=NO_ERROR)
+        goto err;
+        
+    result=SD_WaitCmdRdyOrTo();
+    if (result==NO_ERROR)
+        goto done;
+    if (result != ERR_CMD_RSPCRCERR)
+        goto err;
+
+err:
+    MSDC_FatalErrorHandle();
+done:    
+    return result;
+}
+
+kal_uint32 msdc_tune_cmd_large_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 clk_mode, cmd_resp_ta_cntr, r_smpl;
+
+    times_large++;
+    
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+
+    /* 
+     * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz 
+     * that is ultra high speed mode, tune CMD_RESP_TA first
+     */
+    if ((clk_mode == 1) || (clk_mode == 2) || 
+        (gMSDC_Handle->op_clock >= MSDC_TUNE_UHS_SCLK)) {
+        cmd_resp_ta_cntr++;
+        MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, 
+            cmd_resp_ta_cntr & (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+
+        if (cmd_resp_ta_cntr >= MSDC_TUNE_CMD_RESP_TA_MAX) {
+            r_smpl++;
+            MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+        }
+    }
+    else {
+        /* 
+         * In low speed mode, just tune R_SMPL 
+         * and set MSDC_CMD_RSP_TA_CNTR back to 0
+         */
+        r_smpl++;
+        cmd_resp_ta_cntr = 0;
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+        MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr & 
+            (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+    }
+
+    /* Now all the parameters are set to 0 */
+    if (r_smpl >= 2)
+        ret = 1;
+
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+    
+    MSDC_NOTICE("[SD] <TUNE_CMD_LS><%d> CKMOD=%d, CMD_RSP_TA=%d, R_SMPL=%d\r\n",
+            times_large, clk_mode, cmd_resp_ta_cntr, r_smpl);
+   
+    if (ret)
+        times_large = 0;
+
+    return ret;
+}
+
+kal_uint32 msdc_tune_cmd_small_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 cmd_rxdly, clk_mode, cmd_resp_ta_cntr, r_smpl;
+
+    times_small++;
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+    MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly);
+
+    /* Adjust CMD_RXDLY in PAD macro */
+    cmd_rxdly++;
+    MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly & 0x1F);
+
+    /* Adjust R_SMPL */
+    if (cmd_rxdly >= 32) {
+        r_smpl++;
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+    }
+
+    /* 
+     * Adjust CMD_RSP_TA_CNTR
+     * if MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+     */
+    if (r_smpl >= 2) {
+        if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock >= MSDC_TUNE_UHS_SCLK)) {
+            cmd_resp_ta_cntr++;
+            MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, 
+                cmd_resp_ta_cntr & (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+
+            if (cmd_resp_ta_cntr >= MSDC_TUNE_CMD_RESP_TA_MAX) 
+                ret = 1;
+        }
+        else
+            ret= 1;
+    }
+
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+    MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly);
+
+    MSDC_NOTICE("[SD] <TUNE_CMD_SS><%d> CMD_RXDLY=%d, R_SMPL=%d, CMD_RSP_TA=%d\r\n",
+            times_small, cmd_rxdly, r_smpl, cmd_resp_ta_cntr);
+
+    /* Now all the parameters are set to 0 */
+    if (ret)
+        times_small = 0;
+        
+    return ret;    
+}
+
+SDC_CMD_STATUS SD_CmdTuneResp(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms)
+{
+    kal_uint32 result = ERR_CMD_RSPCRCERR;
+    
+    do {
+        /* Retry the CMD with error handling */
+        result = msdc_tune_cmd_retry(cmd, arg, timeout_ms);
+
+        if ((result == ERR_CMD_TIMEOUT) ||
+            (result == NO_ERROR)) {
+            if (result == NO_ERROR) {
+                if (times_large)
+                    fgCMDTuneLargeScale = 0;
+
+                times_small = 0;
+            }
+            goto done;
+        }
+
+        /* Large scale timing tuning */
+        if (fgCMDTuneLargeScale) {
+            if (msdc_tune_cmd_large_scale())
+                fgCMDTuneLargeScale = 0;
+        } 
+        /* Small scale timing tuning */
+        else {
+            if (msdc_tune_cmd_small_scale())
+                goto done;
+        }
+
+    } while (1);
+
+done:
+    MSDC_CRIT("[SD] <TUNE_CMD%d_DONE>", cmd & 0x3F);
+    if (result == NO_ERROR) 
+        MSDC_CRIT(" %s\r\n", "PASS");
+    else if (result == ERR_CMD_RSPCRCERR)
+        MSDC_CRIT(" %s\r\n", "CRCERR");
+    else if (result == ERR_CMD_TIMEOUT)
+        MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+    return result;
+}
+
+SDC_CMD_STATUS SD_SendCmd(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms)
+{
+	kal_uint32 status;
+	/*send command */
+	status = SD_SendCmdOnly(cmd,arg,timeout_ms);
+	if (status!=NO_ERROR)
+	{
+		MSDC_ERR("[SD][%s %d]send cmd %d error \r\n",__FUNCTION__,__LINE__,cmd);
+		return status;
+	}
+	/*wait command complete*/
+	status=SD_WaitCmdRdyOrTo();
+	if (status != NO_ERROR)
+	{
+		MSDC_FatalErrorHandle();
+		if (status == ERR_CMD_RSPCRCERR)
+		{
+			SD_CmdTuneResp(cmd, arg,timeout_ms);
+		}
+		status = gMSDC_Handle->error;
+		
+		return status;
+	}
+	if (cmd== SDC_CMD_CMD55 )
+	{
+		gMSDC_Handle->app_cmd=1;
+	}
+	else
+    {
+		gMSDC_Handle->app_cmd=0;
+		
+	}
+	return status;
+}
+kal_uint32 SD_PioRead(kal_uint32 * buffer,kal_uint32 num)
+{
+	kal_uint32 *ptr=buffer;
+	kal_uint8 *u8ptr;
+	kal_uint32 left;
+	ptr =buffer;
+	left=num;
+	while(left)
+	{
+		if ((left>=MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=MSDC_FIFO_THD)){
+			int count =MSDC_FIFO_THD>>2;	
+			do{
+				*ptr++=MSDC_FIFO_READ32();
+			}while(--count);
+			left-=MSDC_FIFO_THD;
+			
+		}
+		else if  ((left<MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=left))
+		{
+			while(left>3){
+				*ptr++=MSDC_FIFO_READ32();
+				left-=4;
+			}
+			u8ptr=(kal_uint8 *)ptr;
+			while(left){
+				*u8ptr++=MSDC_FIFO_READ8();
+				left--;
+			}
+			
+			if (gMSDC_Handle->abort){
+				gMSDC_Handle->abort=0;
+				MSDC_ERR("[SD][%s %d]pio read abort!!, num= %d \r\n",__FUNCTION__,__LINE__,num);
+				goto end;
+			}
+		}
+	}
+end:
+	return left;
+}
+
+kal_uint32 SD_PioWrite(kal_uint32 * buffer,kal_uint32 num)
+{
+	kal_uint32 * ptr=buffer;
+	kal_uint8 *u8ptr;
+	kal_uint32 left;
+	ptr=buffer;
+	left=num;
+	while(left){
+		if (left >= MSDC_FIFO_SZ){
+			if (MSDC_TXFIFOCNT()==0){
+				int count =MSDC_FIFO_SZ>>2;
+				do {
+					MSDC_FIFO_WRITE32(*ptr);
+					ptr++;
+				}while(--count);
+				left-=MSDC_FIFO_SZ;
+			}
+		}
+		else if ((left<MSDC_FIFO_SZ)&&(MSDC_TXFIFOCNT()==0)){
+			while(left){
+				while(left>3){
+					MSDC_FIFO_WRITE32(*ptr);
+					ptr++;
+					left-=4;
+				}
+				u8ptr=(kal_uint8 *)ptr;
+				while(left){
+					MSDC_FIFO_WRITE8(*u8ptr);
+					u8ptr++;
+					left--;
+				}
+			}
+		}
+		if (gMSDC_Handle->abort)
+		{
+			gMSDC_Handle->abort=0;
+			MSDC_ERR("[SD][%s %d]pio write abort %d \r\n",__FUNCTION__,__LINE__,num);
+			goto done;
+		}
+	}
+
+done:
+	return left;
+}
+
+#if !defined(MSDC_QMU_ENABLE)
+static kal_uint8 msdc_cal_checksum(const void *buf,kal_uint32 len)
+{
+    kal_uint32 i,sum=0;
+    kal_char *data=(char*)buf;
+    for(i=0;i<len;i++)
+    {
+        sum+=*data++;
+    }
+    return 0xFF-(kal_uint8)sum;
+}
+#endif
+
+static DCL_STATUS SD_ConfigGpdList(kal_uint32 size)
+{
+#if !defined(MSDC_QMU_ENABLE)
+    kal_uint32 i,buflen,data_count;
+    kal_uint32 * data_ptr;
+    kal_uint32 t1;
+    qbm_gpd* cur_gpd=NULL,*cur_bd=NULL;
+    msdc_gpd_t *gpd;
+    msdc_gpd_t *gpd_end;
+    qbm_gpd *head;
+    qbm_gpd *tail;
+    kal_uint8 sel = 0;
+    
+    #define CONFIG_GPDLIST_TIMEOUT 10000
+    
+    head = MSDC_Blk[sel].head;
+    tail = MSDC_Blk[sel].tail;
+    gpd = MSDC_Blk[sel].gpd;
+    gpd_end = MSDC_Blk[sel].gpd_end;
+    
+    gpd->intr   =1;     /*don't generate DMA_done interrupt*/
+    gpd->extlen =0;     /*ignore cmd,arg etc*/
+    gpd->hwo    =1;     /*config hardware owner*/
+    gpd->bdp    =1;     /*use buffer descriptor list*/
+    gpd->ptr    =(void*)(&MSDC_bd[sel][0]);
+    gpd->next   =(void*)gpd_end;
+    
+    #ifdef MSDC_DMA_CHKSUM_EN
+    gpd->chksum =0;
+    gpd->chksum =msdc_cal_checksum(gpd,16);
+    #endif
+   
+    gpd_end->intr   =0;     /*don't generate DMA_done interrupt*/
+    gpd_end->extlen =0;     /*ignore cmd,arg etc*/
+    gpd_end->hwo    =0;     /*config hardware owner*/
+    gpd_end->bdp    =0;     /*use buffer descriptor list*/
+    gpd_end->ptr    =0;
+    gpd_end->next   =NULL;
+
+    #ifdef MSDC_DMA_CHKSUM_EN
+    gpd_end->chksum =0;
+    gpd_end->chksum =msdc_cal_checksum(gpd_end,16);
+    #endif
+    
+    data_count = 0;
+    t1 = drv_get_current_time();
+    
+    for (i=0,cur_gpd=head;;cur_gpd=QBM_DES_GET_NEXT(cur_gpd)) {
+        if (i > MSDC_BD_MAX)
+        {
+            MSDC_ERR("[%s %d]qbm_gpd list is to long,only supprot %d object \r\n",__FUNCTION__,__LINE__,MSDC_BD_MAX);
+            return STATUS_INVALID_ARGUMENT;
+        }
+
+        /* NULL pointer check */
+        if (cur_gpd == NULL) {
+            MSDC_ERR("[%s %d]cur_gpd is NULL pointer!\r\n",__FUNCTION__,__LINE__);
+            return STATUS_INVALID_ARGUMENT;
+        }
+        
+        if (QBM_DES_GET_BDP(cur_gpd))
+        {
+            // if GPD with BD with data buffer
+            cur_bd=QBM_DES_GET_DATAPTR(cur_gpd);
+            while(1)
+            {
+                buflen=QBM_DES_GET_DATALEN(cur_bd);
+                data_ptr=(kal_uint32 *)QBM_DES_GET_DATAPTR(cur_bd);
+                if ((data_count+buflen)>size)
+                { //if buffer length is large the secotors we want to transfer            
+                   buflen=size-data_count;
+                   data_count=size;
+                }
+                else
+                {
+                    data_count+=buflen;
+                }
+                if (buflen)
+                { // if point to a buffer adress on this BD
+                    
+                    if (((cur_gpd==tail)&&(QBM_DES_GET_EOL(cur_bd)))||(data_count==size))
+                        MSDC_bd[sel][i].eol     =1;
+                    else
+                        MSDC_bd[sel][i].eol     =0;
+                    MSDC_bd[sel][i].next    =&MSDC_bd[sel][i+1];
+                    MSDC_bd[sel][i].ptr     =data_ptr;               
+                    MSDC_bd[sel][i].buflen  =buflen;
+                    clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)data_ptr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)data_ptr,buflen));                 
+                    MSDC_bd[sel][i].blkpad   =0;
+                    MSDC_bd[sel][i].dwpad   =0;
+                    MSDC_bd[sel][i].chksum=0;
+                    MSDC_bd[sel][i].chksum=msdc_cal_checksum(&MSDC_bd[sel][i],16);
+                    i++;
+                }          
+                if(QBM_DES_GET_EOL(cur_bd))
+                {
+                    break;
+                }
+                cur_bd=QBM_DES_GET_NEXT(cur_bd);
+            }
+        }
+        else
+        {   
+            // if GPD with data buffer
+            buflen=QBM_DES_GET_DATALEN(cur_gpd);
+            //dbg_print("%d  buflen=%d\r\n",i,buflen);
+            data_ptr=(kal_uint32 *)QBM_DES_GET_DATAPTR(cur_gpd);
+            if ((data_count+buflen)>size)
+            {             
+               buflen=size-data_count;
+               data_count=size;
+               //dbg_print("entry last data_count %d,buflen %d size %d\r\n",data_count,buflen,size);
+            }
+            else
+            {
+                data_count+=buflen;
+            }
+            if (buflen)
+            {
+                if (cur_gpd==tail||data_count==size)
+                    MSDC_bd[sel][i].eol     =1;
+                else
+                    MSDC_bd[sel][i].eol     =0;
+                MSDC_bd[sel][i].next    =&MSDC_bd[sel][i+1];
+                MSDC_bd[sel][i].ptr     =data_ptr;               
+                MSDC_bd[sel][i].buflen  =buflen;
+
+                /* 
+                 * There is NO need to clean the data cache, which is transfered
+                 * from MSD and USB, because the buffer is directly read or write 
+                 * by DMA, CPU are not involved in.
+                 */
+                #if defined(MSDC_SCAT_BUF_FLUSH) || defined(ATEST_DRV_MSDC)
+                clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)data_ptr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)data_ptr,buflen));
+                #endif
+                
+                MSDC_bd[sel][i].blkpad   =0;
+                MSDC_bd[sel][i].dwpad   =0;
+
+                #ifdef MSDC_DMA_CHKSUM_EN
+                MSDC_bd[sel][i].chksum=0;
+                MSDC_bd[sel][i].chksum=msdc_cal_checksum(&MSDC_bd[sel][i], 16);
+                #endif
+                
+                i++;
+            }          
+        }
+        if (cur_gpd==tail)
+            break;
+            
+    }
+
+    if (drv_get_duration_ms(t1)>CONFIG_GPDLIST_TIMEOUT)
+    {
+        MSDC_INFO("[%s %d]config gpd list timeout\r\n",__FUNCTION__,__LINE__,MSDC_BD_MAX);
+        return STATUS_INVALID_ARGUMENT;
+    }
+    
+    //if data buffer is not enough 
+    if (data_count!=size)
+    {
+        MSDC_INFO("[%s %d]data_count %d,size %d\r\n",__FUNCTION__,__LINE__,data_count,size);
+        return STATUS_INVALID_ARGUMENT;
+    }
+
+    /* Flush the GPD and BD from cache to memory */
+    #ifdef MSDC_GPD_BD_BUF_CACHED
+    clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gpd),
+        CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gpd, sizeof(msdc_gpd_t)));
+    clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gpd_end),
+        CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gpd_end, sizeof(msdc_gpd_t)));
+    clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)&MSDC_bd[sel][0]),
+        CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)&MSDC_bd[sel][0], i * sizeof(msdc_bd_t)));
+    #endif
+
+    return STATUS_OK;
+
+#else
+    
+    qbm_gpd *head, *tail, *tail_bak, *p_bps_gpd, *p_cur_gpd;
+    kal_uint8 sel = 0;
+        
+    head = MSDC_Blk[sel].head;
+    tail = MSDC_Blk[sel].tail;
+    tail_bak = tail;
+
+    /* In case of normal transfer */
+    if (!gMSDC_Handle->f_tuning) {
+        p_bps_gpd = g_p_msdc_bps[sel];
+        if (!p_bps_gpd) {
+            MSDC_ERR("[%s %d]Invalid loacal bypass GPD buffer!\r\n",__FUNCTION__,__LINE__);
+            return STATUS_FAIL;
+        }
+
+        /* Link the bypass GPD to tail */
+        qbmt_common_en_q_rx(p_bps_gpd, p_bps_gpd, (void **)&head, (void **)&tail);
+
+        /* Set HWO = 1, cause it is cleared by USB QMU */
+        p_cur_gpd = head;
+        do {
+            if (p_cur_gpd == tail_bak)
+                break;
+
+            QBM_DES_SET_HWO(p_cur_gpd);
+            QBM_CACHE_FLUSH(p_cur_gpd, 2);
+
+            p_cur_gpd = p_cur_gpd->p_next;
+        } while(1);
+    }
+    /* In case of re-try on tuning */
+    else {
+        p_cur_gpd = head;
+
+        /* Re-Set HWO = 1, and flush cache */
+        do {
+            QBM_DES_SET_HWO(p_cur_gpd);
+            QBM_CACHE_FLUSH(p_cur_gpd, sizeof(qbm_gpd));
+
+            if ((p_cur_gpd == tail))
+                break;
+
+            p_cur_gpd = p_cur_gpd->p_next;
+
+        } while(1);
+    }
+
+    /* Set the QMU start address */
+    gMSDC_Handle->buf_addr = (void *)MSDC_Blk[sel].head;
+		    
+    return STATUS_OK;
+    
+#endif
+}
+
+SDC_CMD_STATUS SD_ReqHandleData(kal_uint32 data_adrs, void* buffer, kal_uint32 num,kal_bool isWrite,kal_bool isLinkListBuf)
+{
+	kal_uint32 status ;
+	kal_bool dma;
+	kal_uint32 intsts;
+	kal_uint8 cmd23_sup = 0;
+
+    MSDC_INFO("[SD]SD_Req: CMD%s Addr=%x BlkNum=%d Buf=%x\r\n", 
+        isWrite ? "25(24)" : "18(17)", data_adrs, num, buffer);
+
+	/*Set block size and block num*/
+	if (gSD->mBKLength!=512)
+	{
+		status =SD_SetBlength(512);
+		if (status != NO_ERROR)
+		{
+			return status;
+		}
+			
+	}
+	MSDC_WriteReg32(SDC_BLK_NUM,num);
+	/*set read timeout*/
+	/*check we use dma or pio*/
+	if(gSD->mBKLength*num <512)
+	{
+		/*use pio*/
+		dma=0;
+		//set to PIO mode
+  		 BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+		gMSDC_Handle->dma_xfer=0;
+	}
+	else
+	{
+		/*use dma*/
+		dma=1;
+		//set to DMA mode
+   		BitFieldWrite32((kal_uint32 *)MSDC_CFG, 0, MSDC_CFG_PIO);
+		gMSDC_Handle->dma_xfer=1;
+	}
+	
+	dma=1;						/*driver unsupport PIO now*/
+	gMSDC_Handle->dma_xfer=1;
+	if (dma)
+	{
+		kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0,KAL_AND);
+		/*enable DMA*/
+		MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_PIO);
+		/*start command*/
+        if (!isWrite)
+        {
+            if (num==1)
+            {
+                status=SD_SendCmdOnly(SDC_CMD_CMD17,data_adrs,MSDC_CMD_TIMEOUT);
+            }
+            else
+            {
+		        status=SD_SendCmdOnly(SDC_CMD_CMD18,data_adrs,MSDC_CMD_TIMEOUT);
+            }
+        }
+        else
+        {
+            if (num==1)
+            {
+                status=SD_SendCmdOnly(SDC_CMD_CMD24,data_adrs,MSDC_CMD_TIMEOUT);
+            }
+            else
+            {
+                status=SD_SendCmdOnly(SDC_CMD_CMD25,data_adrs,MSDC_CMD_TIMEOUT);
+            }
+        }
+		if (status !=NO_ERROR)
+		{
+			goto done;
+		}
+		/*map dma data*/
+		
+		/*config dma*/
+		gMSDC_Handle->total_count=num*gSD->mBKLength;
+		gMSDC_Handle->buf_addr=buffer;
+
+		if (isLinkListBuf) {
+		    status = SD_ConfigGpdList(gMSDC_Handle->total_count);
+		    if (status != STATUS_OK) {
+		        MSDC_ERR("[%s %d]Config GPD list fail!\r\n",__FUNCTION__,__LINE__);
+		        return status;
+		    }
+		}
+		    
+		MSDC_DMATransferFirst(isWrite,isLinkListBuf);
+		
+		/*wait cmd rsp*/
+		status=SD_WaitCmdRdyOrTo();
+		if (status != NO_ERROR)
+		{
+			MSDC_FatalErrorHandle();
+			if (status == ERR_CMD_RSPCRCERR)
+			{
+			    if (!isWrite)
+                {   if (num==1)      
+				        status=SD_CmdTuneResp(SDC_CMD_CMD17, data_adrs,MSDC_CMD_TIMEOUT);
+                    else
+                        status=SD_CmdTuneResp(SDC_CMD_CMD18, data_adrs,MSDC_CMD_TIMEOUT);   
+                }
+                else
+                {
+                    if(num==1)
+                        status=SD_CmdTuneResp(SDC_CMD_CMD24, data_adrs,MSDC_CMD_TIMEOUT);
+                    else
+                        status=SD_CmdTuneResp(SDC_CMD_CMD25, data_adrs,MSDC_CMD_TIMEOUT);     
+                }
+			}
+			if(status != NO_ERROR)
+			    goto done;
+		}
+		/*start dma and wait data complete*/
+		status = MSDC_DMATransferFinal(isWrite,isLinkListBuf);
+	}
+	else
+	{
+		/*pio mode*/
+		if (SD_SendCmd(((isWrite==KAL_TRUE) ?SDC_CMD_CMD25:SDC_CMD_CMD18),data_adrs,MSDC_CMD_TIMEOUT))
+		{
+			goto done;
+		}
+		MSDC_SetBits32(MSDC_INTEN,MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+		if(!isWrite)
+		{
+			/*poll to read data from FIFO*/
+			status =SD_PioRead(buffer,num*gSD->mBKLength);
+		}
+		else
+		{
+			/*poll to write data to FIFO*/
+			status =SD_PioWrite(buffer,num*gSD->mBKLength);
+		}
+		
+		MSDC_ClearBits32(MSDC_INTEN, MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+		if (status)
+		{
+			goto done;
+		}
+		intsts =MSDC_PollInts(MSDC_INT_XFER_COMPL|MSDC_INT_DATTMO|MSDC_INT_DATCRCERR,100);
+		if (intsts&MSDC_INT_XFER_COMPL)
+		{
+			status=gMSDC_Handle->error=NO_ERROR;
+		}
+		else if (intsts&MSDC_INT_DATCRCERR){
+			status=gMSDC_Handle->error=ERR_DAT_CRCERR;
+		}
+		else if (intsts&MSDC_INT_DATTMO)
+		{
+			status=gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+		}
+		else
+        	MSDC_ERR("[SD][%s %d]SW timeout in wait PIO data done\r\n",__FUNCTION__,__LINE__);
+	}
+done:
+	if (status)
+	{
+		MSDC_FatalErrorHandle();
+	}
+	
+	/*cmd12 to stop data*/
+	cmd23_sup = (gSD->mSCR.cmd_support >> 1) & 0x1;
+    if (((num>1) && !cmd23_sup) || ((num>1) && cmd23_sup && status))
+	    SD_SendCmd(SDC_CMD_CMD12, SDC_NO_ARG, MSDC_CMD_TIMEOUT);
+	
+	/* Check card status after each operation */
+	MSDC_CheckCardBusy(KAL_FALSE, 10*1000);
+	
+	return status;
+}
+
+kal_uint32 msdc_tune_write_large_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 ultra_hs = 0;
+    kal_uint32 clk_mode, wr_datcrc_ta, w_d_smpl;
+    
+    times_large_w++;
+    
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+
+    /* 
+     * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz 
+     * that is ultra high speed mode, tune WRDAT_CRCS_TA_CNTR first
+     */
+    if ((clk_mode == 1) || (clk_mode == 2) ||  (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+        ultra_hs = 1;
+
+    if (ultra_hs) {
+        wr_datcrc_ta++;
+        MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, 
+            wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+
+        if (wr_datcrc_ta >= MSDC_TUNE_WCRC_TA_MAX) {
+            w_d_smpl++;
+            MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+        }
+    }
+    else {
+        w_d_smpl++;
+        wr_datcrc_ta = 0;
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+        MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, 
+            wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+    }
+
+    if (w_d_smpl >= 2) {
+        ret = 1;    
+    }
+
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+    
+    MSDC_NOTICE("[SD] <TUNE_WR_LS><%d> %s=%d, %s=%d, %s=%d\r\n",
+            times_large_w, "CKMOD", clk_mode, 
+            "WR_DATCRC_TA", wr_datcrc_ta, "W_D_SMPL", w_d_smpl);
+   
+    if (ret)
+        times_large_w = 0;
+
+    return ret;
+}
+
+kal_uint32 msdc_tune_write_small_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 ultra_hs = 0;
+    kal_uint32 clk_mode, wr_datcrc_ta, w_d_smpl, dat0_rd_dly, dat_wr_rxdly;
+    
+    times_small_w++;
+
+    /* 
+     * When re-enter the tuning flow, 
+     * Clear the pad macro then tune from the beginning
+     */
+    if (times_small_w == 1) {
+        MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, 0);
+    }
+    
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+    MSDC_GET_FIELD(MSDC_DAT_RDDLY0, MSDC_DAT_RDDLY0_D0, dat0_rd_dly);
+    MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly);
+
+    /* 
+     * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz 
+     * that is ultra high speed mode, tune WRDAT_CRCS_TA_CNTR 
+     * and PAT_DAT_WR_RXDLY at last
+     */
+    if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+        ultra_hs = 1;
+
+    dat_wr_rxdly++;
+    MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly & 0x1F);
+
+    if (dat_wr_rxdly >= 32) {
+        w_d_smpl++;
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+    }
+
+    if (ultra_hs) {
+        if (w_d_smpl >= 2) {
+            wr_datcrc_ta++;
+            MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, 
+                wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+        }
+
+        if (wr_datcrc_ta >= MSDC_TUNE_WCRC_TA_MAX)
+            ret = 1;
+    }
+
+    if (w_d_smpl >= 2) 
+        ret = 1;
+
+    MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+    MSDC_GET_FIELD(MSDC_DAT_RDDLY0, MSDC_DAT_RDDLY0_D0, dat0_rd_dly);
+    MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly);
+    
+    MSDC_NOTICE("[SD] <TUNE_WR_SS><%d> %s=%d, %s=%d, %s=%d\r\n",
+            times_small_w, "CKMOD", clk_mode, 
+            "WR_DATCRC_TA", wr_datcrc_ta, "W_D_SMPL", w_d_smpl);
+    MSDC_NOTICE("                        %s=%d, %s=%d\r\n",
+            "DAT0_RD_DLY", dat0_rd_dly, "DAT_WR_RXDLY", dat_wr_rxdly);
+            
+    if (ret)
+        times_small_w = 0;
+
+    return ret;
+}
+
+kal_uint32 SD_TuneWrite(kal_uint32 address,void * txbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+    kal_uint32 result = ERR_DAT_CRCERR;
+    
+    do {
+        /* Retry the Write with error handling */
+        result = SD_ReqHandleData(address,txbuffer,num,KAL_TRUE,isLinkListBuf);
+
+        if (/*(result == ERR_DAT_TIMEOUT) ||*/
+            (result == NO_ERROR)) {
+            if (times_large_w)
+                fgWrTuneLargeScale = 0;
+
+            times_small_w = 0;
+            
+            goto done;
+        }
+
+        /* Large scale timing tuning */
+        if (fgWrTuneLargeScale) {
+            if (msdc_tune_write_large_scale())
+                fgWrTuneLargeScale = 0;
+        } 
+        /* Small scale timing tuning */
+        else {
+            if (msdc_tune_write_small_scale())
+                goto done;
+        }
+
+    } while (1);
+
+done:
+    MSDC_CRIT("[SD] <TUNE_WRITE_DONE>");
+    if (result == NO_ERROR) 
+        MSDC_CRIT(" %s\r\n", "PASS");
+    else if (result == ERR_DAT_CRCERR)
+        MSDC_CRIT(" %s\r\n", "CRCERR");
+    else if (result == ERR_DAT_TIMEOUT)
+        MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+    return result;
+}
+
+
+kal_uint32 msdc_tune_read_large_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 ultra_hs = 0;
+    kal_uint32 clk_mode, int_dat_latch, ckgen_dly, r_d_smpl;
+    
+    times_large_r++;
+    
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+
+    /* 
+     * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz 
+     * that is ultra high speed mode, tune INT_DAT_LATCH_CK_SEL
+     * and CKGEN_MSDC_DLY_SEL first
+     */
+    if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+        ultra_hs = 1;
+
+    if (ultra_hs) {
+        /* Sampling edge is fixed by default setting - rising edge */
+        int_dat_latch++;
+        MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, 
+            int_dat_latch & (MSDC_TUNE_INT_DAT_LATCH_CK_MAX - 1));
+
+        if (int_dat_latch >= MSDC_TUNE_INT_DAT_LATCH_CK_MAX) {
+            ckgen_dly++;
+            MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+
+            if (ckgen_dly >= 32)
+                ret = 1;
+        }
+    }
+    else {
+        /* 
+         * In low speed mode, just tune R_D_SMPL 
+         * and set other parameters back to 0
+         */
+        r_d_smpl++;
+        int_dat_latch = 0;
+        ckgen_dly = 0;
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl % 2);
+        MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, 
+            int_dat_latch & (MSDC_TUNE_INT_DAT_LATCH_CK_MAX - 1));
+        MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+        
+    }
+
+    if (r_d_smpl >= 2)
+        ret = 1;
+
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+    
+    MSDC_NOTICE("[SD] <TUNE_RD_LS><%d> %s=%d, %s=%d, %s=%d, %s=%d\r\n",
+            times_large_r, "CKMOD", clk_mode, 
+            "INT_DAT_L", int_dat_latch, "CKGEN_DLY", ckgen_dly,
+            "R_D_SMPL", r_d_smpl);
+   
+    if (ret)
+        times_large_r = 0;
+
+    return ret;
+    
+}
+
+kal_uint32 msdc_tune_read_small_scale()
+{
+    kal_uint32 ret = 0;
+    kal_uint32 ultra_hs = 0;
+    kal_uint32 clk_mode, int_dat_latch, ckgen_dly, r_d_smpl, dat_rddly0, dat_rddly1;
+    kal_uint32 dat0_rd_dly, dat1_rd_dly, dat2_rd_dly, dat3_rd_dly;
+    kal_uint32 dat4_rd_dly, dat5_rd_dly, dat6_rd_dly, dat7_rd_dly;
+
+    kal_uint32 ddr = 0, dcrc_sts;
+    
+    times_small_r++;
+    
+    MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+    
+    /* 
+     * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz 
+     * that is ultra high speed mode, tune INT_DAT_LATCH_CK_SEL
+     * and CKGEN_MSDC_DLY_SEL at last
+     */
+    if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+        ultra_hs = 1;
+
+    /* 
+     * When re-enter the tune in Non-UHS mode, 
+     * Clear the pad macro then tune from the beginning
+     */
+    if ((times_small_r == 1) && (ultra_hs == 0)) {
+        MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, 0);
+        MSDC_WriteReg32(MSDC_DAT_RDDLY0, 0);
+        MSDC_WriteReg32(MSDC_DAT_RDDLY1, 0);
+    }
+    
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+    dat_rddly0 = MSDC_Reg32(MSDC_DAT_RDDLY0);
+    dat_rddly1 = MSDC_Reg32(MSDC_DAT_RDDLY1);
+    
+    /* Get data CRC status */
+    MSDC_GET_FIELD(SDC_DCRC_STS, SDC_DCRC_STS_NEG | SDC_DCRC_STS_POS, dcrc_sts);
+
+    /* Check output clock is SDR mode or DDR mode */
+    ddr =  (clk_mode == 2) ? 1 : 0;
+    if (!ddr) 
+        dcrc_sts &= ~SDC_DCRC_STS_NEG;
+    
+    /* Tune PAD macro first */
+    MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
+    
+    dat0_rd_dly = (dat_rddly0 >> 24) & 0x1F;
+    dat1_rd_dly = (dat_rddly0 >> 16) & 0x1F;
+    dat2_rd_dly = (dat_rddly0 >>  8) & 0x1F;
+    dat3_rd_dly = (dat_rddly0 >>  0) & 0x1F;
+    dat4_rd_dly = (dat_rddly1 >> 24) & 0x1F;
+    dat5_rd_dly = (dat_rddly1 >> 16) & 0x1F;
+    dat6_rd_dly = (dat_rddly1 >>  8) & 0x1F;
+    dat7_rd_dly = (dat_rddly1 >>  0) & 0x1F;
+
+    if (ddr) {
+        dat0_rd_dly = (dcrc_sts & (1 << 0) || dcrc_sts & (1 <<  8)) ? (dat0_rd_dly + 1) : dat0_rd_dly;
+        dat1_rd_dly = (dcrc_sts & (1 << 1) || dcrc_sts & (1 <<  9)) ? (dat1_rd_dly + 1) : dat1_rd_dly;
+        dat2_rd_dly = (dcrc_sts & (1 << 2) || dcrc_sts & (1 << 10)) ? (dat2_rd_dly + 1) : dat2_rd_dly;
+        dat3_rd_dly = (dcrc_sts & (1 << 3) || dcrc_sts & (1 << 11)) ? (dat3_rd_dly + 1) : dat3_rd_dly;
+        dat4_rd_dly = (dcrc_sts & (1 << 4) || dcrc_sts & (1 << 12)) ? (dat4_rd_dly + 1) : dat4_rd_dly;
+        dat5_rd_dly = (dcrc_sts & (1 << 5) || dcrc_sts & (1 << 13)) ? (dat5_rd_dly + 1) : dat5_rd_dly;
+        dat6_rd_dly = (dcrc_sts & (1 << 6) || dcrc_sts & (1 << 14)) ? (dat6_rd_dly + 1) : dat6_rd_dly;
+        dat7_rd_dly = (dcrc_sts & (1 << 7) || dcrc_sts & (1 << 15)) ? (dat7_rd_dly + 1) : dat7_rd_dly;
+    } else {
+        dat0_rd_dly = (dcrc_sts & (1 << 0)) ? (dat0_rd_dly + 1) : dat0_rd_dly;
+        dat1_rd_dly = (dcrc_sts & (1 << 1)) ? (dat1_rd_dly + 1) : dat1_rd_dly;
+        dat2_rd_dly = (dcrc_sts & (1 << 2)) ? (dat2_rd_dly + 1) : dat2_rd_dly;
+        dat3_rd_dly = (dcrc_sts & (1 << 3)) ? (dat3_rd_dly + 1) : dat3_rd_dly;
+        dat4_rd_dly = (dcrc_sts & (1 << 4)) ? (dat4_rd_dly + 1) : dat4_rd_dly;
+        dat5_rd_dly = (dcrc_sts & (1 << 5)) ? (dat5_rd_dly + 1) : dat5_rd_dly;
+        dat6_rd_dly = (dcrc_sts & (1 << 6)) ? (dat6_rd_dly + 1) : dat6_rd_dly;
+        dat7_rd_dly = (dcrc_sts & (1 << 7)) ? (dat7_rd_dly + 1) : dat7_rd_dly;
+    }
+
+    dat_rddly0 = ((dat0_rd_dly & 0x1F) << 24) | ((dat1_rd_dly & 0x1F) << 16) |
+                 ((dat2_rd_dly & 0x1F) << 8)  | ((dat3_rd_dly & 0x1F) << 0);    
+    dat_rddly1 = ((dat4_rd_dly & 0x1F) << 24) | ((dat5_rd_dly & 0x1F) << 16) |
+                 ((dat6_rd_dly & 0x1F) << 8)  | ((dat7_rd_dly & 0x1F) << 0);
+
+    MSDC_WriteReg32(MSDC_DAT_RDDLY0, dat_rddly0);
+    MSDC_WriteReg32(MSDC_DAT_RDDLY1, dat_rddly1);   
+    
+    /* Then R_D_SMPL */
+    if( (dat0_rd_dly >= 32) || (dat1_rd_dly >= 32) || (dat2_rd_dly >= 32) || (dat3_rd_dly >= 32)||
+        (dat4_rd_dly >= 32) || (dat5_rd_dly >= 32) || (dat6_rd_dly >= 32) || (dat7_rd_dly >= 32)){
+
+        /* 
+         * On ultra-hs mode, do NOT tune sampling edge,
+         * because of the 'internal boundary' issue of the current IP
+         */
+        if (!ultra_hs) {
+            r_d_smpl++;
+            MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl % 2);
+        }
+
+        /* Re-tune the data pad macro */
+        MSDC_WriteReg32(MSDC_DAT_RDDLY0, 0);
+        MSDC_WriteReg32(MSDC_DAT_RDDLY1, 0);
+
+        /* Then CKGEN_MSDC_DLY_SEL if it is SDR104 mode */
+        if (ultra_hs) {
+            ckgen_dly++;
+            MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+
+            if (ckgen_dly >= 32)
+                ret = 1;
+        }
+        else {
+            if (r_d_smpl >= 2)
+                ret = 1;
+        }
+        
+    }
+
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+    MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+    MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+    dat_rddly0 = MSDC_Reg32(MSDC_DAT_RDDLY0);
+    dat_rddly1 = MSDC_Reg32(MSDC_DAT_RDDLY1);
+    
+    MSDC_NOTICE("[SD] <TUNE_RD_SS><%d> %s=%d, %s=%d, %s=%d, %s=%d\r\n",
+            times_small_r, "CKMOD", clk_mode, 
+            "INT_DAT_L", int_dat_latch, "CKGEN_DLY", ckgen_dly,
+            "R_D_SMPL", r_d_smpl);
+    MSDC_NOTICE("                        %s=0x%x, %s=0x%x\r\n",
+            "DAT_RDDLY0", dat_rddly0, "DAT_RDDLY1", dat_rddly1);
+            
+    if (ret)
+        times_small_r = 0;
+
+    return ret;
+    
+}
+
+SDC_CMD_STATUS SD_TuneRead(kal_uint32 data_adrs,void *rxbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+    kal_uint32 result = ERR_DAT_CRCERR;
+    
+    do {
+        /* Retry the Read with error handling */
+        result = SD_ReqHandleData(data_adrs,rxbuffer,num,KAL_FALSE,isLinkListBuf);
+
+        if ((result == ERR_DAT_TIMEOUT) ||
+            (result == NO_ERROR)) {
+            if (result == NO_ERROR) {
+                if (times_large_r)
+                    fgReadTuneLargeScale = 0;
+
+                times_small_r = 0;
+            }
+            
+            goto done;
+        }
+
+        /* Large scale timing tuning */
+        if (fgReadTuneLargeScale) {
+            if (msdc_tune_read_large_scale())
+                fgReadTuneLargeScale = 0;
+        } 
+        /* Small scale timing tuning */
+        else {
+            if (msdc_tune_read_small_scale())
+                goto done;
+        }
+
+    } while (1);
+
+done:
+    MSDC_CRIT("[SD] <TUNE_READ_DONE>");
+    if (result == NO_ERROR) 
+        MSDC_CRIT(" %s\r\n", "PASS");
+    else if (result == ERR_DAT_CRCERR)
+        MSDC_CRIT(" %s\r\n", "CRCERR");
+    else if (result == ERR_DAT_TIMEOUT)
+        MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+    return result;
+}
+
+void msdc_tune_init(void) 
+{
+    /* Initialize the tuning releated parameters and registers */
+    fgCMDTuneLargeScale = 1;
+    times_large = 0;
+    times_small = 0;
+    MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, 0);
+    MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_RSPL, 0);
+    MSDC_SET_FIELD_NPW(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, 0);
+    
+    fgWrTuneLargeScale = 1;
+    times_large_w = 0;
+    times_small_w = 0;
+    MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, 0);
+    MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_WDSPL, 0);
+    MSDC_SET_FIELD_NPW(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, 0);
+    
+    fgReadTuneLargeScale = 1;
+    times_large_r = 0;
+    times_small_r = 0;
+    MSDC_WriteReg32_NPW(MSDC_DAT_RDDLY0, 0);
+    MSDC_WriteReg32_NPW(MSDC_DAT_RDDLY1, 0);
+    MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, 0);
+    MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, 0);
+    MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_RDSPL, 0);    
+}
+
+SDC_CMD_STATUS SD_HandleWriteTMO(kal_uint32 address,void *txbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+	kal_uint32 cur_wrta,orig_wr_crcta;
+	kal_uint32 status,i,ret;
+	
+	ret=SD_GetStatus(gSD->mRCA,&status);
+	if (ret){
+		return ERR_DAT_TIMEOUT;
+	}
+	if (status&(R1_OUT_OF_RANGE_31|R1_ADDRESS_ERROR_30)){
+		return ERR_DAT_TIMEOUT;
+	}
+	orig_wr_crcta=(MSDC_Reg32(MSDC_PATCH_BIT1)&MSDC_PATCH_BIT1_WRDAT_CRCS)>>(uffs(MSDC_PATCH_BIT1_WRDAT_CRCS)-1);
+	/*Ncrc may cause Write data timeout*/
+	for (i=0;i<8;i++){
+		cur_wrta=(orig_wr_crcta+i)%8;
+		MSDC_SetData32(MSDC_PATCH_BIT1,MSDC_PATCH_BIT1_WRDAT_CRCS,cur_wrta<<(uffs(MSDC_PATCH_BIT1_WRDAT_CRCS)-1));
+		ret=SD_ReqHandleData(address,txbuffer,num,KAL_TRUE,isLinkListBuf);
+		if (ret==0)
+			return 0;
+		if (ret==ERR_DAT_CRCERR||ret==ERR_CMD_RSPCRCERR)
+		{
+			return ret;
+		}
+	}
+	if (ret)
+	{
+		return ret;
+	}
+	ret=SD_TuneWrite( address,txbuffer,num,isLinkListBuf);
+	return ret;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_Reset
+*
+* DESCRIPTION
+*	reset all cards to idle state
+*
+* PARAMETERS
+*	1. cmd: the content of SDC_CMD register
+*	2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Reset(void)
+{
+	SDC_CMD_STATUS status;
+	status=SD_SendCmd(SDC_CMD_CMD0,SDC_NO_ARG,MSDC_CMD_TIMEOUT);
+	gSD->mState=IDLE_STA;
+	return status;
+    
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd55
+*
+* DESCRIPTION
+*	APP_CMD: inidicate to the card that the next command is an application specified command
+*			rather than a standard command
+*
+* PARAMETERS
+*	rca: relative card address
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd55(kal_uint16 rca)
+{
+	SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD55, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+        
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    //check APP_CMD bit in status register
+    status=MSDC_Reg32(SDC_RESP0);
+
+    if (!(status & R1_APP_CMD_5))
+        return ERR_APPCMD_FAILED;
+
+    return NO_ERROR;
+   
+}
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd8
+*
+* DESCRIPTION
+*	1. Sends SD Memory Card interface conditions for support larger than 2G cards
+*	2. check if the card is compliant to SD2.0 or higher
+*	3. only performed while at IDLE state.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD->mIsCMD8
+*
+*************************************************************************/
+void SD_Cmd8(void)
+{
+    kal_uint32 resp;
+    kal_uint32 retry = 4;
+    MSDC_DEBUG("[SD][%s %d]Cmd8 arg=%x\r\n",__FUNCTION__,__LINE__,SDC_CMD8_ARG);
+
+cmd8_retry:	
+    if (SD_SendCmd(SDC_CMD_CMD8, SDC_CMD8_ARG,MSDC_CMD_TIMEOUT) != NO_ERROR)
+    {
+        MSDC_ERR("[SD][%s %d]SDC_Cmd8 fail\r\n",__FUNCTION__,__LINE__);
+        SD_Reset();
+        gSD->mCMD8Resp = SD_CMD8_RESP_NORESP;
+        return;
+    }
+
+    resp= MSDC_Reg32(SDC_RESP0);
+    MSDC_DEBUG("[SD][%s %d]Cmd8 resp=%x\r\n",__FUNCTION__,__LINE__,resp);
+
+    if (resp == SDC_CMD8_ARG)
+        gSD->mCMD8Resp = SD_CMD8_RESP_VALID;
+    else {
+        MSDC_ERR("[SD]CMD8 check pattern error, %X(%X)\r\n",SDC_CMD8_ARG,resp);
+        
+        if (retry--)
+            goto cmd8_retry;
+
+        gSD->mCMD8Resp = SD_CMD8_RESP_INVALID;
+    }
+
+    return;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd1_MMC
+*
+* DESCRIPTION
+*	 asks all cards in idle state to send their OCR in the response on the CMD line
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	only works for MMC
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+
+SDC_CMD_STATUS SD_Cmd1_MMC(void)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 _ocr, ocr_i,  t2;
+
+    #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+    if (gSD->mCMD8Resp == SD_CMD8_RESP_INVALID)
+        return ERR_CMD8_INVALID;
+
+    ocr_i = (SDC_OCR_DEFAULT | MMC_HIGH_DESITY_CHECK_BIT);
+    #else
+    ocr_i = SDC_OCR_DEFAULT;
+    #endif
+
+    if (gMSDC_Handle->is_init_timeout == KAL_TRUE)
+        return ERR_R3_OCR_BUSY;
+
+    t2 = drv_get_current_time();
+
+    do
+    {
+        /*send cmd1*/
+        if ((status=SD_SendCmd(SDC_CMD_CMD1,ocr_i,MSDC_CMD_TIMEOUT))  != NO_ERROR)
+            return status;
+
+        _ocr=MSDC_Reg32(SDC_RESP0);
+        MSDC_NOTICE("[SD]OCR = %x\r\n", _ocr);
+
+        if ((_ocr & SDC_OCR_DEFAULT) == 0)
+            return ERR_OCR_NOT_SUPPORT;
+
+        if (!gMSDC_Handle->mIsPresent)
+            return MSDC_CARD_NOT_PRESENT;
+
+        if (!(_ocr & SDC_OCR_BUSY))
+        {
+            if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+            {
+                gMSDC_Handle->is_init_timeout = KAL_TRUE;
+                break;
+            }
+
+            msdc_sleep(2);
+        }
+        else {
+            MSDC_CRIT("[SD]OCR = %x\r\n", _ocr);
+            break;
+        }
+    }
+    while (1);
+
+    if (gMSDC_Handle->is_init_timeout)
+        return ERR_CMD_TIMEOUT;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+    if ((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
+    {
+        gSD->flags |= SD_FLAG_HCS_SUPPORT;
+        gMSDC_Handle->mMSDC_type = MMC42_CARD;
+        gSD->mIsBlkAddr = 1;
+    }
+    else
+#endif
+        gMSDC_Handle->mMSDC_type = MMC_CARD;
+
+    gSD->mInactive = KAL_FALSE;
+    gSD->mSDC_ocr = _ocr;
+    gSD->mState = READY_STA;
+
+    return NO_ERROR;
+}
+SDC_CMD_STATUS SD_Cmd11(void)
+{
+    SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD11, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+    {
+        return status;
+    }
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    return NO_ERROR;
+   
+}
+kal_int32 SD_SwitchVolt18()
+{
+    kal_uint32 status,t2;
+    status=SD_Cmd11();
+    if (status !=NO_ERROR)
+        return status;
+    /*make sure SDC is not BUSY*/
+    if (MSDC_TIMEOUT_WAIT((!SD_IS_SDC_BUSY())&&MSDC_Check_Card_Present(),MSDC_CMD_TIMEOUT))
+    {
+	    MSDC_ERR("[SD][%s %d]wait SDC busy timeout\r\n",__FUNCTION__,__LINE__);
+        return ERR_STATUS;
+    }
+    /*check data[3:0] and cmd is lower by card*/
+    if(MSDC_Reg32(MSDC_PS)&((1<<24)|(0xf<<16)))
+        return CHECK_DATA_CMD_LOW_FAIL;
+    /*pull up disabled in CMD and DAT[3:0]*/
+    MSDC_ConfigPin(MSDC_PIN_PULL_NONE);
+    /*switch signal voltage to 1.8v*/
+    gMSDC_Handle->signal_volt=1800;
+    MSDC_SetSignalPower(1,gMSDC_Handle->signal_volt);
+    /*wait 5ms*/
+    msdc_sleep(2);
+    /*PULL UP enable in CMD and DAT[3:0]*/
+    MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+    msdc_sleep(1);
+    /*start to detect volt change */
+    MSDC_SetBits32(MSDC_CFG,MSDC_CFG_BV18SDT);
+    msdc_sleep(20);
+    t2=drv_get_current_time();
+    do{
+        if(((status=MSDC_Reg32(MSDC_CFG))& MSDC_CFG_BV18SDT)==0);
+        {
+            if (status&MSDC_CFG_BV18PSS)
+            {
+                //pass to switch volt to 1.8v
+                return NO_ERROR;
+            }
+            else
+            {
+                //fail to switch volt to 1.8v
+	            MSDC_ERR("[SD][%s %d]1.8v fail ,MSDC_CFG %x\r\n",__FUNCTION__,__LINE__,status);
+                break;
+            }
+        }
+        if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+        {
+            //detect volt change timeout
+	        MSDC_ERR("[SD][%s %d]detect volt change timeout\r\n",__FUNCTION__,__LINE__);
+            break;
+        }
+    }while(1);
+
+    //come to here ,mean timeout or switch 1.8v fail
+    
+    return ERR_STATUS;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_Acmd41_SD
+*
+* DESCRIPTION
+*	asks all cards in idle state to send their OCR in the response on the CMD line
+*	OCR: Operation Condition Register
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	only works for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd41_SD(void)
+{
+	SDC_CMD_STATUS		status;
+    kal_uint32			_ocr = 0, ocr_i = 0,  t2;
+    
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+    if (gSD->mCMD8Resp == SD_CMD8_RESP_NORESP)
+        ocr_i = SDC_OCR_DEFAULT;
+    else if (gSD->mCMD8Resp == SD_CMD8_RESP_VALID) {
+        #if defined(MSDC_CONFIG_SD30_SUPPORT)
+        if (TEMP_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+            ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+        else
+            ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS |SD_ACMD41_S18R | SD_ACMD41_XPC);
+           
+        #else
+        ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+        #endif
+    }
+    else if (gSD->mCMD8Resp == SD_CMD8_RESP_INVALID)
+        return ERR_CMD8_INVALID;
+
+#else
+    ocr_i = SDC_OCR_DEFAULT;
+#endif
+    MSDC_CRIT("[SD][%s %d]Host OCR = %x\r\n",__FUNCTION__,__LINE__,ocr_i);
+ retry:
+    gMSDC_Handle->is_init_timeout = KAL_FALSE;
+    t2 = drv_get_current_time();
+
+    do
+    {
+        /*send ACMD41*/
+        status = SD_Cmd55(SDC_RCA_DEFAULT);
+
+        if (status != NO_ERROR)
+        {
+            return status;
+        }   
+
+        status=SD_SendCmd(SDC_CMD_ACMD41, ocr_i, MSDC_CMD_TIMEOUT);
+        if (status != NO_ERROR)
+        {
+            return status;
+        }
+        
+        /*check response*/
+        _ocr = MSDC_Reg32(SDC_RESP0);
+        MSDC_NOTICE("[SD]ACMD41 resp = %x\r\n", _ocr);
+
+        if ((_ocr & SDC_OCR_DEFAULT) == 0)
+            return ERR_OCR_NOT_SUPPORT;
+
+        if (!gMSDC_Handle->mIsPresent)
+            return ERR_CARD_NOT_PRESENT;
+
+        if (!(_ocr & SDC_OCR_BUSY))
+        {
+            /*if return busy ,we check timeout or not*/
+            if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+            {
+                gMSDC_Handle->is_init_timeout = KAL_TRUE;
+                MSDC_ERR("[SD]ACMD41 Polling BUSY timeout!\r\n");
+                break;
+            }
+
+            msdc_sleep(5);
+        }
+        else
+        {
+            /*not busy */
+            MSDC_CRIT("[SD]OCR = %x\r\n", _ocr);
+            break;
+        }
+    }
+    while (1);
+
+    if (gMSDC_Handle->is_init_timeout)
+        return ERR_R3_OCR_BUSY;
+
+    gSD->mInactive = KAL_FALSE;
+    gSD->mSDC_ocr = _ocr;
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+    gSD->flags |= SD_FLAG_SD_TYPE_CARD;
+
+    if (_ocr & SD_ACMD41_HCS)
+    {
+        #if defined(MSDC_CONFIG_SD30_SUPPORT)
+        if (_ocr & SD_ACMD41_S18R )
+        {
+            status=SD_SwitchVolt18();
+            if (status != NO_ERROR)
+            {
+                return status;  //need delete
+                //fail to switch to 1.8v ,so set signal voltage back to 3.3.v
+                gMSDC_Handle->signal_volt=3300;
+                MSDC_SetSignalPower(1,gMSDC_Handle->signal_volt);
+                power_cycle(1);
+                SD_Reset();
+                SD_Cmd8();
+                ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+                goto retry;
+            }
+
+            gSD->flags|=SD_FLAG_UHS_SUPPORT;
+            gMSDC_Handle->mMSDC_type=SD30_CARD;
+ 	        MSDC_CRIT("[SD][%s %d]SD3.0 UHS Card\r\n",__FUNCTION__,__LINE__);
+        }
+        else
+        #endif
+        {
+            gSD->flags |= SD_FLAG_HCS_SUPPORT;
+            gMSDC_Handle->mMSDC_type = SD20_HCS_CARD;
+ 	        MSDC_CRIT("[SD][%s %d]SD2.0 High Capacity Card\r\n",__FUNCTION__,__LINE__);
+            
+        }
+      
+        
+    }
+    else if (gSD->mCMD8Resp == SD_CMD8_RESP_VALID)
+        gMSDC_Handle->mMSDC_type = SD20_LCS_CARD;
+    else
+#endif
+        gMSDC_Handle->mMSDC_type = SD_CARD;
+
+    gSD->mState = READY_STA;
+
+    return NO_ERROR;
+    
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetCID
+*
+* DESCRIPTION
+*	Read Card Identification.
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_GetCID(kal_uint32 *Cid)
+{
+     int i;
+    SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD2, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+    {
+        	return status;
+    }
+     
+    //read R2
+    for (i = 0; i < 4; i++)
+    {
+        Cid[i]=MSDC_Reg32((SDC_RESP0 + i * sizeof(kal_uint32)));
+    }
+    
+    SD_AnalysisCID(Cid);
+    gSD->mState = IDENT_STA;
+
+    return NO_ERROR;
+    
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_ValidateRCA
+*
+* DESCRIPTION
+*	assing or read RCA
+*
+* PARAMETERS
+*	pRca: used for input or output RCA
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
+*
+*************************************************************************/
+
+// assign or read RCA
+SDC_CMD_STATUS SD_ValidateRCA(kal_uint16* pRca)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 resp;
+    kal_uint8  state;
+    kal_uint32 retry;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+    if (gSD->flags & SD_FLAG_SD_TYPE_CARD )
+#else
+    if (gMSDC_Handle->mMSDC_type == SD_CARD)
+#endif
+    {
+        //read RCA form card
+        retry=10;
+	/*if card return RCA=0  we will retry,*/
+        while(retry--)
+        {
+     		MSDC_DEBUG("[SD][%s %d]send cmd3\r\n",__FUNCTION__,__LINE__);
+	        if ((status = SD_SendCmd(SDC_CMD_CMD3, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+	            return status;
+
+	        //read R6
+	        resp=MSDC_Reg32(SDC_RESP0);
+    		MSDC_DEBUG("[SD][%s %d]cmd3 reps=%x\r\n",__FUNCTION__,__LINE__,resp);	
+#ifdef MSDC_TRACE_LEVEL1
+	        MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+    		if ((resp>>16)!=0)
+    		{
+    	       	 *pRca = resp >>  16;
+    	       	 gSD->mRCA = *pRca;
+    			 break;
+    		}
+    		MSDC_DEBUG("[SD][%s %d]gSD->mRCA=%x\r\n",__FUNCTION__,__LINE__,gSD->mRCA);	
+        }
+	 if (retry==0)
+	 {
+	 	/*always return RCA=0*/
+	 	return ERR_RCA_FAIL;
+	 }
+
+    }
+    else
+    {
+        //assign RCA to card
+        if ((status = SD_SendCmd(SDC_CMD_CMD3_MMC, ((kal_uint32)SDC_RCA_MMC << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+            return status;
+
+        //read R1
+        resp=MSDC_Reg32(SDC_RESP0);
+#ifdef MSDC_TRACE_LEVEL1
+        MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+        SD_GetStatus(SDC_RCA_MMC, &resp);
+        state = 0;
+        GetBitFieldN((kal_uint8*)&state, (kal_uint8*)&resp, 9, 4);
+
+        if (STBY_STA != state)
+            return ERR_RCA_FAIL;
+
+        *pRca = gSD->mRCA = SDC_RCA_MMC;
+    }
+
+    gSD->mState = STBY_STA;
+    return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetDSR
+*
+* DESCRIPTION
+*	set default value to the DSR
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	SDC_DSR_DEFAULT(0x404)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetDSR(void)
+{
+    return SD_SendCmd(SDC_CMD_CMD4, (kal_uint32)SDC_DSR_DEFAULT << 16,MSDC_CMD_TIMEOUT);
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SelectCard
+*
+* DESCRIPTION
+*	select/deselect card
+*
+* PARAMETERS
+*	rca: relative card address
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectCard(kal_uint16 rca)
+{
+    SDC_CMD_STATUS status;
+    MSDC_DEBUG("[SD][%s %d]send cmd7\r\n",__FUNCTION__,__LINE__);
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD7, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+    {
+        return status;
+    }
+	
+    //read R1b
+    if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetCSD
+*
+* DESCRIPTION
+*	Get CSD from addressed card
+*
+* PARAMETERS
+*	rca: relative card address
+*	Csd: used for containing read CSD
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetCSD(kal_uint16 rca, kal_uint32 Csd[4])
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 i;
+    MSDC_DEBUG("[SD][%s %d]send cmd9\r\n",__FUNCTION__,__LINE__);
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD9, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+    {
+        return status;
+    }
+	
+
+    // read R2
+    for (i = 0; i < 4; i++)
+    {
+        Csd[i]=MSDC_Reg32((volatile kal_uint32 *)(SDC_RESP0 + i * 4));
+	    #ifdef MSDC_DEBUG_PRINT
+	    MSDC_DEBUG("%x ",Csd[i]);
+	    #endif
+    }
+	#ifdef MSDC_DEBUG_PRINT
+	MSDC_DEBUG("\r\n ");
+	#endif
+    // analysis CSD...
+    SD_AnalysisCSD(Csd);
+
+    return NO_ERROR;
+}
+
+// addressed send CID
+SDC_CMD_STATUS SD_GetAddressedCID(kal_uint16 rca, kal_uint32 Cid[4])
+{
+     SDC_CMD_STATUS status;
+    kal_uint32 i;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD10, (kal_uint32)rca << 16,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    // read R2
+    for (i = 0; i < 4; i++)
+    {
+#ifndef DRV_LSD
+       Cid[i]=MSDC_Reg32((volatile kal_uint32 *)(SDC_RESP0 + i * 4));
+#else
+       Cid[i]=MSDC_Reg32(SDC_RESP0 + i);
+#endif
+    }
+
+    return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_StopTrans
+*
+* DESCRIPTION
+*	Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	definition of SD_STOP_SLOW is used for some erroneous card
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans(void)
+{
+	SDC_CMD_STATUS status;
+	#define CMD12_TIMEOUT_MS	1000		
+	status = SD_SendCmd(SDC_CMD_CMD12,SDC_NO_ARG,MSDC_CMD_TIMEOUT);
+	MSDC_CLR_FIFO();
+	return status;
+    
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetStatus
+*
+* DESCRIPTION
+*	addressed send status
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetStatus(kal_uint16 rca, kal_uint32* resp)
+{
+    SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD13, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    *resp=MSDC_Reg32(SDC_RESP0);
+    
+    return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetBlength
+*
+* DESCRIPTION
+*	set block length
+*
+* PARAMETERS
+*	BKLength: block length u want to set
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD->mBKLength
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength)
+{
+    SDC_CMD_STATUS status;
+    
+    // maximal value of block length is 2048
+    if (BKLength > SDC_MAX_BKLENGTH)
+        return ERR_INVALID_BKLENGTH;
+
+    if (!gSD->mCSD.r_blk_part && BKLength < gSD->mCSD.max_r_blk_len )
+        return ERR_INVALID_BKLENGTH;
+    if ((status = SD_SendCmd(SDC_CMD_CMD16, BKLength,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    status = SD_CheckStatus();
+    // 2. configure the controller
+    gSD->mBKLength = BKLength;
+   // BitFieldWrite32((kal_uint32*)SDC_CMD, BKLength, SDC_CMD_BLKLEN);
+    return status;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_ReadSingleBlock
+*
+* DESCRIPTION
+*	1. read a single block form data_adrs of card to the rxbuffer
+*	2. the block length is set by set block length
+*
+* PARAMETERS
+*	data_adrs: starting address to read
+*	rxbuffer: as name
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	the size of rxbuffer should be 4*n (n : integer)
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer) // slim
+{
+    return SD_ReadMultiBlock(data_adrs, rxbuffer, 1); // slim
+}
+#else
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+    return SD_ReadMultiBlock(data_adrs, rxbuffer, 1);
+}
+#endif
+/*************************************************************************
+* FUNCTION
+*  SD_ReadMultiBlock
+*
+* DESCRIPTION
+*	read num of blocks into rxbuffer
+*
+* PARAMETERS
+*	data_adrs: starting address to read
+*	rxbuffer: as name
+*	num: number of blocks to read
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+SDC_CMD_STATUS 
+SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num_blk) // slim
+{
+    
+
+}
+#else
+SDC_CMD_STATUS SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num_blk)
+{
+   kal_uint32 status;
+
+   status = SD_ReqHandleData(data_adrs, rxbuffer,num_blk, KAL_FALSE,KAL_FALSE);
+   if (status==ERR_DAT_CRCERR)
+   {
+ 	    status=SD_TuneRead(data_adrs,rxbuffer,num_blk,KAL_FALSE);
+   }
+   return status;
+}
+#endif
+
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_WriteSingleBlock
+*
+* DESCRIPTION
+*	write a single block
+*
+* PARAMETERS
+*	address: starting address to write
+*	txbuffer: as name
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	block length is set by Set_Block_Length
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer) // slim
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+{
+    return SD_WriteMultiBlock(address, txbuffer, 1); // slim
+}
+#else
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+{
+    return SD_WriteMultiBlock(address, txbuffer, 1);
+}
+#endif
+
+void SD_Sleep4Wait(kal_int32 sleep_tick)
+{
+   
+}
+/*************************************************************************
+* FUNCTION
+*	SD_WriteMultiBlock
+*
+* DESCRIPTION
+*	write num blocks starting at address
+*
+* PARAMETERS
+*	address: starting address to write
+*	txbuffer: as name
+*	num: number of blocks to write
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	block length is set by Set_Block_Length
+*
+*************************************************************************/
+//#ifndef DRV_MSDC_SLIM
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num)
+SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num_blk)
+{
+    SDC_CMD_STATUS status;
+    
+    if (gSD->mWPEnabled)
+        return ERR_WRITE_PROTECT;
+    if ((status=SD_ReqHandleData(address, txbuffer, num_blk, KAL_TRUE,KAL_FALSE))!=NO_ERROR)
+    {        
+		if (status ==ERR_DAT_CRCERR)
+		{
+			status=SD_TuneWrite(address,txbuffer,num_blk,KAL_FALSE);
+		}
+		else if (status == ERR_DAT_TIMEOUT)
+		{
+			status=SD_HandleWriteTMO(address,txbuffer,num_blk,KAL_FALSE);
+		}
+    }
+    
+        return status;
+}
+
+SDC_CMD_STATUS SD_GpdWriteMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data)
+{
+    SDC_CMD_STATUS status;
+
+    gMSDC_Handle->f_tuning = 0;
+    
+    if (gSD->mWPEnabled)
+        return ERR_WRITE_PROTECT;
+    if ((status=SD_ReqHandleData(address, gpd_data, num_blk, KAL_TRUE,KAL_TRUE))!=NO_ERROR)
+    {
+        gMSDC_Handle->f_tuning = 1;
+        
+		if (status ==ERR_DAT_CRCERR)
+		{
+			status=SD_TuneWrite(address,gpd_data,num_blk,KAL_TRUE);
+		}
+		else if (status == ERR_DAT_TIMEOUT)
+		{
+			status=SD_HandleWriteTMO(address,gpd_data,num_blk,KAL_TRUE);
+		}
+    }    
+    return status;
+}
+
+SDC_CMD_STATUS SD_GpdReadMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data )
+{
+    kal_uint32 status;
+    
+    gMSDC_Handle->f_tuning = 0;
+    status = SD_ReqHandleData(address, gpd_data,num_blk, KAL_FALSE,KAL_TRUE);
+    
+    if (status==ERR_DAT_CRCERR)
+    {
+        gMSDC_Handle->f_tuning = 1;
+        status=SD_TuneRead(address,gpd_data,num_blk,KAL_TRUE);
+    }
+    return status;
+}
+
+
+//#else
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num) // slim
+//SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num) // slim
+//{
+    
+
+//}
+//#endif
+
+
+/*************************************************************************
+* FUNCTION
+*	SD_SetBusWidth
+*
+* DESCRIPTION
+*	ACMD6: set the data width 00 for 1 bit, 10 for 4 bits
+*
+* PARAMETERS
+*	width: indicate the bus width
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Not every card support 4-bits bus
+*	only for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBusWidth(SD_BITWIDTH width)
+{
+    SDC_CMD_STATUS status;
+    MSDC_DEBUG("[SD][%s %d]send ACMD6 ,change bus width to %d\r\n",__FUNCTION__,__LINE__,width);
+
+    // check if card support 4 bits bus
+    if ((width == BIT_4W) && !(gSD->mSCR.bus_width & 0x04))
+        return ERR_NOT_SUPPORT_4BITS;
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+
+    // send cmd6
+    if ((status = SD_SendCmd(SDC_CMD_ACMD6, width,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+   
+        // set the controler  bus width
+	MSDC_SetBusWidth(width);
+    gSD->bus_width = width;
+    return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_ReadSCR
+*
+* DESCRIPTION
+*	ACMD51: read the SD Configuration Register(8bytes block read)
+*
+* PARAMETERS
+*	scr: used for store SCR
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Make sure the size of SCR is 8 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSCR(kal_uint32* scr)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 blklen;
+
+    ASSERT((kal_uint32)scr % 4  == 0);
+
+    MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+        
+    // set block number 
+    blklen=gSD->mBKLength;
+    gSD->mBKLength = 8;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    MSDC_DEBUG("[SD][%s %d]send acmd51\r\n",__FUNCTION__,__LINE__);
+
+    // set to pio mode and clear fifo
+    BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+    gMSDC_Handle->dma_xfer=0;
+    MSDC_CLR_FIFO();
+    
+    // send command
+    if ((status = SD_SendCmd(SDC_CMD_ACMD51, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    // read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    // read data(8bytes)
+    status=SD_WaitDatRdyOrTo(scr,8,KAL_FALSE);
+    if (status !=NO_ERROR) 
+        return status;
+    MSDC_DEBUG("[SD][%s %d]scr=%x %x\r\n",__FUNCTION__,__LINE__,*scr,*(scr+1));	
+	
+    SD_AnalysisSCR(scr);
+    MSDC_CLR_FIFO();
+    	
+    gSD->mBKLength = blklen;
+
+    return NO_ERROR;
+
+}
+
+static kal_uint32 unstuff_sd_status(kal_uint32 *raw_sd_status, kal_uint32 start, kal_uint32 size)
+{
+    kal_uint32 __mask = (1 << (size)) - 1;
+    int __off = 63 - ((start) / 8);
+    int __shft;
+    kal_uint8 *raw = (kal_uint8 *)raw_sd_status;
+    kal_uint32 __res = 0;
+
+    if ((start & 7) + 1 >= size)
+    {
+        __shft = ((start & 7) + 1) - size;
+        __res = raw[__off] >> __shft;
+    }
+    else if (size <= 32)
+    {
+        size -= ((start & 7) + 1);
+        __shft = size;
+        __res = raw[__off] << __shft;
+        while (size)
+        {
+            __off++;
+            if (size >= 8)
+            {
+                size -= 8;
+                __res |= raw[__off] << size;
+            }
+            else
+            {
+                __mask = (1 << (size)) - 1;
+                __res |= (raw[__off] >> (8 - size)) & __mask;
+                size = 0;
+            }
+        }
+    }
+    return __res & __mask;
+}
+#define UNSTUFF_SD_STATUS(r,s,sz)    unstuff_sd_status(r,s,sz)
+
+/*************************************************************************
+* FUNCTION
+*	SD_ReadSDStatus
+*
+* DESCRIPTION
+*	ACMD13: read the SD Status Register(64bytes block read)
+*
+* PARAMETERS
+*	sd_status: used for store SD Status
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Make sure the size of SD Status is 64 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSDStatus(kal_uint32* sd_status)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 blklen;
+
+    ASSERT((kal_uint32)sd_status % 4  == 0);
+
+    MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+        
+    // set block number 
+    blklen=gSD->mBKLength;
+    gSD->mBKLength = 64;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+
+    // set to pio mode and clear fifo
+    BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+    gMSDC_Handle->dma_xfer=0;
+    
+    // send command
+    if ((status = SD_SendCmd(SDC_CMD_ACMD13, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    // read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    // read data(8bytes)
+    status=SD_WaitDatRdyOrTo(sd_status,64,KAL_FALSE);
+    gSD->mBKLength = blklen;
+
+    if (status !=NO_ERROR) 
+        return status;
+    MSDC_DEBUG("[SD][%s %d]sd_status=%x %x\r\n",__FUNCTION__,__LINE__,*sd_status,*(sd_status+1));	
+	
+    gSD->mSDSts.dat_bus_width = UNSTUFF_SD_STATUS(sd_status, 511, 2);
+    gSD->mSDSts.secured_mode = UNSTUFF_SD_STATUS(sd_status, 509, 1);
+    gSD->mSDSts.sd_card_type = UNSTUFF_SD_STATUS(sd_status, 495, 16);
+    gSD->mSDSts.size_of_prot_area = UNSTUFF_SD_STATUS(sd_status, 479, 32);
+    gSD->mSDSts.speed_class = UNSTUFF_SD_STATUS(sd_status, 447, 8);
+    gSD->mSDSts.perf_move = UNSTUFF_SD_STATUS(sd_status, 439, 8);
+    gSD->mSDSts.au_size = UNSTUFF_SD_STATUS(sd_status, 431, 4);
+    gSD->mSDSts.erase_size = UNSTUFF_SD_STATUS(sd_status, 423, 16);
+    gSD->mSDSts.erase_timeout = UNSTUFF_SD_STATUS(sd_status, 407, 6);
+    gSD->mSDSts.erase_offset = UNSTUFF_SD_STATUS(sd_status, 401, 2);
+    gSD->mSDSts.uhs_speed_grade = UNSTUFF_SD_STATUS(sd_status, 399, 4);
+    gSD->mSDSts.uhs_au_size = UNSTUFF_SD_STATUS(sd_status, 395, 4);
+
+    /* If it is a SD ROM Card, set the WP flag */
+    if (gSD->mSDSts.sd_card_type == 0x0001) {
+        gSD->mWPEnabled = KAL_TRUE;
+        MSDC_CRIT("[SD]It is a ROM Card!\r\n");
+    }
+
+    return NO_ERROR;
+
+}
+
+
+/*************************************************************************
+* FUNCTION
+*	SD_SetPreEraseBlk
+*
+* DESCRIPTION
+*	ACMD23: set the number of write blocksto be pre-erased before writing
+*	used for faster multiple Block Write
+*
+* PARAMETERS
+*	num: used for storing number of blocks during multi-block operation
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetPreEraseBlk(kal_uint32 num)
+{
+    SDC_CMD_STATUS status;
+
+    //[22:0] number of blocks
+    num &= 0x003FFF;
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+
+    // send CMD23
+    if ((status = SD_SendCmd(SDC_CMD_ACMD23, num,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_EraseCmdClass
+*
+* DESCRIPTION
+*	groups of erase commands including CMD32 ~CMD38
+*
+* PARAMETERS
+*	cmd: indicate which command to execute
+*	address: starting address wiht write protection
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	CMD34~CMD37 are only for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_EraseCmdClass(kal_uint32 cmd , kal_uint32 address)
+{
+   SDC_CMD_STATUS status;
+    kal_uint32 sdcard_status;
+    kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+
+    if (cmd != SDC_CMD_CMD38)
+    {
+        if ((status = SD_SendCmd(cmd, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+            return status;
+    }
+    else if ((status = SD_SendCmd(cmd, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+
+    if (cmd == SDC_CMD_CMD38)
+    {
+
+        if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+            return status;
+
+        do
+        {
+            if ((status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&sdcard_status)) != NO_ERROR)
+                return status;
+
+            if (gMSDC_Handle->mIsPresent == KAL_FALSE)
+                return ERR_INVALID_CARD;
+        }
+        while (R1_CURRENT_STATE(sdcard_status) != TRAN_STA);
+    }
+
+    return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_MMC40
+*
+* DESCRIPTION
+*	CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
+*
+* PARAMETERS
+*	access: access mode
+*	index: index to EXT_CSD
+*  value: value to write to EXT_CSD
+*	set:	selected command set
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_MMC40(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
+{
+    SDC_CMD_STATUS status = NO_ERROR;
+    kal_uint32 arg = 0;
+    kal_uint32 resp = 0;
+    kal_bool retry = KAL_FALSE;
+//    kal_uint8 *pData = NULL;
+
+switch_start:
+
+    arg = (access << 24) | (index << 16) | (value << 8) | set;
+
+    // send command
+    if ((status = SD_SendCmd(SDC_CMD_CMD6_MMC, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+    {
+        goto ERR_Exit;
+    }
+
+#ifndef DRV_LSD
+
+    //read R1b
+    if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+        goto ERR_Exit;
+
+#endif
+
+    SD_GetStatus(gSD->mRCA, (kal_uint32*)&status);
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        goto ERR_Exit;
+
+    resp=MSDC_Reg32(SDC_RESP0);
+
+    if ((resp & MMC_SWITCH_ERROR) != 0)
+    {
+        if (retry == KAL_FALSE)
+        {
+#ifdef MSDC_TRACE_LEVEL2
+            MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+            retry = KAL_TRUE;
+            goto switch_start;
+        }
+        else
+            return ERR_MMC_SWITCH_ERROR;
+    }
+
+    return NO_ERROR;
+
+ERR_Exit:
+    return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_SendEXTCSD_MMC40
+*
+* DESCRIPTION
+*	CMD8: read the content of EXT_CSD register
+*
+* PARAMETERS
+*	kal: access mode
+*	index: index to EXT_CSD
+*  value: value to write to EXT_CSD
+*	set:	selected command set
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#ifdef DRV_LSD
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40(kal_uint32* rxbuffer)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 blklen;
+	//    SDC_CMD_STATUS status1;
+	//    kal_bool retry = KAL_FALSE;
+	//kal_uint32 idx = 0;
+
+	//start:
+	blklen=gSD->mBKLength;
+    gSD->mBKLength = 512;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+	 //set to pio mode and clear fifo
+	BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+	gMSDC_Handle->dma_xfer=0;
+	MSDC_CLR_FIFO();
+
+	// read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+	if ((status = SD_SendCmd(SDC_CMD_CMD8_MMC40, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+	    goto ERR_Exit;
+
+	//read R1
+	if ((status = SD_CheckStatus()) != NO_ERROR)
+	    goto ERR_Exit;
+
+	//idx = 0;
+	/*move data from FIFO to buffer*/
+	if ((status = SD_WaitDatRdyOrTo(rxbuffer,512,KAL_FALSE))!=NO_ERROR)
+	{
+		goto ERR_Exit; 
+	}
+
+    kal_mem_cpy(MSDC_eCSD, rxbuffer, 512);
+    gSD->mCSD.ext_csd = (T_EXT_CSD_MMC40 *)MSDC_eCSD;//rxbuffer;
+    gSD->mBKLength=blklen;
+    return NO_ERROR;
+
+ERR_Exit:
+    
+    MSDC_FatalErrorHandle();
+    return status;
+}
+#endif
+/*************************************************************************
+* FUNCTION
+*  SD_CheckTimeoutWithSleep
+*
+* DESCRIPTION
+*	check timeout or not and sleep 1 tick if has been waited more than 10 ms
+*
+* PARAMETERS
+*	start_time: the time start to wait, get with drv_get_current_time
+*     duration_ms: the timeout limitation
+*
+* RETURNS
+*	kal_bool, timeout:KAL_TRUE; not timeout:KAL_FALSE;
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle->is_timeout
+*
+* NOTE:
+*     This function should be called in the wait loop to prevent block other tasks.
+*
+*************************************************************************/
+kal_bool SD_CheckTimeoutWithSleep(kal_int32 start_time,
+                         kal_int32 duration_ms)
+{
+    kal_int32 elapsed_time = drv_get_duration_ms(start_time);    
+    //check timeout or not
+    if(elapsed_time > duration_ms)
+    {
+        gMSDC_Handle->is_timeout = KAL_TRUE;        
+        return KAL_TRUE;
+    }
+    gMSDC_Handle->is_timeout = KAL_FALSE;
+
+    if(elapsed_time < 10)
+    {
+        return KAL_FALSE;
+    }
+    else if ((KAL_FALSE == kal_query_systemInit())
+#ifdef  __TST_WRITE_TO_FILE__/*error recording: considering error recording additionally*/
+                && (KAL_FALSE == INT_QueryExceptionStatus())
+#endif
+                && (KAL_FALSE == kal_if_hisr())
+                && (KAL_FALSE == kal_if_lisr()))
+        {
+            kal_sleep_task(1);
+        }
+    return KAL_FALSE;
+
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_SD11
+*
+* DESCRIPTION
+*	CMD6: switch command to query and select the specific functions. (SD1.1 or later)
+* PARAMETERS
+*	arg: argument
+*	resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_SD11(kal_uint32 arg, T_SWITCH_STATUS* info)
+{
+	SDC_CMD_STATUS status = NO_ERROR;
+	kal_uint32 blklen;
+    gSD->mBKNum=1;
+    blklen=gSD->mBKLength;
+	gSD->mBKLength = SD_CMD6_RESP_LEN;
+	MSDC_WriteReg32(SDC_BLK_NUM,1);
+	//set to pio mode and clear fifo
+	BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+	gMSDC_Handle->dma_xfer=0;
+	MSDC_CLR_FIFO();
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD6_SD11, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+	
+    status=SD_WaitDatRdyOrTo((kal_uint32 *)info,SD_CMD6_RESP_LEN,KAL_FALSE);
+    gSD->mBKLength=blklen;
+    return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_SD11
+*
+* DESCRIPTION
+*	Enable the high speed interface to support up to 50M Hz clock
+*
+* PARAMETERS
+*	arg: argument
+*	resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+
+#ifndef DRV_MSDC_CORRECT_CMD6
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void)
+{
+	SDC_CMD_STATUS status;
+    T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector;
+	MSDC_DEBUG("[SD][%s %d]send cmd6 \r\n",__FUNCTION__,__LINE__);
+
+    if ((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p)) != NO_ERROR)
+        return status;
+
+    if (p->max_current == 0)
+        return ERR_SD_HS_FAIL;
+
+    if ((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) &&
+        (p->group1_result == SD_FUNC_HIGH_SPEED))
+    {
+        if ((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p)) != NO_ERROR)
+            return status;
+
+        if (p->max_current == 0)
+            return ERR_SD_HS_FAIL;
+
+        if (p->group1_result == SD_FUNC_HIGH_SPEED)
+            gSD->flags |= SD_FLAG_HS_SUPPORT;
+    }
+    else
+        return ERR_SD_HS_FAIL;
+
+
+    return NO_ERROR;
+}
+#else
+typedef struct
+{
+    kal_uint16 max_current;
+    kal_uint16 group1_info;
+    kal_uint16 group1_status;
+    kal_uint8  group1_result;
+    kal_uint8  structure_version;
+}T_Group1SwitchStatus;
+/*************************************************************************
+* FUNCTION
+*	SD_ParseGroup1FunctionStatus
+*
+* DESCRIPTION
+*	Parse the Group1 functons' information form the data returned by CMD6
+*
+* PARAMETERS
+*	arg: 
+*		T_Group1SwitchStatus* sf_status :  information of group1 function
+*		kal_uint8* crude_info			: crude data returned by CMD6
+*	resp:
+*
+* RETURNS
+*	void
+*
+* GLOBALS AFFECTED
+*	 None
+* NOTE
+*
+*************************************************************************/
+void SD_ParseGroup1FunctionStatus(T_Group1SwitchStatus* sf_status, kal_uint8* crude_info)
+{
+    sf_status->max_current = (((*(kal_uint8 *)crude_info) << 8)
+        | (*(kal_uint8 *)(crude_info + 1)));
+    sf_status->group1_info = (((*(kal_uint8 *)(crude_info + 12)) << 8)
+        | (*(kal_uint8 *)(crude_info + 13)));
+    sf_status->group1_result = ((*(kal_uint8 *)(crude_info + 16)) & 0xf);
+    sf_status->structure_version = (*(kal_uint8 *)(crude_info + 17));
+    sf_status->group1_status = (((*(kal_uint8 *)(crude_info + 28)) << 8)
+        | (*(kal_uint8 *)(crude_info + 29)));    
+}
+/*************************************************************************
+* FUNCTION
+*	SD_QuerySwithHighSpeed
+*
+* DESCRIPTION
+*	Send CMD6 with query or swith and check the response data.
+*
+* PARAMETERS
+*	arg: kal_uint32 arg
+*	resp:
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	MSDC_Sector
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_QuerySwithHighSpeed(kal_uint32 arg)
+{
+	T_Group1SwitchStatus sf_status;
+	SDC_CMD_STATUS  	 cmd_status;
+	if ((cmd_status = SD_Switch_SD11(arg, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+       return cmd_status;
+    SD_ParseGroup1FunctionStatus(&sf_status,(kal_uint8*)MSDC_Sector);
+	if (0 == sf_status.max_current)
+    	return ERR_HIGH_SPEED_CONSUMPTION;
+	if ((SD_FUNC_HIGH_SPEED == sf_status.group1_result)\
+		&& (0==(sf_status.group1_status & (1 << SD_FUNC_HIGH_SPEED))))
+    	return NO_ERROR;//the high speed function can be switched
+	if ((0xF == sf_status.group1_result) || (!(sf_status.group1_info & (1 << SD_FUNC_HIGH_SPEED))))
+		return ERR_HIGH_SPEED_NOT_SUPPORT;//not support	
+	if (sf_status.group1_status & (1 << SD_FUNC_HIGH_SPEED))//busy      
+        return ERR_HIGH_SPEED_BUSY;
+    return ERR_HIGH_SPEED_COMMON_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*	SD_SelectHighSpeed_SD11
+*
+* DESCRIPTION
+*	Select high speed mode for the SD card that supports CMD6
+*
+* PARAMETERS
+*	arg: void
+*	resp:
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD->flags
+* NOTE
+*
+*************************************************************************/
+
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void)
+{
+    SDC_CMD_STATUS high_speed_status;
+	kal_int32      t1;
+	t1 = drv_get_current_time();
+	do 
+	{
+    	high_speed_status = SD_QuerySwithHighSpeed(SD_CMD6_QUERY_HIGH_SPEED);//query
+    	dbg_print("query high_speed_status: %x\r\n",high_speed_status);
+		if (NO_ERROR == high_speed_status)
+		{
+			high_speed_status = SD_QuerySwithHighSpeed(SD_CMD6_SELECT_HIGH_SPEED);//switch
+			dbg_print("switch high_speed_status: %x\r\n",high_speed_status);
+			if (NO_ERROR == high_speed_status)
+			{
+				gSD->flags |= SD_FLAG_HS_SUPPORT;
+				return NO_ERROR;
+			}
+			if (ERR_HIGH_SPEED_BUSY != high_speed_status)
+				break;			
+		}
+		if (ERR_HIGH_SPEED_BUSY != high_speed_status)
+            break;
+        if (drv_get_duration_ms(t1)>500)
+            return ERR_HIGH_SPEED_TIMEOUT;
+		//if(SD_CheckTimeoutWithSleep(t1,500))
+        //    return ERR_HIGH_SPEED_TIMEOUT;//timeout
+	}while(1);	
+	return high_speed_status;
+}
+
+#endif
+
+void parse_Cmd6FunctionStatus(T_SWITCH_STATUS *new_status,kal_uint8 * cur_Status)
+{
+    new_status->max_current=((*(kal_uint8*)cur_Status)<<8)\
+        | (*(kal_uint8 *)(cur_Status+1));
+    new_status->ver=(*(kal_uint8 *)(cur_Status+17));
+    new_status->group1_info=((*(kal_uint8 *)(cur_Status+12))<<8)\
+        | (*(kal_uint8 *)(cur_Status+13));
+    new_status->group1_result=(*(kal_uint8*)(cur_Status+16))&0xf;
+    new_status->group1_busy=((*(kal_uint8*)(cur_Status+28))<<8)\
+        | (*(kal_uint8 *)(cur_Status+29));
+    
+    new_status->group2_info=((*(kal_uint8 *)(cur_Status+10))<<8)\
+        | (*(kal_uint8 *)(cur_Status+11));
+    new_status->group2_result=((*(kal_uint8*)(cur_Status+16))>>4)&0xf;
+    new_status->group2_busy=((*(kal_uint8*)(cur_Status+26))<<8)\
+        | (*(kal_uint8 *)(cur_Status+27));
+
+    new_status->group3_info=((*(kal_uint8 *)(cur_Status+8))<<8)\
+        | (*(kal_uint8 *)(cur_Status+9));
+    new_status->group3_result=(*(kal_uint8*)(cur_Status+15))&0xf;
+    new_status->group3_busy=((*(kal_uint8*)(cur_Status+24))<<8)\
+        | (*(kal_uint8 *)(cur_Status+25));
+
+    new_status->group4_info=((*(kal_uint8 *)(cur_Status+6))<<8)\
+        | (*(kal_uint8 *)(cur_Status+7));
+    new_status->group4_result=((*(kal_uint8*)(cur_Status+15))>>4)&0xf;
+    new_status->group4_busy=((*(kal_uint8*)(cur_Status+22))<<8)\
+        | (*(kal_uint8 *)(cur_Status+23));
+
+     new_status->group5_info=((*(kal_uint8 *)(cur_Status+4))<<8)\
+        | (*(kal_uint8 *)(cur_Status+5));
+    new_status->group5_result=(*(kal_uint8*)(cur_Status+14))&0xf;
+    new_status->group5_busy=((*(kal_uint8*)(cur_Status+20))<<8)\
+        | (*(kal_uint8 *)(cur_Status+21));
+
+    new_status->group6_info=((*(kal_uint8 *)(cur_Status+2))<<8)\
+        | (*(kal_uint8 *)(cur_Status+3));
+    new_status->group6_result=((*(kal_uint8*)(cur_Status+14))>>4)&0xf;
+    new_status->group6_busy=((*(kal_uint8*)(cur_Status+18))<<8)\
+        | (*(kal_uint8 *)(cur_Status+19));
+    /*
+    dbg_print("new_status->group1_info :%x\r\n",new_status->group1_info);
+    dbg_print("new_status->group1_result:%x\r\n",new_status->group1_result);
+    dbg_print("new_status->group1_busy:%x\r\n",new_status->group1_busy);
+
+    dbg_print("new_status->group2_info :%x\r\n",new_status->group2_info);
+    dbg_print("new_status->group2_result:%x\r\n",new_status->group2_result);
+    dbg_print("new_status->group2_busy:%x\r\n",new_status->group2_busy);
+
+    dbg_print("new_status->group3_info :%x\r\n",new_status->group3_info);
+    dbg_print("new_status->group3_result:%x\r\n",new_status->group3_result);
+    dbg_print("new_status->group3_busy:%x\r\n",new_status->group3_busy);
+
+    dbg_print("new_status->group4_info :%x\r\n",new_status->group4_info);
+    dbg_print("new_status->group4_result:%x\r\n",new_status->group4_result);
+    dbg_print("new_status->group4_busy:%x\r\n",new_status->group4_busy);
+
+    dbg_print("new_status->group5_info :%x\r\n",new_status->group5_info);
+    dbg_print("new_status->group5_result:%x\r\n",new_status->group5_result);
+    dbg_print("new_status->group5_busy:%x\r\n",new_status->group5_busy);
+
+    dbg_print("new_status->group6_info :%x\r\n",new_status->group6_info);
+    dbg_print("new_status->group6_result:%x\r\n",new_status->group6_result);
+    dbg_print("new_status->group6_busy:%x\r\n",new_status->group6_busy);
+    dbg_print("new_status->max_current:%x\r\n",new_status->max_current);
+    dbg_print("new_status->ver:%x\r\n",new_status->ver);
+    */
+    
+}
+
+SDC_CMD_STATUS SD_CheckSwitch(void)
+{
+    //read the function support by current card
+    kal_uint32 status;
+    T_SWITCH_STATUS funcStatus;
+
+    char *uhs_mode[] = {"SDR12", "SDR25", "SDR50", "SDR104", "DDR50"};
+    char *speed_mode[] = {"DS", "HS"};
+    char *drv_strength[] = {"TYPE_A", "TYPE_B", "TYPE_C", "TYPE_D"};
+    char *cur_limit[] = {"200mA", "400mA", "600mA", "800mA"};
+    
+    if ((status = SD_Switch_SD11(SD_CMD6_QUERY_SUPPORT_FUNCTION, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+       return status;
+    parse_Cmd6FunctionStatus(&funcStatus,(kal_uint8*)MSDC_Sector);
+    gSD->card_support.function1=funcStatus.group1_info;
+    gSD->card_support.function2=funcStatus.group2_info;
+    gSD->card_support.function3=funcStatus.group3_info;
+    gSD->card_support.function4=funcStatus.group4_info;
+    #if defined(MSDC_CONFIG_SD30_SUPPORT)
+    if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+    {
+        //for SD3.0
+        /*set bus speed mode*/
+        if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR104)
+            gSD->function_set.function1=FUN1_SET_SDR104;
+        else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_DDR50)
+            gSD->function_set.function1=FUN1_SET_DDR50;
+        else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR50)
+            gSD->function_set.function1=FUN1_SET_SDR50;
+        else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR25_HS)
+            gSD->function_set.function1=FUN1_SET_SDR25_HS;
+        else 
+            gSD->function_set.function1=FUN1_SET_SDR12_DS;
+        /*set command system*/
+        gSD->function_set.function2=FUN2_SET_DEFAULT;
+        /*set driver strength */
+        if (gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_A)
+            gSD->function_set.function3=FUN3_SET_TYPE_A;
+        else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_B)
+            gSD->function_set.function3=FUN3_SET_TYPE_B;
+        else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_C)
+            gSD->function_set.function3=FUN3_SET_TYPE_C;
+        else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_D)
+            gSD->function_set.function3=FUN3_SET_TYPE_D;
+        else
+            gSD->function_set.function3=FUN3_SET_TYPE_A;
+        /*set current limit*/
+        if (gSD->function_set.function1==FUN1_SET_SDR104||gSD->function_set.function1==FUN1_SET_DDR50
+            ||gSD->function_set.function1==FUN1_SET_SDR50)
+        {
+            if(gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_800MA)
+                gSD->function_set.function4=FUN4_SET_800MA;
+            else if (gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_600MA)
+                gSD->function_set.function4=FUN4_SET_600MA;
+            else if (gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_400MA)
+                gSD->function_set.function4=FUN4_SET_400MA;
+            else
+                gSD->function_set.function4=FUN4_SET_200MA;
+        }
+        else
+        {
+            gSD->function_set.function4=FUN4_SET_200MA;
+        }
+
+        MSDC_CRIT("[SD][%s]Switch to %s speed mode! \r\n", __FUNCTION__,
+            uhs_mode[gSD->function_set.function1]);
+        MSDC_CRIT("[SD][%s]Switch to %s drive strength! \r\n", __FUNCTION__,
+            drv_strength[gSD->function_set.function3]);
+        MSDC_CRIT("[SD][%s]Switch to %s current limit! \r\n", __FUNCTION__,
+            cur_limit[gSD->function_set.function4]);
+    }
+    else
+   #endif
+    {
+        //for 2.0 HS DS card
+        if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR25_HS)
+            gSD->function_set.function1=FUN1_SET_SDR25_HS;
+        else 
+            gSD->function_set.function1=FUN1_SET_SDR12_DS;
+
+        MSDC_CRIT("[SD][%s]Switch to %s speed mode! \r\n", __FUNCTION__,
+            speed_mode[gSD->function_set.function1]);
+    }
+    return NO_ERROR;
+    
+}
+
+SDC_CMD_STATUS SD_QuerySwith(kal_uint32 cmd6_arg)
+{
+    
+	SDC_CMD_STATUS  	 cmd_status;
+    T_SWITCH_STATUS  card_support;
+	if ((cmd_status = SD_Switch_SD11(cmd6_arg, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+       return cmd_status;
+    parse_Cmd6FunctionStatus(&card_support,(kal_uint8*)MSDC_Sector);
+    /*
+    dbg_print("card_support.group1_info :%x\r\n",card_support.group1_info);
+    dbg_print("card_support.group1_result:%x\r\n",card_support.group1_result);
+    dbg_print("card_support.group1_busy:%x\r\n",card_support.group1_busy);
+
+    dbg_print("card_support.group2_info :%x\r\n",card_support.group2_info);
+    dbg_print("card_support.group2_result:%x\r\n",card_support.group2_result);
+    dbg_print("card_support.group2_busy:%x\r\n",card_support.group2_busy);
+
+    dbg_print("card_support.group3_info :%x\r\n",card_support.group3_info);
+    dbg_print("card_support.group3_result:%x\r\n",card_support.group3_result);
+    dbg_print("card_support.group3_busy:%x\r\n",card_support.group3_busy);
+
+    dbg_print("card_support.group4_info :%x\r\n",card_support.group4_info);
+    dbg_print("card_support.group4_result:%x\r\n",card_support.group4_result);
+    dbg_print("card_support.group4_busy:%x\r\n",card_support.group4_busy);
+
+    dbg_print("card_support.group5_info :%x\r\n",card_support.group5_info);
+    dbg_print("card_support.group5_result:%x\r\n",card_support.group5_result);
+    dbg_print("card_support.group5_busy:%x\r\n",card_support.group5_busy);
+
+    dbg_print("card_support.group6_info :%x\r\n",card_support.group6_info);
+    dbg_print("card_support.group6_result:%x\r\n",card_support.group6_result);
+    dbg_print("card_support.group6_busy:%x\r\n",card_support.group6_busy);
+    dbg_print("card_support.max_current:%x\r\n",card_support.max_current);
+    dbg_print("card_support.ver:%x\r\n",card_support.ver);
+    */
+    if (0 == card_support.max_current)
+    	return ERR_HIGH_SPEED_CONSUMPTION;
+    #if defined(MSDC_CONFIG_SD30_SUPPORT)
+    if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+    {
+        if ((gSD->function_set.function1==card_support.group1_result)\
+            &&(0==(card_support.group1_busy &(1<<(gSD->function_set.function1)))))
+        {
+
+            if ((gSD->function_set.function3==card_support.group3_result)\
+            &&(0==(card_support.group3_busy &(1<<(gSD->function_set.function3)))))
+            {
+
+                if ((gSD->function_set.function4==card_support.group4_result)\
+                &&(0==(card_support.group4_busy &(1<<(gSD->function_set.function4)))))
+                {
+
+                    return NO_ERROR;
+                }
+            }
+        }
+        dbg_print("gSD->function_set.function1=%x card_support.group1_result=%x\r\n",gSD->function_set.function1,card_support.group1_result);
+        dbg_print("gSD->function_set.function3=%x card_support.group3_result=%x\r\n",gSD->function_set.function3,card_support.group3_result);
+        dbg_print("gSD->function_set.function4=%x card_support.group4_result=%x\r\n",gSD->function_set.function4,card_support.group4_result);
+        dbg_print("busy1 %x busy3 %x busy4 %x\r\n",(card_support.group1_busy &(1<<(gSD->function_set.function1)))\
+            ,(card_support.group3_busy &(1<<(gSD->function_set.function3)))\
+            ,(card_support.group4_busy &(1<<(gSD->function_set.function4))));
+        if ((0xF == card_support.group1_result)\
+            || (!(card_support.group1_info & (1<<(gSD->function_set.function1)))))
+		    return ERR_SPEED_MODE_UNSUPPORT;//not support	
+		if ((0xF == card_support.group3_result)\
+            || (!(card_support.group3_info & (1<<(gSD->function_set.function3)))))
+		    return ERR_DRIVER_TYPE_UNSUPPORT;//not support	
+		if ((0xF == card_support.group4_result)\
+            || (!(card_support.group4_info & (1<<(gSD->function_set.function4)))))
+		    return ERR_CURRENT_LIMIT_UNSUPPORT;//not support	
+
+            
+	    if (card_support.group1_busy & (1 << (gSD->function_set.function1)))//busy      
+            return ERR_SWITCH_BUSY;
+        if (card_support.group3_busy & (1 << (gSD->function_set.function3)))//busy      
+            return ERR_SWITCH_BUSY;
+        if (card_support.group4_busy & (1 << (gSD->function_set.function4)))//busy      
+            return ERR_SWITCH_BUSY;
+    }
+    else
+    #endif
+    {
+        if ((gSD->function_set.function1==card_support.group1_result)\
+            &&(0==(card_support.group1_busy &(1<<(gSD->function_set.function1)))))
+            return NO_ERROR;
+        if ((0xF == card_support.group1_result)\
+            || (!(card_support.group1_info & (1<<(gSD->function_set.function1)))))
+		    return ERR_HIGH_SPEED_NOT_SUPPORT;//not support	
+	    if (card_support.group1_busy & (1 << (gSD->function_set.function1)))//busy      
+            return ERR_HIGH_SPEED_BUSY;
+    }
+    
+    return ERR_HIGH_SPEED_COMMON_ERROR;
+}
+
+SDC_CMD_STATUS SD_SwitchSpeedMode(void)
+{
+    kal_uint32 status,set_function;
+    kal_int32      t1;
+
+    if (gSD->mSCR.spec_ver<SCR_SEC_VER_1)
+    {
+        gSD->function_set.function1=0;
+        return NO_ERROR;
+    }
+    if (!(gSD->mCSD.ccc&CCC_SWITCH))
+    {
+        gSD->function_set.function1=0;
+        return NO_ERROR;
+    }
+        
+	t1 = drv_get_current_time();
+    if ((status =SD_CheckSwitch()) != NO_ERROR)
+        return status;
+    #if defined(MSDC_CONFIG_SD30_SUPPORT)
+    if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+    {
+        set_function=0x00ff0000|gSD->function_set.function1|(gSD->function_set.function3<<8)|(gSD->function_set.function4<<12);
+    }
+    else
+    #endif
+    {
+        set_function=0x00fffff0|gSD->function_set.function1;
+    }
+	do 
+	{   
+    	status = SD_QuerySwith(SD_CMD6_QUERY_SWITCH|set_function);//query
+		if (NO_ERROR == status)
+		{
+			status = SD_QuerySwith(SD_CMD6_SELECT_SWITCH|set_function);//switch
+			if (NO_ERROR == status)
+			{
+			    if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+                {         
+                    gSD->flags |= SD_FLAG_UHS_ENABLED;        
+                }
+                else if (gSD->function_set.function1==1)
+                {
+                    gSD->flags |= SD_FLAG_HS_ENABLED;
+                }
+				
+				return NO_ERROR;
+			}
+			if (ERR_SWITCH_BUSY != status)
+				break;			
+		}
+		if (ERR_SWITCH_BUSY != status)
+            break;
+        if (drv_get_duration_ms(t1)>500)
+            return ERR_SWITCH_TIMEOUT;
+	}while(1);	
+    return status;
+}
+SDC_CMD_STATUS SD_GoInactive(kal_uint16 rca)
+{
+     SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD15, (kal_uint32)rca << 16,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    return NO_ERROR;
+}
+
+SDC_CMD_STATUS SD_ReadStream_MMC(kal_uint32 address, kal_uint32* rxbuffer, kal_uint32 bytes)
+{
+    
+    return 0;	
+} 
+
+
+// write data stream from card only for MMC
+SDC_CMD_STATUS SD_WriteStream_MMC(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 bytes)
+{
+     return 0;
+}
+
+//program CSD, transfer CSD through data line
+SDC_CMD_STATUS SD_ProgramCSD(kal_uint32 Csd[4])
+{
+    SDC_CMD_STATUS status;
+    kal_uint32 blklen;
+    //set block length to 16 , num to 1
+    
+    gSD->mBKNum=1;
+    blklen=gSD->mBKLength;
+	gSD->mBKLength = 16;
+	MSDC_WriteReg32(SDC_BLK_NUM,1);
+	//set to pio mode and clear fifo
+	BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+	gMSDC_Handle->dma_xfer=0;
+	MSDC_CLR_FIFO();
+
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD27, 0,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+    {
+        //SD_WaitDatRdyOrTo();
+        return status;
+    }
+    //send CSD 128 bits
+    status=SD_WaitDatRdyOrTo(Csd,16,KAL_TRUE);
+    //set block length back to 512
+    BitFieldWrite32((kal_uint32*)SDC_CMD, 512, SDC_CMD_BLKLEN);
+    gSD->mBKLength=blklen;
+    return status;
+}
+
+
+//set write protect
+SDC_CMD_STATUS SD_SetWriteProtect(kal_uint32 address)
+{
+    SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD28, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    //wait until data line is ready
+    status =SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+    return status;
+}
+
+//clear write protect
+SDC_CMD_STATUS SD_ClrWriteProtect(kal_uint32 address)
+{
+     SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD29, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    status=SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+    return status;
+}
+
+// send write protect(single block read)
+SDC_CMD_STATUS SD_SendWriteProtect(kal_uint32 address, kal_uint32* WPBits32)
+{
+    SDC_CMD_STATUS status;
+    kal_uint32	tmp,blklen;
+
+    
+    BitFieldWrite32((kal_uint32*)SDC_CMD, 4, SDC_CMD_BLKLEN);
+    blklen=gSD->mBKLength;
+    gSD->mBKLength=4;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    MSDC_CLR_FIFO();
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD30, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    //read 32 write protection bits
+    tmp=MSDC_FIFO_READ32();
+    MSDC_InvertN((kal_uint8*)WPBits32, (kal_uint8*)&tmp, 4);
+    // configure the controller to the original block length
+    BitFieldWrite32((kal_uint32*)SDC_CMD, 512, SDC_CMD_BLKLEN);
+    gSD->mBKLength=blklen;
+
+    return NO_ERROR;
+}
+
+// CMD39: Fast IO-used to write and read 8 bit register
+SDC_CMD_STATUS SD_FastIO_MMC(kal_uint16 rca, kal_bool isWrite, kal_uint8 reg_adrs, kal_uint8 data)
+{
+     SDC_CMD_STATUS status;
+    kal_uint32 arg = 0;
+
+    arg = rca << 16;
+    arg |= isWrite << 15;
+    arg |= reg_adrs << 8;
+    arg |= data;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD39_MMC, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    return NO_ERROR;
+}
+
+
+// Sets the system into interrupt mode (MMC)
+SDC_CMD_STATUS SD_GoIRQ_MMC(void)
+{
+     SDC_CMD_STATUS status;
+
+    if ((status = SD_SendCmd(SDC_CMD_CMD40_MMC, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    status = *(kal_uint32*)SDC_RESP0;
+#ifdef MSDC_TRACE_LEVEL2
+    MD_TRC_MSDC_INFORM_R0(status, __LINE__);
+#endif
+
+    return NO_ERROR;
+}
+
+// Used to set/reset password ,lock/unlock the card and force erase total card.
+// similiar to a signle block write structure.(CMD42)
+// max password length = 16
+SDC_CMD_STATUS SD_LockUnlock(SD_LOCK_OP op, kal_char* Oldpwd, kal_char* Newpwd, kal_uint8 Oldlen, kal_uint8 Newlen)
+{
+     SDC_CMD_STATUS status;
+    kal_uint8 lockbk[SDC_MAX_LOCKBK];
+    kal_uint32 blklen, *ptr = (kal_uint32*)lockbk, count;
+
+    if (Oldlen > 16 || Newlen > 16)
+        return ERR_ERRORS;
+
+    /* save the original block length*/
+    blklen = gSD->mBKLength;
+
+    kal_mem_set(lockbk, 0, SDC_MAX_LOCKBK);
+
+    switch (op)
+    {
+        case SET_PWD:
+            lockbk[0] = 0x01;
+            break;
+
+        case CLR_PWD:
+            lockbk[0] = 0x02;
+            break;
+
+        case LOCK_CARD:
+            lockbk[0] = 0x04;
+            break;
+
+        case UNLOCK_CARD:
+            lockbk[0] = 0x00;
+            break;
+
+        case ERASE:
+            lockbk[0] = 0x08;
+            break;
+    }
+
+    lockbk[1] = Oldlen + Newlen;
+    kal_mem_cpy(&lockbk[2], Oldpwd, Oldlen);
+    kal_mem_cpy(&lockbk[2 + Oldlen], Newpwd, Newlen);
+
+    /* set block length */
+    if (op != ERASE)
+    {
+        SD_SetBlength(2 + lockbk[1]);
+        count = ((lockbk[1] + 2) % sizeof(kal_uint32)) ? ((lockbk[1] + 2) / sizeof(kal_uint32) + 1) :
+                ((lockbk[1] + 2) / sizeof(kal_uint32));
+        gSD->mBKNum=1;
+        blklen=gSD->mBKLength;
+    	gSD->mBKLength = 2 + lockbk[1];
+    	MSDC_WriteReg32(SDC_BLK_NUM,1);
+    	//set to pio mode and clear fifo
+    	BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+    	gMSDC_Handle->dma_xfer=0;
+    	MSDC_CLR_FIFO();
+    }
+    else
+    {
+        SD_SetBlength(1);
+        gSD->mBKNum=1;
+        blklen=gSD->mBKLength;
+	    gSD->mBKLength = 1;
+	    MSDC_WriteReg32(SDC_BLK_NUM,1);
+	    //set to pio mode and clear fifo
+	    BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+	    gMSDC_Handle->dma_xfer=0;
+	    MSDC_CLR_FIFO();
+        count = 1;
+    }
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    /* send command */
+    if ((status = SD_SendCmd(SDC_CMD_CMD42, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    /* read R1b */
+    SD_CheckStatus();
+    /* clear FIFO */
+    MSDC_CLR_FIFO();
+   
+	
+#ifndef DRV_LSD
+	status=SD_WaitDatRdyOrTo(ptr,count,KAL_TRUE);
+    
+#endif
+		
+    /* wait util card has finished programming */
+    SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+    // restore the block length back
+     if (status != NO_ERROR)
+     {
+     	 return gMSDC_Handle->error;
+     }
+	 
+    // restore the block length back
+	 SD_SetBlength(blklen);
+    gSD->mBKLength=blklen;
+    /* check status*/
+    SD_GetStatus(gSD->mRCA, &status);
+	
+    if (status & R1_LOCK_UNLOCK_FAILED_24)
+        return ERR_LOCK_UNLOCK_FAILED;
+
+    if ((op == LOCK_CARD) && !(status & R1_CARD_IS_LOCKED_25))
+        return ERR_LOCK_UNLOCK_FAILED;
+
+    if ((op == UNLOCK_CARD) && (status & R1_CARD_IS_LOCKED_25))
+        return ERR_LOCK_UNLOCK_FAILED;
+
+    return NO_ERROR;
+}
+
+// ACMD13: read SD status(512bits = 64bytes single block read)
+SDC_CMD_STATUS SD_GetSDStatus(kal_uint32* sd_status)
+{
+     SDC_CMD_STATUS status;
+    kal_uint32 blklen;
+
+    
+    //if ((status = SD_SetBlength(64)) != NO_ERROR)
+    //    return status;
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+    // save the orignial block length
+    blklen=gSD->mBKLength;
+    gSD->mBKLength = 64;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+    
+    //set to pio mode and clear fifo
+    BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+    gMSDC_Handle->dma_xfer=0;
+    MSDC_CLR_FIFO();
+    // send ACMD13
+    if ((status = SD_SendCmd(SDC_CMD_ACMD13, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+    
+    // read sd status(64bytes = 4x16)
+    status=SD_WaitDatRdyOrTo(sd_status,64,KAL_FALSE);
+	if (status !=NO_ERROR) 
+	{
+		return status;
+    }
+    gSD->mBKLength=blklen;
+    return NO_ERROR;
+}
+//ACMD22: get the number of written write blocks(4bytes single block read)
+SDC_CMD_STATUS SD_GetNumWrittenBlk(kal_uint32* num)
+{
+     SDC_CMD_STATUS status;
+    kal_uint32 blklen, tmp;
+
+    // send APP_CMD
+    if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+        return status;
+    
+    blklen=gSD->mBKLength;
+    gSD->mBKLength = 4;
+    MSDC_WriteReg32(SDC_BLK_NUM,1);
+    MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+    
+    //set to pio mode and clear fifo
+    BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+    gMSDC_Handle->dma_xfer=0;
+    MSDC_CLR_FIFO();
+    
+    // send CMD22
+    if ((status = SD_SendCmd(SDC_CMD_ACMD22, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+        return status;
+
+    //read R1
+    if ((status = SD_CheckStatus()) != NO_ERROR)
+        return status;
+
+    // read the number of written write blocks(4bytes)
+
+    if ((status=SD_WaitDatRdyOrTo(&tmp,4,KAL_FALSE))!=NO_ERROR)
+		return status;
+   
+    MSDC_InvertN((kal_uint8*)num, (kal_uint8*)&tmp, 4);
+
+    // resotre block length
+    gSD->mBKLength=blklen;
+    return NO_ERROR;
+}
+
+#ifdef DRV_MSDC_HW_CONTENTION
+extern kal_semid dclMsdcArb;
+#endif
+
+void SD_startFastFormat(void)
+{
+	#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+	#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+    kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+    /* RVCT doesn't support inline assemlber; bypass temporarily */
+    retAddr = 0;
+#else   /* __RVCT__ */
+    /* get the return address */
+    __asm
+    {
+        MOV retAddr, lr
+    }
+#endif  /* __RVCT__ */
+
+
+    if (NULL == dclMsdcArb)
+        ASSERT(0);
+
+    if (kal_query_systemInit() == KAL_FALSE)
+    {
+        /*must gain resource here before calling writeSectors*/
+        kal_take_sem(dclMsdcArb, 1);
+        SD_setArbRetAddr(retAddr);
+        SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+    }
+
+#endif
+
+
+#ifdef DRV_LSD
+    LSD_startFastFormat();
+#elif defined(__DRV_MSDC_FAST_FORMAT__)
+    gMSDC_Handle->MSDC_fastFormat = KAL_TRUE;
+#endif
+}
+
+void SD_closeFastFormat(void)
+{
+	#ifdef DRV_LSD
+	LSD_closeFastFormat();
+	#elif defined(__DRV_MSDC_FAST_FORMAT__)
+	gMSDC_Handle->MSDC_fastFormat = KAL_FALSE;
+	#endif
+
+	#ifdef DRV_MSDC_HW_CONTENTION
+
+	if (kal_query_systemInit() == KAL_FALSE)
+	{
+	    /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+	    SD_setArbThdId(NULL);
+	    kal_give_sem(dclMsdcArb);
+	}
+
+	#endif
+
+	#if defined(__AUDIO_DSP_LOWPOWER__)
+	AUDMA_UNLOCK(AUDMA_ID_MSDC);
+	#endif
+
+}
+
+
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE")))SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum)
+SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum)
+{
+     SDC_CMD_STATUS status;
+    kal_uint32 sectorMult,maxBlk;
+
+    if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+        sectorMult = 1;
+    else
+        sectorMult = SECTOR_SIZE;
+    maxBlk=gSD->mCSD.capacity /512;
+    if(0 == sectorNum || sectorNum > maxBlk || startSector > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+
+	/*check that ending block should be smaller than maximum block number*/
+	if((startSector + sectorNum - 1) > maxBlk){
+		//ASSERT(0);
+		status = STATUS_INVALID_CTRL_DATA;
+		return status;
+	}
+    MSDC_PDNControl(KAL_FALSE);
+
+    // there are differences between SD and MMC
+    // tag erase start(CMD32)
+    if ((status = SD_EraseCmdClass(SDC_CMD_CMD32, sectorMult * startSector)) != NO_ERROR)
+    {
+        goto ErrorExit;
+    }
+
+    // tag erase end(CMD33)
+    if ((status = SD_EraseCmdClass(SDC_CMD_CMD33, sectorMult * (startSector + sectorNum - 1))) != NO_ERROR)
+    {
+        goto ErrorExit;
+    }
+
+    // erase...(CMD38)
+    if ((status = SD_EraseCmdClass(SDC_CMD_CMD38, 0)) != NO_ERROR)
+    {
+        goto ErrorExit;
+    }
+
+ErrorExit:
+    MSDC_PDNControl(KAL_TRUE);
+    return status;
+}
+
+#ifdef IC_MODULE_TEST
+
+kal_bool MSDC_ModuleTest_Report(void)
+{
+     
+	 SDC_CMD_STATUS status;
+	 
+	 if (gMSDC_Handle->mIsInitialized == KAL_FALSE)
+		 return KAL_FALSE;
+ 
+	 MSDC_PDNControl(KAL_FALSE);
+ 
+	 gMSDC_Handle->mIsInitialized = KAL_TRUE;
+	 gMSDC_Handle->trySingleLine = KAL_TRUE;
+ 
+	 status = SD_Initialize();
+ 
+	 if (status == NO_ERROR)
+		 return KAL_TRUE;
+	 else
+		 return KAL_FALSE;
+ 
+}
+#endif
+
+#else
+#ifdef DRV_LSD
+T_SDC_HANDLE	gSD_blk[SD_NUM];
+T_SDC_HANDLE	*gSD = gSD_blk;
+#endif
+#endif //  defined(__MSDC_SD_MMC__)
+
+#ifdef MSDC_DEBUG
+
+#define TST_ADRS	512*12
+kal_uint32 SD_MMC_Test(void)
+{
+
+	 return 0;
+
+}
+#endif	// FPGA_DEBUG
+
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_internal_api.h"
+#include "kal_public_defs.h"
+
+//#include "gpt_sw.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "upll_ctrl.h"
+//#include	"Drv_trc.h"
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+void SD_dummyAPI(void) {}
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength) {}
+SDDriver_t sd_driver_MTK1 =
+{
+    (DCL_SINGLE_BLK_RD)SD_dummyAPI,
+    (DCL_MUL_BLK_RD)SD_dummyAPI,
+    (DCL_SINGLE_BLK_WR)SD_dummyAPI,
+    (DCL_MUL_BLK_WR)SD_dummyAPI,
+    (DCL_SD_INITITALIZE)SD_dummyAPI,
+    (DCL_SET_PRE_ERASE_CNT)SD_dummyAPI,
+    (DCL_SD_SET_CALLBACK)SD_dummyAPI,
+    (DCL_SET_READ_TEST_FLAG)SD_dummyAPI,
+    (DCL_SD_READ_TEST)SD_dummyAPI,
+    (DCL_SD_SET_UPLL_CLOCK_TEST)SD_dummyAPI,
+    (DCL_SD_ERASE_BLK)SD_dummyAPI,
+    (DCL_GPD_MUL_BLK_RD)SD_dummyAPI,
+    (DCL_GPD_MUL_BLK_WR)SD_dummyAPI,
+};
+#endif //DCL_MSDC_INTERFACE
+
+void SD_startFastFormat(void) {}
+void SD_closeFastFormat(void) {}
+T_SDC_HANDLE	gSD_blk[SD_NUM];
+T_SDC_HANDLE	*gSD = gSD_blk;
+
+#if defined( __MSDC_BASIC_LOAD__) || defined( __MEUT__)
+kal_uint32 msdc_ReadTestFlag;
+#endif
+
+#endif //DRV_MSDC_OFF
+
+
diff --git a/mcu/driver/storage/mc/src/sd2.c b/mcu/driver/storage/mc/src/sd2.c
new file mode 100644
index 0000000..c1b4dca
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd2.c
@@ -0,0 +1,2414 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sd.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   driver functons for SD/MMC 
+ *   
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR ADD
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+//#include "kal_internal_api.h"
+#include "kal_debug.h"
+#include "kal_public_defs.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "app_buff_alloc.h"
+#include "intrCtrl.h"
+#include "gpio_sw.h"
+#include "init.h"
+*/
+//RHR
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "reg_base.h"
+#include "upll_ctrl.h"
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+T_SDC_HANDLE	*gSD2 = &gSD_blk[SD_MSDC2];
+extern MSDC_HANDLE *msdc2_handle;
+extern kal_uint32 MSDC_Sector2[128];
+
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_bool INT_USBBoot(void);
+extern int MSDC_GetCustom(void);
+
+/*************************************************************************
+* FUNCTION
+*  SD_Acmd42
+*
+* DESCRIPTION
+*	connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd42_2(kal_bool connect)
+{
+	SDC_CMD_STATUS status;
+
+	// send APP_CMD
+	if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+		return status;
+	// send cmd6
+	if((status = SD_Send_Cmd_2(SDC_CMD_ACMD42,connect))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;	
+
+	gSD2->mCD_DAT3 = KAL_FALSE;	// pull-up resistor is disconnected for data trnasfer
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetMMC40_4bit_high_speed
+*
+* DESCRIPTION
+*	Check inserted card is SD or MMC
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*  SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetMMC40_bus_high_speed_2(void)
+{
+		kal_uint32 clock, hs;
+	#ifdef DRV_MSDC_MT6225_SERIES
+		/*use larger driving current. In mt6225 and mt6227D, IOCON is 32 bit register and DLT cannot be 0*/
+		MSDC_LSD_WriteReg(MSDC_IOCON2,0x36);
+		MSDC_SetIOCONRegDLT2();
+	#else
+		MSDC_LSD_WriteReg(MSDC_IOCON2,0x1B);
+	#endif
+
+		if(SD_SetBlength_2(512)!=NO_ERROR)			
+			goto err;
+		
+		// read the EXT_CSD
+		if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+			goto err;;
+
+		// set high speed
+		if(gSD2->mCSD.ext_csd->card_type & HS_52M)
+		{
+			// should be 52000
+			//clock = 52000;
+                        clock = msdc2_handle->msdc_clock / 2;
+			hs = 1;
+			//MSDC_LSD_WriteReg32(MSDC_IOCON,0x010002FF);
+			MSDC_LSD_ClearBits32(MSDC_CFG2,MSDC_CFG_CRED);;
+			
+		}
+		else if(gSD2->mCSD.ext_csd->card_type & HS_26M)
+		{
+			// should be 26000
+			clock = 26000;
+			hs = 1;
+		}
+		else
+		{
+			clock = 13000;
+			hs = 0;
+		}
+		if(hs)
+		{
+			// select proper power class
+			if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
+				(gSD2->mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
+				goto err;
+			
+			// enable high speed (26M or 52M)
+			if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,
+				EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
+				goto err;
+
+			// latch data at falling edge to cover the card driving capability
+			// MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_RED);			
+		}
+		
+		msdc2_handle->msdc_clock = MSDC_CLOCK;
+		MSDC_SetClock2(clock);
+	
+	#ifdef DRV_MSDC_MT6225_SERIES
+		/*change DLT and set cmd latch at rising edge*/
+		MSDC_LSD_WriteReg(MSDC_IOCON2,0x8036);
+		MSDC_SetIOCONRegDLT2();
+	#endif
+
+		#if 0  // MSDC2 only support 1-bit data
+/* under construction !*/
+		#if defined(MMC40_USE_4BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#elif defined(MMC40_USE_8BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#endif
+		#endif
+		
+		if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+			goto err;;
+				
+		return NO_ERROR;
+err:
+		return ERR_MMC_BUS_HS_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_CheckSDorMMC
+*
+* DESCRIPTION
+*	Check inserted card is SD or MMC
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*  SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+*	gMSDC_Handle
+*
+*************************************************************************/
+T_MSDC_CARD SD_CheckSDorMMC_2()
+{
+	SDC_CMD_STATUS status; 
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	SD_Cmd8_2();
+#endif
+	if((status = SD_Acmd41_SD_2())==NO_ERROR)
+		return msdc2_handle->mMSDC_type;	// SD_CARD
+	else if((status = SD_Cmd1_MMC_2())==NO_ERROR)
+		return msdc2_handle->mMSDC_type;	// MMC_CARD
+
+	return UNKNOWN_CARD;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_SetDefault
+*
+* DESCRIPTION
+*	set default values to gSD
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_SetDefault_2(void)
+{
+	kal_mem_set(gSD2,0,sizeof(T_SDC_HANDLE));
+	gSD2->mBKLength = 512;
+	gSD2->mRCA = 0;
+	gSD2->mInactive = KAL_FALSE;
+	gSD2->mState = IDLE_STA;
+	gSD2->bus_width = 1;
+	gSD2->mCD_DAT3 = KAL_TRUE;
+}
+
+void SD_Use24M_Clock_2(void)
+{
+	if(msdc2_handle->mMSDC_type == SD_CARD || msdc2_handle->mMSDC_type == SD20_LCS_CARD
+		|| msdc2_handle->mMSDC_type == SD20_HCS_CARD)
+	{
+		UPLL_Enable(UPLL_OWNER_MSDC2);
+		MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+		msdc2_handle->msdc_clock = MSDC_CLOCK_USB;
+		MSDC_SetClock2(MSDC_SD_OP_CLOCK);
+		gSD2->flags |= SD_FLAG_USE_USB_CLK;	
+	}
+}
+
+void SD_Use13M_Clock_2(void)
+{
+	MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+	msdc2_handle->msdc_clock = MSDC_CLOCK;
+	MSDC_SetClock2(MSDC_OP_CLOCK);
+	gSD2->flags &= ~SD_FLAG_USE_USB_CLK;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_Initialize
+*
+* DESCRIPTION
+*	Initial SD controller and card
+*
+* PARAMETERS
+*	
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Initialize_2(void)
+{
+	kal_uint32 cid[4],csd[4],scr[4];
+	kal_uint16 rca, iocon;
+	SDC_CMD_STATUS status;
+
+	if(msdc2_handle->mIsInitialized == KAL_TRUE)
+	{
+		return NO_ERROR;
+	}
+	// reset the events
+	kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+	// reset msdc
+	if(MSDC_Reg32(MSDC_CFG2) & MSDC_CFG_RST)
+	{
+		MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_RST);
+	}
+	else
+	{
+		RESET_MSDC2();
+	}
+	
+	#if defined(DRV_MSDC_MT6225_SERIES)
+	MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_CRED);
+	#endif
+	
+	// set the output driving capability from customization interface
+	iocon = MSDC_SetData(MSDC_IOCON2, 0xff, MSDC_GetIOCtrlParam2());		
+	// set pull up the data and cmd 
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG0);
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG1);
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG2);	
+	// set read timeout x5ms
+	BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)40,SDC_CFG_DTOC);
+	//set clock of serial clcok for initialization
+	MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+	msdc2_handle->msdc_clock = MSDC_CLOCK;
+	MSDC_SetClock2(MSDC_INI_CLOCK);	
+	MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+	// initial global sturctures
+	SD_SetDefault_2();
+		
+	// send the card to IDLE state
+	if((status = SD_Reset_2())!=NO_ERROR)
+	{
+		goto err;
+	}
+
+	// and validate the OCR  (CMD0,CMD1 or ADMD41)
+	if(SD_CheckSDorMMC_2() == UNKNOWN_CARD)
+	{
+		status = ERR_STATUS;
+		goto err;
+	}
+
+	// get CID(CMD2)
+	if((status = SD_GetCID_2(cid))!=NO_ERROR)
+	{
+		goto err;
+	}
+	// get or set RCA(CMD3)
+	if((status = SD_ValidateRCA_2(&rca))!=NO_ERROR)
+	{
+		goto err;
+	}
+	// get CSD and analysis the CSD(CMD9)
+	if((status = SD_GetCSD_2(gSD2->mRCA,csd))!=NO_ERROR)
+	{
+		goto err;
+	}		
+	// Set driver stage register DSR to default value (0x0404)(CMD4)
+	if(gSD2->mCSD.dsr_imp)
+		if((status = SD_SetDSR_2())!=NO_ERROR)
+		{
+			//dbg_print("6\r\n");
+			goto err;
+		}
+	
+	if(MSDC_GetCustom() & MSDC2_WP)
+	{
+		if((MSDC_Reg(SDC_STA2) & SDC_STA_WP))
+			gSD2->mWPEnabled = KAL_TRUE;
+	}
+	status = SD_SelectCard_2(gSD2->mRCA);
+	if(status == CARD_IS_LOCKED)
+		gSD2->mIsLocked = KAL_TRUE;
+
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(gSD2->flags & SD_FLAG_SD_TYPE_CARD)
+	#else
+	if(msdc2_handle->mMSDC_type == SD_CARD)
+	#endif
+	{		
+		SD_Use24M_Clock_2();
+		MSDC_SetIOCONRegDLT2();
+		if((status = SD_ReadSCR_2(scr))!=NO_ERROR)
+		{
+			goto err;
+		}	
+		#if 0 // MSDC2 only support 1-bit data
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#endif
+		
+		#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+		if((status = SD_Acmd42_2(KAL_FALSE))!=NO_ERROR)
+		{
+			goto err;
+		}
+		#endif
+		
+		if(gSD2->flags & SD_FLAG_CMD6_SUPPORT)
+		{
+			status = SD_SelectHighSpeed_SD11_2();
+			if(status == NO_ERROR)
+			{
+				gSD2->flags |= SD_FLAG_HS_ENABLED;
+				MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+				msdc2_handle->msdc_clock = MSDC_CLOCK;
+				MSDC_SetClock(26000);			
+			}
+		}
+	}
+	else
+	{
+		if(msdc2_handle->mMSDC_type == MMC_CARD && gSD2->mCSD.spec_ver >= 4)
+		{
+			msdc2_handle->mMSDC_type = MMC40_CARD;
+			if((status = SD_SetMMC40_bus_high_speed_2())!= NO_ERROR)
+				goto err;
+		}	
+		else
+		{
+			SD_Use13M_Clock_2();
+		}
+	}
+	status = SD_SetBlength_2(512);
+err:	
+	if(status != NO_ERROR)
+	{
+		tst_sys_trace("SD2 mount fail!");
+		SD_SetDefault();
+		msdc2_handle->mIsInitialized = KAL_FALSE;
+	}
+	else
+	{
+		tst_sys_trace("SD2 mount ok!");
+		msdc2_handle->mIsInitialized = KAL_TRUE;
+	}
+	kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+
+	return status	;
+}
+
+static kal_uint32 power2(kal_uint32 num)
+{
+   return 1 << num;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisCSD
+*
+* DESCRIPTION
+*	Analysis Card Specific Data and store in the member of gSD
+*
+* PARAMETERS
+*	csd: input csd for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_AnalysisCSD_2(kal_uint32* csd)
+{	
+	kal_uint8 *ptr;
+	kal_uint32 c_mult,c_size;
+	
+	ptr = (kal_uint8*)csd;
+	c_mult = c_size = 0;
+	// these offsets refer to the spec. of SD and MMC 
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.csd_ver, ptr, 126,2);	
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.tacc,ptr,112,8);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.nsac,ptr,104,8);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.tran_speed,ptr,96,8);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.ccc,ptr,84,12);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_len,ptr,80,4);
+	gSD2->mCSD.r_blk_len = power2(gSD2->mCSD.r_blk_len);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_part,ptr,79,1);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_misali,ptr,78,1);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_misali,ptr,77,1);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.dsr_imp,ptr,76,1);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_part,ptr,21,1);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_len,ptr,22,4);
+	gSD2->mCSD.w_blk_len = power2(gSD2->mCSD.w_blk_len);
+	GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_enable,ptr,31,1);
+	// there are some difference of CSD between SD and MMC
+	if(msdc2_handle->mMSDC_type == MMC_CARD)
+	{
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.spec_ver, ptr, 122,4);		
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_mmc,ptr,42,5);
+		gSD2->mCSD.erase_sec_size_mmc = (gSD2->mCSD.erase_sec_size_mmc+1)*gSD2->mCSD.w_blk_len; 
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_grp_size_mmc,ptr,37,5);
+		gSD2->mCSD.erase_grp_size_mmc = (gSD2->mCSD.erase_grp_size_mmc+1)*gSD2->mCSD.erase_sec_size_mmc;
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_size_mmc,ptr,32,5);		
+		gSD2->mCSD.wp_grp_size_mmc = (gSD2->mCSD.wp_grp_size_mmc + 1)*gSD2->mCSD.erase_grp_size_mmc;	
+	}
+	else // SD_CARD
+	{
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_sd,ptr,39,7);
+		gSD2->mCSD.erase_sec_size_sd += 1;
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_prg_size_sd,ptr,32,7);
+		gSD2->mCSD.wp_prg_size_sd = (gSD2->mCSD.wp_prg_size_sd+1) * gSD2->mCSD.erase_sec_size_sd;
+		GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_blk_en_sd,ptr,46,1);
+	}
+	
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(msdc2_handle->mMSDC_type == SD20_HCS_CARD && gSD2->mCSD.csd_ver >= SD_CSD_VER_20)
+	{
+		GetBitFieldN((kal_uint8*)&c_size,ptr,48,22);
+		gSD2->mBKNum = (c_size+1);
+		gSD2->mCSD.capacity = (kal_uint64)gSD2->mBKNum*512*1024;
+	}
+	else
+	#endif
+	{
+		GetBitFieldN((kal_uint8*)&c_mult,ptr,47,3);
+		c_mult = power2(c_mult+2);
+		GetBitFieldN((kal_uint8*)&c_size,ptr,62,12);
+		gSD2->mBKNum = (c_size+1)*c_mult;
+		gSD2->mCSD.capacity = (c_size+1)*c_mult*gSD2->mCSD.r_blk_len;
+	}
+	
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisCID
+*
+* DESCRIPTION
+*	Analysis Card Identificaton and store in the member of gSD
+*
+* PARAMETERS
+*	cid: input of card ID for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+void SD_AnalysisCID_2(kal_uint32* cid)
+{
+	kal_uint8	i;
+	kal_uint8* pcid;
+	pcid = (kal_uint8*)cid;
+
+	if(msdc2_handle->mMSDC_type == MMC_CARD)
+	{
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.year,pcid,8,4);
+		gSD2->mCID.year += 1997;
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.month,pcid,12,4);
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.psn,pcid,16,32);
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.prv,pcid,48,8);
+		for(i=0;i<6;i++)
+			gSD2->mCID.pnm[i] = *(pcid+7+i);
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.oid,pcid,104,16);
+		GetBitFieldN((kal_uint8*)&gSD2->mCID.mid,pcid,120,8);
+		
+		// special case handling
+		{
+			kal_uint8 pnm[] = {0xFF,0xFF,0xFF,0xFF,0x36,0x31};
+			if(gSD2->mCID.mid == 6 && gSD2->mCID.oid == 0 &&
+				!kal_mem_cmp(gSD2->mCID.pnm,pnm,6))
+			{
+				gSD2->flags |= SD_FLAG_MMC_MRSW_FAIL;
+			}
+		}
+	}
+	else // SD_CARD
+	{
+		gSD2->mCID.mid = *(pcid+15);
+		gSD2->mCID.oid = *(pcid+13) + 256*(*(pcid+14));
+		for(i=0;i<5;i++)
+			gSD2->mCID.pnm[i] = *(pcid+8+i);
+		gSD2->mCID.prv = *(pcid+7);
+		//gSD2->mCID.psn = *(kal_uint32*)(pcid+3);
+		gSD->mCID.psn = (*(kal_uint32*)(pcid+4)<<8)|*(pcid+3);
+		gSD2->mCID.month = (kal_uint8)GET_BIT(*(pcid+1),0,BIT_MASK_4);
+		gSD2->mCID.year = GET_BIT(*(pcid+1),4,BIT_MASK_4)+16*GET_BIT(*(pcid+2),0,BIT_MASK_4) + 2000;
+	}
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_AnalysisSCR
+*
+* DESCRIPTION
+*	Analysis SD Card Configuration Register and store in the member of gSD
+*
+* PARAMETERS
+*	scr: input of scr for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	Only for SD card.
+*
+*************************************************************************/
+void SD_AnalysisSCR_2(kal_uint32* scr)
+{
+	kal_uint8 *pscr;
+
+	pscr = (kal_uint8*)scr;
+	gSD2->mSCR.spec_ver = (kal_uint8)GET_BIT(*(pscr),0,BIT_MASK_4);
+	if(gSD2->mSCR.spec_ver > SD_SPEC_101)
+		gSD2->flags |= SD_FLAG_CMD6_SUPPORT;
+	gSD2->mSCR.dat_after_erase = (kal_uint8)GET_BIT(*(pscr+1),7,BIT_MASK_1);
+	gSD2->mSCR.security = (kal_uint8)GET_BIT(*(pscr+1),4,BIT_MASK_3);
+	gSD2->mSCR.bus_width = (kal_uint8)GET_BIT(*(pscr+1),0,BIT_MASK_4);
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo
+*
+* DESCRIPTION
+*	Wait until command ready or timeout
+*
+* PARAMETERS
+*	
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_2(void)
+{
+	MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+
+	{
+	volatile kal_uint16 sdc_cmdsta;
+	kal_uint32 t1;
+
+	t1 = drv_get_current_time();
+	while(!(sdc_cmdsta = MSDC_Reg(SDC_CMDSTA2))
+		&& MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+	{
+		if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+			msdc2_handle->is_timeout = KAL_TRUE;
+	}
+	MSDC_STOP_TIMER2();
+	MSDC_CLR_INT2();
+	msdc2_handle->cmd_sta = sdc_cmdsta;
+	if(sdc_cmdsta & SDC_CMDSTA_CMDTO)            
+	{
+		kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd timeout");
+		return ERR_CMD_TIMEOUT;
+	}
+	else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)   
+	{
+		kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd crc");
+		return ERR_CMD_RSPCRCERR;
+	}
+	else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)      
+		return NO_ERROR;                                     	
+	}
+	if(msdc2_handle->is_timeout)
+		return MSDC_GPT_TIMEOUT_ERR;
+	
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WaitDatRdyOrTo_2
+*
+* DESCRIPTION
+*	Wait until data ready or timeout
+*
+* PARAMETERS
+*	
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitDatRdyOrTo_2(void)
+{
+	MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+	
+
+	{
+	volatile kal_uint16 sdc_datsta;	
+	kal_uint32 t1;
+
+	t1 = drv_get_current_time();
+	while(!(sdc_datsta = MSDC_Reg(SDC_DATSTA2))
+		&& MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+	{
+		if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+			msdc2_handle->is_timeout = KAL_TRUE;		
+	};
+	MSDC_STOP_TIMER2();
+	MSDC_CLR_INT2();
+	msdc2_handle->dat_sta = sdc_datsta;
+	if(sdc_datsta & SDC_DATSTA_DATTO)              
+	{
+		kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat timeout");
+		return ERR_DAT_TIMEOUT;                    
+	}
+	else if(sdc_datsta & SDC_DATSTA_DATCRCERR)     
+	{
+		kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat crc");
+		return ERR_DAT_CRCERR;                     
+	}
+	else if(sdc_datsta & SDC_DATSTA_BLKDONE)       
+		return NO_ERROR;                                     
+	}
+	if(msdc2_handle->is_timeout)
+		return MSDC_GPT_TIMEOUT_ERR;
+	
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCardNotBusy_2
+*
+* DESCRIPTION
+*	Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*	
+* RETURNS
+*	void
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+
+SDC_CMD_STATUS SD_WaitCardNotBusy_2(void)
+{
+	kal_uint32 t1;
+
+	t1 = drv_get_current_time();
+	MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+#ifdef MSDC_USE_INT
+	{
+	kal_uint32 	flags = 0;
+	if(!msdc2_handle->mIsPresent)
+		return;
+	kal_retrieve_eg_events(msdc2_handle->MSDC_Events,EVENT_SDR1BIRQ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);				
+	}
+#else	
+	{
+	while(SD_IS_R1B_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+	{
+		if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+			msdc2_handle->is_timeout = KAL_TRUE;
+	};
+	MSDC_CLR_INT2();
+	MSDC_STOP_TIMER2();
+	}
+#endif
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_CheckStatus_2
+*
+* DESCRIPTION
+*	Check command status
+*
+* PARAMETERS
+*	
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_CheckStatus_2()
+{
+	kal_uint32 status;
+
+	MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+	if(status & SDC_CSTA_MASK)
+		ASSERT(0);
+	if((status & SDC_CSTA_MASK)==0 )
+		return NO_ERROR;
+	if(status &SDC_CARD_IS_LOCKED)
+		return CARD_IS_LOCKED;
+
+	return ERR_STATUS;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Send_Cmd_2
+*
+* DESCRIPTION
+*	to launch the command packet to the card
+*
+* PARAMETERS
+*	1. cmd: the content of SDC_CMD register
+*	2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*	1. Check if controller is available  before launch any commands 
+*	2. Maybe add check if card is busy (R1b)
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_2(kal_uint32 cmd, kal_uint32 arg)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 t1;
+
+	t1 = drv_get_current_time();
+	MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+	// check the controller is ready (stop transaction will fail)
+	if(cmd != SDC_CMD_CMD12)		
+	{
+		while(SD_IS_SDC_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+				msdc2_handle->is_timeout = KAL_TRUE;
+		}
+	}
+	else
+	{
+		while(SD_IS_CMD_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+				msdc2_handle->is_timeout = KAL_TRUE;
+		}
+	}
+	MSDC_STOP_TIMER2();
+	if(msdc2_handle->is_timeout)
+		return MSDC_GPT_TIMEOUT_ERR;
+	
+	MSDC_CLR_INT2();
+	// fill out the argument
+	MSDC_LSD_WriteReg32(SDC_ARG2,arg);
+	// launch the command
+	MSDC_LSD_WriteReg32(SDC_CMD2,cmd);
+	if((status = SD_WaitCmdRdyOrTo_2())!=NO_ERROR)
+		return status; 
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Reset
+*
+* DESCRIPTION
+*	reset all cards to idle state
+*
+* PARAMETERS
+*	1. cmd: the content of SDC_CMD register
+*	2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Reset_2(void)
+{
+	SDC_CMD_STATUS status;
+
+	status = SD_Send_Cmd_2(SDC_CMD_CMD0,SDC_NO_ARG);
+	gSD2->mState = IDLE_STA;
+
+	return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd55_2
+*
+* DESCRIPTION
+*	APP_CMD: inidicate to the card that the next command is an application specified command
+*			rather than a standard command
+*
+* PARAMETERS
+*	rca: relative card address
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd55_2(kal_uint16 rca)
+{
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD55,(kal_uint32)rca<<16))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;
+	//check APP_CMD bit in status register
+	MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+	if(status & SDC_CSTA_MASK)
+		ASSERT(0);
+	if(!(status & R1_APP_CMD_5))
+		return ERR_APPCMD_FAILED;
+
+	return NO_ERROR;	
+}
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd8
+*
+* DESCRIPTION
+*	1. Sends SD Memory Card interface conditions for support larger than 2G cards
+*	2. check if the card is compliant to SD2.0 or higher
+*	3. only performed while at IDLE state.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*	gSD2->mIsCMD8
+*
+*************************************************************************/
+void SD_Cmd8_2(void)
+{
+	kal_uint32 resp;
+
+	if(SD_Send_Cmd_2(SDC_CMD_CMD8,SDC_CMD8_ARG)!=NO_ERROR)
+	{
+		SD_Reset_2();
+		gSD2->mCMD8Resp = SD_CMD8_RESP_NORESP;
+		return;
+	}
+	MSDC_LSD_ReadReg32(SDC_RESP02,&resp);
+	if(resp == SDC_CMD8_ARG)
+		gSD2->mCMD8Resp = SD_CMD8_RESP_VALID;
+	else
+		gSD2->mCMD8Resp = SD_CMD8_RESP_INVALID;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Cmd1_MMC
+*
+* DESCRIPTION
+*	 asks all cards in idle state to send their OCR in the response on the CMD line
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	only works for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd1_MMC_2(void)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 _ocr, ocr_i, t1, t2;
+
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+		return ERR_CMD8_INVALID;
+	ocr_i = (SDC_OCR_DEFAULT|MMC_HIGH_DESITY_CHECK_BIT);
+	#else
+	ocr_i = SDC_OCR_DEFAULT;
+	#endif
+
+	if(msdc2_handle->is_init_timeout == KAL_TRUE)
+		return ERR_R3_OCR_BUSY;
+	t2 = drv_get_current_time();
+	do{
+		t1 = drv_get_current_time();
+		MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+		while((MSDC_IS_BUSY2)
+			&& MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+				msdc2_handle->is_timeout = KAL_TRUE;
+		};
+		MSDC_STOP_TIMER2();		
+		if(msdc2_handle->is_timeout)
+			return MSDC_GPT_TIMEOUT_ERR;		
+		MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+		MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD1);
+		if((status = SD_WaitCmdRdyOrTo_2())  != NO_ERROR)
+		{
+			return status;
+		}		
+		MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+		if((_ocr & SDC_OCR_DEFAULT) == 0)
+			return ERR_OCR_NOT_SUPPORT;
+		if(!msdc2_handle->mIsPresent)
+			return MSDC_CARD_NOT_PRESENT;
+		
+		if(!(_ocr&SDC_OCR_BUSY))		
+		{
+			if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+			{
+				msdc2_handle->is_init_timeout = KAL_TRUE;			
+				break;
+			}					
+			if((kal_query_systemInit() == KAL_TRUE) 
+#ifdef  __TST_WRITE_TO_FILE_ONLY__ 			/*error recording: considering error recording additionally*/
+				|| (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+			)
+				MSDC_GPTI_BusyWait(30);
+			else
+				kal_sleep_task(7);
+				
+		}
+		else
+			break;		
+	}while(1);
+
+	if(msdc2_handle->is_init_timeout)
+		return ERR_CMD_TIMEOUT;
+
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
+	{
+		gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+		msdc2_handle->mMSDC_type = MMC42_CARD;
+		tst_sys_trace("MMC4.2 or higher");
+	}
+	else
+	#endif
+	msdc2_handle->mMSDC_type = MMC_CARD;
+	gSD2->mInactive = KAL_FALSE;
+	gSD2->mSDC_ocr = _ocr;
+	gSD2->mState = READY_STA;
+	
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_Acmd41_SD
+*
+* DESCRIPTION
+*	asks all cards in idle state to send their OCR in the response on the CMD line
+*	OCR: Operation Condition Register
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	only works for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd41_SD_2(void)
+{
+
+	SDC_CMD_STATUS		status;
+	kal_uint32			_ocr = 0, ocr_i, t1, t2;
+	
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)	
+	if(gSD2->mCMD8Resp == SD_CMD8_RESP_NORESP)
+		ocr_i = SDC_OCR_DEFAULT;
+	else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+		ocr_i = (SDC_OCR_DEFAULT|SD_ACMD41_HCS);
+	else if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+		return ERR_CMD8_INVALID;	
+#else	
+	ocr_i = SDC_OCR_DEFAULT;
+#endif	
+
+	msdc2_handle->is_init_timeout = KAL_FALSE;
+	t2 = drv_get_current_time();
+	do{
+		t1 = drv_get_current_time();		
+		MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+		while((MSDC_IS_BUSY2)
+			&& MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+				msdc2_handle->is_timeout = KAL_TRUE;			
+		};
+		MSDC_STOP_TIMER2();
+		if(msdc2_handle->is_timeout)
+			return MSDC_GPT_TIMEOUT_ERR;		
+		status=SD_Cmd55_2(SDC_RCA_DEFAULT);
+		if(status != NO_ERROR)
+		{
+			return status;
+		}
+		MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+		t1 = drv_get_current_time();
+		while((MSDC_IS_BUSY2)
+			&& MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+		{
+			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+				msdc2_handle->is_timeout = KAL_TRUE;			
+		};
+		MSDC_STOP_TIMER2();
+		if(msdc2_handle->is_timeout)
+			return MSDC_GPT_TIMEOUT_ERR;		
+		MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+		MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD41_SD);
+		if((status = SD_WaitCmdRdyOrTo_2())  != NO_ERROR)
+		{
+			return status;
+		}		
+		MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+		if((_ocr & SDC_OCR_DEFAULT) == 0)
+			return ERR_OCR_NOT_SUPPORT;
+		if(!msdc2_handle->mIsPresent)
+			return ERR_CARD_NOT_PRESENT;	
+		if(!(_ocr&SDC_OCR_BUSY))		
+		{
+			if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+			{
+				#ifdef DRV_LSD
+				LSD_ASSERT(0, __LINE__);
+				#endif
+				msdc2_handle->is_init_timeout = KAL_TRUE;			
+				break;
+			}					
+			if((kal_query_systemInit() == KAL_TRUE) 
+#ifdef  __TST_WRITE_TO_FILE_ONLY__ 			/*error recording: considering error recording additionally*/
+				|| (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+			)
+				MSDC_GPTI_BusyWait(30);
+			else
+				kal_sleep_task(7);
+		}
+		else
+			break;		
+	}
+	while(1);
+
+	if(msdc2_handle->is_init_timeout)
+		return ERR_R3_OCR_BUSY;
+
+	gSD2->mInactive = KAL_FALSE;
+	gSD2->mSDC_ocr = _ocr;
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	gSD2->flags |= SD_FLAG_SD_TYPE_CARD;	
+	if(_ocr & SD_ACMD41_HCS)
+	{
+		gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+		msdc2_handle->mMSDC_type = SD20_HCS_CARD;
+		tst_sys_trace("SD2.0 or higher");
+	}
+	else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+		msdc2_handle->mMSDC_type = SD20_LCS_CARD;
+	else
+	#endif
+		msdc2_handle->mMSDC_type = SD_CARD;
+	gSD2->mState = READY_STA;
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetCID
+*
+* DESCRIPTION
+*	Read Card Identification.
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_GetCID_2(kal_uint32 Cid[4])
+{
+	int i;
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD2,SDC_NO_ARG))!=NO_ERROR)
+		return status;
+	//read R2
+	for(i=0;i<4;i++)
+		MSDC_LSD_ReadReg32((SDC_RESP02+i*sizeof(kal_uint32)), &Cid[i]);
+	SD_AnalysisCID_2(Cid);
+	gSD2->mState = IDENT_STA;
+	
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_ValidateRCA
+*
+* DESCRIPTION
+*	assing or read RCA
+*
+* PARAMETERS
+*	pRca: used for input or output RCA
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+* NOTE
+*	RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
+*
+*************************************************************************/
+
+// assign or read RCA
+SDC_CMD_STATUS SD_ValidateRCA_2(kal_uint16* pRca)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 resp;
+	kal_uint8  state;
+
+	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	if(gSD2->flags & SD_FLAG_SD_TYPE_CARD )
+	#else
+	if(msdc2_handle->mMSDC_type == SD_CARD)
+	#endif
+	{
+		//read RCA form card
+		if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_SD,SDC_NO_ARG))!=NO_ERROR)
+			return status;
+		//read R6
+		MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+		*pRca = resp >>  16;
+		gSD2->mRCA =*pRca;
+		
+	}
+	else
+	{
+		//assign RCA to card
+		if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_MMC,(kal_uint32)SDC_RCA_MMC<<16))!=NO_ERROR)
+			return status;
+
+		//read R1
+		MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+		SD_GetStatus_2(SDC_RCA_MMC,&resp);
+		state = 0;
+		GetBitFieldN((kal_uint8*)&state,(kal_uint8*)&resp,9,4);
+		if(STBY_STA != state)
+			return ERR_RCA_FAIL;		
+		*pRca = gSD2->mRCA = SDC_RCA_MMC;			
+	}
+
+	gSD2->mState = STBY_STA;
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetDSR
+*
+* DESCRIPTION
+*	set default value to the DSR
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	SDC_DSR_DEFAULT(0x404)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetDSR_2(void)
+{
+	return SD_Send_Cmd_2(SDC_CMD_CMD4,(kal_uint32)SDC_DSR_DEFAULT<<16);
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SelectCard
+*
+* DESCRIPTION
+*	select/deselect card
+*
+* PARAMETERS
+*	rca: relative card address
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectCard_2(kal_uint16 rca)
+{
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD7,(kal_uint32)rca<<16))!=NO_ERROR)
+		return status;
+		
+	//read R1b
+	if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)	
+		return status;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetCSD
+*
+* DESCRIPTION
+*	Get CSD from addressed card
+*
+* PARAMETERS
+*	rca: relative card address
+*	Csd: used for containing read CSD
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetCSD_2(kal_uint16 rca, kal_uint32 Csd[4])
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 i;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD9,(kal_uint32)rca<<16))!=NO_ERROR)
+		return status;
+	for(i=0;i<4;i++)
+	{
+		MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Csd[i]);
+	}
+	SD_AnalysisCSD_2(Csd);
+
+	return NO_ERROR;
+}
+
+// addressed send CID
+SDC_CMD_STATUS SD_GetAddressedCID_2(kal_uint16 rca, kal_uint32 Cid[4])
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 i;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD10,(kal_uint32)rca<<16))!=NO_ERROR)
+		return status;
+	for(i=0;i<4;i++)
+	{
+		MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Cid[i]);
+	}
+	return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_StopTrans_2
+*
+* DESCRIPTION
+*	Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*	definition of SD_STOP_SLOW is used for some erroneous card
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_2(kal_bool isTx)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 retry = 0;
+
+	while(retry < 30)
+	{
+		if((status = SD_Send_Cmd_2(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+		{
+			retry ++;
+		}
+		else
+		{
+			break;
+		}
+	}
+	if(retry >= 30)
+	{
+		return status;
+	}
+	if(isTx)
+		SD_WaitCardNotBusy_2();
+	
+
+#ifdef SD_STOP_SLOW 	
+		while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+		do{	
+		SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+			}while((status & R1_CUR_STATE) >> 9 !=  TRAN_STA);
+#endif
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_GetStatus_2
+*
+* DESCRIPTION
+*	addressed send status
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetStatus_2(kal_uint16 rca, kal_uint32* resp)
+{
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD13,(kal_uint32)rca <<16))!=NO_ERROR)
+		return status;
+
+	MSDC_LSD_ReadReg32(SDC_RESP02,resp);
+	if((*resp) & SDC_CSTA_MASK)
+		ASSERT(0);
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_SetBlength_2
+*
+* DESCRIPTION
+*	set block length
+*
+* PARAMETERS
+*	BKLength: block length u want to set
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD2->mBKLength
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBlength_2(kal_uint32 BKLength)
+{
+	SDC_CMD_STATUS status;
+
+	// maximal value of block length is 2048
+	if(BKLength > SDC_MAX_BKLENGTH)
+		return ERR_INVALID_BKLENGTH;
+	if(!gSD2->mCSD.r_blk_part && BKLength < gSD2->mCSD.max_r_blk_len )
+		return ERR_INVALID_BKLENGTH;		
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD16,BKLength))!=NO_ERROR)
+		return status;
+	//read R1
+	status = SD_CheckStatus_2();		
+	// 2. configure the controller
+	gSD2->mBKLength = BKLength;
+	BitFieldWrite32((kal_uint32*)SDC_CFG2,BKLength,SDC_CFG_BLKLEN);
+
+	return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+*  SD_ReadSingleBlock
+*
+* DESCRIPTION
+*	1. read a single block form data_adrs of card to the rxbuffer
+*	2. the block length is set by set block length
+*
+* PARAMETERS
+*	data_adrs: starting address to read
+*	rxbuffer: as name
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	the size of rxbuffer should be 4*n (n : integer)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSingleBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+	kal_uint32 count;
+	SDC_CMD_STATUS status;
+
+	
+	EnableMSDC_DMA2();
+	count = MSDC_SD_BLOCK_SIZE;
+	MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count,KAL_FALSE);
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD17,data_adrs))!=NO_ERROR)	
+		goto ERR_Exit;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto ERR_Exit;
+	status = MSDC_DMATransferFinal2();
+	if(status != NO_ERROR)
+	{
+		goto ERR_Exit;			
+	}		
+	if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+		goto ERR_Exit;
+	
+	DisableMSDC_DMA2();
+	MSDC_CLR_FIFO2();
+	
+	return NO_ERROR;
+ERR_Exit:
+	{
+		kal_uint32 tmp;
+		
+		#ifdef MSDC_USE_INT
+		kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+		#endif
+		DisableMSDC_DMA2();
+		RESET_MSDC2();
+
+		// SD_StopTrans_2(KAL_FALSE);		
+		SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+		MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+		MSDC_CLR_FIFO2();		
+		return status;
+	}
+	
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_ReadMultiBlock
+*
+* DESCRIPTION
+*	read num of blocks into rxbuffer
+*
+* PARAMETERS
+*	data_adrs: starting address to read
+*	rxbuffer: as name
+*	num: number of blocks to read
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadMultiBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 j, count;
+	#ifndef MSDC_DMA
+	kal_uint32 i;	
+	#endif
+
+	EnableMSDC_DMA2();
+	count = MSDC_SD_BLOCK_SIZE;	
+	MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count*num,KAL_FALSE);	
+	#ifndef DRV_LSD
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD18,data_adrs))!=NO_ERROR)
+	#else
+	LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD18|(num<<20) ,data_adrs))!=NO_ERROR)
+	#endif
+		goto ERR_Exit;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto ERR_Exit;	
+	count = MSDC_SD_BLOCK_SIZE;	
+	status = MSDC_DMATransferFinal2();
+	if(status != NO_ERROR)
+			goto ERR_Exit;	
+
+	if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+		goto ERR_Exit;
+	
+	
+	MSDC_CLR_INT2();
+	DisableMSDC_DMA2();
+
+	if(gSD2->flags & SD_FLAG_MMC_MRSW_FAIL)
+	{
+		kal_uint32 delay = 200;
+		while(delay--);		
+	}
+	if((status = SD_StopTrans_2(KAL_FALSE))!=NO_ERROR)
+	{
+		//if((data_adrs/gSD2->mBKLength + j) < gSD2->mBKNum)			
+			goto ERR_Exit;		
+	}
+	MSDC_CLR_FIFO2();			
+	return NO_ERROR;
+	
+ERR_Exit:
+
+	#ifdef MSDC_USE_INT	
+	kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+	#endif
+	DisableMSDC_DMA2();
+	RESET_MSDC2();		
+	SD_StopTrans_2(KAL_FALSE);		
+	SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&j);
+	MSDC_LSD_ReadReg32(SDC_DATSTA2,&j);
+	MSDC_CLR_FIFO2();
+	return status;
+	
+}
+
+/*************************************************************************
+* FUNCTION
+*  SD_WriteSingleBlock
+*
+* DESCRIPTION
+*	write a single block
+*
+* PARAMETERS
+*	address: starting address to write
+*	txbuffer: as name
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteSingleBlock_2(kal_uint32 address, kal_uint32* txbuffer)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 count;
+	kal_uint32 *ptr;	
+#if defined(MT6225)
+	kal_bool is_aligned;
+	ECO_VERSION eco;
+	eco = INT_ecoVersion();	
+#endif
+
+	if(gSD2->mWPEnabled)
+		return ERR_WRITE_PROTECT;
+	EnableMSDC_DMA2();
+	count = MSDC_SD_BLOCK_SIZE;
+	
+	#if defined(MT6225)
+	if(eco <= ECO_E3)
+	{
+		is_aligned = ((kal_uint32)txbuffer%4 == 0); 
+		if(is_aligned)
+		{
+			ptr = txbuffer;
+		}
+		else
+		{
+			kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+			ptr = MSDC_Sector2;
+		}
+	}
+	else
+	{
+		ptr = txbuffer;
+	}
+	#else
+	ptr = txbuffer;
+	#endif
+	
+	EnableMSDC_DMA2();
+	count = MSDC_SD_BLOCK_SIZE;	
+	MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);	
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD24,address))!=NO_ERROR)
+		goto ERR_Exit;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto ERR_Exit;
+	status = MSDC_DMATransferFinal2();
+	if(status != NO_ERROR)
+		goto ERR_Exit;	
+	if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)	
+		 goto ERR_Exit;	
+	DisableMSDC_DMA2();
+	if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+		goto ERR_Exit;
+	
+
+	return NO_ERROR;
+ERR_Exit:
+	{
+		kal_uint32 tmp;
+		
+		#ifdef MSDC_USE_INT	
+		kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+		#endif
+		DisableMSDC_DMA2();
+		RESET_MSDC2();
+		SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+		MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+		return status;
+	}
+	
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_WriteMultiBlock
+*
+* DESCRIPTION
+*	write num blocks starting at address
+*
+* PARAMETERS
+*	address: starting address to write
+*	txbuffer: as name
+*	num: number of blocks to write
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteMultiBlock_2(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 count;
+	kal_uint32 *ptr;
+	#if defined(MT6225)
+	kal_bool is_aligned, dma_issue;
+	ECO_VERSION eco;
+	eco = INT_ecoVersion();	
+	if(eco <= ECO_E3) 
+		dma_issue = KAL_TRUE;
+	#endif
+		
+	if(gSD2->mWPEnabled)
+		return ERR_WRITE_PROTECT;
+	EnableMSDC_DMA2();	
+	count = MSDC_SD_BLOCK_SIZE;	
+	#if defined(MT6225)
+	if(dma_issue)
+	{
+		is_aligned = ((kal_uint32)txbuffer%4 == 0); 
+		if(is_aligned)
+		{
+			MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);	
+		}
+		else
+		{
+			kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+			ptr = txbuffer;
+			MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+		}
+	}
+	else
+	{
+		MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);	
+	}
+	#elif defined(MSDC_MULTI_BLOCK_WRITE)
+	MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+	#else
+	ptr = txbuffer;
+	MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+	#endif
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD25,address))!=NO_ERROR)
+		goto ERR_Exit;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto ERR_Exit;
+	   
+	#if defined(MT6225)
+	if(dma_issue)
+	{
+		if(is_aligned)
+		{
+			status = MSDC_DMATransferFinal2();
+			if(status != NO_ERROR)
+				goto ERR_Exit;
+			if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+				goto ERR_Exit;		
+		}
+		else
+		{
+			kal_uint32 j;
+			
+			for(j=0;j<num;j++)
+			{
+				if(msdc2_handle->mIsPresent  == KAL_FALSE)
+				{
+					status = ERR_CARD_NOT_PRESENT;
+					goto ERR_Exit;		
+				}
+				if(j!=0)
+				{
+					kal_mem_cpy(MSDC_Sector2, ptr, 512);
+					MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+				}
+				status = MSDC_DMATransferFinal2();
+				ptr += MSDC_SD_BLOCK_SIZE; 
+				if(status != NO_ERROR)
+					goto ERR_Exit;		
+				if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)	
+					goto ERR_Exit;
+			}	
+		}	
+	}
+	else
+	{
+		status = MSDC_DMATransferFinal2();
+		if(status != NO_ERROR)
+			goto ERR_Exit;
+		if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+			goto ERR_Exit;		
+	}
+	#elif defined(MSDC_MULTI_BLOCK_WRITE)
+		status = MSDC_DMATransferFinal2();
+		if(status != NO_ERROR)
+			goto ERR_Exit;
+		if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+			goto ERR_Exit;			
+	#else // not MT6225
+	{
+		kal_uint32 j;
+		
+		for(j=0;j<num;j++)
+		{
+			if(msdc2_handle->mIsPresent  == KAL_FALSE)
+			{
+				status = ERR_CARD_NOT_PRESENT;
+				goto ERR_Exit;		
+			}
+			if(j!=0)
+			{
+				MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+			}
+			status = MSDC_DMATransferFinal2();
+			ptr += MSDC_SD_BLOCK_SIZE; 
+			if(status != NO_ERROR)
+				goto ERR_Exit;		
+			if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)	
+				goto ERR_Exit;
+		}
+	
+	}	
+	#endif // MT6225
+
+	DisableMSDC_DMA2();
+	if((status = SD_StopTrans_2(KAL_TRUE))!=NO_ERROR)
+		goto ERR_Exit;
+	
+	MSDC_CLR_INT2();
+	
+	return NO_ERROR;
+ERR_Exit:
+	{
+		kal_uint32 tmp;
+		
+		DisableMSDC_DMA2();
+		RESET_MSDC2();
+		SD_StopTrans_2(KAL_TRUE);		
+		SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+		MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+		return status;
+	}
+	
+}
+/*************************************************************************
+* FUNCTION
+*	SD_SetBusWidth
+*
+* DESCRIPTION
+*	ACMD6: set the data width 00 for 1 bit, 10 for 4 bits
+*
+* PARAMETERS
+*	width: indicate the bus width
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Not every card support 4-bits bus
+*	only for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBusWidth_2(SD_BITWIDTH width)
+{
+	SDC_CMD_STATUS status;
+
+	// check if card support 4 bits bus
+	if((width == BIT_4W) && !(gSD2->mSCR.bus_width&0x04))
+		return ERR_NOT_SUPPORT_4BITS;
+	// send APP_CMD
+	if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+		return status;
+	// send cmd6
+	if((status = SD_Send_Cmd_2(SDC_CMD_ACMD6,width))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;	
+	// set the controler MDLEN to enalbe 4bits bus width
+	MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+	gSD2->bus_width = 4;
+	
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_ReadSCR
+*
+* DESCRIPTION
+*	ACMD51: read the SD Configuration Register(8bytes block read)
+*
+* PARAMETERS
+*	scr: used for store SCR
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Make sure the size of SCR is 8 bytes 
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSCR_2(kal_uint32* scr)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 blklen,i, t1;
+
+	ASSERT((kal_uint32)scr % 4  == 0);
+	// save the original block length 
+	blklen = gSD2->mBKLength;
+	// set block length(MSDC_CFG2)
+	if((status = SD_SetBlength_2(8))!=NO_ERROR)
+		return status;
+	// send APP_CMD
+	if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+		return status;
+	// send command
+	if((status = SD_Send_Cmd_2(SDC_CMD_ACMD51,SDC_NO_ARG))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;	
+	// read data(8bytes)	
+#ifndef DRV_LSD
+	// failed to use DMA with burst mode
+	t1 = drv_get_current_time();
+	MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+	for(i=0;i<2;)
+	{	
+		if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+			msdc2_handle->is_timeout = KAL_TRUE;		
+		if(!msdc2_handle->mIsPresent)
+			return ERR_CARD_NOT_PRESENT;
+		if(msdc2_handle->is_timeout)
+			return MSDC_GPT_TIMEOUT_ERR;
+		if(!MSDC_IS_FIFO_EMPTY2)
+		{
+			*(kal_uint32*)(scr+i) = MSDC_Reg32(MSDC_DAT2);
+			i++;
+		}
+	}
+#else
+	LSD_readFIFO(scr ,2);
+	
+#endif
+	MSDC_STOP_TIMER2();
+	// analysis scr
+	SD_AnalysisSCR(scr);
+	// clean EVENT_SDDATIRQ
+	#ifdef MSDC_USE_INT	
+	kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+	#endif
+	MSDC_CLR_FIFO2();
+	return NO_ERROR;
+	
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_SetPreEraseBlk
+*
+* DESCRIPTION
+*	ACMD23: set the number of write blocksto be pre-erased before writing
+*	used for faster multiple Block Write
+*
+* PARAMETERS
+*	num: used for storing number of blocks during multi-block operation
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetPreEraseBlk_2(kal_uint32 num)
+{
+	SDC_CMD_STATUS status;
+
+	//[22:0] number of blocks 
+	num &= 0x003FFF;
+	// send APP_CMD
+	if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+		return status;
+	// send CMD23
+	if((status = SD_Send_Cmd_2(SDC_CMD_ACMD23,num))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;	
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_EraseCmdClass
+*
+* DESCRIPTION
+*	groups of erase commands including CMD32 ~CMD38
+*
+* PARAMETERS
+*	cmd: indicate which command to execute
+*	address: starting address wiht write protection
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	CMD34~CMD37 are only for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_EraseCmdClass_2(kal_uint32 cmd ,kal_uint32 address)
+{
+	SDC_CMD_STATUS status;
+
+	if(cmd != SDC_CMD_CMD38)
+	{
+		if((status = SD_Send_Cmd_2(cmd,address))!=NO_ERROR)
+			return status;
+	}
+	else if((status = SD_Send_Cmd_2(cmd,SDC_NO_ARG))!=NO_ERROR)
+			return status;
+
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;
+
+	if(cmd == SDC_CMD_CMD38)
+	{
+		SD_WaitCardNotBusy_2();
+		do{	
+		SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+		if(msdc2_handle->mIsPresent == KAL_FALSE)
+			break;
+			}while(CurState(status)!=  TRAN_STA);
+	}
+	
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_MMC40
+*
+* DESCRIPTION
+*	CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
+*
+* PARAMETERS
+*	access: access mode
+*	index: index to EXT_CSD
+*  value: value to write to EXT_CSD
+*	set:	selected command set 
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_MMC40_2(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg = 0;
+	
+	arg = (access<<24)|(index<<16)|(value<<8)|set;
+	// send command
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_MMC40,arg))!=NO_ERROR)
+		return status;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		return status;
+
+	return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_SendEXTCSD_MMC40
+*
+* DESCRIPTION
+*	CMD8: read the content of EXT_CSD register
+*
+* PARAMETERS
+*	kal: access mode
+*	index: index to EXT_CSD
+*  value: value to write to EXT_CSD
+*	set:	selected command set 
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40_2(kal_uint32* rxbuffer)
+{
+	SDC_CMD_STATUS status;
+	kal_bool retry_4bit = KAL_FALSE;
+
+start:
+	// read the block	of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+	EnableMSDC_DMA2();
+	MSDC_DMATransferFirst2((kal_uint32)rxbuffer,128,KAL_FALSE);		
+#ifdef DRV_LSD
+	LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD8_MMC40,SDC_NO_ARG))!=NO_ERROR)
+		goto ERR_Exit;
+	//read R1
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto ERR_Exit;		
+	// read the block	of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+	status = MSDC_DMATransferFinal2();	
+	if(status != NO_ERROR)
+		goto ERR_Exit;			
+	if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+		goto ERR_Exit;
+	
+	DisableMSDC_DMA2();
+	MSDC_CLR_FIFO2();	
+	gSD2->mCSD.ext_csd = (T_EXT_CSD_MMC40 *)rxbuffer;
+	return NO_ERROR;	
+	
+ERR_Exit:
+
+	if(retry_4bit == KAL_FALSE)
+	{
+		retry_4bit = KAL_TRUE;
+		MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+		gSD2->bus_width = 4;
+		goto start;
+	}
+	MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+	gSD2->bus_width = 1;
+	DisableMSDC_DMA2();
+	MSDC_CLR_FIFO2();	
+	RESET_MSDC2();
+
+	return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_SD11
+*
+* DESCRIPTION
+*	CMD6: switch command to query and select the specific functions. (SD1.1 or later)
+* PARAMETERS
+*	arg: argument
+*	resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_SD11_2(kal_uint32 arg, T_SWITCH_STATUS* info)
+{
+	SDC_CMD_STATUS status = NO_ERROR;
+	
+	BitFieldWrite32((kal_uint32*)SDC_CFG2,SD_CMD6_RESP_LEN,SDC_CFG_BLKLEN);	
+	EnableMSDC_DMA2();
+	MSDC_DMATransferFirst2((kal_uint32)info,(SD_CMD6_RESP_LEN>>2),KAL_FALSE);	
+	if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_SD11,arg))!=NO_ERROR)
+		goto exit;
+	if((status = SD_CheckStatus_2())!=NO_ERROR)
+		goto exit;
+	status = MSDC_DMATransferFinal2();	
+	
+exit:	
+	DisableMSDC_DMA2();	
+	return status;
+}
+
+/*************************************************************************
+* FUNCTION
+*	SD_Switch_SD11
+*
+* DESCRIPTION
+*	Enable the high speed interface to support up to 50M Hz clock 
+*
+* PARAMETERS
+*	arg: argument
+*	resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11_2(void)
+{
+	SDC_CMD_STATUS status;
+	T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector2;
+	
+	if((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p))!=NO_ERROR)
+		return status;
+	if(p->max_current == 0)
+		return ERR_SD_HS_FAIL;
+	if((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) && 
+		(p->group1_result == SD_FUNC_HIGH_SPEED))
+	{
+		if((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p))!=NO_ERROR)
+				return status;
+		if(p->max_current == 0)
+			return ERR_SD_HS_FAIL;
+		if(p->group1_result == SD_FUNC_HIGH_SPEED)
+			gSD2->flags |= SD_FLAG_HS_SUPPORT;
+	}	
+	else
+		return ERR_SD_HS_FAIL;
+
+
+	return NO_ERROR;
+}
+
+kal_bool MSDC_ModuleTest_Report_2(void)
+{
+    return msdc2_handle->mIsInitialized;
+}
+
+#endif // defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sd_adap.c b/mcu/driver/storage/mc/src/sd_adap.c
new file mode 100644
index 0000000..2fc5fd6
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_adap.c
@@ -0,0 +1,343 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2007
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sd_adap.c
+ *
+ * Project:
+ * --------
+ *   Maui
+ *
+ * Description:
+ * ------------
+ *   MSDC/SD driver adaption layer
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifdef __EMMC_BOOTING__
+
+#include "sd_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "dcl.h"
+
+#if defined(__UBL__) || defined(__FUE__)
+#include <bl_MTK_BB_REG.H>
+#else
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#endif
+
+
+/*** external data & function ***/
+
+
+/*** internal data & function ***/
+
+static SDC_CMD_STATUS DRV_SD_AddrLookupTbl(unsigned int sector, emmc_addr *addr);
+
+/*** external function body ***/
+
+DRV_STATUS_CODE DRV_SD_Init(void)
+{
+#if (defined(__UBL__) || defined(__FUE__)) && defined(MT6256_S00)
+    // enable GPIO for MSDC
+    //DRV_WriteReg16(0x701D0610, 0x1110);
+    //DRV_WriteReg16(0x701D0620, 0x0111);
+    DRV_WriteReg16(GPIO_base+0x0610, 0x1110);
+    DRV_WriteReg16(GPIO_base+0x0620, 0x0111);
+    // enable GPT3
+    //DRV_WriteReg32(0x7007001C, 1);
+    DRV_WriteReg32(GPT_base+0x001C, 1);
+    
+#endif
+
+#if !defined(DCL_MSDC_INTERFACE)
+	MSDC_Initialize();
+#else
+	DclSD_Initialize();
+#endif//!defined(DCL_MSDC_INTERFACE)
+
+    return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_DeInit(void)
+{
+    MSDC_DeInit();
+
+    // reset GPIO to disable MSDC
+
+    return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_MountDevice(
+	mcdev_enum id,
+	unsigned int flags
+	)
+{
+	SDC_CMD_STATUS status = NO_ERROR;
+	status = MountDevice(GetMsdcHandle(id), 0, 0, flags);
+	if (512 != status)
+		return DRV_MOUNT_DEV_FAILURE;
+
+	return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_ReadSectors(
+	mcdev_enum id,
+	unsigned int sector,
+	unsigned int sectors,
+	void * buffer,
+	unsigned int flags
+	)
+{
+	SDC_CMD_STATUS status = NO_ERROR;
+	emmc_addr addr;
+
+	get_MSDC_lock(&gSD->mSDdrv_lock);
+
+	status = DRV_SD_AddrLookupTbl(sector, &addr);
+	if (NO_ERROR != status)
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_READ_FAILURE;
+	}
+
+	if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(addr.partition))
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_READ_FAILURE;
+	}
+
+#if defined(DRV_MSDC_BLOCKING_TRANSFER_SUPPORT)
+	status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer, SD_FLAG_BLOCKING_TRANSFER);
+#else
+	status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer);
+#endif
+	if (NO_ERROR != status)
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_READ_FAILURE;
+	}
+
+	if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(eMMC_user_Area))
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_READ_FAILURE;
+	}
+
+	free_MSDC_lock(&gSD->mSDdrv_lock);
+	return DRV_SUCCESS;
+}
+
+//! under construction [Samuel, 2010/10/01]
+DRV_STATUS_CODE DRV_SD_WriteSectors(
+	mcdev_enum id,
+	unsigned int sector,
+	unsigned int sectors,
+	void * buffer,
+	unsigned int flags
+	)
+{
+	SDC_CMD_STATUS status = NO_ERROR;
+	emmc_addr addr;
+
+//#if !defined(__UBL__) && !defined(__FUE__)
+//	ASSERT(0); // so far this function can only be used in bootloader
+//#endif
+
+	get_MSDC_lock(&gSD->mSDdrv_lock);
+
+	status = DRV_SD_AddrLookupTbl(sector, &addr);
+	if (NO_ERROR != status)
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_WRITE_FAILURE;
+	}
+
+	if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(addr.partition))
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_WRITE_FAILURE;
+	}
+
+	status = WriteSectors(GetMsdcHandle(id), addr.offset, sectors, buffer);
+	if (NO_ERROR != status)
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_WRITE_FAILURE;
+	}
+
+	//! TODO: check why it fails
+	if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(eMMC_user_Area))
+	{
+		free_MSDC_lock(&gSD->mSDdrv_lock);
+		return DRV_WRITE_FAILURE;
+	}
+
+	free_MSDC_lock(&gSD->mSDdrv_lock);
+	return DRV_SUCCESS;
+}
+
+/*** internal function body ***/
+
+//! 1st designed for eMMC
+static SDC_CMD_STATUS DRV_SD_AddrLookupTbl(unsigned int sector, emmc_addr *addr)
+{
+	if (gSD->emmc_info.isEmmcV44 == KAL_FALSE)
+		return ERR_INVALID_CARD;
+
+	if (sector >= (gSD->emmc_info.bootPartitionSize + gSD->emmc_info.gp1PartitionSize))
+		return ERR_INVALID_BLOCK; // out-of-range
+
+	if (sector < gSD->emmc_info.bootPartitionSize)
+	{
+		addr->partition = eMMC_boot_partition1;
+		addr->offset = sector;
+	}
+	else
+	{
+		addr->partition = eMMC_GP_partition1;
+		addr->offset = sector - gSD->emmc_info.bootPartitionSize;
+	}
+
+	return DRV_SUCCESS;
+}
+
+#endif//__EMMC_BOOTING__
+
+
+
+#ifdef __CARD_DOWNLOAD__
+
+#include "msdc_adap_bl.h"
+#include "drv_comm.h"
+#include "msdc_def.h"
+
+/*** external data & function ***/
+
+extern FS_Driver FS_SdDrv;
+
+/*** function body ***/
+
+int BL_MSDC_Init(void)
+{
+    // enable GPIO for MSDC
+    DRV_SetBits(0x80021800, 0x5540);
+    DRV_SetBits(0x80021900, 0x55);
+
+    MSDC_Initialize();
+
+    return 0;
+}
+
+int BL_MSDC_DeInit(void)
+{
+    MSDC_DeInit();
+
+    // reset GPIO to disable MSDC
+    DRV_ClearBits(0x80021800, 0x5540);
+    DRV_ClearBits(0x80021900, 0x55);
+
+    return 0;
+}
+
+int BL_MSDC_MountDevice(int DeviceNumber, int DeviceType, unsigned int Flags)
+{
+    return FS_SdDrv.MountDevice((void*)&MSDC_Blk[0], DeviceNumber, DeviceType, Flags);
+}
+
+int BL_MSDC_ReadSectors(unsigned int Sector, unsigned int Sectors, void * Buffer)
+{
+    return FS_SdDrv.ReadSectors((void*)&MSDC_Blk[0], Sector, Sectors, Buffer);
+}
+
+int BL_MSDC_GetDiskGeometry(FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+    return FS_SdDrv.GetDiskGeometry((void*)&MSDC_Blk[0], DiskGeometry, MediaDescriptor);
+}
+
+int BL_MSDC_GetCardPSN(unsigned int *psn)
+{
+    FS_DeviceInfo info;
+    FS_SdDrv.IOCtrl((void*)&MSDC_Blk[0], FS_IOCTRL_QUERY_CARD_INFO, &info);
+
+    *psn = info.DeviceInfo.Card.PSN;
+
+    return 0;
+}
+
+#endif//__CARD_DOWNLOAD__
+
diff --git a/mcu/driver/storage/mc/src/sd_drv.c b/mcu/driver/storage/mc/src/sd_drv.c
new file mode 100644
index 0000000..cd52c95
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_drv.c
@@ -0,0 +1,3668 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   ms_drv.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Adaption driver of file system for SD card
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "drv_msgid.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#endif
+#include "init.h"
+*/
+//RHR
+#include "kal_trace.h"
+#include "kal_general_types.h"
+#include "fs_errcode.h"
+#include "fs_iprot.h"
+#include "drv_comm.h"
+#include "drv_features.h"
+#include "drvpdn.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "msdc_reg_adap.h"
+#include "reg_base.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "intrCtrl.h"
+#include "msdc_lsd.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#include "cache_sw.h"
+#include "qmu_bm.h"
+
+//! EMB
+#include "init.h"
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+#endif
+#if defined(MSDC_TRACE_LEVEL3)
+#define __DRV_MSDC_DEBUG_PERF_MEASURE__
+#endif
+//#define __CMMB_CAS_FULL_CARD_SUPPORT__
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+#include "cas_drv.h"
+#endif
+
+#ifdef DRV_LSD
+//#define LSD_SINGLE_READ
+//#define LSD_SINGLE_WRITE
+/*to test where card consumes power whenever it is in transfer state*/
+//#define TEST_TRANSFER_STATE_CONSUME_POWER
+#endif
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1		CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM	CG_CON1_SIM
+#endif
+
+#ifndef MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET1
+#endif
+
+#else /*when MSDC_TEST_MSDC2_FROM_MSDC1_CODE is defined, we direct CON1 related macro to CON0 related*/
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET0
+#endif
+#endif//MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#endif
+
+#if defined(__MSDC_SD_MMC__)
+
+#define MAX_CLUSTERS (0x0FFF6 - 2)
+#define MSDC_MEDIA_DESCRIPTOR		0xF8
+#define SD_MAX_RETRY	2
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+kal_semid dualMsdcArb;
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+kal_semid dclMsdcArb;
+typedef struct{
+	kal_uint32	callerRetAddr;
+	kal_uint32	ownerThdId;
+} SD_ARB_DBG;
+static SD_ARB_DBG	sdArbDbg;
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+static kal_bool	isFullCard;
+#endif
+
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+#define MSDC_DLT_NOT_TESTED 0xFFFFFFFF
+#define MSDC_RED_DLT_INVALID 0xFFFFFFFF
+#endif
+
+extern kal_bool INT_USBBoot(void);
+extern void SLA_CustomLogging(kal_char *customJob, kal_int32 saAction); 
+
+#ifdef __DRV_MSDC_ENHANCE_FORMAT_BY_ERASE__
+kal_bool useEraseOnFormat = KAL_TRUE;
+#else
+kal_bool useEraseOnFormat = KAL_FALSE;
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+kal_uint64 gMSDC_perf_block_read_freq[5] = {0, 0, 0, 0, 0};
+kal_uint64 gMSDC_perf_block_read_time[5] = {0, 0, 0, 0, 0};
+// for write operation performance measurement
+kal_uint64 gMSDC_perf_block_write_freq[5] = {0, 0, 0, 0, 0};
+kal_uint64 gMSDC_perf_block_write_time[5] = {0, 0, 0, 0, 0};
+#endif
+
+#if defined(__DEMAND_PAGING__) && !defined(__FUE__) && !defined(__UBL__)
+#define DEMP_LOCK(addr, size) \
+    demp_lock_pages(DEMP_LOCK_EMMC, (kal_uint32)addr, size)
+#define DEMP_UNLOCK(addr, size) \
+    demp_unlock_pages(DEMP_LOCK_EMMC, (kal_uint32)addr, size)
+#else
+#define DEMP_LOCK(addr, size)
+#define DEMP_UNLOCK(addr, size)
+#endif
+#if defined(DCL_MSDC_INTERFACE)
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+/*
+	2008/12/16
+	sd driver was protected under file system, and now we have to share the resource with CAS CMD and SDIO
+	we have implemented new architecture by DCL ways, but DCL haven't been QC and 
+	maybe dangerous to enable it in 08B. We adopt SIM driver's method to import new control interface without the 
+	change of file system.
+*/
+
+int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags);
+
+#ifdef DRV_MSDC_HW_CONTENTION
+void SD_setArbRetAddr(kal_uint32 retAddr)
+{
+	sdArbDbg.callerRetAddr = retAddr;
+}
+
+void SD_setArbThdId(kal_uint32 ThdId)
+{
+	sdArbDbg.ownerThdId = ThdId;
+}
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+#define SD_FULL_CARD_DEBUG_BUF_SIZE (1024*32)
+kal_uint32 SD_casTxDebugBuffer[SD_FULL_CARD_DEBUG_BUF_SIZE];
+kal_uint32 SD_casRxDebugBuffer[SD_FULL_CARD_DEBUG_BUF_SIZE];
+kal_uint32 SD_casCmdState = 0;
+
+
+void SD_setFullCard(kal_bool cardType)
+{
+	isFullCard = cardType;
+}
+
+#endif
+
+int  ReadSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+	int status;
+    
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+sd_select_enum sel;
+#endif    
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling ReadSectors*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+
+#endif//DRV_MSDC_HW_CONTENTION
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+			kal_take_sem(dualMsdcArb, 1);
+	}
+#endif//DRV_MSDC_HW_CONTENTION
+
+   #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+      sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+      sel = SD_SIM;
+      #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+	get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+  #else
+	get_MSDC_lock(&gSD->mSDdrv_lock);
+  #endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+	status = ReadSectors(DriveData, Sector, Sectors, Buffer);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+	free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+	if(2 == SD_casCmdState && FS_NO_ERROR == status){/*previous command is CAS write*/
+		if(4 == Sector) /*CAS read command*/
+			SD_casCmdState *= 3;
+		else/*FS read interleaved in CAS command, backup result*/
+		{
+			kal_mem_cpy(SD_casRxDebugBuffer, Buffer, (((SD_FULL_CARD_DEBUG_BUF_SIZE) < (Sectors * 512)) ? (SD_FULL_CARD_DEBUG_BUF_SIZE) : (Sectors * 512)));
+		}
+	}
+
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_give_sem(dualMsdcArb);
+	}
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+	return status;
+
+}
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+static int  WriteSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+	int status;
+ 	#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+   	#endif    
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling WriteSectors*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_take_sem(dualMsdcArb, 1);
+                }
+#endif	
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+	if(M_CAM_CAS_HANDLE == (kal_uint32)DriveData) /*if CAS command, set debug state to 1*/
+		SD_casCmdState = 1;
+	else if(2 == SD_casCmdState)/*if FS command and debug state = 2, record the information*/
+	{
+		kal_mem_cpy(SD_casTxDebugBuffer, Buffer, (((SD_FULL_CARD_DEBUG_BUF_SIZE) < (Sectors * 512)) ? (SD_FULL_CARD_DEBUG_BUF_SIZE) : (Sectors * 512)));
+	}
+
+#endif
+
+   #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+      sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+      sel = SD_SIM;
+      #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+	get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+  #else
+	get_MSDC_lock(&gSD->mSDdrv_lock);
+  #endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+	status = WriteSectors(DriveData, Sector, Sectors, Buffer);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+  free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+	free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+	if (FS_NO_ERROR == status)
+		SD_casCmdState *= 2;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_give_sem(dualMsdcArb);
+		}
+#endif
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+	return status;
+
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+int  MountDevice_NEW(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags)
+{
+	int status;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    sd_select_enum sel;
+#endif 
+
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+
+	if(NULL == dclMsdcArb)
+		dclMsdcArb = kal_create_sem("MSDC lock", 1);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling MountDevice*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_take_sem(dualMsdcArb, 1);			
+    }
+#endif
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+          if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+         {
+            sel = SD_EXT;
+         }
+          else
+         {
+    #if defined(__SIM_PLUS__)
+            sel = SD_SIM;
+    #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+            sel = SD_T_CARD_2;
+    #endif
+         }
+		  init_MSDC_lock(&gSD_blk[0].mSDdrv_lock, "SD_DRV_LOCK");
+    get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);	    
+#else
+		init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");
+		get_MSDC_lock(&gSD->mSDdrv_lock);
+#endif	
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+	status = MountDevice(DriveData, DeviceNumber, DeviceType, Flags);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+        free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+        free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_give_sem(dualMsdcArb);
+		}
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+	return status;
+
+}
+kal_uint32 Get_BDStructNum(void)
+{
+    return MSDC_BD_MAX;
+}
+int Gpd_ReadSectors(void * DriveData, kal_uint32 Sector, UINT Sectors,  qbm_gpd *head,qbm_gpd *tail)
+{
+     kal_uint8 retry = 0,single_line=0;
+	DCL_STATUS dclStatus = 0;
+	SD_CTRL_GPD_READ_T data;
+	
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    kal_uint32 time1,time2;
+#endif
+
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	DCL_BOOL isCardExist = KAL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+	DCL_BOOL isFFRunning = KAL_FALSE;  
+#if defined(DRV_MSDC_RETRY_DLT_IN_READ_ERR)
+    kal_uint32 ClkFactor;
+#endif
+    	
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+	}
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_READ_SECTOR_ERROR;	
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_READ_SECTOR_ERROR;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel;
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_READ_SECTOR_ERROR;
+#endif
+
+ 
+        
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+    if (!isCardExist)
+    {		
+    	DclSD_Close(dclHandle);
+    	return FS_MSDC_MOUNT_ERROR;
+    }
+
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+
+    #if 0
+/* under construction !*/
+/* under construction !*/
+	#endif
+
+#ifdef	__DRV_MSDC_FAST_FORMAT__
+/*since there is no readSectors command enclosed in fast format, this flag should be always flase when we do readSectors*/
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_FAST_FORMAT_RUNNING, (DCL_CTRL_DATA_T*)&isFFRunning);
+    if ((DCL_BOOL)KAL_TRUE == isFFRunning)
+	    ASSERT(0);
+#endif
+
+    gMSDC_Handle->timeout_count = 0;
+    gMSDC_Handle->dataCrcError_count = 0;
+
+    	//retry ++;
+   do{
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time1 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_READSECTOR_START(time1, retry, gSD->sd_r, MSDC_Reg32(MSDC_IOCON));
+#endif
+
+    	MSDC_SLA_Start_Logging("GPR");
+
+    	data.bufferHead = head;
+        data.bufferTail = tail;
+    	data.u4Sector = Sector;
+    	data.u4Sectors = Sectors;
+    	dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_GPD_READ, (DCL_CTRL_DATA_T*)&data);
+    	//if (dclStatus == STATUS_ERROR_WRONG_STATE)
+    	//{
+    	//	DclSD_Close(dclHandle);
+    	//	return FS_MSDC_MOUNT_ERROR;
+    	//}
+
+    	MSDC_SLA_Stop_Logging("GPR");
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time2 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_READSECTOR_END(dclStatus, time2,\
+    		(kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+        switch (Sectors)
+        {
+            case 1:
+                gMSDC_perf_block_read_freq[0] += Sectors;
+                gMSDC_perf_block_read_time[0] += (time2-time1);
+                break;
+            case 2:
+                gMSDC_perf_block_read_freq[1] += Sectors;
+                gMSDC_perf_block_read_time[1] += (time2-time1);
+                break;
+            case 3:
+            case 4:
+                gMSDC_perf_block_read_freq[2] += Sectors;
+                gMSDC_perf_block_read_time[2] += (time2-time1);
+                break;
+            case 5:
+            case 6:
+            case 7:
+            case 8:
+                gMSDC_perf_block_read_freq[3] += Sectors;
+                gMSDC_perf_block_read_time[3] += (time2-time1);
+                break;
+            default:// Sector > 8
+                gMSDC_perf_block_read_freq[4] += Sectors;
+                gMSDC_perf_block_read_time[4] += (time2-time1);
+                break;
+        }
+#endif
+
+    	if(dclStatus != STATUS_OK )
+    	{		
+    		if(kal_query_systemInit()== KAL_TRUE)
+            {
+                            /*12/26, Blue remove this to enable read retry in booting up*/
+    			#if defined(MSDC_TRACE_LEVEL3)
+                            MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+    			#endif
+                            //MSDC_PDNControl(KAL_TRUE);
+                            //return FS_MSDC_READ_SECTOR_ERROR;
+            }
+
+            if (dclStatus ==STATUS_ERROR_CRCERROR)
+            {
+                
+                if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund) 
+                {
+                        gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+                        MSDC_ERR("[MSDC]Read(GPD) CRC Error, reduce Bus Clock\r\n");
+                        MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+                }
+                else
+                {
+                    MSDC_ERR("[MSDC]Read(GPD) CRC Error, try single line\r\n");
+                    
+                    if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+                    {
+                        gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+                        single_line=1;
+                    }
+                    else           
+                    {
+                        dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                        break;
+                    }
+                    DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                    if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+                    {
+                        dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                        break;
+                    }
+                }
+            }
+            else if (dclStatus==STATUS_ERROR_TIMEOUT)
+            {
+                
+                if (retry++ >=3)
+                {
+                    dclStatus= FS_MSDC_READ_SECTOR_ERROR;
+                    break;
+                }
+                MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+                
+                //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+                DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+                    dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                    break;
+                }
+            }
+            else
+            {
+
+                break;
+            }
+    	} // end of if error
+	
+    } while(dclStatus != STATUS_OK);
+    
+//#if defined(MSDC_CACHED_SUPPORT_WRITE_THROUGH_SERIES) && !defined(__UBL__)
+//	invalidate_wt_cache((kal_uint32)Buffer, 512 * Sectors);
+//#endif
+
+	DclSD_Close(dclHandle);
+	//return FS_NO_ERROR;
+	return dclStatus;
+}
+int Gpd_WriteSectors(void * DriveData, kal_uint32 Sector, UINT Sectors,  qbm_gpd *head,qbm_gpd *tail)
+{
+    //SDC_CMD_STATUS status;
+	kal_uint8 retry = 0,single_line=0;
+	//kal_uint32 adrs;
+	DCL_STATUS dclStatus = 0;
+	
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    kal_uint32 time1,time2;
+#endif
+
+	SD_CTRL_GPD_WRITE_T data;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	//kal_uint32 timeout_count = 0;
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+    //Need check this line !!!!!!!!!!!!!!!!!!!
+   // DEMP_LOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+   }
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_WRITE_SECTOR_ERROR;	
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_WRITE_SECTOR_ERROR;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel;  
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_WRITE_SECTOR_ERROR;
+#endif
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+
+	#if 0
+/* under construction !*/
+/* under construction !*/
+    #endif
+
+if(!isCardExist)
+{
+    DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+    if(!isCardExist)
+    {
+        DclSD_Close(dclHandle);
+        return FS_MSDC_MOUNT_ERROR;
+    }
+}
+	
+	gMSDC_Handle->timeout_count = 0;	
+    do{
+    	retry++;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time1 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_WRITESECTOR_START(time1, retry, gSD->sd_w, 0);
+#endif
+
+    	MSDC_SLA_Start_Logging("GPW");
+
+    	data.bufferHead = head;
+        data.bufferTail = tail;
+    	data.u4Sector = Sector;
+    	data.u4Sectors = Sectors;
+    	dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_GPD_WRITE, (DCL_CTRL_DATA_T*)&data);
+    	//if (dclStatus == STATUS_ERROR_WRONG_STATE)
+    	//{
+    	//	DclSD_Close(dclHandle);
+    	//   DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+    	//	return FS_MSDC_WRITE_SECTOR_ERROR;
+    	//}
+    			
+    	MSDC_SLA_Stop_Logging("GPW");
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time2 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_WRITESECTOR_END(dclStatus, time2,
+    		(kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for write operation performance measurement
+        switch (Sectors)
+        {
+            case 1:
+                gMSDC_perf_block_write_freq[0] += Sectors;
+                gMSDC_perf_block_write_time[0] += (time2-time1);
+                break;
+            case 2:
+                gMSDC_perf_block_write_freq[1] += Sectors;
+                gMSDC_perf_block_write_time[1] += (time2-time1);
+                break;
+            case 3:
+            case 4:
+                gMSDC_perf_block_write_freq[2] += Sectors;
+                gMSDC_perf_block_write_time[2] += (time2-time1);
+                break;
+            case 5:
+            case 6:
+            case 7:
+            case 8:
+                gMSDC_perf_block_write_freq[3] += Sectors;
+                gMSDC_perf_block_write_time[3] += (time2-time1);
+                break;
+            default:// Sector > 8
+                gMSDC_perf_block_write_freq[4] += Sectors;
+                gMSDC_perf_block_write_time[4] += (time2-time1);
+                break;
+        }
+#endif
+
+    	if(dclStatus != STATUS_OK)
+    	{
+    		if(kal_query_systemInit()== KAL_TRUE)
+            {
+                            /*12/26, Blue remove this to enable read retry in booting up*/
+    			#if defined(MSDC_TRACE_LEVEL3)
+                            MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+    			#endif
+                            //MSDC_PDNControl(KAL_TRUE);
+                            //return FS_MSDC_READ_SECTOR_ERROR;
+            }
+
+            if (dclStatus ==STATUS_ERROR_CRCERROR)
+            {
+                
+                if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund) 
+                {
+                        gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+                        MSDC_ERR("[MSDC]Write(GPD) CRC Error, reduce Bus Clock\r\n");
+                        MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+                }
+                else
+                {
+                    MSDC_ERR("[MSDC]Write(GPD) CRC Error, try single line\r\n");
+                    
+                    if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+                    {
+                        gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+                        single_line=1;
+                    }
+                    else           
+                    {
+                        dclStatus=FS_MSDC_WRITE_SECTOR_ERROR;
+                        break;
+                    }
+                    DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                    if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+                    {
+                        dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+                        break;
+                    }
+                }
+            }
+            else if (dclStatus==STATUS_ERROR_TIMEOUT)
+            {
+                if (retry++ >=3)
+                {
+                    dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+                    break;
+                }
+                MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+                
+                //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+                DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+                    dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+                    break;
+                }
+            }
+            else
+            {
+                break;
+            }
+    	}
+    }while(dclStatus!=STATUS_OK);
+	DclSD_Close(dclHandle);
+    //DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+	return dclStatus;
+}
+
+int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors,qbm_gpd *head,qbm_gpd *tail)
+{
+    int status;
+    
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+sd_select_enum sel;
+#endif    
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling ReadSectors*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+
+#endif//DRV_MSDC_HW_CONTENTION
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+			kal_take_sem(dualMsdcArb, 1);
+	}
+#endif//DRV_MSDC_HW_CONTENTION
+
+   #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+      sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+      sel = SD_SIM;
+      #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+	get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+  #else
+	//get_MSDC_lock(&gSD->mSDdrv_lock);
+  #endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+	status = Gpd_ReadSectors(DriveData, Sector, Sectors, head,tail);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+	//free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_give_sem(dualMsdcArb);
+	}
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+	return status;
+}
+int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, qbm_gpd *head,qbm_gpd *tail)
+{
+    int status;
+ 	#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+   	#endif    
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling WriteSectors*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_take_sem(dualMsdcArb, 1);
+                }
+#endif	
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+   #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+      sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+      sel = SD_SIM;
+      #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+	get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+  #else
+    //get_MSDC_lock(&gSD->mSDdrv_lock);
+  #endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+	status = Gpd_WriteSectors(DriveData, Sector, Sectors,head,tail);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+  free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+	//free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+	if (FS_NO_ERROR == status)
+		SD_casCmdState *= 2;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_give_sem(dualMsdcArb);
+		}
+#endif
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+	return status;
+}
+
+static int  DiscardSectors(void * DriveData, kal_uint32 Sector, UINT Sectors)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+   return FS_NO_ERROR;
+}
+
+/*-----------------------------------*/
+int  ReadSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+	kal_uint8 retry = 0,single_line=0;
+	DCL_STATUS dclStatus = 0;
+	SD_CTRL_READ_T data;
+	
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    kal_uint32 time1,time2;
+#endif
+
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	DCL_BOOL isCardExist = KAL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+	DCL_BOOL isFFRunning = KAL_FALSE;  
+#if defined(DRV_MSDC_RETRY_DLT_IN_READ_ERR)
+    kal_uint32 ClkFactor;
+#endif
+    	
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+	}
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_READ_SECTOR_ERROR;	
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_READ_SECTOR_ERROR;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel;
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_READ_SECTOR_ERROR;
+#endif
+
+        
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+    if (!isCardExist)
+    {		
+    	DclSD_Close(dclHandle);
+    	return FS_MSDC_MOUNT_ERROR;
+    }
+
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+    MD_TRC_MSDC_INFORM_READSECTOR_ENTRY((kal_uint32)DriveData, Sector, Sectors, (kal_uint32)Buffer, \
+	(kal_uint32)kal_get_current_thread_ID(), MSDC_Reg32(MSDC_CFG), isCardExist, isCardInited);
+
+#ifdef	__DRV_MSDC_FAST_FORMAT__
+/*since there is no readSectors command enclosed in fast format, this flag should be always flase when we do readSectors*/
+    DclSD_Control(dclHandle, SD_CTRL_CMD_IS_FAST_FORMAT_RUNNING, (DCL_CTRL_DATA_T*)&isFFRunning);
+    if ((DCL_BOOL)KAL_TRUE == isFFRunning)
+	    ASSERT(0);
+#endif
+
+    gMSDC_Handle->timeout_count = 0;
+    gMSDC_Handle->dataCrcError_count = 0;
+
+	//retry ++;
+    do{
+
+    #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time1 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_READSECTOR_START(time1, retry, gSD->sd_r, MSDC_Reg32(MSDC_IOCON));
+    #endif
+
+    	MSDC_SLA_Start_Logging("BFR");
+    	
+    	data.bufferAddr = Buffer;
+    	data.u4Sector = Sector;
+    	data.u4Sectors = Sectors;
+    	dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_READ, (DCL_CTRL_DATA_T*)&data);
+    	//if (dclStatus == STATUS_ERROR_WRONG_STATE)
+    	//{
+    	//	DclSD_Close(dclHandle);
+    	//	return FS_MSDC_MOUNT_ERROR;
+    	//}
+
+    	MSDC_SLA_Stop_Logging("BFR");
+
+    #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time2 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_READSECTOR_END(dclStatus, time2,\
+    		(kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+    #endif
+    
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+        switch (Sectors)
+        {
+            case 1:
+                gMSDC_perf_block_read_freq[0] += Sectors;
+                gMSDC_perf_block_read_time[0] += (time2-time1);
+                break;
+            case 2:
+                gMSDC_perf_block_read_freq[1] += Sectors;
+                gMSDC_perf_block_read_time[1] += (time2-time1);
+                break;
+            case 3:
+            case 4:
+                gMSDC_perf_block_read_freq[2] += Sectors;
+                gMSDC_perf_block_read_time[2] += (time2-time1);
+                break;
+            case 5:
+            case 6:
+            case 7:
+            case 8:
+                gMSDC_perf_block_read_freq[3] += Sectors;
+                gMSDC_perf_block_read_time[3] += (time2-time1);
+                break;
+            default:// Sector > 8
+                gMSDC_perf_block_read_freq[4] += Sectors;
+                gMSDC_perf_block_read_time[4] += (time2-time1);
+                break;
+        }
+#endif
+
+    	if(dclStatus != STATUS_OK )
+    	{	
+    	    if(kal_query_systemInit()== KAL_TRUE)
+            {
+                            /*12/26, Blue remove this to enable read retry in booting up*/
+    			#if defined(MSDC_TRACE_LEVEL3)
+                            MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+    			#endif
+                            //MSDC_PDNControl(KAL_TRUE);
+                            //return FS_MSDC_READ_SECTOR_ERROR;
+            }
+
+            if (dclStatus ==STATUS_ERROR_CRCERROR)
+            {
+                
+                if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund) 
+                {
+                        gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+                        MSDC_ERR("[MSDC]Read CRC Error, reduce Bus Clock\r\n");
+                        MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+                }
+                else
+                {
+                    MSDC_ERR("[MSDC]Read CRC Error, try single line\r\n");
+                    if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+                    {
+                        gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+                        single_line=1;
+                    }
+                    else           
+                    {
+                        dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                        break;
+                    }
+                    DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                    if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+                    {
+                        dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                        break;
+                    }
+                }
+            }
+            else if (dclStatus==STATUS_ERROR_TIMEOUT)
+            {
+                
+                if (retry++ >=3)
+                {
+                    dclStatus= FS_MSDC_READ_SECTOR_ERROR;
+                    break;
+                }
+                MSDC_ERR("[MSDC][%s]Timeout Error, retry,count<%d>\r\n",__FUNCTION__,retry);
+                
+                //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+                DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+                    dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                    break;
+                }
+            }
+            else
+            {
+                break;
+            }
+    		
+    	} // end of if error
+	
+    } while(dclStatus != STATUS_OK);
+    
+#if defined(MSDC_CACHED_SUPPORT_WRITE_THROUGH_SERIES) && !defined(__UBL__)
+	invalidate_wt_cache((kal_uint32)Buffer, 512 * Sectors);
+#endif
+
+	DclSD_Close(dclHandle);
+	//return FS_NO_ERROR;
+	return dclStatus;
+}
+
+/*-----------------------------------*/
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+int WriteSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+	//SDC_CMD_STATUS status;
+	kal_uint8 retry = 0,single_line=0;
+	//kal_uint32 adrs;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+	kal_uint32 time1, time2;
+#endif
+
+	DCL_STATUS dclStatus = 0;
+	SD_CTRL_READ_T data;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	//kal_uint32 timeout_count = 0;
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+    DEMP_LOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+   }
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_WRITE_SECTOR_ERROR;	
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_WRITE_SECTOR_ERROR;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel;  
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_WRITE_SECTOR_ERROR;
+#endif
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+	MD_TRC_MSDC_INFORM_WRITESECTOR_ENTRY((kal_uint32)DriveData, Sector, Sectors, (kal_uint32)Buffer, 
+		(kal_uint32)kal_get_current_thread_ID(), MSDC_Reg32(MSDC_CFG), isCardExist, isCardInited);
+
+    if(!isCardExist)
+    {
+        DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+        if(!isCardExist)
+        {
+            DclSD_Close(dclHandle);
+            return FS_MSDC_MOUNT_ERROR;
+        }
+    }
+	
+	gMSDC_Handle->timeout_count = 0;	
+    do{
+    
+    #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time1 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_WRITESECTOR_START(time1, retry, gSD->sd_w, 0);
+    #endif
+    
+    	MSDC_SLA_Start_Logging("BFW");
+
+    	data.bufferAddr = Buffer;
+    	data.u4Sector = Sector;
+    	data.u4Sectors = Sectors;
+    	dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_WRITE, (DCL_CTRL_DATA_T*)&data);
+    	//if (dclStatus == STATUS_ERROR_WRONG_STATE)
+    	//{
+    	//	DclSD_Close(dclHandle);
+    	//   DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+    	//	return FS_MSDC_WRITE_SECTOR_ERROR;
+    	//}
+    			
+    	MSDC_SLA_Stop_Logging("BFW");
+
+    #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+    	time2 = drv_get_current_time();
+    	MD_TRC_MSDC_INFORM_WRITESECTOR_END(dclStatus, time2,
+    		(kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+    #endif
+    
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for write operation performance measurement
+        switch (Sectors)
+        {
+            case 1:
+                gMSDC_perf_block_write_freq[0] += Sectors;
+                gMSDC_perf_block_write_time[0] += (time2-time1);
+                break;
+            case 2:
+                gMSDC_perf_block_write_freq[1] += Sectors;
+                gMSDC_perf_block_write_time[1] += (time2-time1);
+                break;
+            case 3:
+            case 4:
+                gMSDC_perf_block_write_freq[2] += Sectors;
+                gMSDC_perf_block_write_time[2] += (time2-time1);
+                break;
+            case 5:
+            case 6:
+            case 7:
+            case 8:
+                gMSDC_perf_block_write_freq[3] += Sectors;
+                gMSDC_perf_block_write_time[3] += (time2-time1);
+                break;
+            default:// Sector > 8
+                gMSDC_perf_block_write_freq[4] += Sectors;
+                gMSDC_perf_block_write_time[4] += (time2-time1);
+                break;
+        }
+#endif
+
+	    if(dclStatus != STATUS_OK)
+	    {
+		    if(kal_query_systemInit()== KAL_TRUE)
+            {
+                            /*12/26, Blue remove this to enable read retry in booting up*/
+    			#if defined(MSDC_TRACE_LEVEL3)
+                            MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+    			#endif
+                            //MSDC_PDNControl(KAL_TRUE);
+                            //return FS_MSDC_READ_SECTOR_ERROR;
+            }
+
+            if (dclStatus ==STATUS_ERROR_CRCERROR)
+            {
+                
+                if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund) 
+                {
+                        gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+                        MSDC_ERR("[MSDC]CRC Error, reduce Bus Clock\r\n");
+                        MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+                }
+                else
+                {
+                    MSDC_ERR("[MSDC]CRC Error, try single line\r\n");
+                    if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+                    {
+                        gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+                        single_line=1;
+                    }
+                    else           
+                    {
+                        dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+                        break;
+                    }
+                    DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                    if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+                    {
+                        dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+                        break;
+                    }
+                }
+            }
+            else if (dclStatus==STATUS_ERROR_TIMEOUT)
+            {
+                if (retry++ >=3)
+                {
+                    dclStatus= FS_MSDC_WRITE_SECTOR_ERROR;
+                    break;
+                }
+                MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+                
+                //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+                DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+                
+                if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+                    dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+                    break;
+                }
+            }
+            else
+            {
+                break;
+                
+            }
+	    }
+    }while(dclStatus!=STATUS_OK);
+
+	DclSD_Close(dclHandle);
+    DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+	return dclStatus;
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+#if !defined(__FUE__) && !defined(__UBL__)
+void SD_SelfFormat(void)
+{
+    
+    FS_PartitionRecord Par;
+    //static kal_uint8 p[512];
+
+    kal_mem_set((void*)&Par, 0, sizeof Par);
+    if(0x20000000000ULL > gSD->mCSD.capacity){
+    	Par.Sectors = (kal_uint32)(gSD->mCSD.capacity/512);
+    }
+    else{
+    	ASSERT(0);
+    }
+ 
+        FS_CreateMasterBootRecord(MSDC_Sector, &Par);
+ 
+        WriteSectors(gMSDC_Handle, 0, 1, MSDC_Sector);
+ 
+    Par = ((FS_MasterBootRecord *)MSDC_Sector)->PTable[0];
+    FS_CreateBootSector((void*)MSDC_Sector, &Par, 0xF8, 0, FS_FMT_SINGLE_FAT );
+    WriteSectors(gMSDC_Handle, Par.RelativeSector, 1, MSDC_Sector);
+ /*  End of SelfFormat */
+
+}
+#endif//__UBL__
+
+/*-----------------------------------*/
+int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags)
+{	
+	kal_uint8 retry = 0;
+	DCL_STATUS dclStatus = 0;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)	
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+   }
+	else
+	{
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_MOUNT_ERROR;	
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return FS_MSDC_MOUNT_ERROR;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel; 
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_MOUNT_ERROR;
+#endif
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+	if(isCardInited)
+	{
+		DclSD_Close(dclHandle);
+		return DCL_SECTOR_SIZE;
+	}
+	gMSDC_Handle->is_init_timeout = KAL_FALSE;		
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	if(!isCardExist)
+	{		
+		//dbg_print("not present \r\n");
+		
+		#if defined(_NAND_FLASH_BOOTING_)
+		// add the following code for solving plug in or out the SD card during 
+		// NFB loading process. The card detection interruptwill disapperared 		 
+		// while interrupt controller is masked.
+
+		DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+		#endif // _NAND_FLASH_BOOTING_
+		
+		if (!isCardExist)
+		{
+			DclSD_Close(dclHandle);
+			return FS_MSDC_MOUNT_ERROR;
+		}
+	}
+start:
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+	gMSDC_Handle->msdc_clkTuneTriedWr = MSDC_DLT_NOT_TESTED;
+	gMSDC_Handle->msdc_clkTuneTriedRd = MSDC_DLT_NOT_TESTED;
+	gMSDC_Handle->msdc_RedDlt_forRd = MSDC_RED_DLT_INVALID;
+	gMSDC_Handle->msdc_RedDlt_forWr = MSDC_RED_DLT_INVALID;
+#endif		
+
+	dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL);
+	if (dclStatus != STATUS_OK)
+		goto err_exit;
+
+	//if(SD_MountDevice(DeviceType) != FS_NO_ERROR)
+		//return FS_MSDC_MOUNT_ERROR;
+
+	//dbg_print("Mount success! \r\n");
+
+	DclSD_Close(dclHandle);
+
+	init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");
+	
+#if defined(MSDC_SDMMC_NAND) && !defined(__UBL__)
+	/*for SDMMC NAND, some manufacturs sale NAND with all sectors zero, we should format it first*/
+	if (ReadSectors( DriveData, 0, 1, MSDC_Sector) != NO_ERROR)
+		goto err_exit;
+	if (0xaa550000 != (MSDC_Sector[127] & 0xffff0000)){/*it doesn't have correct MBR*/
+		if (ReadSectors(DriveData, 1, 1, MSDC_Sector) != NO_ERROR)
+			goto err_exit;
+		if (0xaa550000 != (MSDC_Sector[127] & 0xffff0000)){/*it doesn't have correct PBR*/
+			SD_SelfFormat();
+		}
+	}
+#endif
+
+	return DCL_SECTOR_SIZE;
+   
+err_exit:
+	if(retry++ <= SD_MAX_RETRY && gMSDC_Handle->is_init_timeout == KAL_FALSE)
+	{
+		//dbg_print("SD MountDevice failed! retry: %d \r\n",retry);
+		goto start;
+	}
+	#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	isCardExist = KAL_FALSE;
+	DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	#endif	
+
+	/*these cards do not support hot plug and we should set it not present now*/
+	#if defined(__SIM_PLUS__)
+	if(INT_USBBoot() == KAL_TRUE && current_card == SD_SIM)
+	{
+		isCardExist = KAL_FALSE;
+		DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	}
+	#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+
+	if(INT_USBBoot() == KAL_TRUE && current_card == SD_T_CARD_2)
+	{
+		isCardExist = KAL_FALSE;
+		DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	}
+	#endif //__SIM_PLUS__ or DRV_MSDC_DUAL_TCARD_BY_SWITCH
+
+	DclSD_Close(dclHandle);
+	gMSDC_Handle->mIsPresent=KAL_FALSE;
+	return FS_MSDC_MOUNT_ERROR;
+	
+}
+
+
+/*-----------------------------------*/
+static int  MediaChanged(void * DriveData)
+{
+	//DCL_STATUS dclStatus = 0;
+	kal_bool everPlugOut = KAL_FALSE;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+        int status;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+			kal_take_sem(dualMsdcArb, 1);			
+	}
+ #endif
+
+   #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+
+  if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         {
+            #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)	
+	         if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+            {
+               kal_give_sem(dualMsdcArb);
+            }
+            #endif
+         return FS_MSDC_READ_SECTOR_ERROR;	
+         }
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         {
+            #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)	
+	         if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+            {
+               kal_give_sem(dualMsdcArb);
+            }
+            #endif            
+            return FS_MSDC_READ_SECTOR_ERROR;
+         }
+      #else
+		ASSERT(0);
+      #endif
+   }	  
+   
+   	prSwitch.u4TargetInterface=sel; 	  
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+   if(dclHandle == DCL_HANDLE_INVALID)
+      return FS_MSDC_READ_SECTOR_ERROR; //safe for normal case
+#endif
+	
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+#ifdef DRV_MSDC_VMC_CTRL
+	MSDC_turnOnVMC(isCardExist);
+#endif
+
+	if(isCardExist)
+	{
+		DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+		if(isCardInited)
+		{
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+			DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+			//DclSD_Close(dclHandle);
+   	   	status=FS_NO_ERROR;
+   		goto Error;
+		}
+		else
+		{
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+			/*current state is present not mount, we have to check whether it plug out before*/
+			DclSD_Control(dclHandle, SD_CTRL_CMD_QUERY_EVER_PLUGOUT, (DCL_CTRL_DATA_T*)&everPlugOut);
+			if(KAL_TRUE == everPlugOut){
+				/*send FMT a new message, and return plug out*/
+				DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+	#if !defined(FMT_NOT_PRESENT)
+				MSDC_SendCardInd(MOD_FMT, SD_EXT, MSG_ID_MSDC_CARD_DETECT_IND);
+	#endif
+				//DclSD_Close(dclHandle);
+				status=FS_MSDC_NOT_PRESENT;
+				goto Error;
+			}
+			DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+			//DclSD_Close(dclHandle);
+			status=FS_MSDC_PRESNET_NOT_READY;
+			goto Error;
+		}
+	}
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+	DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+		status=FS_MSDC_NOT_PRESENT;
+Error:	
+	DclSD_Close(dclHandle);
+   #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)	
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+		{
+			kal_give_sem(dualMsdcArb);
+		}
+   #endif
+	return status;
+}
+
+/*-----------------------------------*/
+static int GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isCardInited = KAL_FALSE;
+	int status = FS_NO_ERROR;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+    #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_take_sem(dualMsdcArb, 1);			
+    }	    	 
+    #endif
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+   }
+	else
+   {
+      #if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      sel = SD_T_CARD_2;
+      #endif
+   }
+    get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+   if(sel==SD_EXT)
+	{
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+        if (dclHandle == DCL_HANDLE_INVALID) {
+            status = FS_MSDC_READ_SECTOR_ERROR;	
+            goto err_exit;
+        }
+    }
+	else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+        if (dclHandle == DCL_HANDLE_INVALID) {
+            status = FS_MSDC_READ_SECTOR_ERROR;
+            goto err_exit;
+        }
+      #else
+         ASSERT(0);
+      #endif
+   }
+	  
+	prSwitch.u4TargetInterface=sel; 	   
+	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+	  
+   #else
+   get_MSDC_lock(&gSD->mSDdrv_lock);
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+    if(dclHandle == DCL_HANDLE_INVALID) {
+        status = FS_MSDC_READ_SECTOR_ERROR;
+        goto err_exit;
+    }
+#endif
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+	if(isCardExist && isCardInited){
+		kal_mem_set((void*)DiskGeometry, 0, sizeof * DiskGeometry);
+		if(0x20000000000ULL > gSD->mCSD.capacity){
+			DiskGeometry->Sectors = (kal_uint32)(gSD->mCSD.capacity/512);
+   		}
+	   	else{
+	   	    DclSD_Close(dclHandle);
+	   	    status = FS_MSDC_NOT_PRESENT;
+	   	    goto err_exit;
+	   		//ASSERT(0);
+   		}
+	   	// 0xF8 is the standard value for fixed media, 0xF0 is for removable media.
+	   	// The important point is whatever value is put in here must also be put in the first
+	   	// byte of he FAT[0].
+		*MediaDescriptor = MSDC_MEDIA_DESCRIPTOR;
+		if(gSD->mWPEnabled) {
+			status = FS_WRITE_PROTECTION;		
+			goto err_exit;
+		}
+DclSD_Close(dclHandle);		
+        status = FS_NO_ERROR;	
+	}
+	else{
+DclSD_Close(dclHandle);
+		status = FS_MSDC_NOT_PRESENT;
+	}
+err_exit:	
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+        free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+        free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)    
+	
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_give_sem(dualMsdcArb);
+	}    	
+#endif
+    
+    return status;	
+}
+
+int SD_GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+    return GetDiskGeometry(DriveData, DiskGeometry, MediaDescriptor);
+}
+
+/*-----------------------------------*/
+extern void MSDC_ErrorRecordingReset();
+static int  ShutDown(void * DriveData)
+{
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef  __TST_WRITE_TO_FILE__
+	/*error recording: write error log to memory card here*/
+   if(KAL_TRUE == INT_QueryExceptionStatus())
+	MSDC_ErrorRecordingReset();
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+    AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+   return FS_NO_ERROR;
+}
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+kal_bool SD_canUseErase()
+{
+	if (KAL_TRUE == useEraseOnFormat && 0 == gSD->mSCR.dat_after_erase){
+	    if (MMC_CARD == gMSDC_Handle->mMSDC_type
+	        || MMC40_CARD == gMSDC_Handle->mMSDC_type
+	        || MMC42_CARD == gMSDC_Handle->mMSDC_type
+	        || MMC_CARD_SIMPLUS == gMSDC_Handle->mMSDC_type) {
+	        return KAL_FALSE;
+	    }
+	    else {
+		    tst_sys_trace("enhanced format");
+		    return KAL_TRUE;
+		}
+	}
+	else{
+		return KAL_FALSE;
+	}
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+/*******************************************
+ * File System <--> Device Driver Interface
+ * High Level Format
+ *
+ * Sample Code
+ ******************************************/
+#include <fs_type.h>
+//#include <rtfiles.h>
+#include "fs_gprot.h"
+
+/* FIXME */
+//kal_uint8 SectorBuffer[512];
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+extern int SDCreateBootSector(void * BootSector, kal_uint32 Sectors, FS_PartitionRecord *Partition);
+extern int SDCreateMasterBootRecord(void * MasterBootRecord, kal_uint32 Sectors);
+
+int highlevelformat(void * DriveData, UINT BaseSectorNumber)
+{
+    int FATType;
+    int RootDirSectors;  
+    int InfoSector;
+    int	i;
+    kal_uint32 x, y;
+    kal_uint32 FATSectors, Written;
+    kal_uint32 FatCount, StartOfFAT;   
+//    kal_uint32 status;
+    kal_uint32 boot_sector_offset = BaseSectorNumber; 
+#if __COOL_FORMAT__	
+	kal_uint32 total_sectors;
+#endif
+    FS_BootRecord *PBR;
+    kal_uint8 MediaDescriptor;
+    int Result = FS_NO_ERROR;
+    
+#if __COOL_FORMAT__    
+    FS_MasterBootRecord *mbr;
+    FS_BootRecord *bs;   
+#endif
+    DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+    
+    #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    sd_select_enum sel;
+    #endif 
+
+    #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+    {
+        kal_take_sem(dualMsdcArb, 1);
+    }
+    #endif	
+    
+    #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+    {
+        sel = SD_EXT;
+    }
+    else
+    {
+        #if defined(__SIM_PLUS__)
+        sel = SD_SIM;
+        #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+        sel = SD_T_CARD_2;
+        #endif
+    }
+    
+    get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+    
+    #else    
+    get_MSDC_lock(&gSD->mSDdrv_lock);
+    #endif
+    
+    do {
+        
+        #if __COOL_FORMAT__
+        mbr = (FS_MasterBootRecord *)MSDC_Sector;
+        bs = (FS_BootRecord *)msdc_uncachedBuf;
+        
+        total_sectors = gSD->mCSD.capacity/512;
+
+//        status = SD_FlushSectors(0, total_sectors);
+//        if (status != NO_ERROR)
+//            break;
+            
+        //
+        // 1. Create MBR.
+        //
+        boot_sector_offset = SDCreateMasterBootRecord(mbr, total_sectors);
+
+        if (boot_sector_offset > 0) { 
+                
+            //
+            // 2. Write MBR.
+            //
+            Result = WriteSectors(&MSDC_Blk[0], 0, 1, (void *)mbr);
+            if (Result != STATUS_OK) {
+                break;
+            }
+
+            //
+            // 3. Create boot sector.
+            //
+            if (SDCreateBootSector(bs, total_sectors, &mbr->PTable[0]) > 0) {
+
+                // 
+                // 4. Write boot sector to boot_sector_offset
+                //
+                Result = WriteSectors(&MSDC_Blk[0], boot_sector_offset, 1, bs); 
+                if (Result != STATUS_OK) {
+                    break;
+                }
+                
+            }
+            else {
+                Result = FS_INVALID_FILE_SYSTEM;
+                break;
+            }
+        }
+        else {
+            Result = FS_INVALID_FILE_SYSTEM;        
+            break;
+        }
+        #endif
+        
+        //
+        // 5. Finally, perform high level format. 
+        //    According to SD spec, 2G~32G card's start address is 0x2000
+        //
+        
+        /* HLF - 1 - Read the PBR sector */
+        ///* FIXME */ DrvDirect.ReadSector(SectorBuffer     /* Buffer */ ,
+        //                                 BaseSectorNumber /* Sector Number */);
+        Result = ReadSectors(DriveData, boot_sector_offset, 1, MSDC_Sector);  
+        if (Result != STATUS_OK)
+            break;
+        
+        //PBR = (FS_BootRecord*)&MSDC_Sector;
+        PBR = (FS_BootRecord*)MSDC_Sector;
+        
+        /* HLF - 2 - Setup PBR sector content and attributes */
+        {
+        if (PBR->BP.SectorsOnDisk != 0)
+            PBR->BP.TotalSectors = PBR->BP.SectorsOnDisk;
+        
+        if (PBR->Signature != 0xAA55 ||
+            //PBR->BP.TotalSectors > Par.Partition.Sectors ||
+            PBR->BP.TotalSectors > (gSD->mCSD.capacity/512) ||
+            PBR->BP.BytesPerSector != 512 ||
+            PBR->BP.SectorsPerCluster == 0 ||
+            PBR->BP.ReservedSectors == 0 ||
+            PBR->BP.NumberOfFATs == 0)
+        {
+            Result = FS_INVALID_FILE_SYSTEM;  
+            break; 
+        }
+        
+        FATSectors     = (PBR->BP.SectorsPerFAT) ? PBR->BP.SectorsPerFAT : PBR->BP.E._32.SectorsPerFAT;
+        RootDirSectors = (PBR->BP.DirEntries * 32 + (PBR->BP.BytesPerSector - 1)) / PBR->BP.BytesPerSector;
+        
+        Written        = PBR->BP.TotalSectors
+                        - PBR->BP.ReservedSectors
+                        - PBR->BP.NumberOfFATs * FATSectors
+                        - RootDirSectors;
+        Written = Written / PBR->BP.SectorsPerCluster;
+        
+        if (Written <= 0xFF4L)            FATType = 12;
+        else if (Written <= 0xFFF4L)      FATType = 16;
+        else if (Written <= 0xFFFFFF4L)   FATType = 32;
+        else {
+            Result = FS_INVALID_FILE_SYSTEM;  
+            break; 
+        }
+        Written = 0;
+        
+        if (FATType == 32)
+        {
+            RootDirSectors = PBR->BP.SectorsPerCluster;
+            
+            if (PBR->BP.E._32.RootDirCluster != 2)
+            {
+                PBR->BP.E._32.RootDirCluster = 2;
+
+                //above seek and write seems mean write to specific sector
+                Result = WriteSectors(DriveData, boot_sector_offset, 1, (void *)PBR);
+                if (Result != STATUS_OK)
+                    break;
+            
+                Result = WriteSectors(DriveData, boot_sector_offset + PBR->BP.E._32.BackupBootSector , 1, (void *)PBR);            
+                if (Result != STATUS_OK)
+                    break;
+            }
+        }
+        
+        
+        FatCount       = PBR->BP.NumberOfFATs;
+        StartOfFAT     = PBR->BP.ReservedSectors;
+        InfoSector     = PBR->BP.E._32.FSInfoSector;
+        }
+        
+        /*we get MediaDescriptor for step 6 usage, since we will clear MSDC_Sector*/
+        MediaDescriptor = PBR->BP.MediaDescriptor;
+        /*we need MSDC_Sector to be 512-byte-0 now*/
+        kal_mem_set(MSDC_Sector, 0, 512);
+        
+        /* HLF - 3 - Formating cont, FAT32 reserved sector write down */                
+        if ((FATType == 32) && (InfoSector > 0) && (InfoSector < StartOfFAT))
+        {
+            /* FIXME */ 
+            //DrvDirect.ZeroSector( BaseSectorNumber + InfoSector /* Start Sector Number */ ,
+            //                      1                             /* Zero Sector Count   */ );
+            Result = WriteSectors(DriveData, boot_sector_offset + InfoSector, 1, MSDC_Sector);
+            if (Result != STATUS_OK)
+                break;
+        }
+        
+        
+        if (KAL_TRUE == SD_canUseErase()) {
+
+            DCL_STATUS dclStatus = 0;
+            SD_CTRL_FLUSH_T flush;
+            
+            dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+            if (dclHandle == DCL_HANDLE_INVALID)
+                ASSERT(0);
+            
+            flush.startSector = boot_sector_offset + StartOfFAT;
+            flush.sectorNum = (FATSectors * FatCount) + RootDirSectors;
+            
+            dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_FLUSH, (DCL_CTRL_DATA_T*)&flush);
+            if (STATUS_OK != dclStatus)
+                ASSERT(0);
+            
+            DclSD_Close(dclHandle);
+        }
+        else {
+            /*	start and cloase API are only called in this section of this function, we don't called these API in other places
+            file system should help protect the single task accessing, so driver should be able to protect the integrity of this start-close pair
+            */
+            dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+            if (dclHandle == DCL_HANDLE_INVALID)
+                ASSERT(0);
+            
+            DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_START, NULL);
+            DclSD_Close(dclHandle);            
+            
+            /* HLF - 4 - Formating cont, start, FAT Table write down , remember FAT begin sector */
+            {
+            /* FIXME */ 
+            //DrvDirect.ZeroSector( BaseSectorNumber + StartOfFAT /* Start Sector Number */ ,
+            //                      FATSectors * FatCount         /* Zero Sector Count   */ );
+            #if defined(__DRV_MSDC_FAST_FORMAT__)
+            
+            Result = WriteSectors(DriveData, boot_sector_offset + StartOfFAT, FATSectors * FatCount , MSDC_Sector);
+            
+            if (Result != STATUS_OK) {
+                dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+                if (dclHandle == DCL_HANDLE_INVALID)
+                    ASSERT(0);
+                    
+                DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+                DclSD_Close(dclHandle);
+                goto highlevelformat_exit;
+            }
+            #else
+            for (i = 0; i < FATSectors * FatCount; i++) {
+                
+                Result = WriteSectors(DriveData, boot_sector_offset + StartOfFAT + i, 1 , MSDC_Sector);
+                
+                if (Result != STATUS_OK) {
+                    
+                    dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+                    if (dclHandle == DCL_HANDLE_INVALID)
+                        ASSERT(0);
+                    
+                    DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+                    DclSD_Close(dclHandle);
+                    goto highlevelformat_exit;
+                }
+            }
+            #endif
+        }
+        
+        /* HLF - 5 - Formating cont, Root directory write down */
+        {
+        
+        x = StartOfFAT + FATSectors * FatCount;
+        /* FIXME */ 
+        //DrvDirect.ZeroSector( BaseSectorNumber + x          /* Start Sector Number */ ,
+        //                      RootDirSectors                /* Zero Sector Count   */ );
+        #if defined(__DRV_MSDC_FAST_FORMAT__)
+        
+        Result = WriteSectors(DriveData, boot_sector_offset + x, RootDirSectors , MSDC_Sector);
+        
+        if (Result != STATUS_OK) {
+            
+            dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+            
+            if (dclHandle == DCL_HANDLE_INVALID)
+                ASSERT(0);
+            
+            DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+            DclSD_Close(dclHandle);
+            goto highlevelformat_exit;
+        }
+        #else
+        for (i = 0; i < RootDirSectors; i++) {
+            
+            Result = WriteSectors(DriveData, boot_sector_offset + x + i, 1 , MSDC_Sector);
+            
+            if (0 > Result) {
+                dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+                
+                if (dclHandle == DCL_HANDLE_INVALID)
+                    ASSERT(0);
+                
+                DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+                DclSD_Close(dclHandle);
+                goto highlevelformat_exit;
+            }
+        }
+        #endif
+        }
+        
+        dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);        
+        if (dclHandle == DCL_HANDLE_INVALID)
+            ASSERT(0);
+            
+        DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+        DclSD_Close(dclHandle);
+        }
+        
+        /* HLF - 6 - Formating final, 1st FAT sector must be rewritten */
+        {
+        kal_uint16 * FPtr16;
+        kal_uint8 * FPtr8;
+        switch (FATType)
+        {
+            case 32:
+            //kal_uint32 * FPtr = (void*) ScratchSector;
+            MSDC_Sector[2] = 0x0FFFFFFF; // this is for the root dir
+            MSDC_Sector[1] = 0x0FFFFFFF;
+            //break;
+            case 16:
+            FPtr16 = (void*)MSDC_Sector;
+            FPtr16[1] = 0xFFFF;
+            //break;
+            case 12:
+            FPtr8 = (void *)MSDC_Sector;
+            /* FIXME */ FPtr8[2] = 0xFF;
+            /* FIXME */ FPtr8[1] = 0xFF;
+            /* FIXME */ FPtr8[0] = MediaDescriptor;
+            break;
+            default:
+            ASSERT(0);
+            break;
+        }
+        for (i = 0, y = StartOfFAT;
+        i < FatCount;
+        i++  , y+= FATSectors)
+        {
+        ///* FIXME */ DrvDirect.WriteSector(SectorBuffer     /* Buffer */ ,
+        //                              BaseSectorNumber + y /* Sector Number */);
+            Result = WriteSectors(DriveData, boot_sector_offset + y, 1 , MSDC_Sector);
+        }
+        }
+   
+    } while (0);
+
+highlevelformat_exit: 
+    #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+    #else
+	free_MSDC_lock(&gSD->mSDdrv_lock);
+    #endif
+
+    #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+    if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_give_sem(dualMsdcArb);
+	}
+    #endif
+
+   /* HLF - 7 - The END */
+   return Result;
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+int SD_IOCtrl(void * DriveData, UINT CtrlAction, void * CtrlData)
+{
+	FS_DeviceInfo *info;
+	kal_bool on;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+//	DCL_STATUS dclStatus = 0;
+	DCL_BOOL isCardExist = DCL_FALSE;
+//	DCL_BOOL isCardInited = DCL_FALSE;
+	int status = FS_NO_ERROR;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+#endif
+	
+    #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_take_sem(dualMsdcArb, 1);			
+    }
+    #endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)	
+    	if ((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+    	{
+    		sel = SD_EXT;
+    	}
+    	else
+    	{
+#if defined(__SIM_PLUS__)
+    		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    		sel = SD_T_CARD_2;
+#endif
+    	}
+        init_MSDC_lock(&gSD_blk[0].mSDdrv_lock, "SD_DRV_LOCK");//guilin++
+        get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);	
+        
+       if(sel==SD_EXT)
+    	{
+		dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+          if (dclHandle == DCL_HANDLE_INVALID) {
+            status = FS_INVALID_OPERATION;
+             goto err_exit;
+            }
+       }
+       else
+       {
+          #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+          dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+          if (dclHandle == DCL_HANDLE_INVALID) {
+            status = FS_INVALID_OPERATION;            
+             goto err_exit;             
+            }
+          #else
+             ASSERT(0);
+          #endif
+       }
+    	DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&sel);
+#else	
+        init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");//guilin++
+        get_MSDC_lock(&gSD->mSDdrv_lock);
+		dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+		if (dclHandle == DCL_HANDLE_INVALID) {
+            status = FS_INVALID_OPERATION;		    
+             goto err_exit;			
+            }
+#endif			
+
+	switch (CtrlAction)
+	{
+	case FS_IOCTRL_QUERY_CARD_INFO:
+		info = CtrlData;
+		/*
+			1. If memory card is inserted, set flag FS_DEVICE_FLAG_PRESENT   in   info->DeviceInfo.Card.Flag
+			2. If memory card is NOT inserted, clear flag FS_DEVICE_FLAG_PRESENT   in   info->DeviceInfo.Card.Flag
+		*/
+
+		DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+		if (isCardExist){
+			info->DeviceInfo.Card.Flag |= FS_DEVICE_FLAG_PRESENT;
+			info->DeviceInfo.Card.PSN = gSD->mCID.psn;
+		    //
+		    // bus_width = 5, -> 4bit
+		    // bus_width = 1, -> 1bit
+		    //
+		    #if defined(MSDC_SD_BITS4_BUS)
+		    info->DeviceInfo.Card.SerialMode = KAL_FALSE;
+		    #else
+		    info->DeviceInfo.Card.SerialMode = KAL_TRUE;
+		    #endif
+		}
+		else{
+			info->DeviceInfo.Card.Flag &= ~FS_DEVICE_FLAG_PRESENT;
+			info->DeviceInfo.Card.PSN = 0;
+			info->DeviceInfo.Card.SerialMode = KAL_TRUE;
+		}
+		break;
+			
+	case FS_IOCTRL_CONTROL_DEV_POWER:
+	    on = *(kal_bool*)CtrlData;
+
+	    if(gMSDC_Handle->msdc_custom_handle.PowerCtrl)
+		    gMSDC_Handle->msdc_custom_handle.PowerCtrl(on);
+	    break;
+
+	default:
+        status = FS_UNSUPPORTED_DRIVER_FUNCTION;          
+         goto err_exit;         
+		//ASSERT(0);
+		//break;
+	}
+
+err_exit:	
+	DclSD_Close(dclHandle);
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+    free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+    free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)    
+	
+	if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+	{
+		kal_give_sem(dualMsdcArb);
+	}
+#endif
+    
+    return status;	    
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+FS_Driver FS_SdDrv = {
+   MountDevice_NEW,
+   ShutDown,
+   ReadSectors_NEW,
+   WriteSectors_NEW,
+   MediaChanged,
+   DiscardSectors,
+   GetDiskGeometry,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   highlevelformat,
+   NULL,
+   MSDC_GetCardStatus,
+   NULL,
+   NULL,
+   NULL,
+   SD_IOCtrl//ioctrl
+};
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+
+kal_uint8 CommandTag[32] = 
+{
+	0x2A, 0x4D, 0x4D, 0x43, 0x2A, 0x4D, 0x45, 0x4D, 0x4F, 0x52, 0x59, 0x2A, 0x49, 0x4F, 0x2A, 0x43,
+	0x4F, 0x53, 0x2A, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44, 0x2A, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+
+static const kal_uint8 RETRY_TAG[3] = 
+{
+	0x00, 0x01, 0x60
+};
+
+extern FS_Driver FS_SdDrv;
+
+
+CAS_CMD_STA CAS_CMD(kal_uint8 *txBuffer, kal_uint32 txSize, kal_uint8 *rxBuffer, kal_uint32 *rxSize)
+{
+	kal_uint16 sizeTotal;
+	kal_uint32	txBlockNum, rxBlockNum;
+	kal_bool	receiveDone;
+	CAS_CMD_STA status = CAS_CMD_NO_ERROR;
+	kal_uint32	retryTimes = 0, reWriteTimes = 0;
+	int retValue;
+
+
+	if(1 > (*rxSize) || 1 > txSize)
+		ASSERT(0);
+
+	if(KAL_FALSE == gMSDC_Handle->mIsPresent){
+		status = CAS_CMD_NOT_EXIST;
+		goto exit;
+	}
+
+	if(KAL_FALSE == isFullCard)
+		return CAS_CMD_NOT_CAS_CARD;
+
+	if((KAL_TRUE == gMSDC_Handle->mIsPresent) && (KAL_FALSE == gMSDC_Handle->mIsInitialized)){
+		status = CAS_CMD_EXIST_NOT_READY;
+		goto exit;
+	}
+
+	if(3 < (txSize/512))
+		txBlockNum = 16;
+	else
+		txBlockNum = 4;
+
+	rxBlockNum = 1 + (((*rxSize) -1)/512) ;
+
+	memcpy(txBuffer, CommandTag, 32);
+	txBuffer[32] = (kal_uint8)(txSize >> 8);
+	txBuffer[33] = (kal_uint8)(txSize);
+			
+retry:
+	retValue = FS_SdDrv.WriteSectors((void *)M_CAM_CAS_HANDLE, M_CAM_CAS_BLOCK, txBlockNum, txBuffer);
+
+	if((FS_NO_ERROR != retValue) && (KAL_FALSE == gMSDC_Handle->mIsPresent)){
+		status = CAS_CMD_NOT_EXIST;
+		goto exit;
+	}
+
+	if (FS_NO_ERROR != retValue) 
+	{
+		tst_sys_trace("CAS write failed\r\n");
+		status = CAS_CMD_WRITE_FAIL;
+		goto exit;
+	}
+
+
+	/*from M-CAM's spec, we should wait 15ms before the read command*/
+	kal_sleep_task(4);
+
+	receiveDone = KAL_FALSE;
+	while(KAL_FALSE == receiveDone){
+
+		retValue = FS_SdDrv.ReadSectors((void *)M_CAM_CAS_HANDLE, M_CAM_CAS_BLOCK, rxBlockNum, rxBuffer);
+
+		if (FS_NO_ERROR != retValue) 
+		{
+			tst_sys_trace("CAS read failed\r\n");
+			status = CAS_CMD_READ_FAIL;
+			break;
+		}
+		
+
+		// check header
+		if (kal_mem_cmp(rxBuffer, CommandTag, 32) != 0) 
+		{
+			reWriteTimes++;
+			if(2 > reWriteTimes){
+				tst_sys_trace("read: not correct header, retry\r\n");
+				goto retry;
+			}
+
+			tst_sys_trace("read: not correct header\r\n");
+			status = CAS_CMD_NOT_CAS_CARD;
+			break;
+		}
+
+		// 0x00 01 60
+		if (kal_mem_cmp(rxBuffer + 32, RETRY_TAG, 3) == 0) 
+		{
+			tst_sys_trace("card is busy");
+			
+			if(134 < retryTimes){/*according to M-CAM's spec, it maybe busy for 2 seconds*/
+				tst_sys_trace("busy timeout");
+				status= CAS_CMD_BUSY_TIMEOUT;
+				break;
+			}
+
+			kal_sleep_task(4);
+			retryTimes++;
+			continue;
+		}
+		else
+		{
+			*rxSize = (rxBuffer[32]<<8) |rxBuffer[33];
+			status = CAS_CMD_NO_ERROR;
+			receiveDone = KAL_TRUE;
+			break;
+		}
+	}
+	
+exit:
+	
+	return status;
+}
+#endif //__CMMB_CAS_FULL_CARD_SUPPORT__
+
+#endif // (__MSDC_SD_MMC__)
+
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "fs_gprot.h"
+#include "qmu_bm.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+*/
+//RHR
+/*following is dummy API*/
+
+
+static int  MountDevice_NEW(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags){}
+static int  ShutDown(void * DriveData){}
+static int  ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer){}
+static int  WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer){}
+static int  MediaChanged(void * DriveData){}
+static int  DiscardSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors){}
+static int  GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor){}
+int highlevelformat(void * DriveData, kal_uint32 BaseSectorNumber){}
+int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors,qbm_gpd *head,qbm_gpd *tail){}
+int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, qbm_gpd *head,qbm_gpd *tail){}
+kal_uint32 Get_BDStructNum(void){}
+
+
+extern int MSDC_GetCardStatus(void * DriveData, int AckType);
+
+FS_Driver FS_SdDrv = {
+   MountDevice_NEW,
+   ShutDown,
+   ReadSectors_NEW,
+   WriteSectors_NEW,
+   MediaChanged,
+   DiscardSectors,
+   GetDiskGeometry,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   highlevelformat,
+   NULL,
+   MSDC_GetCardStatus   
+};
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sd_drv2.c b/mcu/driver/storage/mc/src/sd_drv2.c
new file mode 100644
index 0000000..275b98a
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_drv2.c
@@ -0,0 +1,421 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sd_drv2.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Adaption driver of file system for SD card for MSDC_2
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_internal_api.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#endif
+#include "init.h"
+*/
+//RHR
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "intrCtrl.h"
+#include "cache_sw.h"    //doublelo add
+#if defined(__MSDC2_SD_MMC__)
+
+#define SECTOR_SIZE 512	
+#define MSDC_MEDIA_DESCRIPTOR		0xF8
+#define SD_MAX_RETRY	2
+extern MSDC_HANDLE *msdc2_handle;
+extern T_SDC_HANDLE	*gSD2;
+
+static int  ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer);
+static int  WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer);
+static kal_uint32 sd_r,sd_w;
+
+static int  DiscardSectors(void * DriveData, DWORD Sector, UINT Sectors)
+{
+   return FS_NO_ERROR;
+}
+
+static int  ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
+{
+	
+	SDC_CMD_STATUS status;
+	kal_uint8 retry = 0;
+	kal_uint32 adrs;
+	MSDC_HANDLE *msdc = (MSDC_HANDLE *)DriveData ;
+	
+#ifdef MSDC_CACHED_SUPPORT
+	/*tell buffer type each time this function called*/
+	if (INT_QueryIsCachedRAM(Buffer, Sectors * SECTOR_SIZE)){
+		msdc2_handle->isCachedBuf = KAL_TRUE;
+	}
+	else
+		msdc2_handle->isCachedBuf = KAL_FALSE;
+#endif
+	
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)	
+	if(gSD2->flags & SD_FLAG_HCS_SUPPORT)
+		adrs = Sector;
+	else
+#endif		
+	adrs = Sector * SECTOR_SIZE;
+	msdc2_handle->timeout_count = 0;
+start:
+	if(!msdc2_handle->mIsInitialized)
+	{
+		//dbg_print("Read but not Initialized \r\n");
+		MSDC_PDNControl2(KAL_TRUE);
+		return FS_MSDC_READ_SECTOR_ERROR;
+	}
+	retry ++;
+	MSDC_PDNControl2(KAL_FALSE);
+	if(Sectors > 1)
+		status = SD_ReadMultiBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors);
+	else
+		status = SD_ReadSingleBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer);
+	if(status != NO_ERROR )
+	{		
+		sd_r++;
+		if(kal_query_systemInit()== KAL_TRUE)
+		{
+			MSDC_PDNControl2(KAL_TRUE);
+			return FS_MSDC_READ_SECTOR_ERROR;
+		}		
+		//dbg_print("read retry:%d,status:%d,total %d\r\n",retry,status,sd_r);
+		if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR)
+			msdc2_handle->timeout_count++;
+		if(msdc2_handle->timeout_count++ == 3 && msdc2_handle->mIsPresent == KAL_TRUE)
+		{
+			tst_sys_trace("[MSDC]:re-mount(read fail)");
+			msdc2_handle->mIsInitialized = KAL_FALSE;
+			retry = 0;
+			if(SD_Initialize_2() != NO_ERROR)
+			{
+				MSDC_PDNControl2(KAL_TRUE);
+				return FS_MSDC_READ_SECTOR_ERROR;
+			}
+		}
+		if(retry >= SD_MAX_RETRY)
+		{
+			MSDC_PDNControl2(KAL_TRUE);
+			return FS_MSDC_READ_SECTOR_ERROR;
+		}
+		else
+		{
+			// kal_prompt_trace(MOD_AUD,"CRC etry:%d,status:%d",retry,status);
+			goto start;			
+		}
+	}
+	MSDC_PDNControl2(KAL_TRUE);
+   return FS_NO_ERROR;
+}
+
+static int  WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
+{
+	SDC_CMD_STATUS status;
+	kal_uint8 retry = 0;
+	kal_uint32 adrs;
+		
+#ifdef MSDC_CACHED_SUPPORT
+	/*tell buffer type each time this function called*/
+	if (INT_QueryIsCachedRAM(Buffer, Sectors * SECTOR_SIZE)){
+		msdc2_handle->isCachedBuf = KAL_TRUE;
+
+	}
+	else
+		msdc2_handle->isCachedBuf = KAL_FALSE;
+#endif
+		
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)	
+		if(gSD2->flags & SD_FLAG_HCS_SUPPORT)
+			adrs = Sector;
+		else
+#endif		
+		adrs = Sector * SECTOR_SIZE;	
+	msdc2_handle->timeout_count = 0;	
+start:
+	if(!msdc2_handle->mIsInitialized)
+	{
+		//dbg_print("Write but not Initialized \r\n");
+		MSDC_PDNControl2(KAL_TRUE);
+		return FS_MSDC_WRITE_SECTOR_ERROR;
+	}
+	retry++;
+	MSDC_PDNControl2(KAL_FALSE);
+	if(Sectors > 1)
+	{
+		if(msdc2_handle->mMSDC_type == SD_CARD)
+			SD_SetPreEraseBlk_2(Sectors);		
+		status = SD_WriteMultiBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors);
+	}
+	else
+		status = SD_WriteSingleBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer);	
+	if(status != NO_ERROR)
+	{
+		sd_w++;		
+		if(kal_query_systemInit()== KAL_TRUE)
+		{
+			MSDC_PDNControl2(KAL_TRUE);
+			return FS_MSDC_WRITE_SECTOR_ERROR;
+		}
+		if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR)
+			msdc2_handle->timeout_count++;
+		if(msdc2_handle->timeout_count++ == 3 && msdc2_handle->mIsPresent == KAL_TRUE)
+		{
+			tst_sys_trace("[MSDC]:SD re-mount (write fail)");
+			msdc2_handle->mIsInitialized = KAL_FALSE;
+			retry = 0;
+			if(SD_Initialize_2() != NO_ERROR)
+			{
+				MSDC_PDNControl2(KAL_TRUE);
+				return FS_MSDC_WRITE_SECTOR_ERROR;
+			}
+		}		
+		if(retry >= SD_MAX_RETRY)
+		{
+			MSDC_PDNControl2(KAL_TRUE);
+			return FS_MSDC_WRITE_SECTOR_ERROR;
+		}
+		else
+		{
+			// kal_prompt_trace(MOD_AUD,"CRC write Error retry %d",retry);
+			goto start;			
+		}
+	}
+	MSDC_PDNControl2(KAL_TRUE);
+   return FS_NO_ERROR;
+}
+
+static int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
+{	
+	kal_uint8 retry = 0;
+	
+	if(msdc2_handle->mIsInitialized)
+		return SECTOR_SIZE;
+	msdc2_handle->is_init_timeout = KAL_FALSE;		
+start:		
+	if(!msdc2_handle->mIsPresent)
+	{		
+		//dbg_print("not present \r\n");
+		
+		#if defined(_NAND_FLASH_BOOTING_)
+		// add the following code for solving plug in or out the SD card during 
+		// NFB loading process. The card detection interruptwill disapperared 		 
+		// while interrupt controller is masked.
+		IRQMask(IRQ_MSDC2_CODE);
+		if(MSDC_Reg(MSDC_PS) & MSDC_PS_PIN0)
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+			else
+				msdc2_handle->mIsPresent = KAL_TRUE;	
+		}
+		else
+		{
+			if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+				msdc2_handle->mIsPresent = KAL_TRUE;
+			else
+				msdc2_handle->mIsPresent = KAL_FALSE;	
+		}
+		IRQUnmask(IRQ_MSDC2_CODE);
+		#endif // _NAND_FLASH_BOOTING_
+		
+		if(!msdc2_handle->mIsPresent)	
+		{
+			MSDC_PDNControl2(KAL_TRUE);			
+			return FS_MSDC_MOUNT_ERROR;
+		}
+	}
+	MSDC_PDNControl2(KAL_FALSE);
+	if(SD_Initialize_2() != NO_ERROR)
+	{		
+		goto err_exit;
+	}	
+	//if(SD_MountDevice(DeviceType) != FS_NO_ERROR)
+		//return FS_MSDC_MOUNT_ERROR;
+
+	//dbg_print("Mount success! \r\n");
+	MSDC_PDNControl2(KAL_TRUE);
+   return SECTOR_SIZE;
+   
+err_exit:
+	if(retry++ <= SD_MAX_RETRY && msdc2_handle->is_init_timeout == KAL_FALSE)
+	{
+		//dbg_print("SD MountDevice failed! retry: %d \r\n",retry);
+		goto start;
+	}
+	#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+	msdc2_handle->mIsPresent = KAL_FALSE;
+	#endif		
+	MSDC_PDNControl2(KAL_TRUE);
+	return FS_MSDC_MOUNT_ERROR;
+	
+}
+static int  MediaChanged(void * DriveData)
+{		
+	if(msdc2_handle->mIsPresent)
+	{
+		if(msdc2_handle->mIsInitialized)
+		{
+   		return FS_NO_ERROR;
+		}
+		else
+		{
+			return FS_MSDC_PRESNET_NOT_READY;
+		}
+	}
+	return FS_MSDC_NOT_PRESENT;
+}
+
+/*-----------------------------------*/
+static int  GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{	
+   kal_mem_set((void*)DiskGeometry, 0, sizeof * DiskGeometry);
+   DiskGeometry->Sectors = gSD2->mCSD.capacity/512;
+	*MediaDescriptor = MSDC_MEDIA_DESCRIPTOR;
+	if(gSD2->mWPEnabled)
+		return FS_WRITE_PROTECTION;		
+   return FS_NO_ERROR;
+}
+
+/*-----------------------------------*/
+static int  ShutDown(void * DriveData)
+{
+#ifdef  __TST_WRITE_TO_FILE_ONLY__
+	/*error recording: write error log to memory card here*/
+	MSDC_ErrorRecordingReset();
+#endif
+   return FS_NO_ERROR;
+}
+
+FS_Driver FS_SdDrv2 = {
+   MountDevice,
+   ShutDown,
+   ReadSectors,
+   WriteSectors,
+   MediaChanged,
+   DiscardSectors,
+   GetDiskGeometry,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   MSDC_GetCardStatus2
+};
+#endif // (__MSDC_SD_MMC__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdio_drv.c b/mcu/driver/storage/mc/src/sdio_drv.c
new file mode 100644
index 0000000..b64c066
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdio_drv.c
@@ -0,0 +1,3460 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sdio_drv.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   driver of for SDIO card
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/#include "drv_features.h"
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"  
+#include "reg_base.h"
+#include "msdc_reg_adap.h"
+//#include "app_buff_alloc.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+#include "intrCtrl.h"  
+#include "sdio_sw.h"
+#include "cache_sw.h"
+#include "init.h"
+#include "dma_hw.h"
+#include "drv_trc.h"
+#include "kal_debug.h"
+/*RHR*/
+#include "drvpdn.h"
+/*RHR*/
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1		CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM	CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET1
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR	CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET	CG_SET0
+#endif
+
+#endif
+
+ 
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+
+#if defined(DRV_MSDC_MT6225_SERIES)
+#define DRV_MSDC_DATA_LATCH_TIMING
+#endif 
+
+#pragma arm section zidata = "NONCACHEDZI",  rwdata = "NONCACHEDRW"  // doublelo modify for DMA non-cached issue
+ kal_uint32 sdio_uncachedU32;
+ kal_uint32 mcudma_flag=128;// mcu:<128byte ; dma:>=128byte
+ kal_uint32 forcemcu=0; // 1:forcemcu
+#pragma arm section zidata, rwdata
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+SDC_CMD_STATUS SDIO_Initialize(void);
+void SDIO_get_CCCR(kal_uint8 *buf, kal_uint32 bufLen);
+void SDIO_get_FBR(kal_uint8 *buf, kal_uint32 bufLen);
+
+SDIODriver_t sdio_driver_MTK1 = {
+	(DCL_SDIO_REG_WR)SDIO_Register_Write,
+	(DCL_SDIO_REG_WR_ISR)SDIO_Register_Write_isr,
+	(DCL_SDIO_DATA_WR)SDIO_Data_Write,
+	(DCL_SDIO_REG_RD)SDIO_Register_Read,
+	(DCL_SDIO_DATA_RD)SDIO_Data_Read,
+	(DCL_SDIO_CHECK_INTR)SDIO_check_IO_Int,
+	(DCL_SDIO_ENABLE_INTR)SDIO_enable_IO_Int,
+	(DCL_SDIO_INIT)SDIO_Initialize,
+	(DCL_SDIO_ABORT)SDIO_abort_IO,
+	(DCL_SDIO_SW_RST)SDIO_SW_reset,
+	(DCL_SDIO_QRY_BLOCK_SIZE)SDIO_query_BLK_size,
+    (DCL_SDIO_SET_BLOCK_SIZE)SDIO_configure_BLK_size,
+    (DCL_SDIO_GET_BLOCK_SIZE)SDIO_get_BLK_size,
+	(DCL_SDIO_ENABLE_IO)SDIO_enable_IO,
+	(DCL_SDIO_SET_BUS_WIDTH)SDIO_configure_bus,
+	(DCL_SDIO_GET_CCCR)SDIO_get_CCCR,
+	(DCL_SDIO_GET_FBR)SDIO_get_FBR,
+    (DCL_SDIO_CMD52_READ )SDIO_cmd52_read,
+    (DCL_SDIO_CMD52_WRITE)SDIO_cmd52_write,
+    (DCL_SDIO_CMD52_WRITE_READ)SDIO_cmd52_write_read,
+    (DCL_SDIO_CMD53_READ )SDIO_cmd53_read,
+    (DCL_SDIO_CMD53_WRITE)SDIO_cmd53_write,
+	(DCL_SDIO_int_registration)SDIO_int_registration,
+    (DCL_SDIO_MCUDMA_READ)SDIO_mcudma_read,
+    (DCL_SDIO_MCUDMA_WRITE)SDIO_mcudma_write,
+        (DCL_SDIO_CLKPADRED_READ)SDIO_clkpadred_read,
+        (DCL_SDIO_CLKPADRED_WRITE)SDIO_clkpadred_write,
+        (DCL_SDIO_FORCEMCU_READ)SDIO_forcemcu_read,
+        (DCL_SDIO_FORCEMCU_WRITE)SDIO_forcemcu_write,
+        (DCL_SDIO_GETCLK)SDIO_getclk,
+        (DCL_SDIO_SETCLK)SDIO_setclk
+};
+#endif
+__align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+__align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+__align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+sdio_dcb_struct gSDIO;
+kal_mutexid sdio_mutex; 
+
+void sdio_dummyFunction(void)
+{
+	/*this function is to make source insight more visible since the usage of "__align" is out of the capability of source insight's parser*/
+}
+DCL_SDC_CMD_STATUS SDIO_cmd52_write_read_func(rw_dir_enum rwcmd, kal_bool rawcmd, DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{
+    SDC_CMD_STATUS status;
+    cmd52_config_struct cmd52;
+   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    cmd52.rw = rwcmd;
+    cmd52.func = function;
+    cmd52.raw = rawcmd;
+    cmd52.stop = KAL_FALSE;
+    cmd52.adrs = addr;
+    cmd52.data = wdata;
+    status = SDIO_Cmd52(&cmd52);
+    if(r5resp)
+        *r5resp = gSDIO.resp;
+    if(rdata)
+        *rdata = cmd52.data;
+    SDIO_resume_IO(SDIO_FUCN_0); 
+    return status;
+}
+DCL_SDC_CMD_STATUS SDIO_cmd52_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{   
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+    return SDIO_cmd52_write_read_func(SDIO_READ,KAL_FALSE,function,addr,0,rdata,r5resp);
+#endif
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd52_write(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+    return SDIO_cmd52_write_read_func(SDIO_WRITE,KAL_FALSE,function,addr,wdata,0,r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_cmd52_write_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+    return SDIO_cmd52_write_read_func(SDIO_WRITE,KAL_TRUE,function,addr,wdata,rdata,r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_read_write_func(rw_dir_enum rwcmd, DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+    SDC_CMD_STATUS status;
+    cmd53_config_struct cmd53;
+
+    SDIO_dispatch_IO(function);
+    cmd53.rw = rwcmd;
+    cmd53.func = function;
+    cmd53.block = block;
+    cmd53.buffer = data;
+    cmd53.count = count;
+    cmd53.op = op;
+    cmd53.adrs = (kal_uint32)addr;
+    status = SDIO_Cmd53(&cmd53);
+    if(r5resp)
+        *r5resp = gSDIO.resp;
+    SDIO_resume_IO(function);
+    return status;            
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+    return SDIO_cmd53_read_write_func(SDIO_READ, function, addr, data, op, count, block, r5resp);
+#endif
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_write(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+    return SDIO_cmd53_read_write_func(SDIO_WRITE, function, addr, data, op, count, block, r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_mcudma_read(DCL_UINT32 *rdata)
+{   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    *rdata = mcudma_flag;
+    SDIO_resume_IO(SDIO_FUCN_0);
+    return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_mcudma_write(DCL_UINT32 wdata)
+{
+    SDC_CMD_STATUS status=NO_ERROR;
+   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    mcudma_flag = wdata;
+    SDIO_resume_IO(SDIO_FUCN_0); 
+    return status;
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_clkpadred_read(DCL_UINT32 *rdata)
+{   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    *rdata = 1&(MSDC_Reg32(MSDC_CLKACB_CFG)>>7);
+    SDIO_resume_IO(SDIO_FUCN_0);
+    return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_clkpadred_write(DCL_UINT32 wdata)
+{
+    SDC_CMD_STATUS status=NO_ERROR;
+   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    if(wdata & 1)
+    {
+        MSDC_SetBits32(MSDC_CLKACB_CFG, MSDC_CLKACB_CFG_CLKPAD_RED);
+    }
+    else
+    {
+        MSDC_ClearBits32(MSDC_CLKACB_CFG, MSDC_CLKACB_CFG_CLKPAD_RED);
+    }
+    SDIO_resume_IO(SDIO_FUCN_0); 
+    return status;
+}
+
+DCL_SDC_CMD_STATUS SDIO_forcemcu_read(DCL_UINT32 *rdata)
+{   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    *rdata = forcemcu;
+    SDIO_resume_IO(SDIO_FUCN_0);
+    return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_forcemcu_write(DCL_UINT32 wdata)
+{
+    SDC_CMD_STATUS status=NO_ERROR;
+   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    forcemcu = wdata;
+    SDIO_resume_IO(SDIO_FUCN_0); 
+    return status;
+}
+
+DCL_SDC_CMD_STATUS SDIO_getclk(DCL_UINT32 *rdata)
+{   
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    *rdata = gMSDC_Handle->op_clock ;
+    SDIO_resume_IO(SDIO_FUCN_0);
+    return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_setclk(DCL_UINT32 wdata)//KHZ
+{
+	msdc_clk_setting cs,cs2;
+	DCL_UINT32 temp1,temp2;
+	SDC_CMD_STATUS status=ERR_ERRORS;
+
+    SDIO_dispatch_IO(SDIO_FUCN_0);
+    temp1=0;temp2=0x0fffffff;
+    cs2.cardClk = 0;
+	for (cs.sclkf = 0; cs.sclkf < MSDC_SCLKF_NUM; cs.sclkf ++)
+	{
+		for (cs.clksrc = 0; cs.clksrc < MSDC_CLKSRC_NUM; cs.clksrc ++)
+		{
+			cs.cardClk = gMsdcClksrcRate[cs.clksrc] / DIV_SCLKF(cs.sclkf);
+			if(wdata >= cs.cardClk)
+			{
+    			temp1 = wdata - cs.cardClk;
+    			if (temp1 <= temp2)
+    			{
+                    temp2 = temp1;
+                    cs2.cardClk = cs.cardClk;
+                    cs2.clksrc = cs.clksrc;
+                    cs2.sclkf = cs.sclkf;
+                    if(temp1 == 0)
+                        goto SDIO_setclk_return;
+    			}
+			}
+		}
+	}
+
+SDIO_setclk_return:
+    if(cs2.cardClk)
+    {
+        MSDC_LSD_ClearBits32(SDC_CFG,SDC_CFG_SIEN);
+    	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)cs2.sclkf,MSDC_CFG_SCLKF);
+    	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)cs2.clksrc,MSDC_CFG_CLKSRC);
+    	MSDC_LSD_SetBits32(SDC_CFG,SDC_CFG_SIEN);
+    	gMSDC_Handle->op_clock = cs2.cardClk;
+    	status = NO_ERROR;
+    }
+    SDIO_resume_IO(SDIO_FUCN_0);
+    return status;
+}
+
+
+#ifdef __MSDC_CD_EINT__
+void SDIO_EINT_Registration()
+{
+    cardDetectionEINTPolarity = KAL_TRUE; // default pull high
+    MSDC_debounceTime = 30;
+
+    EINT_Mask(MSDC_EINT_NO);
+    EINT_Registration(MSDC_EINT_NO, KAL_TRUE, cardDetectionEINTPolarity, SDIO_HISR_Entry, KAL_TRUE); //PMU_CHR_EINT_PIN=8
+    EINT_SW_Debounce_Modify(MSDC_EINT_NO, MSDC_debounceTime);    // 32768Hz
+    EINT_UnMask(MSDC_EINT_NO);
+
+}
+#endif
+/*************************************************************************
+* FUNCTION
+*  SDIO_Initialize
+*
+* DESCRIPTION
+*	SDIO Intialization function
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	
+*************************************************************************/
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+SDC_CMD_STATUS SDIO_Initialize(void)
+{	
+	kal_uint16 rca;
+   #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+	kal_uint16 iocon;
+   #else
+	kal_uint32 iocon;
+   #endif
+	SDC_CMD_STATUS status;
+	kal_uint32 flags;	
+	kal_uint32 retry_count = 0;
+	kal_uint32 count=0;	   
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+    MSDC_PDNControl(KAL_FALSE);//guilin
+	TurnOnMSDC();	
+	#ifdef MSDC_INT
+	kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,
+			(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ|EVENT_PINIRQ),
+			KAL_OR_CONSUME,&flags,KAL_NO_SUSPEND);
+	#else
+	/*check if the card is present*/
+	if(MSDC_Reg(MSDC_PS) & MSDC_PS_PIN0)
+	{  /*card not present (1)*/
+		gMSDC_Handle->mIsPresent = KAL_FALSE;
+	}
+	else
+	{  /*card present (0)*/
+		gMSDC_Handle->mIsPresent = KAL_TRUE;
+	}
+	#endif
+#ifdef __MSDC_NOT_SUPPORT_HOT_PLUG__
+    gMSDC_Handle->mIsPresent = KAL_TRUE;
+#endif
+   /*create mutex*/
+   sdio_mutex = kal_create_mutex("MutexSDIO");
+
+	/* reset msdc*/
+	RESET_MSDC();//MSDC_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+   /*Driving current*/
+	//MSDC_WriteReg32(MSDC_IOCON,0xC3);
+	//MSDC_WriteReg32(MSDC_IOCON,0xdb);
+
+   /* set the output driving capability from customization interface*/
+   #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+	MSDC_SetData(MSDC_IOCON, 0xff, MSDC_GetIOCtrlParam());
+   #else /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+	iocon = 0;
+	iocon |= MSDC_GetIOCtrlParam();
+	 #ifdef MCU_208M
+	    iocon |= 0x08000000;
+   #elif defined(MCU_78M)
+      iocon |= 0x04000000;
+   #elif defined(MCU_52M)
+      iocon |= 0x02000000;
+   #endif
+
+	MSDC_SetData32(MSDC_IOCON, 0xff0000ff, iocon);
+   
+   #if defined(MCU_52M)
+   	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)1, MSDC_CFG_CRED);
+   #endif
+   #endif /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+#if !defined(DRV_MSDC_REG_V3) // guilin
+	/*set pull up in CMD/DAT line configuration*/	
+	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG1);
+	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG2);
+#endif // guilin
+	/*set write timeout=(40+1)*65536*(1/serial clock)*/
+	BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)255,SDC_CFG_DTOC);	
+	/*set write timeout=(40+1)*65536*(1/serial clock)*/
+	BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)15,SDC_CFG_WDOD);		
+
+ 	/* disable 4-bit*/
+	MSDC_ClearBits32(SDC_CFG,SDC_CFG_MDLEN);	   		
+	/* enable serila clock 104/8=13MHz*/	
+	//BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);			
+	/* enable serila clock 104/255*4=100KHz*/	
+	//MSDC_Reg32(MSDC_CFG)|= 0x8; 
+	MSDC_ClearBits32(SDC_CFG,SDC_CFG_SIEN);
+	#ifdef MCU_208M
+		BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)32,MSDC_CFG_SCLKF);	
+	#else
+	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)32,MSDC_CFG_SCLKF);		
+	#endif
+
+	gMSDC_Handle->msdc_clock = MSDC_CLOCK;
+	MSDC_SetClock(MSDC_INI_CLOCK);
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+	MSDC_SetIOCONRegDLT();
+#endif	
+	MSDC_SetBits32(SDC_CFG,SDC_CFG_SIEN);
+	/* config the sdio controller*/
+	/* enable SDIO mode*/
+	MSDC_SetBits32(SDC_CFG, SDC_CFG_SDIO);
+	/* enable 74 SD clk by s/w */
+	 MSDC_SetBits32(MSDC_CFG, 0x80);
+	/* enable SDIO interrupt*/
+	MSDC_WriteReg32(SDIO_CFG, 1); 		
+	{
+		kal_uint32 i;
+		for(i=0;i<100000;i++);
+	}	
+	
+	/* stop SD clk by s/w */
+	 MSDC_ClearBits32(MSDC_CFG, 0x80);
+
+	/*SDIO initialization CMD*/
+   status = SDIO_Cmd5(0);
+	SDIO_STATUS_CHECK;
+   #ifdef _SDIO_DEBUG_
+	dbg_print("write CMD5(0) %d\r\n", status);						
+	dbg_print("card OCR %d\r\n", gSDIO.ocr);						
+	#endif
+	do 
+	{	
+	   retry_count++;
+	   if(gSDIO.ocr & 0x8000)
+	   {					      
+	   	if((status = SDIO_Cmd5(0x8000))!=NO_ERROR)	   	
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card deny OCR \r\n");													   	
+	   		#endif
+	   		
+	   	}	
+	   	else	   				
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card accept OCR \r\n");							   		
+	   	#endif	
+	   	}	
+	   	
+	   	gSDIO.ocr_valid = KAL_TRUE;	
+	   }
+	   else 
+	   {	   
+	      #ifdef _SDIO_DEBUG_
+	      dbg_print("card not match OCR \r\n");												  
+	      dbg_print("uses card's OCR \r\n");												  
+	      #endif												  
+	      if((status = SDIO_Cmd5(gSDIO.ocr))!=NO_ERROR)	   	
+	      {
+	         #ifdef _SDIO_DEBUG_
+	   		dbg_print("card deny OCR \r\n");													   			   			   	
+	   		#endif	
+	   	}	
+	   	else	   	
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card accept OCR \r\n");							   	
+	   		#endif	
+	   	}	
+	   	
+	   	gSDIO.ocr_valid = KAL_TRUE;	
+	   }
+	   if(retry_count>=100)
+	      goto err;
+	}while(gSDIO.io_ready!=KAL_TRUE);	
+	MSDC_ClearBits32(SDC_CFG,SDC_CFG_SIEN);			
+	#ifdef MCU_208M
+	 BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)4,MSDC_CFG_SCLKF);		  
+	#elif defined(MCU_78M)   
+   BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);		   	
+   #else
+   BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY4,MSDC_CFG_SCLKF);		   	
+   #endif   /*MCU_208M*/
+
+   BitFieldWrite32((kal_uint32*)MSDC_CFG,1,MSDC_CFG_CLKSRC);		   	
+   BitFieldWrite32((kal_uint32*)MSDC_CFG,1,MSDC_CFG_SCLKF);		   	
+	SD_Use24M_Clock();
+	//SD_Use45M_Clock();
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+	MSDC_SetIOCONRegDLT();
+#endif				
+				
+	MSDC_SetBits32(SDC_CFG,SDC_CFG_SIEN);   
+	status = SD_ValidateRCA(&rca);
+	SDIO_STATUS_CHECK;
+	#ifdef _SDIO_DEBUG_
+	dbg_print("CMD7 select card \r\n");								
+	dbg_print("CMD3 request RCA \r\n");
+	#endif
+	
+	status = SD_SelectCard(rca);
+	SDIO_STATUS_CHECK;
+	
+	/* get parameters*/
+	/*read CCCR, FBR, CIS tuple*/	
+	status=SDIO_read_CCCR();
+	SDIO_STATUS_CHECK;
+   status=SDIO_read_capacity();   
+   SDIO_STATUS_CHECK;
+   status=SDIO_read_power_control();
+   SDIO_STATUS_CHECK;
+	
+	#if 1/*support 4-bits*/
+	/*enable multiple block interrupt */
+	if(!(SDIO_support_LSC()))	
+	{	
+#ifndef DRV_MSDC_USING_2ND
+	   if(SDIO_support_S4MI()){
+	      status=SDIO_enable_E4MI(KAL_TRUE);   
+	   	SDIO_STATUS_CHECK;
+	   }
+
+       if(gMSDC_Handle->trySingleLine == KAL_FALSE) //guilin
+    	   status=SDIO_configure_bus(BIT_4W);	   
+	   else
+           status=SDIO_configure_bus(BIT_1W);      
+	   SDIO_STATUS_CHECK;
+
+	   /* enable serila clock 104/8=13MHz*/	
+	   //BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);    	   
+#else
+		 //MSDC2 only support 1-bit Mode
+		 status=SDIO_configure_bus(BIT_1W);
+		SDIO_STATUS_CHECK;
+#endif	      
+	}
+	else/*low speed card*/
+	{
+#ifndef DRV_MSDC_USING_2ND		
+	   if(SDIO_support_4BLS()){
+	      status=SDIO_configure_bus(BIT_4W);	      
+	      SDIO_STATUS_CHECK;
+	   }
+#else
+		//MSDC2 only support 1-bit Mode
+#endif	      
+	}    
+	#else
+/* under construction !*/
+	#endif  
+	status=SDIO_read_CIS(SDIO_FUCN_0);
+	SDIO_STATUS_CHECK;
+   /*enable I/O function*/
+	for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+	{	   
+	   kal_uint32 retry=0;
+	   kal_bool ready;
+	   for(retry=0;retry<100;retry++) 
+	   {
+	      status=SDIO_enable_IO(count, KAL_TRUE);
+	      SDIO_STATUS_CHECK;
+	      status = SDIO_check_IO_ready(count, &ready);
+	      SDIO_STATUS_CHECK;
+	      if(ready==KAL_TRUE)
+	         break;
+	   }   	   
+	   status=SDIO_read_FBR(count);	 
+	   SDIO_STATUS_CHECK;
+	   for(retry=0;retry<100;retry++)   	   
+	   {
+	      status=SDIO_read_CIS(count);	   
+	      if(status==NO_ERROR)
+	         break;
+	   }   
+	   
+	}      
+	if(SDIO_support_MPS()){
+	   status=SDIO_enable_MPS(KAL_TRUE);
+	   SDIO_STATUS_CHECK;
+	}
+	   
+	status=SDIO_read_CCCR();   
+	SDIO_STATUS_CHECK;
+	/* for Sandisk SDIO WIFI card*/   
+#if 0//guilin test #ifdef __MSDC_BASIC_LOAD__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+	
+
+err:
+	if(status != NO_ERROR)
+	{
+		tst_sys_trace("sdio_initialize error \r\n");
+		kal_prompt_trace(MOD_MSDC_HISR,"sdio_initialize error");
+		kal_mem_set(gSD,0,sizeof(gSD));
+		gMSDC_Handle->mIsInitialized = KAL_FALSE;
+	}
+	else
+	{
+		tst_sys_trace("sdio_initialize ok \r\n");
+		kal_prompt_trace(MOD_MSDC_HISR,"sdio_initialize ok");
+		gMSDC_Handle->mIsInitialized = KAL_TRUE;
+   
+	return status;
+}
+
+/*SDIO commnad set*/
+/*************************************************************************
+* FUNCTION
+*  SD_StopTrans
+*
+* DESCRIPTION
+*	Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Use polling to check write command completely
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_poll(void)
+{
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_poll(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+		return status;
+	/*Read R1b*/
+	if((status = SD_CheckStatus())!=NO_ERROR)
+		return status;
+
+
+#ifdef SD_STOP_SLOW
+		//while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+		//do{
+		//SD_GetStatus(gSD->mRCA,(kal_uint32*)&status);
+			//}while((status & R1_CUR_STATE) >> 9 !=  TRAN_STA);
+#endif
+
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_WaitCardNotBusy
+*
+* DESCRIPTION
+*	Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+*	void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+/*R1b*/
+void SDIO_WaitCardNotBusy(void)
+{
+	while( MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+}
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+*	write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_poll(void)
+{
+	kal_uint16 sdc_cmdsta = 0;
+	kal_uint32 counter = 0;
+	
+	while(MSDC_Reg(SDC_STA)&0x2){};
+   #if 1
+	do{
+		sdc_cmdsta = MSDC_Reg(SDC_CMDSTA);
+		if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+			return ERR_CMD_TIMEOUT;
+		else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+			return ERR_CMD_RSPCRCERR;
+		else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+			break;
+	}while(counter++ < 10000);
+   #endif
+	if (counter >= 10000)
+	{
+		return ERR_NORESP;
+	}
+
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+*	write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_poll(kal_uint32 cmd, kal_uint32 arg)
+{
+	SDC_CMD_STATUS status;
+	volatile kal_uint16 sdc_cmdsta,sdc_datsta;
+//    kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d(0x%x) arg=0x%x",__FUNCTION__,__LINE__,cmd&0x03f,cmd,arg);
+	/*check the controller is ready (stop transaction will fail)*/
+	//if( != SDC_CMD_CMD12)
+	if(!(SDC_CMD_STOP&cmd))
+		while(SD_IS_SDC_BUSY && gMSDC_Handle->mIsPresent);
+	else
+		while(SD_IS_CMD_BUSY && gMSDC_Handle->mIsPresent);
+
+    sdc_cmdsta = MSDC_Reg(SDC_CMDSTA);
+    sdc_datsta = MSDC_Reg(SDC_DATSTA);
+
+	/* fill out the argument*/
+	MSDC_WriteReg32(SDC_ARG,arg);
+	/* launch the command*/
+	MSDC_WriteReg32(SDC_CMD,cmd);
+	if((status = SD_WaitCmdRdyOrTo_poll())!=NO_ERROR){
+//        kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d(0x%x) arg=0x%x status=0x%x",__FUNCTION__,__LINE__,cmd&0x03f,cmd,arg,status);
+		return status;
+}
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd53
+*
+* DESCRIPTION
+*	IO_RW_DIRECT command
+*
+* PARAMETERS
+*  command 53 structrue
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_uint8 debug_flag = 0;
+SDC_CMD_STATUS SDIO_Cmd53(cmd53_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg;
+	kal_uint32 cmd;
+	kal_uint32 *ptr = (kal_uint32 *) p->buffer;	
+
+//guilin	ASSERT(p->adrs < 0x20000 && p->count < 0x200);   
+   #ifdef MSDC_DMA      
+   /*
+   if (INT_QueryIsCachedRAM(ptr, p->count))
+   {
+      EXT_ASSERT(0, (kal_uint32)ptr, p->count, 0);
+   }
+*/
+#ifdef MSDC_CACHED_SUPPORT
+	/*tell buffer type each time this function called*/
+	if (INT_QueryIsCachedRAM(ptr, p->count)){
+		gMSDC_Handle->isCachedBuf = KAL_TRUE;
+   }
+	else
+		gMSDC_Handle->isCachedBuf = KAL_FALSE;
+#endif
+   
+   #endif /* MSDC_DMA */
+#ifndef DRV_MSDC_USING_2ND
+   IRQMask(IRQ_MSDC_CODE);      
+#else
+  IRQMask(IRQ_MSDC2_CODE);
+#endif
+    MSDC_CLR_FIFO(); // guilin
+	
+	arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+	cmd = SDC_CMD_CMD53 | (p->rw << 13);
+	if(p->block)
+	{
+		cmd |= (2 << 11);	// multi-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+	}
+	else
+	{
+		cmd |= (1 << 11);	// single-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG,p->count,SDC_CFG_BLKLEN);
+	}
+
+	// send cmd53	   
+   //if(p->rw == SDIO_WRITE)
+   if(0)/*R1b*/
+   {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   else/*R1*/
+   {
+       cmd &= ~0x380;
+      cmd |= 0x80;      
+   }      
+   #ifdef MSDC_DMA      
+    if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+	{
+      kal_uint32 total_size=0;
+
+	   EnableMSDC_DMA();   
+      if(p->block)		
+			total_size = (p->count*gSDIO.block_size[p->func]);				
+		else
+		   total_size =p->count;
+		total_size=total_size>>2;	
+			
+   	if(p->rw == SDIO_READ)
+      	MSDC_DMATransferFirst((kal_uint32)ptr,total_size,KAL_FALSE);
+      else
+   		MSDC_DMATransferFirst((kal_uint32)ptr,total_size,KAL_TRUE);
+   }
+   #endif /* MSDC_DMA */
+
+  	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+	{ 
+	   goto ERROR_EXIT;		
+	}		
+	MSDC_LSD_ReadReg32(SDC_RESP0,&status);	
+	status = (status & 0xff00)>>8;
+	gSDIO.resp = status;   			
+    if(gSDIO.resp & 0xcf)//guilin
+    {
+        status = gSDIO.resp;
+        goto ERROR_EXIT;
+    }
+	/* start data transfer*/
+	if(p->rw == SDIO_READ)
+	{
+        kal_uint32 i;
+        #ifdef MSDC_DMA
+      if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+      {
+		status = MSDC_DMATransferFinal();
+		/*check DMA*/
+		if(status != NO_ERROR)	   
+		   goto ERROR_EXIT;
+		/*check Data ready*/   
+		if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+         goto ERROR_EXIT;	
+	   
+      DisableMSDC_DMA();
+ 	   MSDC_CLR_FIFO();	   
+        }
+      else
+      #endif/*MSDC_DMA*/
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT);
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+		}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT);
+					i++;
+					if((i%((p->count+3)>> 2)==0)&&(i!=0))
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+		}
+		}
+	}
+	else
+	{	// SDIO_WRITE
+        kal_uint32 i;     
+        #ifdef MSDC_DMA 
+       if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+       {
+		status = MSDC_DMATransferFinal();
+		/*check DMA*/
+		if(status != NO_ERROR)	   
+		   goto ERROR_EXIT;
+		/*check Data ready*/   
+		if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+         goto ERROR_EXIT;	
+	   
+      DisableMSDC_DMA();
+	   MSDC_CLR_FIFO();	   	         
+        }
+        else
+        #endif/*MSDC_DMA*/ 
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      			      
+				if(!MSDC_IS_FIFO_FULL)
+				{
+					MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+				}				
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			   
+				if(!MSDC_IS_FIFO_FULL)
+				{
+					MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+					i++;
+					if(i%((p->count+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;						     
+				}
+			}
+		   }
+		}
+	}   
+	//SD_StopTrans_poll();
+	/*Blue modify for Inno SDIO card*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+#endif
+	  /*Blue modify for Innofidi SDIO card. Innofidi SDIO card has issue on this command, when 1) block mode read, 2)limited block counts, 3) no timeout occur, we skill this command*/
+	if((p->block) && (SDIO_READ == p->rw) && (p->count < 0x200) && (KAL_FALSE == gMSDC_Handle->is_timeout)){
+	  	/*do nothing*/
+	}
+	else{
+        	SDIO_stop();
+  	}
+
+#ifndef DRV_MSDC_USING_2ND
+	IRQUnmask(IRQ_MSDC_CODE);
+#else
+	IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+    RESET_MSDC(); // guilin
+    MSDC_CLR_FIFO(); // guilin
+
+	return NO_ERROR;
+	ERROR_EXIT:
+   {  
+      kal_uint32 tmp;
+      #ifdef MSDC_DMA
+      DisableMSDC_DMA();
+      #endif
+      if(p->block)
+	      SD_StopTrans_poll();
+        SDIO_stop();
+		MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+		MSDC_LSD_ReadReg32(SDC_DATSTA,&tmp);
+		MSDC_CLR_FIFO();
+#ifndef DRV_MSDC_USING_2ND
+      IRQUnmask(IRQ_MSDC_CODE);
+#else
+    IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+   	return status;
+   }
+}
+
+/*SDIO_Cmd53_poll*/
+SDC_CMD_STATUS SDIO_Cmd53_isr(cmd53_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg;
+	kal_uint32 cmd,i;
+	kal_uint32 *ptr = (kal_uint32 *) p->buffer;	
+
+	ASSERT(p->adrs < 0x20000 && p->count < 0x200);      
+	arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+	cmd = SDC_CMD_CMD53 | (p->rw << 13);
+	if(p->block)
+	{
+		cmd |= (2 << 11);	// multi-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+	}
+	else
+	{
+		cmd |= (1 << 11);	// single-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG,p->count,SDC_CFG_BLKLEN);
+	}
+
+	// send cmd53	   
+   //if(p->rw == SDIO_WRITE)
+   if(0)/*R1b*/
+   {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   else/*R1*/
+   {
+       cmd &= ~0x380;
+      cmd |= 0x80;      
+   }      
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+	{ 
+	   goto ERROR_EXIT;		
+	}		
+	MSDC_LSD_ReadReg32(SDC_RESP0,&status);	
+	status = (status & 0xff00)>>8;
+	gSDIO.resp = status;   			
+	/* start data transfer*/
+	if(p->rw == SDIO_READ)
+	{
+
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{
+			      
+				if(!MSDC_IS_FIFO_EMPTY)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT);
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+				
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT);
+					i++;
+					if(i%((p->count+3)>> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+
+		}
+
+		}
+	}
+	else
+	{	// SDIO_WRITE
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      			      
+				if(!MSDC_IS_FIFO_FULL)
+				{
+					MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+				}
+				
+
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			   
+				if(!MSDC_IS_FIFO_FULL)
+				{
+					MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+					i++;
+					if(i%((p->count+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;						     
+				}
+			}
+
+		}
+
+		}
+	}   	
+
+	/*Blue modify for Inno SDIO card*/
+	if((p->block) && (MSDC_Reg(SDC_STA) & SDC_STA_DATBUSY) )
+	  SD_StopTrans_poll();
+   SDIO_stop();	
+	return NO_ERROR;
+	ERROR_EXIT:
+   {  
+      kal_uint32 tmp;      
+      #ifdef MSDC_DMA  
+      DisableMSDC_DMA();
+      #endif
+      if(p->block)
+	      SD_StopTrans_poll();
+      SDIO_stop();
+		MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+		MSDC_LSD_ReadReg32(SDC_DATSTA,&tmp);
+		MSDC_CLR_FIFO();    
+   	return status;
+   }
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd52
+*
+* DESCRIPTION
+*	IO_RW_DIRECT command
+*
+* PARAMETERS
+*  command 52 structrue
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+/* refer to the IO_RW_DIRECT command (CMD52) in SDIO 1.1 chapter 5.1*/
+SDC_CMD_STATUS SDIO_Cmd52(cmd52_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg = 0;
+	kal_uint32 cmd;	
+   
+#ifndef DRV_MSDC_USING_2ND
+   IRQMask(IRQ_MSDC_CODE);
+#else
+	IRQMask(IRQ_MSDC2_CODE);
+#endif
+
+	if(p->rw == SDIO_WRITE)
+	{
+		arg |= (IO_ARG_RW_FLAG|p->data);
+	}
+	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+	cmd = SDC_CMD_CMD52 ;
+	if(p->stop)
+		cmd |= SDC_CMD_STOP;
+      
+   if(p->stop)
+    //if(0)
+    {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   #if 1
+   else
+   {
+      cmd &= ~0x380;
+      cmd |= 0x80;      
+   }    
+   #endif
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+		goto ERROR_EXIT;         		
+	while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);	
+	MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+	if((p->rw == SDIO_READ)||((p->rw==SDIO_WRITE)&&(p->raw==KAL_TRUE)) ) // guilin
+	{
+		p->data = status & 0xff;
+	}
+	status = (status & 0xff00)>>8;
+	gSDIO.state = (status & 0x30)>>4;	
+	gSDIO.resp = status;	
+    if(gSDIO.resp & R5_ERROR_CHECK)//guilin
+    {
+        status = gSDIO.resp;
+        goto ERROR_EXIT;
+    }
+#ifndef DRV_MSDC_USING_2ND
+	IRQUnmask(IRQ_MSDC_CODE);   
+#else
+	IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+
+   return NO_ERROR;   
+   ERROR_EXIT:
+   {
+      kal_uint32 tmp;
+		MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+		MSDC_CLR_FIFO();
+#ifndef DRV_MSDC_USING_2ND
+      IRQUnmask(IRQ_MSDC_CODE);	   
+#else
+		IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+   	return status;
+   }	
+	
+	
+}
+SDC_CMD_STATUS SDIO_Cmd52_isr(cmd52_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg = 0;
+	kal_uint32 cmd;
+
+	if(p->rw == SDIO_WRITE)
+	{
+		arg |= (IO_ARG_RW_FLAG|p->data);
+	}
+	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+	cmd = SDC_CMD_CMD52 ;
+	if(p->stop)
+		cmd |= SDC_CMD_STOP;
+	   if(p->stop)
+    //if(0)
+    {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   #if 1
+   else
+   {
+      cmd &= ~0x380;
+      cmd |= 0x80;      
+   }    
+   #endif	
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)		
+		goto ERROR_EXIT;	
+   while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+	MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+	if(p->rw == SDIO_READ)
+	{
+		p->data = status & 0xff;
+	}
+	status = (status & 0xff00)>>8;
+	gSDIO.state = (status & 0x30)>>4;	
+	gSDIO.resp = status;   
+	return NO_ERROR;   
+	/*error handle*/
+   ERROR_EXIT:
+   {  
+      kal_uint32 tmp;  
+		MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+		MSDC_CLR_FIFO();      
+   	return status;
+   }		
+
+}   
+
+/* for SDIO*/
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd5
+*
+* DESCRIPTION
+*	SDIO initialization command
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	it is similar to the operation of ACMD41 for SD memory cards.
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Cmd5(kal_uint32 ocr)
+{
+	SDC_CMD_STATUS status;     
+   
+	if((status = SD_Send_Cmd_poll(SDC_CMD_CMD5,ocr))!=NO_ERROR)	
+		return status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+	/*we use different flag to distinguish SD and MMC, we have to set this flag to enable high density support*/
+	gSD->flags |= SD_FLAG_SD_TYPE_CARD;
+#endif	
+	/*read R4*/
+	MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+	gSDIO.ocr = status &0xFFFFFF;
+	status >>= 24;
+	gSDIO.num_func = (kal_uint8)(status & 0x70) >> 4;	
+	gSDIO.mem_present = ((status & 0x08) != 0) ;	
+	gSDIO.io_ready = ((status & SDIO_R4_CARD_READY)!=0);
+	#ifdef _SDIO_DEBUG_
+	dbg_print("card function number %d\r\n", gSDIO.num_func);							
+	dbg_print("memory card present %d\r\n", gSDIO.mem_present);						
+	dbg_print("card ready %d\r\n", gSDIO.io_ready);	
+	#endif
+	return NO_ERROR;
+}
+
+void SDIO_dispatch_IO(SDIO_function_id_enum function)   
+{
+   /*single function*/   
+   kal_take_mutex(sdio_mutex);    
+   /*multiple function*/
+   /*not support now*/
+}
+
+void SDIO_resume_IO(SDIO_function_id_enum function)   
+{
+   /*single function*/   
+   kal_give_mutex(sdio_mutex);    
+   /*multiple function*/
+   /*not support now*/
+   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CIS
+*
+* DESCRIPTION
+*	This function is to read function's CIS
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	This function is only user for SDIO bus driver
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CIS(SDIO_function_id_enum function)
+{
+   kal_uint32 i=0, j=0;
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;      
+   ASSERT(function<8);          
+   /* read all configuration register of CCCR*/
+   while(1)
+   {
+	   cmd52.rw = SDIO_READ;
+	   cmd52.func = SDIO_FUCN_0;
+	   cmd52.raw = KAL_FALSE;
+	   cmd52.stop = KAL_FALSE;
+	   if(function==0)
+	      cmd52.adrs =(kal_uint32)((sdio_cccr_reg[11]<<16)|(sdio_cccr_reg[10]<<8)|
+	                                      (sdio_cccr_reg[9])+i);
+	   else 
+	      cmd52.adrs =(kal_uint32)((sdio_fbr_reg[11]<<16)|(sdio_fbr_reg[10]<<8)|
+	                                      (sdio_fbr_reg[9])+i);
+	   cmd52.data = 0;
+	   if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	      return status;
+	   sdio_tuple[function][i]=cmd52.data;
+	   i++;
+	   if(cmd52.data==CISTPL_NULL||cmd52.data==CISTPL_END)
+	      return NO_ERROR;
+	   else
+	   {
+	      kal_uint32 tuple_size=0;
+	      cmd52.rw = SDIO_READ;	      
+	      cmd52.raw = KAL_FALSE;
+	      cmd52.stop = KAL_FALSE;
+	      cmd52.adrs++;
+	      if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	         return status;
+	      sdio_tuple[function][i]=cmd52.data;	      
+	      tuple_size=cmd52.data;
+	      i++;
+	      for(j=0;j<tuple_size;j++)
+	      {
+	         cmd52.adrs++;
+	         if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	            return status;
+	         sdio_tuple[function][i]=cmd52.data;	      
+	         i++;
+	      }      
+	   }         
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CCCR_ver
+*
+* DESCRIPTION
+*	This function is to read card's CCCR version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/   
+/*read SDIO CCCR version*/
+SDC_CMD_STATUS SDIO_read_CCCR_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+      
+   #if 1
+   *version=sdio_cccr_reg[0]&SDIO_CCCR_VERISON_MASK;	   
+   #else  
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+	
+}
+
+SDC_CMD_STATUS SDIO_stop(void)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+         
+   cmd52_config_struct cmd52;   
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_TRUE;
+	cmd52.adrs = 6;
+	cmd52.data = 1;
+	status = SDIO_Cmd52(&cmd52);	   
+	/*wait card is not busy*/	
+   SDIO_WaitCardNotBusy();		
+	return status;	
+}
+SDC_CMD_STATUS SDIO_WaitDatRdyOrTo(void)
+{
+	// maybe have to add a timer
+	register kal_uint16 sdc_datsta = 0;
+
+	int counter = 0;
+	//while(MSDC_Reg(SDC_STA)&0x4){};
+	do{
+		sdc_datsta = MSDC_Reg(SDC_DATSTA);
+
+		/*Blue modify for Inno SDIO card, in SDIO, this data timeout is legal*/
+		if((0 == MSDC_Reg(DMA_RLCT(gMSDC_Handle->msdc_dmaport))) && (0x3 == sdc_datsta))
+			sdc_datsta = 0x1;
+		
+		if(sdc_datsta & SDC_DATSTA_DATTO)
+			return ERR_DAT_TIMEOUT;
+		else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+			return ERR_DAT_CRCERR;
+		else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+			break;
+	}while(1);//(counter++  < 1000);
+
+	if (counter >= 1000)
+		return ERR_NORESP;
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_SDIO_ver
+*
+* DESCRIPTION
+*	This function is to read card's SDIO version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/   
+/*read SDIO spec version*/
+SDC_CMD_STATUS SDIO_read_SDIO_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   
+   #if 1
+   *version=sdio_cccr_reg[0]&SDIO_VERISON_MASK>>SDIO_VERISON_SHIFT;	
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+	
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_SD_ver
+*
+* DESCRIPTION
+*	This function is to read card's SD version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+/*read SD spec version*/
+SDC_CMD_STATUS SDIO_read_SD_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   
+   #if 1
+   *version=sdio_cccr_reg[1]&SDIO_SD_VERISON_MASK;	
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CCCR
+*
+* DESCRIPTION
+*	This function is to read card CCCR
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CCCR(void)
+{
+   #if 1
+   kal_uint32 i;
+    SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	for(i=0;i<SDIO_CCCR_SIZE;i++)
+	{
+	   cmd52.adrs =i;
+	   status = SDIO_Cmd52(&cmd52);	
+	   if(status != NO_ERROR)
+	        return status;
+	   sdio_cccr_reg[i]=cmd52.data;	   
+	}   
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_FBR
+*
+* DESCRIPTION
+*	This function is to read card FBR
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_FBR(SDIO_function_id_enum function)
+{
+   #if 1  /*to cover 5911 issue*/ 
+   SDC_CMD_STATUS status;   
+   cmd52_config_struct cmd52;   
+   kal_uint32 i=0;
+      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;	
+	cmd52.data = 0;
+	for(i=0;i<SDIO_FBR_SIZE;i++)
+	{
+	   cmd52.adrs = 0x100*function+i;
+	   status=SDIO_Cmd52(&cmd52);
+	   sdio_fbr_reg[i] = cmd52.data;	
+	}   
+	
+	return status;	
+   #else 
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_power_control
+*
+* DESCRIPTION
+*	This function is to read card's power control
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_power_control(void)
+{
+   SDC_CMD_STATUS status;   
+   cmd52_config_struct cmd52;   
+      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x12;
+	cmd52.data = 0;
+	status=SDIO_Cmd52(&cmd52);
+	gSDIO.power_control = cmd52.data;	
+	return status;	
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_MPS
+*
+* DESCRIPTION
+*	This function is to query card's power control
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_support_MPS(void)
+{
+     return ((gSDIO.power_control&0x1));   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_MPS
+*
+* DESCRIPTION
+*	This function is to enable card's power control
+*
+* PARAMETERS
+*  enable: enable or disable
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_MPS(kal_bool enable)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+      
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x12;
+	if(enable)
+	   cmd52.data |= 0x2;
+	else
+	   cmd52.data &= ~0x2;
+	   
+	status=SDIO_Cmd52(&cmd52);	   
+	if(enable)   	
+	   gSDIO.power_control |= 0x2;
+	else
+	   gSDIO.power_control &= ~0x2;   
+		
+	return status;	
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_capacity
+*
+* DESCRIPTION
+*	This function is to read card's capacity
+*
+* PARAMETERS
+*  enable: None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_capacity(void)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   #if 1
+   gSDIO.capability = sdio_cccr_reg[8];
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;	
+}      
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SDC
+*
+* DESCRIPTION
+*	This function is to query if card can support SDC
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+/*query card capacity*/
+kal_bool SDIO_support_SDC(void)
+{   
+   return ((gSDIO.capability&0x1));   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SMB
+*
+* DESCRIPTION
+*	This function is to query if card can support Multiple Block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SMB(void)
+{   
+   return ((gSDIO.capability&0x2)>>1);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SRW
+*
+* DESCRIPTION
+*	This function is to query if card can support Suspend/Resume
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SRW(void)
+{   
+   return ((gSDIO.capability&0x4)>>2);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SBS
+*
+* DESCRIPTION
+*	This function is to query if card can support Read/Wait
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SBS(void)
+{   
+   return ((gSDIO.capability&0x8)>>3);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_S4MI
+*
+* DESCRIPTION
+*	This function is to query if card can support interrupt during multiple block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_S4MI(void)
+{   
+   return ((gSDIO.capability&0x10)>>4);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_E4MI
+*
+* DESCRIPTION
+*	This function is to enable interrupt during multiple block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_E4MI(kal_bool enable)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   kal_uint8 temp_data; 
+   
+   if(!SDIO_support_S4MI())
+      return SDIO_4MI_NOT_SUPPORT;
+   
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 8;
+	if(enable)
+	{
+	   cmd52.data = 0x20;
+	   temp_data=0x20;
+	}   
+	else
+	{
+	   cmd52.data = 0;
+	   temp_data=0;
+	}   
+	if((status = SDIO_Cmd52(&cmd52))==NO_ERROR)
+	{
+	   /*double check*/
+	   cmd52.rw = SDIO_READ;   
+	   status = SDIO_Cmd52(&cmd52);	      
+	   if((cmd52.data&0x20)!=temp_data)	   
+	      ASSERT(0);	   
+	          
+	   if(enable)
+	      gSDIO.capability|=0x20;	   
+	   else
+	     gSDIO.capability&=~0x20;	       	   	   	   
+	}   	
+	
+	return status;		      
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_E4MI
+*
+* DESCRIPTION
+*	This function is to query if card is a low speed card
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_LSC(void)
+{   
+   return ((gSDIO.capability&0x40)>>6);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_4BLS
+*
+* DESCRIPTION
+*	This function is to query if card can support 4-bits in low speed card
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_4BLS(void)
+{   
+   return ((gSDIO.capability&0x80)>>7);   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_configure_bus
+*
+* DESCRIPTION
+*	This function is to configure bus width
+*
+* PARAMETERS
+*  bus: bus width
+*
+* RETURNS
+*  bus
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_bus(SD_BITWIDTH bus)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 7;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{	   
+	   return status;	   
+	}   
+	cmd52.data &= ~0x3;
+	cmd52.data |= (bus|0x80);/*also disable card detection*/
+	cmd52.rw = SDIO_WRITE;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{	 
+	   return status;
+	}   
+	gSDIO.bit_width=bus;
+	if(bus==BIT_4W)	
+	   MSDC_SetBits32(SDC_CFG,SDC_CFG_MDLEN);	        
+	
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_IO
+*
+* DESCRIPTION
+*	This function is to enable function
+*
+* PARAMETERS
+*  function: function id
+*  enable: enable or disable
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO(SDIO_function_id_enum function, kal_bool enable)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 2;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;	   
+	}   
+	if(enable)   	
+	   cmd52.data |= (function<<1);	
+	else   	
+	   cmd52.data &= ~(function<<1);	 
+		
+	cmd52.rw = SDIO_WRITE;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;
+	}   
+   SDIO_resume_IO(SDIO_FUCN_0); 
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_ready
+*
+* DESCRIPTION
+*	This function is to check function status
+*
+* PARAMETERS
+*  function: function id
+*  *ready: ready or not
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready(SDIO_function_id_enum function, kal_bool *ready)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 3;
+	status = SDIO_Cmd52(&cmd52);	   
+	*ready=(cmd52.data&(1<<function))>>function;		   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_IO_Int
+*
+* DESCRIPTION
+*	This function is to configure function interrupt enable
+*
+* PARAMETERS
+*  function: function id
+*  enable: enable or diable
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO_Int(SDIO_function_id_enum function, kal_bool enable)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 4;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;	   
+	}	   
+	if(enable)   	
+	   cmd52.data |= (1<<function);	
+	else   	
+	   cmd52.data &= ~(1<<function);	 
+		
+	cmd52.rw = SDIO_WRITE;
+		
+	status = SDIO_Cmd52(&cmd52);	      	   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_int_registration
+*
+* DESCRIPTION
+*	This function is to register interrupt handler
+*
+* PARAMETERS
+*  function: function id
+*  func: interrupt handler
+* RETURNS
+*  None
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+void SDIO_int_registration(SDIO_function_id_enum function, void (func)(void))
+{   
+   gSDIO.callback[function]=func;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_HISR_Entry
+*
+* DESCRIPTION
+*	This function is to handle SDIO interrupt
+*
+* PARAMETERS
+*  None 
+*
+* RETURNS
+*  None
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS int_status;
+void SDIO_HISR_Entry(void)
+{
+   
+   cmd52_config_struct cmd52;
+   cmd53_config_struct cmd53;
+   kal_uint8 uvalue[4];
+   kal_uint32 count;   
+   if(gSDIO.state!=CMD&&gSDIO.state!=TRN)		      
+   {
+      #ifdef MSDC_INT
+		kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_SDMCIRQ,KAL_OR);		      		
+		#endif
+	}	
+   else
+   {   
+      #if 1
+	   cmd52.rw = SDIO_READ;
+	   cmd52.func = 0;
+	   cmd52.raw = KAL_FALSE;
+	   cmd52.stop = KAL_FALSE;
+	   cmd52.adrs = 5;
+	   
+	   if((int_status = SDIO_Cmd52_isr(&cmd52))==NO_ERROR)	
+	   { 
+	    //kalDevRegWrite//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+	    uvalue[0]=2;
+	    uvalue[1]=0;
+	    uvalue[2]=0;
+	    uvalue[3]=0;
+	    cmd53.adrs = 0x04;
+	    cmd53.block = KAL_FALSE;
+	    cmd53.buffer=(kal_uint32)&uvalue[0];
+	    cmd53.count =4;
+	    cmd53.func=DCL_SDIO_FUCN_1;
+	    cmd53.op=DCL_SDIO_FIX;
+	    cmd53.rw=SDIO_WRITE;
+	    SDIO_Cmd53_isr(&cmd53);
+	    
+//guilin         for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)	
+//guilin         {
+//guilin            if(cmd52.data&(1<<count))
+//guilin               gSDIO.callback[count]();
+//guilin         }
+      }
+      else
+      {
+        /*dbg_print("int read failed\r\n");*/
+      }    
+      #endif        
+   }            
+}   
+
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_Int
+*
+* DESCRIPTION
+*	This function is to check interrupt status
+*
+* PARAMETERS
+*  function: function id
+*  *pending: interrupt status 
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/  
+SDC_CMD_STATUS SDIO_check_IO_Int(SDIO_function_id_enum function, kal_bool *pending)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 5;
+	status = SDIO_Cmd52(&cmd52);	
+	*pending=(cmd52.data&(1<<function))>>function;		   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_configure_BLK_size
+*
+* DESCRIPTION
+*	This function is to configure block size
+*
+* PARAMETERS
+*  function: function id
+*  size: block size
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_BLK_size(SDIO_function_id_enum function, kal_uint32 size)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x10+0x100*function;
+	cmd52.data = size&0xff;
+	status = SDIO_Cmd52(&cmd52);	   
+   if(size>=256)
+   {
+	   cmd52.adrs = 0x11+0x100*function;
+	   cmd52.data = (size&0xff00)>>8;    
+	   status = SDIO_Cmd52(&cmd52);	   
+	}   
+   if(status==NO_ERROR)					   
+   {
+	   gSDIO.block_size[function]=size;   	   		
+	   /*set block length as size*/
+	   BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)size,SDC_CFG_BLKLEN);
+	}   
+    SDIO_resume_IO(SDIO_FUCN_0); 
+    return status;
+}
+
+SDC_CMD_STATUS SDIO_get_BLK_size(SDIO_function_id_enum function, kal_uint32 *size)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   kal_uint32 temp,temp1;
+
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+
+   temp = MSDC_Reg32(SDC_CFG)&SDC_CFG_BLKLEN;
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;//function;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x10+0x100*function;
+	status = SDIO_Cmd52(&cmd52);	
+    if(status==NO_ERROR)
+    {
+        temp1 = cmd52.data;
+    }
+    else
+    {
+        goto SDIO_get_BLK_size_exit;
+    }
+	cmd52.adrs = 0x11+0x100*function;
+	status = SDIO_Cmd52(&cmd52);	
+    if(status==NO_ERROR)
+    {
+        temp1 |= (kal_uint32)cmd52.data <<8;
+    }
+    else
+    {
+        goto SDIO_get_BLK_size_exit;
+    }
+
+    if(temp == temp1 && temp ==gSDIO.block_size[function])
+    {
+	   *size = temp;   	   		
+	}
+	else
+	{
+        *size = temp1;
+        status = ERR_INVALID_BKLENGTH; // error
+        kal_prompt_trace(MOD_MSDC_HISR,"ERROR,block=%d %d %d",temp,temp1,gSDIO.block_size[function]);
+	}
+
+SDIO_get_BLK_size_exit:
+
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_query_BLK_size
+*
+* DESCRIPTION
+*	This function is to query function's maximum block size
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  size: block size
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_uint32 SDIO_query_BLK_size(SDIO_function_id_enum function)
+{
+   kal_uint32 max_block_size;
+   kal_uint32 i;
+   for(i=0;i<SDIO_TUPLE_SIZE;i++) 
+   {      
+      if(sdio_tuple[function][i]==0x22)
+      {
+         if(function==SDIO_FUCN_0)   
+            max_block_size=(sdio_tuple[function][i+3])|(sdio_tuple[function][i+4]<<8);
+         else
+            max_block_size=(sdio_tuple[function][i+14])|(sdio_tuple[function][i+15]<<8);   
+         return   max_block_size;         
+      }  
+   }
+   return 0;         
+}  
+/*************************************************************************
+* FUNCTION
+*  SDIO_query_IO_id
+*
+* DESCRIPTION
+*	This function is to query application function id
+*
+* PARAMETERS
+*  ap: application type
+*
+* RETURNS
+*  function: function id
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDIO_function_id_enum SDIO_query_IO_id(SDIO_interface_code_enum ap)
+{
+   switch(ap)
+   {
+      case SDIO_INTERFACE_NULL:        
+      break;      
+      case SDIO_INTERFACE_UART:
+      break;
+      case SDIO_INTERFACE_A_BT:
+      break;
+      case SDIO_INTERFACE_B_BT:
+      break;
+      case SDIO_INTERFACE_GPS:
+      break;
+      case SDIO_INTERFACE_CAMERA:
+      break;
+      case SDIO_INTERFACE_PHS:
+      break;
+      case SDIO_INTERFACE_WLAN:
+         return 1;
+      break;
+      default:
+      break;
+   }   
+   return 0;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_SW_reset
+*
+* DESCRIPTION
+*	This function is to reset all I/O function
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDC_CMD_STATUS SDIO_SW_reset(void)
+{
+   cmd52_config_struct cmd52;
+   SDC_CMD_STATUS status;
+      
+   /*use CMD52 to reset card*/	   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 6;
+	cmd52.data = 0xff;
+	status=SDIO_Cmd52(&cmd52);	   	
+	return status; 
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_abort_IO
+*
+* DESCRIPTION
+*	This function is to abort function
+*
+* PARAMETERS
+*  function:function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDC_CMD_STATUS SDIO_abort_IO(SDIO_function_id_enum function)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 6;
+	cmd52.data = function&0x7;						
+	status = SDIO_Cmd52(&cmd52);  			   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*Function for WiFi */
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Write
+*
+* DESCRIPTION
+*	This function is to write register
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+/*Write Register*/
+kal_bool SDIO_Register_Write(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 data,
+                             cmd53_op_enum op)
+{
+
+	kal_uint32 tmp = data;
+   cmd53_config_struct cmd53;
+   
+   SDIO_dispatch_IO(function);
+	sdio_uncachedU32 = data;
+	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)&sdio_uncachedU32;
+	cmd53.count = 4;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	      
+	}   	   
+}                                                         
+kal_bool SDIO_Register_Write_isr(SDIO_function_id_enum function, 
+                                 kal_uint32 addr, 
+                                 kal_uint32 data,
+                                 cmd53_op_enum op)
+{
+
+	kal_uint32 tmp = data;
+        cmd53_config_struct cmd53;
+      
+	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)&tmp;
+	cmd53.count = 4;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+	{	   
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   return KAL_TRUE;   	      
+	}   	   
+}                                                         
+/*Write Data */   
+/*************************************************************************
+* FUNCTION
+*  SDIO_Data_Write
+*
+* DESCRIPTION
+*	This function is to write memory
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*  count: transfer count
+*  block: block/byte mode 
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/                           
+kal_bool SDIO_Data_Write(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint8  *data,
+                             cmd53_op_enum op,
+                             kal_uint32 count,
+                             kal_bool block)
+{
+   cmd53_config_struct cmd53;
+   //kal_uint32 size, i;
+   //kal_uint32 sdio_buffer[256];
+   
+   SDIO_dispatch_IO(function);
+   #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+   #endif 
+ 	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = block;
+	cmd53.buffer = (kal_uint32)data;//(kal_uint32)&sdio_buffer[0];
+	cmd53.count = count;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Read
+*
+* DESCRIPTION
+*	This function is to Read register
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/                                                        
+/*Read Register*/
+kal_bool SDIO_Register_Read(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 *data,
+                             cmd53_op_enum op)
+{
+   cmd53_config_struct cmd53;
+   
+   SDIO_dispatch_IO(function);
+	cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32) &sdio_uncachedU32;
+	cmd53.count = 4;
+	cmd53.op = op;;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))	
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   *data = sdio_uncachedU32  ;
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	      
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Read_poll
+*
+* DESCRIPTION
+*	This function is to Read register by SDIO bus driver
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	only for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_Register_Read_poll(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 *data,
+                             cmd53_op_enum op)
+{
+   cmd53_config_struct cmd53;
+   
+	cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)data;
+	cmd53.count = 4;
+	cmd53.op = op;;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))	
+	{
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   return KAL_TRUE;   	      
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Data_Read
+*
+* DESCRIPTION
+*	This function is to read memory
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*  count: transfer count
+*  block: block/byte mode 
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Read(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint8  *data,
+                             cmd53_op_enum op,
+                             kal_uint32 count,
+                             kal_bool block)
+{
+   cmd53_config_struct cmd53;
+   SDIO_dispatch_IO(function);
+   cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = block;
+	cmd53.buffer = (kal_uint32)data;
+	cmd53.count = count;
+	cmd53.op = op;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	  	   
+	}      
+}                                
+   
+void SDIO_get_CCCR(kal_uint8 *buf, kal_uint32 bufLen)
+{
+	if(bufLen < SDIO_CCCR_SIZE)
+		ASSERT(0);
+	if(NULL == buf)
+		ASSERT(0);
+
+	kal_mem_cpy(buf, sdio_cccr_reg, SDIO_CCCR_SIZE);
+}      
+
+void SDIO_get_FBR(kal_uint8 *buf, kal_uint32 bufLen)
+{
+	if(bufLen < SDIO_FBR_SIZE)
+		ASSERT(0);
+	if(NULL == buf)
+		ASSERT(0);
+
+	kal_mem_cpy(buf, sdio_fbr_reg, SDIO_FBR_SIZE);
+}                                
+   
+/*not support in MT6228 and MT6229*/
+#ifdef __SDIO_SRW_SRW__
+/*************************************************************************
+* FUNCTION
+*  SDIO_suspend_IO
+*
+* DESCRIPTION
+*	This function is to suspend function
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_suspend_IO(SDIO_bus_status_enum *bus_status)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_TRUE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xc;
+	cmd52.data = 1;						
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   	
+	*bus_status=(cmd52.data&0x2)>>1;
+			   	   		
+	return NO_ERROR;      
+}   
+
+/*************************************************************************
+* FUNCTION
+*  SDIO_select_IO
+*
+* DESCRIPTION
+*	This function is to resume function
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_select_IO(SDIO_function_id_enum function, kal_bool *resume_data)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_TRUE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xd;
+	cmd52.data = function&0xf;						
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   	
+	*resume_data=(cmd52.data&0x80)>>7;
+			   	   		
+	return NO_ERROR;         
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_exec
+*
+* DESCRIPTION
+*	This function is to check function execution status
+*
+* PARAMETERS
+*  execute_status: execute status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/   
+SDC_CMD_STATUS SDIO_check_IO_exec(SDIO_function_id_enum function, kal_bool *execution)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xe;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   			
+	if(function!=SDIO_FUCN_MEM)		 
+	   *execution=(cmd52.data&(1<<function))>>function ;									   	   		
+	else
+	   *execution=cmd52.data&0x1;									   	   		
+	   
+	return NO_ERROR;         
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_ready_flag
+*
+* DESCRIPTION
+*	This function is to check function execution status
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready_flag(SDIO_function_id_enum function, kal_bool *ready)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xf;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   			
+	if(function!=SDIO_FUCN_MEM)		 
+	   *ready=(cmd52.data&(1<<function))>>function ;									   	   		
+	else
+	   *ready=cmd52.data&0x1;									   	   		
+	   
+	return NO_ERROR;         
+}
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+extern kal_semid dclMsdcArb;
+#endif
+
+
+
+/*here is the interface for device driver, since SDIO should share the same HW resouce with SD card*/
+SDC_CMD_STATUS SDIO_Initialize_al()
+{
+	kal_uint32 retAddr;
+	SDC_CMD_STATUS status;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+	
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here */
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+	MSDC_Switch_SDIO(SD_SDIO);
+#endif
+	MD_TRC_MSDC_SDIO_API_INIT();
+
+	 status = SDIO_Initialize();
+
+	MD_TRC_MSDC_SDIO_API_INIT_END(status);
+
+	/*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(KAL_FALSE == kal_query_systemInit()){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+
+	return status;
+}
+
+SDC_CMD_STATUS SDIO_configure_BLK_size_al(SDIO_function_id_enum function, kal_uint32 size)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+	
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here */
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+	MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+	/*do original job*/
+	status = SDIO_configure_BLK_size(function, size);
+
+	MD_TRC_MSDC_SDIO_API_SET_BLK_SIZE(function, size, status, 0);
+
+	/*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(KAL_FALSE == kal_query_systemInit()){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+
+	return status;
+}
+
+SDC_CMD_STATUS SDIO_Cmd52_al(cmd52_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+	
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here */
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+	MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+	MD_TRC_MSDC_SDIO_API_CMD52(p->rw, p->func, p->raw, p->stop, p->data, p->adrs,
+		0, MSDC_Reg32(MSDC_CFG));
+
+	status = SDIO_Cmd52(p);
+
+	MD_TRC_MSDC_SDIO_API_CMD52_END(status, MSDC_Reg32(SDC_RESP0));
+	/*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(KAL_FALSE == kal_query_systemInit()){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+
+	return status;
+}
+
+kal_bool SDIO_Data_Read_al
+(
+	SDIO_function_id_enum function, 
+	kal_uint32 addr, 
+	kal_uint8  *data,
+	cmd53_op_enum op,
+	kal_uint32 count,
+	kal_bool block
+)
+{
+	kal_bool status;
+	kal_uint32 retAddr;
+	kal_uint32 time1, time2;
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+	
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(NULL == dclMsdcArb)
+		ASSERT(0);
+	if(kal_query_systemInit()== KAL_FALSE){
+		/*must gain resource here before calling ReadSectors*/
+		kal_take_sem(dclMsdcArb, 1);
+		SD_setArbRetAddr(retAddr);
+		SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+	}
+#endif
+
+	/*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+	MSDC_backupHwSetting();
+	MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+	MD_TRC_MSDC_SDIO_API_DREAD(function, addr, (kal_uint32)data, op, count, 
+		block, 0, MSDC_Reg32(MSDC_CFG));
+
+	time1 = drv_get_current_time();
+
+	status = SDIO_Data_Read(function, addr, data, op, count, block);
+
+	time2 = drv_get_current_time();
+	MD_TRC_MSDC_SDIO_API_DREAD_END(status, (double)(count*32768)/(time2-time1), MSDC_Reg32(MSDC_IOCON), MSDC_Reg32(SDC_CFG));
+
+	/*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+	if(KAL_FALSE == kal_query_systemInit()){
+		/*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+		SD_setArbThdId(NULL);		
+		kal_give_sem(dclMsdcArb);
+	}
+#endif
+
+	return status;
+}
+#endif
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdio_drv2.c b/mcu/driver/storage/mc/src/sdio_drv2.c
new file mode 100644
index 0000000..e788c47
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdio_drv2.c
@@ -0,0 +1,2540 @@
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "msdc_reg_adap.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+
+#include "intrCtrl.h"  
+#include "sdio_sw.h"
+#include "cache_sw.h"
+#include "init.h"
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1		CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM	CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC	CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR	CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET	CG_SET1
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2	CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR	CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET	CG_SET0
+#endif
+
+#endif
+ 
+#if defined(__MSDC2_SD_SDIO__)
+
+#if defined(__MSDC_SD_SDIO)
+#error__MSDC_SD_SDIO can not coexit with  __MSDC2_SD_SDIO__
+#endif
+
+#if defined(DRV_MSDC_MT6225_SERIES)
+#define DRV_MSDC_DATA_LATCH_TIMING
+#endif 
+__align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+__align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+__align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+sdio_dcb_struct gSDIO;
+kal_mutexid sdio_mutex;
+MSDC_HANDLE *msdc2_sdio = &MSDC_Blk[SD_MSDC2];
+extern T_SDC_HANDLE	*gSD2;
+
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_uint32 MSDC_GetCustom(void);
+/*************************************************************************
+* FUNCTION
+*  SDIO_Initialize
+*
+* DESCRIPTION
+*	SDIO Intialization function
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Initialize(void)
+{	
+	kal_uint16 rca;
+   #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+	kal_uint16 iocon;
+   #else
+	kal_uint32 iocon;
+   #endif
+	SDC_CMD_STATUS status;
+	kal_uint32 flags;	
+	kal_uint32 retry_count = 0;
+	kal_uint32 count=0;	   
+	
+	TurnOnMSDC2();	
+	#ifdef MSDC_INT
+	kal_retrieve_eg_events(msdc2_sdio->MSDC_Events,
+			(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ|EVENT_PINIRQ),
+			KAL_OR_CONSUME,&flags,KAL_NO_SUSPEND);
+	#else
+	/*check if the card is present*/
+	if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+	{  /*card not present (1)*/
+		msdc2_sdio->mIsPresent = KAL_FALSE;
+	}
+	else
+	{  /*card present (0)*/
+		msdc2_sdio->mIsPresent = KAL_TRUE;
+	}
+	#endif
+
+   /*create mutex*/
+   sdio_mutex = kal_create_mutex("MutexSDIO");
+
+	/* reset msdc*/
+	MSDC_SetBits32(MSDC_CFG2, MSDC_CFG_RST);
+	
+   /* set the output driving capability from customization interface*/
+   #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+	MSDC_SetData(MSDC_IOCON2, 0xff, MSDC_GetIOCtrlParam2());
+   #else /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+	iocon = 0;
+	iocon |= MSDC_GetIOCtrlParam2();
+   #ifdef MCU_78M
+      iocon |= 0x04000000;
+   #elif defined(MCU_52M)
+      iocon |= 0x02000000;
+   #endif
+	MSDC_SetData(MSDC_IOCON2, 0xff0000ff, iocon);
+
+   #if defined(MCU_52M)
+   	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)1, MSDC_CFG_CRED);
+   #endif
+   #endif /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+	/*set pull up in CMD/DAT line configuration*/	
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG1);
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG2);
+
+	/*set write timeout=(40+1)*65536*(1/serial clock)*/
+	BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)255,SDC_CFG_DTOC);	
+	/*set write timeout=(40+1)*65536*(1/serial clock)*/
+	BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)15,SDC_CFG_WDOD);		
+
+ 	/* disable 4-bit*/
+	MSDC_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);	   		
+	/* enable serila clock 104/8=13MHz*/	
+	//BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);			
+	/* enable serila clock 104/255*4=100KHz*/	
+	//MSDC_Reg32(MSDC_CFG2)|= 0x8; 
+	MSDC_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)64,MSDC_CFG_SCLKF);		
+	msdc2_sdio->msdc_clock = MSDC_CLOCK;
+	MSDC_SetClock(MSDC_INI_CLOCK);
+	MSDC_SetIOCONRegDLT();
+
+	MSDC_SetBits32(SDC_CFG2,SDC_CFG_SIEN);
+	/* config the sdio controller*/
+	/* enable SDIO mode*/
+	MSDC_Reg32(SDC_CFG2)|= SDC_CFG_SDIO; 
+	/* enable SDIO interrupt*/
+	MSDC_WriteReg32(SDIO_CFG2, 1); 		
+	{
+		kal_uint32 i;
+		for(i=0;i<1000;i++);
+	}	
+	/*SDIO initialization CMD*/
+   status = SDIO_Cmd5(0);
+   #ifdef _SDIO_DEBUG_
+	dbg_print("write CMD5(0) %d\r\n", status);						
+	dbg_print("card OCR %d\r\n", gSDIO.ocr);						
+	#endif
+	do 
+	{	
+	   retry_count++;
+	   if(gSDIO.ocr & 0x8000)
+	   {					      
+	   	if((status = SDIO_Cmd5(0x8000))!=NO_ERROR)	   	
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card deny OCR \r\n");													   	
+	   		#endif
+	   		
+	   	}	
+	   	else	   				
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card accept OCR \r\n");							   		
+	   	#endif	
+	   	}	
+	   	
+	   	gSDIO.ocr_valid = KAL_TRUE;	
+	   	gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+	   }
+	   else 
+	   {	   
+	      #ifdef _SDIO_DEBUG_
+	      dbg_print("card not match OCR \r\n");												  
+	      dbg_print("uses card's OCR \r\n");												  
+	      #endif												  
+	      if((status = SDIO_Cmd5(gSDIO.ocr))!=NO_ERROR)	   	
+	      {
+	         #ifdef _SDIO_DEBUG_
+	   		dbg_print("card deny OCR \r\n");													   			   			   	
+	   		#endif	
+	   	}	
+	   	else	   	
+	   	{
+	   	   #ifdef _SDIO_DEBUG_
+	   		dbg_print("card accept OCR \r\n");							   	
+	   		#endif	
+	   	}	
+	   	
+	   	gSDIO.ocr_valid = KAL_TRUE;	
+	   	gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+	   }
+	   if(retry_count>=100)
+	      goto err;
+	}while(gSDIO.io_ready!=KAL_TRUE);	
+	MSDC_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);			
+#ifdef MCU_78M   
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+#elif defined(MCU_208M)
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY16,MSDC_CFG_SCLKF);
+#else
+	BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY4,MSDC_CFG_SCLKF);		   	
+#endif   /*MCU_78M*/
+
+	SD_Use24M_Clock_2();
+	//SD_Use45M_Clock();
+	MSDC_SetIOCONRegDLT2();
+
+	MSDC_SetBits32(SDC_CFG2,SDC_CFG_SIEN);   
+	status = SD_ValidateRCA_2(&rca);
+	#ifdef _SDIO_DEBUG_
+	dbg_print("CMD7 select card \r\n");								
+	dbg_print("CMD3 request RCA \r\n");
+	#endif
+	
+	status = SD_SelectCard_2(rca);
+	
+	/* get parameters*/
+	/*read CCCR, FBR, CIS tuple*/	
+	status=SDIO_read_CCCR();
+   status=SDIO_read_capacity();   
+   status=SDIO_read_power_control();
+	
+#if 0	
+	#if 0/*support 4-bits*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#else
+/* under construction !*/
+	#endif  
+#endif
+
+	/*enable multiple block interrupt */
+	if(!(SDIO_support_LSC()))	
+	{	
+		 //MSDC2 only support 1-bit Mode
+		 status=SDIO_configure_bus(BIT_1W);
+	}
+	else/*low speed card*/
+	{
+		//MSDC2 only support 1-bit Mode
+	}    
+
+	
+	status=SDIO_read_CIS(SDIO_FUCN_0);
+   /*enable I/O function*/
+	for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+	{	   
+	   kal_uint32 retry=0;
+	   kal_bool ready;
+	   for(retry=0;retry<100;retry++) 
+	   {
+	      status=SDIO_enable_IO(count, KAL_TRUE);
+	      SDIO_check_IO_ready(count, &ready);
+	      if(ready==KAL_TRUE)
+	         break;
+	   }   	   
+	   status=SDIO_read_FBR(count);	 
+	   for(retry=0;retry<100;retry++)   	   
+	   {
+	      status=SDIO_read_CIS(count);	   
+	      if(status==NO_ERROR)
+	         break;
+	   }   
+	   
+	}      
+	if(SDIO_support_MPS())
+	   status=SDIO_enable_MPS(KAL_TRUE);
+	   
+	status=SDIO_read_CCCR();   
+	
+	/* for Sandisk SDIO WIFI card*/   
+	
+	
+
+err:
+	if(status != NO_ERROR)
+	{
+		//dbg_print("10\r\n");
+		kal_mem_set(gSD,0,sizeof(gSD));
+		msdc2_sdio->mIsInitialized = KAL_FALSE;
+		
+	}
+	else
+		msdc2_sdio->mIsInitialized = KAL_TRUE;
+   
+	return status;
+}
+
+/*SDIO commnad set*/
+/*************************************************************************
+* FUNCTION
+*  SD_StopTrans
+*
+* DESCRIPTION
+*	Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+*	SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Use polling to check write command completely
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_poll(void)
+{
+	SDC_CMD_STATUS status;
+
+	if((status = SD_Send_Cmd_poll(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+		return status;
+	/*Read R1b*/
+	if((status = SD_CheckStatus())!=NO_ERROR)
+		return status;
+
+
+#ifdef SD_STOP_SLOW
+		while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+		do{
+		SD_GetStatus_2(gSD->mRCA,(kal_uint32*)&status);
+			}while((status & R1_CUR_STATE) >> 9 !=  TRAN_STA);
+#endif
+
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_WaitCardNotBusy
+*
+* DESCRIPTION
+*	Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+*	void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*	Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+/*R1b*/
+void SDIO_WaitCardNotBusy(void)
+{
+	while( MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+}
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+*	write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_poll(void)
+{
+	kal_uint16 sdc_cmdsta = 0;
+	kal_uint32 counter = 0;
+	
+	while(MSDC_Reg(SDC_STA2)&0x2){};
+   #if 1
+	do{
+		sdc_cmdsta = MSDC_Reg(SDC_CMDSTA2);
+		if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+			return ERR_CMD_TIMEOUT;
+		else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+			return ERR_CMD_RSPCRCERR;
+		else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+			break;
+	}while(counter++ < 10000);
+   #endif
+	if (counter >= 10000)
+	{
+		return ERR_NORESP;
+	}
+
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+*	write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_poll(kal_uint32 cmd, kal_uint32 arg)
+{
+	SDC_CMD_STATUS status;
+
+	/*check the controller is ready (stop transaction will fail)*/
+	//if( != SDC_CMD_CMD12)
+	if(!(SDC_CMD_STOP&cmd))
+		while(SD_IS_SDC_BUSY_2 && msdc2_sdio->mIsPresent);
+	else
+		while(SD_IS_CMD_BUSY_2 && msdc2_sdio->mIsPresent);
+
+	/* fill out the argument*/
+	MSDC_WriteReg32(SDC_ARG2,arg);
+	/* launch the command*/
+	MSDC_WriteReg32(SDC_CMD2,cmd);
+	if((status = SD_WaitCmdRdyOrTo_poll())!=NO_ERROR)
+		return status;
+
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd53
+*
+* DESCRIPTION
+*	IO_RW_DIRECT command
+*
+* PARAMETERS
+*  command 53 structrue
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_uint8 debug_flag = 0;
+SDC_CMD_STATUS SDIO_Cmd53(cmd53_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg;
+	kal_uint32 cmd;
+	kal_uint32 *ptr = (kal_uint32 *) p->buffer;	
+
+	ASSERT(p->adrs < 0x20000 && p->count < 0x200);   
+   #ifdef MSDC_DMA      
+   if (INT_QueryIsCachedRAM(ptr, p->count))
+   {
+      EXT_ASSERT(0, (kal_uint32)prt, p->count, 0);
+   }
+   #endif /* MSDC_DMA */
+   IRQMask(IRQ_MSDC2_CODE);      
+	arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+	cmd = SDC_CMD_CMD53 | (p->rw << 13);
+	if(p->block)
+	{
+		cmd |= (2 << 11);	// multi-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG2,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+	}
+	else
+	{
+		cmd |= (1 << 11);	// single-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG2,p->count,SDC_CFG_BLKLEN);
+	}
+
+	// send cmd53	   
+   //if(p->rw == SDIO_WRITE)
+   if(0)/*R1b*/
+   {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   else/*R1*/
+   {
+       cmd &= ~0x380;
+      cmd |= 0x80;      
+   }      
+   #ifdef MSDC_DMA      
+	{
+      kal_uint32 total_size=0;
+
+	   EnableMSDC_DMA2();   
+      if(p->block)		
+			total_size = (p->count*gSDIO.block_size[p->func]);				
+		else
+		   total_size =p->count;
+		total_size=total_size>>2;	
+			
+   	if(p->rw == SDIO_READ)
+      	MSDC_DMATransferFirst2((kal_uint32)ptr,total_size,KAL_FALSE);
+      else
+   		MSDC_DMATransferFirst2((kal_uint32)ptr,total_size,KAL_TRUE);
+   }
+   #endif /* MSDC_DMA */
+
+  	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+	{ 
+	   goto ERROR_EXIT;		
+	}		
+	MSDC_Reg32(SDC_RESP02,&status);	
+	status = (status & 0xff00)>>8;
+	gSDIO.resp = status;   			
+	/* start data transfer*/
+	if(p->rw == SDIO_READ)
+	{
+      #ifdef MSDC_DMA      
+		status = MSDC_DMATransferFinal2();
+		/*check DMA*/
+		if(status != NO_ERROR)	   
+		   goto ERROR_EXIT;
+		/*check Data ready*/   
+		if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+         goto ERROR_EXIT;	
+	   
+      DisableMSDC_DMA2();
+	   MSDC_CLR_FIFO2();	   
+	         
+      #else/*!MSDC_DMA*/
+      kal_uint32 i;
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY2)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+		}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY2)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+					i++;
+					if((i%((p->count+3)>> 2)==0)&&(i!=0))
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+		}
+		}
+		#endif/*MSDC_DMA*/
+	}
+	else
+	{	// SDIO_WRITE
+	   #ifdef MSDC_DMA      
+		status = MSDC_DMATransferFinal2();
+		/*check DMA*/
+		if(status != NO_ERROR)	   
+		   goto ERROR_EXIT;
+		/*check Data ready*/   
+		if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+         goto ERROR_EXIT;	
+	   
+      DisableMSDC_DMA2();
+	   MSDC_CLR_FIFO2();	   	         
+      #else/* MSDC_DMA*/ 
+      kal_uint32 i;     
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      			      
+				if(!MSDC_IS_FIFO_FULL2)
+				{
+					MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+				}				
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			   
+				if(!MSDC_IS_FIFO_FULL2)
+				{
+					MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+					i++;
+					if(i%((p->count+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;						     
+				}
+			}
+		   }
+		}
+		#endif/*MSDC_DMA*/    
+	}   
+	//SD_StopTrans_poll();
+	if(p->block)
+	  SD_StopTrans_poll();
+        SDIO_stop();
+	IRQUnmask(IRQ_MSDC2_CODE);
+	return NO_ERROR;
+	ERROR_EXIT:
+   {  
+      kal_uint32 tmp;
+      #ifdef MSDC_DMA
+      DisableMSDC_DMA2();
+      #endif
+      if(p->block)
+	      SD_StopTrans_poll();
+        SDIO_stop();
+		MSDC_Reg32(SDC_CMDSTA2,&tmp);
+		MSDC_Reg32(SDC_DATSTA2,&tmp);
+		MSDC_CLR_FIFO2();
+      IRQUnmask(IRQ_MSDC2_CODE);
+   	return status;
+   }
+}
+
+/*SDIO_Cmd53_poll*/
+SDC_CMD_STATUS SDIO_Cmd53_isr(cmd53_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg;
+	kal_uint32 cmd,i;
+	kal_uint32 *ptr = (kal_uint32 *) p->buffer;	
+
+	ASSERT(p->adrs < 0x20000 && p->count < 0x200);      
+	arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+	cmd = SDC_CMD_CMD53 | (p->rw << 13);
+	if(p->block)
+	{
+		cmd |= (2 << 11);	// multi-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG2,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+	}
+	else
+	{
+		cmd |= (1 << 11);	// single-block
+		BitFieldWrite32((kal_uint32*)SDC_CFG2,p->count,SDC_CFG_BLKLEN);
+	}
+
+	// send cmd53	   
+   //if(p->rw == SDIO_WRITE)
+   if(0)/*R1b*/
+   {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   else/*R1*/
+   {
+       cmd &= ~0x380;
+      cmd |= 0x80;      
+   }      
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+	{ 
+	   goto ERROR_EXIT;		
+	}		
+	MSDC_Reg32(SDC_RESP02,&status);	
+	status = (status & 0xff00)>>8;
+	gSDIO.resp = status;   			
+	/* start data transfer*/
+	if(p->rw == SDIO_READ)
+	{
+
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{
+			      
+				if(!MSDC_IS_FIFO_EMPTY2)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+				
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			      
+				if(!MSDC_IS_FIFO_EMPTY2)
+				{
+					*(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+					i++;
+					if(i%((p->count+3)>> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+			}
+
+		}
+
+		}
+	}
+	else
+	{	// SDIO_WRITE
+		if(p->block)
+		{
+			kal_uint32 total;
+
+			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+			for(i=0;i< total;)
+			{			      			      
+				if(!MSDC_IS_FIFO_FULL2)
+				{
+					MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+					i++;
+					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;					
+				}
+				}
+				
+
+			}
+		}
+		else
+		{
+			for(i=0;i< (p->count+3)>>2;)
+			{			   
+				if(!MSDC_IS_FIFO_FULL2)
+				{
+					MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+					i++;
+					if(i%((p->count+3) >> 2)==0)
+				{
+					debug_flag = 1;
+					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+					   goto ERROR_EXIT;						     
+				}
+			}
+
+		}
+
+		}
+	}   	
+	if(p->block)
+	  SD_StopTrans_poll();
+   SDIO_stop();	
+	return NO_ERROR;
+	ERROR_EXIT:
+   {  
+      kal_uint32 tmp;      
+      #ifdef MSDC_DMA  
+      DisableMSDC_DMA2();
+      #endif
+      if(p->block)
+	      SD_StopTrans_poll();
+      SDIO_stop();
+		MSDC_Reg32(SDC_CMDSTA2,&tmp);
+		MSDC_Reg32(SDC_DATSTA2,&tmp);
+		MSDC_CLR_FIFO2();    
+   	return status;
+   }
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd52
+*
+* DESCRIPTION
+*	IO_RW_DIRECT command
+*
+* PARAMETERS
+*  command 52 structrue
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+/* refer to the IO_RW_DIRECT command (CMD52) in SDIO 1.1 chapter 5.1*/
+SDC_CMD_STATUS SDIO_Cmd52(cmd52_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg = 0;
+	kal_uint32 cmd;	
+   
+   IRQMask(IRQ_MSDC2_CODE);
+	if(p->rw == SDIO_WRITE)
+	{
+		arg |= (IO_ARG_RW_FLAG|p->data);
+	}
+	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+	cmd = SDC_CMD_CMD52 ;
+	if(p->stop)
+		cmd |= SDC_CMD_STOP;
+      
+   if(p->stop)
+    //if(0)
+    {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   #if 1
+   else
+   {
+      cmd &= ~0x380;
+      cmd |= 0x80;      
+   }    
+   #endif
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+		goto ERROR_EXIT;         		
+	while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);	
+	MSDC_Reg32(SDC_RESP02,&status);
+	if(p->rw == SDIO_READ)
+	{
+		p->data = status & 0xff;
+	}
+	status = (status & 0xff00)>>8;
+	gSDIO.state = (status & 0x30)>>4;	
+	gSDIO.resp = status;	
+	IRQUnmask(IRQ_MSDC2_CODE);   
+   return NO_ERROR;   
+   ERROR_EXIT:
+   {
+      kal_uint32 tmp;
+		MSDC_Reg32(SDC_CMDSTA2,&tmp);
+		MSDC_CLR_FIFO2();
+      IRQUnmask(IRQ_MSDC2_CODE);	   
+   	return status;
+   }	
+	
+	
+}
+SDC_CMD_STATUS SDIO_Cmd52_isr(cmd52_config_struct *p)
+{
+	SDC_CMD_STATUS status;
+	kal_uint32 arg = 0;
+	kal_uint32 cmd;
+
+	if(p->rw == SDIO_WRITE)
+	{
+		arg |= (IO_ARG_RW_FLAG|p->data);
+	}
+	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+	cmd = SDC_CMD_CMD52 ;
+	if(p->stop)
+		cmd |= SDC_CMD_STOP;
+	   if(p->stop)
+    //if(0)
+    {
+      cmd &= ~0x380;
+      cmd |= 0x380;
+   }   
+   #if 1
+   else
+   {
+      cmd &= ~0x380;
+      cmd |= 0x80;      
+   }    
+   #endif	
+	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)		
+		goto ERROR_EXIT;	
+   while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+	MSDC_Reg32(SDC_RESP02,&status);
+	if(p->rw == SDIO_READ)
+	{
+		p->data = status & 0xff;
+	}
+	status = (status & 0xff00)>>8;
+	gSDIO.state = (status & 0x30)>>4;	
+	gSDIO.resp = status;   
+	return NO_ERROR;   
+	/*error handle*/
+   ERROR_EXIT:
+   {  
+      kal_uint32 tmp;  
+		MSDC_Reg32(SDC_CMDSTA2,&tmp);
+		MSDC_CLR_FIFO2();      
+   	return status;
+   }		
+
+}   
+
+/* for SDIO*/
+/*************************************************************************
+* FUNCTION
+*  SDIO_Cmd5
+*
+* DESCRIPTION
+*	SDIO initialization command
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	it is similar to the operation of ACMD41 for SD memory cards.
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Cmd5(kal_uint32 ocr)
+{
+	SDC_CMD_STATUS status;     
+   
+	if((status = SD_Send_Cmd_poll(SDC_CMD_CMD5,ocr))!=NO_ERROR)	
+		return status;
+
+	/*read R4*/
+	MSDC_Reg32(SDC_RESP02,&status);
+	gSDIO.ocr = status &0xFFFFFF;
+	status >>= 24;
+	gSDIO.num_func = (kal_uint8)(status & 0x70) >> 4;	
+	gSDIO.mem_present = ((status & 0x08) != 0) ;	
+	gSDIO.io_ready = ((status & SDIO_R4_CARD_READY)!=0);
+	#ifdef _SDIO_DEBUG_
+	dbg_print("card function number %d\r\n", gSDIO.num_func);							
+	dbg_print("memory card present %d\r\n", gSDIO.mem_present);						
+	dbg_print("card ready %d\r\n", gSDIO.io_ready);	
+	#endif
+	return NO_ERROR;
+}
+
+void SDIO_dispatch_IO(SDIO_function_id_enum function)   
+{
+   /*single function*/   
+   kal_take_mutex(sdio_mutex);    
+   /*multiple function*/
+   /*not support now*/
+}
+
+void SDIO_resume_IO(SDIO_function_id_enum function)   
+{
+   /*single function*/   
+   kal_give_mutex(sdio_mutex);    
+   /*multiple function*/
+   /*not support now*/
+   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CIS
+*
+* DESCRIPTION
+*	This function is to read function's CIS
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	This function is only user for SDIO bus driver
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CIS(SDIO_function_id_enum function)
+{
+   kal_uint32 i=0, j=0;
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;      
+   ASSERT(function<8);          
+   /* read all configuration register of CCCR*/
+   while(1)
+   {
+	   cmd52.rw = SDIO_READ;
+	   cmd52.func = function;
+	   cmd52.raw = KAL_FALSE;
+	   cmd52.stop = KAL_FALSE;
+	   if(function==0)
+	      cmd52.adrs =(kal_uint32)((sdio_cccr_reg[11]<<16)|(sdio_cccr_reg[10]<<8)|
+	                                      (sdio_cccr_reg[9]<<8)+i);
+	   else 
+	      cmd52.adrs =(kal_uint32)((sdio_fbr_reg[11]<<16)|(sdio_fbr_reg[10]<<8)|
+	                                      (sdio_fbr_reg[9]<<8)+i);
+	   cmd52.data = 0;
+	   if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	      return status;
+	   sdio_tuple[function][i]=cmd52.data;
+	   i++;
+	   if(cmd52.data==CISTPL_NULL||cmd52.data==CISTPL_END)
+	      return NO_ERROR;
+	   else
+	   {
+	      kal_uint32 tuple_size=0;
+	      cmd52.rw = SDIO_READ;	      
+	      cmd52.raw = KAL_FALSE;
+	      cmd52.stop = KAL_FALSE;
+	      cmd52.adrs++;
+	      if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	         return status;
+	      sdio_tuple[function][i]=cmd52.data;	      
+	      tuple_size=cmd52.data;
+	      i++;
+	      for(j=0;j<tuple_size;j++)
+	      {
+	         cmd52.adrs++;
+	         if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	            return status;
+	         sdio_tuple[function][i]=cmd52.data;	      
+	         i++;
+	      }      
+	   }         
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CCCR_ver
+*
+* DESCRIPTION
+*	This function is to read card's CCCR version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/   
+/*read SDIO CCCR version*/
+SDC_CMD_STATUS SDIO_read_CCCR_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+      
+   #if 1
+   *version=sdio_cccr_reg[0]&SDIO_CCCR_VERISON_MASK;	   
+   #else  
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+	
+}
+
+SDC_CMD_STATUS SDIO_stop(void)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+         
+   cmd52_config_struct cmd52;   
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_TRUE;
+	cmd52.adrs = 6;
+	cmd52.data = 1;
+	status = SDIO_Cmd52(&cmd52);	   
+	/*wait card is not busy*/	
+   SDIO_WaitCardNotBusy();		
+	return status;	
+}
+SDC_CMD_STATUS SDIO_WaitDatRdyOrTo(void)
+{
+	// maybe have to add a timer
+	register kal_uint16 sdc_datsta = 0;
+
+	int counter = 0;
+	//while(MSDC_Reg(SDC_STA2)&0x4){};
+	do{
+		sdc_datsta = MSDC_Reg(SDC_DATSTA2);
+		if(sdc_datsta & SDC_DATSTA_DATTO)
+			return ERR_DAT_TIMEOUT;
+		else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+			return ERR_DAT_CRCERR;
+		else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+			break;
+	}while(1);//(counter++  < 1000);
+
+	if (counter >= 1000)
+		return ERR_NORESP;
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_SDIO_ver
+*
+* DESCRIPTION
+*	This function is to read card's SDIO version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/   
+/*read SDIO spec version*/
+SDC_CMD_STATUS SDIO_read_SDIO_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   
+   #if 1
+   *version=sdio_cccr_reg[0]&SDIO_VERISON_MASK>>SDIO_VERISON_SHIFT;	
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+	
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_SD_ver
+*
+* DESCRIPTION
+*	This function is to read card's SD version 
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*
+*************************************************************************/
+/*read SD spec version*/
+SDC_CMD_STATUS SDIO_read_SD_ver(kal_uint8 *version)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   
+   #if 1
+   *version=sdio_cccr_reg[1]&SDIO_SD_VERISON_MASK;	
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_CCCR
+*
+* DESCRIPTION
+*	This function is to read card CCCR
+*
+* PARAMETERS
+*  *version
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CCCR(void)
+{
+   #if 1
+   kal_uint32 i;
+    SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	for(i=0;i<SDIO_CCCR_SIZE;i++)
+	{
+	   cmd52.adrs =i;
+	   status = SDIO_Cmd52(&cmd52);	
+	   sdio_cccr_reg[i]=cmd52.data;	   
+	}   
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_FBR
+*
+* DESCRIPTION
+*	This function is to read card FBR
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_FBR(SDIO_function_id_enum function)
+{
+   #if 1  /*to cover 5911 issue*/ 
+   SDC_CMD_STATUS status;   
+   cmd52_config_struct cmd52;   
+   kal_uint32 i=0;
+      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;	
+	cmd52.data = 0;
+	for(i=0;i<SDIO_FBR_SIZE;i++)
+	{
+	   cmd52.adrs = 0x100*function+i;
+	   status=SDIO_Cmd52(&cmd52);
+	   sdio_fbr_reg[i] = cmd52.data;	
+	}   
+	
+	return status;	
+   #else 
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_power_control
+*
+* DESCRIPTION
+*	This function is to read card's power control
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_power_control(void)
+{
+   SDC_CMD_STATUS status;   
+   cmd52_config_struct cmd52;   
+      
+   cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x12;
+	cmd52.data = 0;
+	status=SDIO_Cmd52(&cmd52);
+	gSDIO.power_control = cmd52.data;	
+	return status;	
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_MPS
+*
+* DESCRIPTION
+*	This function is to query card's power control
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_support_MPS(void)
+{
+     return ((gSDIO.power_control&0x1));   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_MPS
+*
+* DESCRIPTION
+*	This function is to enable card's power control
+*
+* PARAMETERS
+*  enable: enable or disable
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_MPS(kal_bool enable)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+      
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x12;
+	if(enable)
+	   cmd52.data |= 0x2;
+	else
+	   cmd52.data &= ~0x2;
+	   
+	status=SDIO_Cmd52(&cmd52);	   
+	if(enable)   	
+	   gSDIO.power_control |= 0x2;
+	else
+	   gSDIO.power_control &= ~0x2;   
+		
+	return status;	
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_read_capacity
+*
+* DESCRIPTION
+*	This function is to read card's capacity
+*
+* PARAMETERS
+*  enable: None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_capacity(void)
+{
+   SDC_CMD_STATUS status=NO_ERROR;
+   #if 1
+   gSDIO.capability = sdio_cccr_reg[8];
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+	#endif
+	return status;	
+}      
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SDC
+*
+* DESCRIPTION
+*	This function is to query if card can support SDC
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+/*query card capacity*/
+kal_bool SDIO_support_SDC(void)
+{   
+   return ((gSDIO.capability&0x1));   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SMB
+*
+* DESCRIPTION
+*	This function is to query if card can support Multiple Block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SMB(void)
+{   
+   return ((gSDIO.capability&0x2)>>1);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SRW
+*
+* DESCRIPTION
+*	This function is to query if card can support Suspend/Resume
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SRW(void)
+{   
+   return ((gSDIO.capability&0x4)>>2);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_SBS
+*
+* DESCRIPTION
+*	This function is to query if card can support Read/Wait
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_SBS(void)
+{   
+   return ((gSDIO.capability&0x8)>>3);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_S4MI
+*
+* DESCRIPTION
+*	This function is to query if card can support interrupt during multiple block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_S4MI(void)
+{   
+   return ((gSDIO.capability&0x10)>>4);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_E4MI
+*
+* DESCRIPTION
+*	This function is to enable interrupt during multiple block
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_E4MI(kal_bool enable)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   kal_uint8 temp_data; 
+   
+   if(!SDIO_support_S4MI())
+      return SDIO_4MI_NOT_SUPPORT;
+   
+   cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 8;
+	if(enable)
+	{
+	   cmd52.data = 0x20;
+	   temp_data=0x20;
+	}   
+	else
+	{
+	   cmd52.data = 0;
+	   temp_data=0;
+	}   
+	if((status = SDIO_Cmd52(&cmd52))==NO_ERROR)
+	{
+	   /*double check*/
+	   cmd52.rw = SDIO_READ;   
+	   status = SDIO_Cmd52(&cmd52);	      
+	   if((cmd52.data&0x20)!=temp_data)	   
+	      ASSERT(0);	   
+	          
+	   if(enable)
+	      gSDIO.capability|=0x20;	   
+	   else
+	     gSDIO.capability&=~0x20;	       	   	   	   
+	}   	
+	
+	return status;		      
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_E4MI
+*
+* DESCRIPTION
+*	This function is to query if card is a low speed card
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_LSC(void)
+{   
+   return ((gSDIO.capability&0x40)>>6);   
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_support_4BLS
+*
+* DESCRIPTION
+*	This function is to query if card can support 4-bits in low speed card
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  support or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_bool SDIO_support_4BLS(void)
+{   
+   return ((gSDIO.capability&0x80)>>7);   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_configure_bus
+*
+* DESCRIPTION
+*	This function is to configure bus width
+*
+* PARAMETERS
+*  bus: bus width
+*
+* RETURNS
+*  bus
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_bus(SD_BITWIDTH bus)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 7;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{	   
+	   return status;	   
+	}   
+	cmd52.data &= ~0x3;
+	cmd52.data |= (bus|0x80);/*also disable card detection*/
+	cmd52.rw = SDIO_WRITE;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{	 
+	   return status;
+	}   
+	gSDIO.bit_width=bus;
+	if(bus==BIT_4W)	
+	   MSDC_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);	        
+	
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_IO
+*
+* DESCRIPTION
+*	This function is to enable function
+*
+* PARAMETERS
+*  function: function id
+*  enable: enable or disable
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO(SDIO_function_id_enum function, kal_bool enable)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 2;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;	   
+	}   
+	if(enable)   	
+	   cmd52.data |= (function<<1);	
+	else   	
+	   cmd52.data &= ~(function<<1);	 
+		
+	cmd52.rw = SDIO_WRITE;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;
+	}   
+   SDIO_resume_IO(SDIO_FUCN_0); 
+	return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_ready
+*
+* DESCRIPTION
+*	This function is to check function status
+*
+* PARAMETERS
+*  function: function id
+*  *ready: ready or not
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready(SDIO_function_id_enum function, kal_bool *ready)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 3;
+	status = SDIO_Cmd52(&cmd52);	   
+	*ready=(cmd52.data&(1<<function))>>function;		   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_enable_IO_Int
+*
+* DESCRIPTION
+*	This function is to configure function interrupt enable
+*
+* PARAMETERS
+*  function: function id
+*  enable: enable or diable
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO_Int(SDIO_function_id_enum function, kal_bool enable)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 4;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	{
+	   SDIO_resume_IO(SDIO_FUCN_0); 
+	   return status;	   
+	}	   
+	if(enable)   	
+	   cmd52.data |= (1<<function);	
+	else   	
+	   cmd52.data &= ~(1<<function);	 
+		
+	cmd52.rw = SDIO_WRITE;
+		
+	status = SDIO_Cmd52(&cmd52);	      	   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_int_registration
+*
+* DESCRIPTION
+*	This function is to register interrupt handler
+*
+* PARAMETERS
+*  function: function id
+*  func: interrupt handler
+* RETURNS
+*  None
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+void SDIO_int_registration(SDIO_function_id_enum function, void (func)(void))
+{   
+   gSDIO.callback[function]=func;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_HISR_Entry
+*
+* DESCRIPTION
+*	This function is to handle SDIO interrupt
+*
+* PARAMETERS
+*  None 
+*
+* RETURNS
+*  None
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS int_status;
+void SDIO_HISR_Entry(void)
+{
+   
+   cmd52_config_struct cmd52;
+   kal_uint32 count;   
+   if(gSDIO.state!=CMD&&gSDIO.state!=TRN)		      
+   {
+      #ifdef MSDC_INT
+		kal_set_eg_events(msdc2_sdio->MSDC_Events,EVENT_SDMCIRQ,KAL_OR);		      		
+		#endif
+	}	
+   else
+   {   
+      #if 1
+	   cmd52.rw = SDIO_READ;
+	   cmd52.func = 0;
+	   cmd52.raw = KAL_FALSE;
+	   cmd52.stop = KAL_FALSE;
+	   cmd52.adrs = 5;
+	   
+	   if((int_status = SDIO_Cmd52_isr(&cmd52))==NO_ERROR)	
+	   { 
+         for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)	
+         {
+            if(cmd52.data&(1<<count))
+               gSDIO.callback[count]();
+         }
+      }
+      else
+      {
+        /*dbg_print("int read failed\r\n");*/
+      }    
+      #endif        
+   }            
+}   
+
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_Int
+*
+* DESCRIPTION
+*	This function is to check interrupt status
+*
+* PARAMETERS
+*  function: function id
+*  *pending: interrupt status 
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/  
+SDC_CMD_STATUS SDIO_check_IO_Int(SDIO_function_id_enum function, kal_bool *pending)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 5;
+	status = SDIO_Cmd52(&cmd52);	
+	*pending=(cmd52.data&(1<<function))>>function;		   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_configure_BLK_size
+*
+* DESCRIPTION
+*	This function is to configure block size
+*
+* PARAMETERS
+*  function: function id
+*  size: block size
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_BLK_size(SDIO_function_id_enum function, kal_uint32 size)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0x10+0x100*function;
+	cmd52.data = size&0xff;
+	status = SDIO_Cmd52(&cmd52);	   
+   if(size>=256)
+   {
+	   cmd52.adrs = 0x11+0x100*function;
+	   cmd52.data = (size&0xff00)>>8;    
+	   status = SDIO_Cmd52(&cmd52);	   
+	}   
+   if(status==NO_ERROR)					   
+   {
+	   gSDIO.block_size[function]=size;   	   		
+	   /*set block length as size*/
+	   BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)size,SDC_CFG_BLKLEN);
+	}   
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_query_BLK_size
+*
+* DESCRIPTION
+*	This function is to query function's maximum block size
+*
+* PARAMETERS
+*  function: function id
+*
+* RETURNS
+*  size: block size
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/
+kal_uint32 SDIO_query_BLK_size(SDIO_function_id_enum function)
+{
+   kal_uint32 max_block_size;
+   kal_uint32 i;
+   for(i=0;i<SDIO_TUPLE_SIZE;i++) 
+   {      
+      if(sdio_tuple[function][i]==0x22)
+      {
+         if(function==SDIO_FUCN_0)   
+            max_block_size=(sdio_tuple[function][i+3])|(sdio_tuple[function][i+4]<<8);
+         else
+            max_block_size=(sdio_tuple[function][i+14])|(sdio_tuple[function][i+15]<<8);   
+         return   max_block_size;         
+      }  
+   }
+   return 0;         
+}  
+/*************************************************************************
+* FUNCTION
+*  SDIO_query_IO_id
+*
+* DESCRIPTION
+*	This function is to query application function id
+*
+* PARAMETERS
+*  ap: application type
+*
+* RETURNS
+*  function: function id
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDIO_function_id_enum SDIO_query_IO_id(SDIO_interface_code_enum ap)
+{
+   switch(ap)
+   {
+      case SDIO_INTERFACE_NULL:        
+      break;      
+      case SDIO_INTERFACE_UART:
+      break;
+      case SDIO_INTERFACE_A_BT:
+      break;
+      case SDIO_INTERFACE_B_BT:
+      break;
+      case SDIO_INTERFACE_GPS:
+      break;
+      case SDIO_INTERFACE_CAMERA:
+      break;
+      case SDIO_INTERFACE_PHS:
+      break;
+      case SDIO_INTERFACE_WLAN:
+         return 1;
+      break;
+      default:
+      break;
+   }   
+   return 0;
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_SW_reset
+*
+* DESCRIPTION
+*	This function is to reset all I/O function
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDC_CMD_STATUS SDIO_SW_reset(void)
+{
+   cmd52_config_struct cmd52;
+   SDC_CMD_STATUS status;
+      
+   /*use CMD52 to reset card*/	   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 6;
+	cmd52.data = 0xff;
+	status=SDIO_Cmd52(&cmd52);	   	
+	return status; 
+}   
+/*************************************************************************
+* FUNCTION
+*  SDIO_abort_IO
+*
+* DESCRIPTION
+*	This function is to abort function
+*
+* PARAMETERS
+*  function:function id
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+SDC_CMD_STATUS SDIO_abort_IO(SDIO_function_id_enum function)
+{   
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+   SDIO_dispatch_IO(SDIO_FUCN_0);
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 6;
+	cmd52.data = function&0x7;						
+	status = SDIO_Cmd52(&cmd52);  			   	   		
+	SDIO_resume_IO(SDIO_FUCN_0); 
+	return status;
+}
+/*Function for WiFi */
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Write
+*
+* DESCRIPTION
+*	This function is to write register
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/ 
+/*Write Register*/
+kal_bool SDIO_Register_Write(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 data,
+                             cmd53_op_enum op)
+{
+
+	kal_uint32 tmp = data;
+   cmd53_config_struct cmd53;
+   
+   SDIO_dispatch_IO(function);
+	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)&tmp;
+	cmd53.count = 4;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	      
+	}   	   
+}                                                         
+kal_bool SDIO_Register_Write_isr(SDIO_function_id_enum function, 
+                                 kal_uint32 addr, 
+                                 kal_uint32 data,
+                                 cmd53_op_enum op)
+{
+
+	kal_uint32 tmp = data;
+        cmd53_config_struct cmd53;
+      
+	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)&tmp;
+	cmd53.count = 4;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+	{	   
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   return KAL_TRUE;   	      
+	}   	   
+}                                                         
+/*Write Data */   
+/*************************************************************************
+* FUNCTION
+*  SDIO_Data_Write
+*
+* DESCRIPTION
+*	This function is to write memory
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*  count: transfer count
+*  block: block/byte mode 
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/                           
+kal_bool SDIO_Data_Write(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint8  *data,
+                             cmd53_op_enum op,
+                             kal_uint32 count,
+                             kal_bool block)
+{
+   cmd53_config_struct cmd53;
+   //kal_uint32 size, i;
+   //kal_uint32 sdio_buffer[256];
+   
+   SDIO_dispatch_IO(function);
+   #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+   #endif 
+ 	cmd53.rw = SDIO_WRITE;
+	cmd53.func = function;
+	cmd53.block = block;
+	cmd53.buffer = (kal_uint32)data;//(kal_uint32)&sdio_buffer[0];
+	cmd53.count = count;
+	cmd53.op = op; 
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Read
+*
+* DESCRIPTION
+*	This function is to Read register
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	
+*************************************************************************/                                                        
+/*Read Register*/
+kal_bool SDIO_Register_Read(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 *data,
+                             cmd53_op_enum op)
+{
+   cmd53_config_struct cmd53;
+   
+   SDIO_dispatch_IO(function);
+	cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)data;
+	cmd53.count = 4;
+	cmd53.op = op;;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))	
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	      
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Register_Read_poll
+*
+* DESCRIPTION
+*	This function is to Read register by SDIO bus driver
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*	only for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_Register_Read_poll(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint32 *data,
+                             cmd53_op_enum op)
+{
+   cmd53_config_struct cmd53;
+   
+	cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = KAL_FALSE;
+	cmd53.buffer = (kal_uint32)data;
+	cmd53.count = 4;
+	cmd53.op = op;;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))	
+	{
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   return KAL_TRUE;   	      
+	}   
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_Data_Read
+*
+* DESCRIPTION
+*	This function is to read memory
+*
+* PARAMETERS
+*  function:function id
+*  addr: address
+*  data: write data
+*  op: fixed or incrementing address
+*  count: transfer count
+*  block: block/byte mode 
+*
+* RETURNS
+*  success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Read(SDIO_function_id_enum function, 
+                             kal_uint32 addr, 
+                             kal_uint8  *data,
+                             cmd53_op_enum op,
+                             kal_uint32 count,
+                             kal_bool block)
+{
+   cmd53_config_struct cmd53;
+   SDIO_dispatch_IO(function);
+   cmd53.rw = SDIO_READ;
+	cmd53.func = function;
+	cmd53.block = block;
+	cmd53.buffer = (kal_uint32)data;
+	cmd53.count = count;
+	cmd53.op = op;
+	cmd53.adrs = (kal_uint32)addr;
+	if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_FALSE;   	   
+	}   
+	else   
+	{
+	   SDIO_resume_IO(function);
+	   return KAL_TRUE;   	  	   
+	}      
+}                                
+   
+/*not support in MT6228 and MT6229*/
+#ifdef __SDIO_SRW_SRW__
+/*************************************************************************
+* FUNCTION
+*  SDIO_suspend_IO
+*
+* DESCRIPTION
+*	This function is to suspend function
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_suspend_IO(SDIO_bus_status_enum *bus_status)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_TRUE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xc;
+	cmd52.data = 1;						
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   	
+	*bus_status=(cmd52.data&0x2)>>1;
+			   	   		
+	return NO_ERROR;      
+}   
+
+/*************************************************************************
+* FUNCTION
+*  SDIO_select_IO
+*
+* DESCRIPTION
+*	This function is to resume function
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_select_IO(SDIO_function_id_enum function, kal_bool *resume_data)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_WRITE;
+	cmd52.func = 0;
+	cmd52.raw = KAL_TRUE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xd;
+	cmd52.data = function&0xf;						
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   	
+	*resume_data=(cmd52.data&0x80)>>7;
+			   	   		
+	return NO_ERROR;         
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_exec
+*
+* DESCRIPTION
+*	This function is to check function execution status
+*
+* PARAMETERS
+*  execute_status: execute status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/   
+SDC_CMD_STATUS SDIO_check_IO_exec(SDIO_function_id_enum function, kal_bool *execution)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xe;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   			
+	if(function!=SDIO_FUCN_MEM)		 
+	   *execution=(cmd52.data&(1<<function))>>function ;									   	   		
+	else
+	   *execution=cmd52.data&0x1;									   	   		
+	   
+	return NO_ERROR;         
+}
+/*************************************************************************
+* FUNCTION
+*  SDIO_check_IO_ready_flag
+*
+* DESCRIPTION
+*	This function is to check function execution status
+*
+* PARAMETERS
+*  bus_status: bus status
+*
+* RETURNS
+*  SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready_flag(SDIO_function_id_enum function, kal_bool *ready)
+{
+   SDC_CMD_STATUS status;
+   cmd52_config_struct cmd52;
+   
+	cmd52.rw = SDIO_READ;
+	cmd52.func = 0;
+	cmd52.raw = KAL_FALSE;
+	cmd52.stop = KAL_FALSE;
+	cmd52.adrs = 0xf;
+	if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+	   return status;	   			
+	if(function!=SDIO_FUCN_MEM)		 
+	   *ready=(cmd52.data&(1<<function))>>function ;									   	   		
+	else
+	   *ready=cmd52.data&0x1;									   	   		
+	   
+	return NO_ERROR;         
+}
+#endif
+#endif
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdiotest.c b/mcu/driver/storage/mc/src/sdiotest.c
new file mode 100644
index 0000000..7cda55b
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdiotest.c
@@ -0,0 +1,596 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2001
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   sdiotest.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   SDIO test code
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+ 
+// MTK 
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "reg_base.h" 
+#include "intrCtrl.h"
+
+// SDIO
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+#include "sdio_test.h"
+#include "sdio_sw.h"
+
+#if (defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)) || defined(__MSDC2_SD_SDIO__)
+extern cmd52_config_struct cmd52_config;
+extern cmd53_config_struct cmd53_config;
+#define WIFI_FUNC		1
+
+
+
+__align(4) kal_uint8 buffer[1024];
+extern __align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+extern __align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+extern __align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+volatile kal_uint32 cmd = 0, arg = 0;
+volatile kal_uint32 flag52 = 1, flag53 = 0, flag_SD = 0, flag_4bit = 1;
+cmd52_config_struct cmd52_config;
+cmd53_config_struct cmd53_config;
+void SDIO_test_main2(void);
+extern MSDC_HANDLE *msdc2_handle ;
+
+void sdio_clr_int(void)
+{
+   UINT32      mcrValue;
+   //SDIO_Register_Read_poll(SDIO_FUCN_1, MCR_ISAR, (kal_uint32*)&mcrValue , SDIO_FIX);   
+   //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);   
+}
+void test_hisr(void) 
+{
+   dbg_print("interrupt callback\r\n");	
+   sdio_clr_int();							
+}   
+ 
+
+void test_sdio_ini(void)
+{
+	SDC_CMD_STATUS status;	
+	kal_uint8 version;
+	kal_uint16 tick;
+	kal_bool ready;
+	kal_uint32 retry_count=0;
+	kal_uint32 block_size=0;
+	
+	
+	/*initialize*/
+	dbg_print("SDIO initilaization start\r\n");				
+	status=SDIO_Initialize();
+	dbg_print("SDIO initilaization end=%d\r\n", status);
+	dbg_print("SDIO test start\r\n");
+	
+	/*CCCR verison*/	
+	status=SDIO_read_CCCR_ver(&version);
+	dbg_print("read CCCR ver status %d ver %d \r\n", status, version);								
+	/*SDIO verison*/	
+   status=SDIO_read_SDIO_ver(&version);
+   dbg_print("read SDIO ver status %d ver %d \r\n", status, version);										
+	/*SD verison*/	
+	status=SDIO_read_SD_ver(&version);
+   dbg_print("read SDIO SD status %d ver %d \r\n", status, version);								
+
+	/* check card capability*/	
+	status=SDIO_read_capacity();
+	if(!status)
+	{		
+		dbg_print("SDC %d%\r\n", SDIO_support_SDC());							
+		dbg_print("SMB %d%\r\n", SDIO_support_SMB());							
+		dbg_print("SRW %d%\r\n", SDIO_support_SRW());							
+		dbg_print("SBS %d%\r\n", SDIO_support_SBS());							
+		dbg_print("S4MI %d%\r\n", SDIO_support_S4MI());							
+		//dbg_print("E4MI %d%\r\n", SDIO_enable_E4MI(KAL_TRUE));							
+		dbg_print("LSC %d%\r\n", SDIO_support_LSC());							
+		dbg_print("4BLS %d%\r\n", SDIO_support_4BLS());										
+	}
+	else
+	{
+		dbg_print("read capacity %d failed \r\n", cmd52_config.adrs);						
+	}	
+		
+	/* enable SDIO function*/	
+	retry_count=0;
+	
+				
+   /* set the block size of func1 to 128*/
+			   	   						
+	dbg_print("set function block size %d \r\n", 128);						
+		
+	status=SDIO_configure_BLK_size(SDIO_FUCN_1, 128);
+	dbg_print("set block size (function 1) %d\r\n", status);												
+	status=SDIO_configure_BLK_size(SDIO_FUCN_0, 128);
+	dbg_print("set block size(function 0) %d\r\n", status);																
+	
+	// config the sdio controller
+	MSDC_SetBits32(SDC_CFG, SDC_CFG_SDIO);// enable SDIO mode
+	MSDC_WriteReg32(SDIO_CFG, 1); // enable SDIO interrupt
+	
+	// *****************************************//
+	// always turn on the serial clock
+	// MSDC_SetBits32(MSDC_CFG, MSDC_CFG_SCKON);
+	// *****************************************//	
+
+	
+	
+	status=SDIO_query_IO_id(SDIO_INTERFACE_WLAN);
+	dbg_print("SDIO_INTERFACE_WLAN function id =%d\r\n", status);	
+	
+	status=SDIO_query_IO_id(SDIO_INTERFACE_WLAN);
+	dbg_print("SDIO_INTERFACE_WLAN function id =%d\r\n", status);					  
+	block_size=SDIO_query_BLK_size(SDIO_FUCN_1);
+	dbg_print("function 1 block size =%d\r\n", block_size);					  
+	
+	SDIO_int_registration(SDIO_FUCN_1, test_hisr);
+	status=SDIO_enable_IO_Int(SDIO_FUCN_0, KAL_TRUE);
+	dbg_print("enable card int%d \r\n",status);		
+	status=SDIO_enable_IO_Int(SDIO_FUCN_1, KAL_TRUE);
+	dbg_print("enable function %d int%d \r\n",SDIO_FUCN_1, status);		
+	/* read all configuration register of CCCR*/	
+	status=SDIO_read_CCCR();
+	dbg_print("read all CCCR=%d\r\n", status);
+	status=SDIO_read_FBR(1);
+	dbg_print("read all FBR=%d\r\n", status);	
+	
+	
+	/*start WiFi test*/
+#ifndef MSDC2_SDIO_DVT
+	if(KAL_TRUE == gMSDC_Handle->mIsInitialized)
+#else
+	if(KAL_TRUE == msdc2_handle->mIsInitialized)
+#endif
+	{
+		SDIO_test_main2();
+		SDIO_test_main();	
+	}
+	else{
+		return;
+	}
+	while(0)
+	{
+		if(flag52)
+		{
+			cmd52_config.rw = SDIO_READ;
+			cmd52_config.func = 0;
+			cmd52_config.raw = KAL_FALSE;
+			cmd52_config.stop = KAL_FALSE;
+			cmd52_config.adrs = 0;
+			cmd52_config.data = 0;
+			SDIO_Cmd52(&cmd52_config);
+		}
+		// check SMB first (Support Multi-Block)
+		// config the block size
+		if(flag53)
+		{
+			cmd53_config.rw = SDIO_READ;
+			cmd53_config.func = 0;
+			cmd53_config.block = KAL_FALSE;
+			cmd53_config.buffer = (kal_uint32)buffer;
+			cmd53_config.count = 4;
+			cmd53_config.op = SDIO_INC;
+			cmd53_config.adrs = 0;
+			SDIO_Cmd53(&cmd53_config);
+			//dbg_print("SDIO initilaization end=%d\r\n", status);
+		}
+	}
+	
+}
+
+
+
+kal_bool IPC_2126_MCR_Read(kal_uint16 offset, kal_uint32 *pValue)
+{  
+	kal_bool status;
+   #if 1
+   status = SDIO_Register_Read(SDIO_FUCN_1, 
+                      (kal_uint32) offset, 
+                      pValue,
+                      SDIO_FIX);
+   return status;
+   #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+   #endif
+}
+void IPC_2126_MCR_Read_N(kal_uint16 offset, kal_uint32 pValue, kal_uint32 count, kal_bool block )
+{
+	cmd53_config.rw = SDIO_READ;
+	cmd53_config.func = WIFI_FUNC;
+	cmd53_config.block = block;
+	cmd53_config.buffer = (kal_uint32)pValue;
+	cmd53_config.count = count;
+	cmd53_config.op = SDIO_FIX;
+	cmd53_config.adrs = (kal_uint32)offset;
+	SDIO_Cmd53(&cmd53_config);
+
+}
+kal_bool IPC_2126_MCR_Write(kal_uint16 offset, kal_uint32 value)
+{
+	kal_uint32 tmp = value;
+	kal_bool	status;
+	#if 1
+   status = SDIO_Register_Write(SDIO_FUCN_1, 
+                      (kal_uint32) offset, 
+                      value,
+                      SDIO_FIX);
+	
+	return status;
+   #else                                              
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+   #endif
+}
+void IPC_2126_MCR_Write_N(kal_uint16 offset, kal_uint32 value, kal_uint32 count, kal_bool block )
+{
+	cmd53_config.rw = SDIO_WRITE;
+	cmd53_config.func = WIFI_FUNC;
+	cmd53_config.block = block;
+	cmd53_config.buffer = (kal_uint32)value;
+	cmd53_config.count = count;	
+	cmd53_config.op = SDIO_FIX;
+	cmd53_config.adrs = (kal_uint32)offset;
+	SDIO_Cmd53(&cmd53_config);
+
+}
+/*----------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param
+* \return
+*/
+/*----------------------------------------------------------------*/
+volatile kal_bool my_flag = 1;
+volatile kal_bool my_flag_2 = 0;
+__align(4) kal_uint8       value[1024]= {0xff};
+int SDIO_test_main(void)
+{
+    kal_uint32      mcrValue;
+    int         tbttCount = 0;
+    kal_uint32 test_count=0;
+    kal_bool pending;
+         SDC_CMD_STATUS status;
+    //SDIO_ARG    arg;
+
+    kal_uint32  i;
+    kal_uint32	loopTestIndex;
+
+    /* Reset chip and enable all clocks */
+    NIC_MCR_WRITE(NULL, MCR_SCR, (SCR_BB_MRST | SCR_MAC_RST |
+                SCR_BB_SIORST | SCR_MAC_REGRST));
+    NIC_MCR_WRITE(NULL, MCR_SCR, SCR_CLK_ALL_EN);
+    NIC_MCR_READ(NULL, MCR_SCR, value);
+
+    /* Here maybe need delay for OSC stable */
+	 for(i=0;i<10000;i++);
+
+    /* Check chip ID */
+    NIC_MCR_READ(NULL, MCR_PCICR, &mcrValue);
+    //printk("IPN2128 ChipIDVersion read test: [0x%08lX] \n", mcrValue);
+    if ((mcrValue & CHIP_ID_MASK) != CHIP_ID_REV) {
+        //printk(KERN_ALERT "IPN2128 not found... \n");
+    }
+    //if(my_flag)
+    NIC_MCR_WRITE(NULL, MCR_SDCR, BITS(4,6)); /* Use enhanced mode */
+
+    /* Reset TSF and enable TBTT interrupt */
+    /* Set our local TSF timer to 0 */
+    NIC_MCR_WRITE(NULL, MCR_TTAR1, 0);
+    NIC_MCR_WRITE(NULL, MCR_TTAR2, 0);
+    NIC_MCR_WRITE(NULL, MCR_TTAR0, TTAR0_TSF_TIMER_VALUE_CHANGE);
+
+    /* Set the next TBTT time and the TBTT event generation period. */
+    NIC_MCR_WRITE(NULL, MCR_NTTCR, ((100) &
+        NTTCR_NEXT_TBTT_TIME) | (100 << 16));
+
+    /* Enable the TBTT event generator. */
+    NIC_MCR_WRITE(NULL, MCR_MPTCR, MPTCR_EN_COMP_NEXT_TBTT_TIME | MPTCR_TBTT_ENABLE);
+
+    /* Enable interrupt */ //IER_PRE_TBTT_INT, IER_SDIO_ABNORMAL_INT
+    NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_TBTT_INT);
+    NIC_MCR_READ(NULL, MCR_IER, &mcrValue);
+
+    /* In loop, cmd53 is repeated to test interrupt event with cmd53 read */
+    while (1) 
+    {
+         
+			/*cmd52_config.rw = SDIO_READ;
+			cmd52_config.func = 0;
+			cmd52_config.raw = KAL_FALSE;
+			cmd52_config.stop = KAL_FALSE;
+			cmd52_config.adrs = 5;
+			cmd52_config.data = 0;
+			SDIO_Cmd52(&cmd52_config);*/
+       //status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  
+		 //if(	pending != 0 )  
+		 if(mcrValue!=0)
+		 {
+		 	tbttCount++;
+		 	dbg_print("Int Pending %d \r\n", pending);								
+		 	dbg_print("TBTT count %d \r\n", tbttCount);								
+		 	NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+		 	dbg_print("ISAR %d \r\n", mcrValue);										 		
+		 }
+		 else 
+		   NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+    	/*
+        NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); 
+        if (mcrValue & ISAR_TBTT_INT) {
+            tbttCount++;
+            //printk("TBTT event occurs %d\n", tbttCount);
+		*/
+        if (tbttCount >= 10) break; /* 10sec */
+
+    }
+
+    /* Enable interrupt of abnormal interrupt */
+    NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_SDIO_ABNORMAL_INT);
+    NIC_MCR_READ(NULL, MCR_IER, &mcrValue);
+
+#if 1
+    /* Do illegal (byte/block) Read/Write to trigger abnormal interrupt */
+    loopTestIndex = 30;
+    while (loopTestIndex--) 
+    {
+			kal_uint8 test;
+			
+			dbg_print("start %d int test\r\n", test_count);										 		
+        
+			test = 0;
+
+			test++;
+        IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0],8, KAL_FALSE);
+        status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  
+#ifndef MSDC2_SDIO_DVT
+			if(MSDC_Reg(SDIO_STA) == 1)
+#else
+			if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+				test--;
+        //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+        //dbg_print("ISAR %d \r\n", mcrValue);										 		
+			if(test)
+				ASSERT(0);
+
+			test++;
+		  IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0],8, KAL_FALSE);
+		  status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  
+#ifndef MSDC2_SDIO_DVT
+		  			if(MSDC_Reg(SDIO_STA) == 1)
+#else
+			if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+				test--;
+        //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+        //dbg_print("ISAR %d \r\n", mcrValue);										 		
+			if(test)
+				ASSERT(0);
+
+			test++;
+        IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0], 1, KAL_TRUE);
+        status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  
+#ifndef MSDC2_SDIO_DVT
+			if(MSDC_Reg(SDIO_STA) == 1)
+#else
+			if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+				test--;
+        NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+        //dbg_print("ISAR %d \r\n", mcrValue);										 		
+			if(test)
+				ASSERT(0);
+
+        test++;
+        IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 1, KAL_TRUE);
+        status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  
+#ifndef MSDC2_SDIO_DVT
+			if(MSDC_Reg(SDIO_STA) == 1)
+#else
+			if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+				test--;
+        //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+        //dbg_print("ISAR %d \r\n", mcrValue);										 		
+			if(test)
+				ASSERT(0);
+
+ #if 0
+ 		#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+      #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+      #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+		#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+        if(my_flag_2)
+        		break;
+    }
+#endif
+
+    return 0;
+} /* end of main() */
+
+   
+void SDIO_test_main2(void)
+{
+    UINT32      mcrValue;
+    UINT32      tmcrValue;
+    UINT32      i;
+    UINT8       mcr[4];
+    int         tbttCount;
+    SDC_CMD_STATUS status;
+    kal_uint32 j;
+    
+    
+    /* Reset chip and enable all clocks */
+    NIC_MCR_WRITE(NULL, MCR_SCR, (SCR_BB_MRST | SCR_MAC_RST |
+                SCR_BB_SIORST | SCR_MAC_REGRST));
+    for(j=0;j<100000;j++);                
+    /* Here delay 1us to complete reset process */
+    NIC_MCR_WRITE(NULL, MCR_SCR, SCR_CLK_ALL_EN);    
+    /* Check chip ID */
+    NIC_MCR_READ(NULL, MCR_PCICR, &mcrValue);
+    IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+   //SDIO_Register_Read(SDIO_FUCN_1, MCR_PCICR, (kal_uint32*)&tmcrValue, SDIO_FIX);
+    //SDIO_Data_Read(SDIO_FUCN_1, MCR_PCICR, &mcr[0], SDIO_FIX, 4, KAL_FALSE);
+    
+    //printk("IPN2128 ChipIDVersion read test: [0x%08lX] \n", mcrValue);
+    if ((mcrValue & CHIP_ID_MASK) != CHIP_ID_REV) {
+        //printk(KERN_ALERT "IPN2128 not found... \n");
+    }
+    NIC_MCR_WRITE(NULL, MCR_SDCR, BITS(4,6)); /* Use enhanced mode */
+
+    /* Reset TSF and enable TBTT interrupt */
+    /* Set our local TSF timer to 0 */
+    NIC_MCR_WRITE(NULL, MCR_TTAR1, 0);
+    NIC_MCR_WRITE(NULL, MCR_TTAR2, 0);
+    NIC_MCR_WRITE(NULL, MCR_TTAR0, TTAR0_TSF_TIMER_VALUE_CHANGE);
+
+    /* Set the next TBTT time and the TBTT event generation period (20ms). */
+    NIC_MCR_WRITE(NULL, MCR_NTTCR, ((100) &
+        NTTCR_NEXT_TBTT_TIME) | (20 << 16));
+
+    /* Enable the TBTT event generator. */
+    NIC_MCR_WRITE(NULL, MCR_MPTCR, MPTCR_EN_COMP_NEXT_TBTT_TIME | MPTCR_TBTT_ENABLE);
+
+    /* Enable interrupt */
+    NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_TBTT_INT | IER_SDIO_ABNORMAL_INT);
+ 
+#if 1
+    /* In loop, cmd53 is repeated to test interrupt event with cmd53 read */
+    tbttCount = 0;
+    dbg_print("trigger interrupt during sigle block \r\n");
+    while (1) 
+    {
+        kal_bool pending;
+        //status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);  		 
+        NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+        if (mcrValue & ISAR_TBTT_INT) 
+        {
+            kal_uint32 test_count;
+            tbttCount++;
+            dbg_print("TBTT event occurs %d\r\n", tbttCount);
+            for(test_count=0;test_count<100;test_count++)
+            {}
+            if (tbttCount >= 100) break; /* 10sec */
+        }       
+    }
+#endif
+
+#if 1
+    /* Read/Writel multiple block with TBTT interrupt */
+    while (1) {
+    	/*
+        arg = BUILD_IO_RW_EXTENDED_ARG(SDIO_RWFLAG_WRITE,
+            1, SDIO_IO_BLOCK_MODE, SDIO_IO_FIX_ADDR, 0x0128, 4);
+        sdioCmd53ReadWrite(x_slot, arg, (__u8*)&value[0]);
+		*/
+
+
+      /*
+        arg = BUILD_IO_RW_EXTENDED_ARG(SDIO_RWFLAG_READ,
+            1, SDIO_IO_BLOCK_MODE, SDIO_IO_FIX_ADDR, 0x0128, 4);
+        sdioCmd53ReadWrite(x_slot, arg, (__u8*)&value[0]);
+		*/
+		   dbg_print("trigger interrupt during multiple block \r\n");
+			memset(value, 0, 1024);
+		  IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+		  //memset(value, 0x5, 1024);
+    		NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+    		//IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 128, KAL_FALSE);
+    		//IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[128], 128, KAL_FALSE);
+    		//IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[256], 128, KAL_FALSE);
+    		//IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[384], 128, KAL_FALSE);
+    		//memset(value, 0x5, 1024);
+    		NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+	     IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+	     NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+        NIC_MCR_READ(NULL, 0x118, &mcrValue);
+
+        if(my_flag)
+        		break;
+
+
+    }
+#endif
+
+}
+#endif
+
+
diff --git a/mcu/driver/storage/mc/src/usbms_msdc.c b/mcu/driver/storage/mc/src/usbms_msdc.c
new file mode 100644
index 0000000..fafceb6
--- /dev/null
+++ b/mcu/driver/storage/mc/src/usbms_msdc.c
@@ -0,0 +1,784 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    usbms_msdc.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *  This file implements usb adaption layer of msdc card for mass storage
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+#if defined(__USB_MSD_SUPPORT__) || defined(ATEST_DRV_MSDC)
+
+//RHR ADD
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+#include "drv_comm.h"
+#include "gpt_sw.h"
+#include "usb_comm.h"
+#include "usb_drv.h"
+#include "usb.h"
+#include "usbms_drv.h"
+#include "usbms_adap.h"
+#include "usb_custom.h"
+#include "Rtfiles.h"
+#include "fat_fs.h"
+#include "custom_fs.h"
+*/
+//RHR
+#include "msdc_def.h"
+#include "fs_type.h"
+/***********************************************
+	MS and SD Disk Related functions
+************************************************/
+
+//#if !defined(DCL_MSDC_INTERFACE)
+#include "msdc_def.h"
+//#endif
+
+#ifdef __MSDC_MS__
+	#include "ms_def.h"
+	extern FS_Driver FS_MsDrv;
+	FS_Driver *CardDrv = &FS_MsDrv;
+#elif defined(__MSDC_MSPRO__)	
+	#include "mspro_def.h"	
+	FS_Driver *CardDrv = &FS_MspDrvAll;		
+#elif defined(__MSDC_SD_MMC__)
+	#if defined(DCL_MSDC_INTERFACE)
+	#include "dcl.h"
+	#else
+	#include "sd_def.h"
+	#endif
+	extern FS_Driver FS_SdDrv;
+	FS_Driver *CardDrv = &FS_SdDrv;
+#endif
+
+#include "qmu_bm.h"
+#include "usbms_msdc.h"
+
+extern int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors,qbm_gpd *head,qbm_gpd *tail);
+extern int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, qbm_gpd *head,qbm_gpd *tail);
+extern kal_uint32 Get_BDStructNum(void);
+kal_bool usbms_query_max_bd_num(kal_uint16 * max_bd_num)
+{
+    *max_bd_num = (kal_uint16)Get_BDStructNum();
+    return KAL_TRUE;
+}
+#if ( (defined(__MSDC_MS__)) || (defined(__MSDC_SD_MMC__)) || (defined(__MSDC_MSPRO__)) )
+kal_bool usbms_read_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type)
+{
+	kal_int32 status;
+	void *ID = NULL;
+	ASSERT(CardDrv != NULL);
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+		default:
+			ID = NULL;
+			return KAL_FALSE;			
+	}	
+	
+	status = CardDrv->ReadSectors((void*)ID, LBA, sec_len, data);
+
+	if(status)
+		return KAL_FALSE;
+
+	return KAL_TRUE;
+}
+kal_bool usbms_gpd_read_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type)
+{
+    kal_int32 status;
+	void *ID = NULL;
+	ASSERT(CardDrv != NULL);
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+		default:
+			ID = NULL;
+			return KAL_FALSE;			
+	}	
+	status = Gpd_ReadSectors_NEW((void*)ID, LBA, sec_len, head,tail);
+
+	if(status)
+		return KAL_FALSE;
+
+	return KAL_TRUE;
+}
+kal_bool usbms_write_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type)
+{
+	kal_int32 status;
+	void *ID = NULL;
+	ASSERT(CardDrv != NULL);
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+		default:
+			ID = NULL;
+			return KAL_FALSE;		
+	}
+	
+	status = CardDrv->WriteSectors((void*)ID, LBA, sec_len, data);	
+	
+	if(status)
+		return KAL_FALSE;
+
+	return KAL_TRUE;
+}
+kal_bool usbms_gpd_write_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type)
+{
+    kal_int32 status;
+	void *ID = NULL;
+	ASSERT(CardDrv != NULL);
+
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+		default:
+			ID = NULL;
+			return KAL_FALSE;			
+	}	
+	status = Gpd_WriteSectors_NEW((void*)ID, LBA, sec_len, head,tail);
+
+	if(status)
+		return KAL_FALSE;
+
+	return KAL_TRUE;
+}
+
+/*
+typedef  enum{
+ 	USB_MS_EXIST,
+ 	USB_MS_CHANGED,
+ 	USB_MS_NOT_EXIST,
+ 	USB_MS_LOCKED
+}USB_MS_EXIST_ENUM;
+*/
+/*status =0(ok),1(MediaChanged),2(NoMedia)*/
+
+#if defined(DCL_MSDC_INTERFACE)
+
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type)
+{
+	DCL_BOOL changed = DCL_FALSE;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;	
+	DCL_BOOL isCardExist = DCL_FALSE;
+	DCL_BOOL isWP = DCL_FALSE;
+#if defined(__MSDC_SD_MMC__)&&(defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+	SD_CTRL_GET_CAPACITY_T capacity;
+#endif
+//jinxing add for dual T-card.
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+	void *ID = NULL;
+
+
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+	#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+	#endif
+
+	#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+	#endif
+			default:
+				ID = NULL;
+				return DEV_STATUS_NOMEDIA;			
+	}	
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)ID == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+	}
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+    dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+	if (dclHandle == DCL_HANDLE_INVALID)
+		return DEV_STATUS_NOMEDIA;
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return DEV_STATUS_NOMEDIA;
+      #else
+         ASSERT(0);
+      #endif
+   }
+   prSwitch.u4TargetInterface=sel;
+   //DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+#else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+	if (dclHandle == DCL_HANDLE_INVALID)
+		return DEV_STATUS_NOMEDIA;
+#endif
+//jinxing add done
+	DclSD_Control(dclHandle, SD_CTRL_CMD_GET_AND_CLEAR_MEDIA_CHANGED, (DCL_CTRL_DATA_T*)&changed);
+	if(changed)
+	{
+		DclSD_Close(dclHandle);
+		return DEV_STATUS_MEDIA_CHANGE;
+	}
+
+	DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+	if (isCardExist)
+	{
+		#if defined(__MSDC_SD_MMC__)
+		DclSD_Control(dclHandle, SD_CTRL_CMD_WRITE_PROTECTION, (DCL_CTRL_DATA_T*)&isWP);
+		if(isWP)
+		{		
+			DclSD_Close(dclHandle);
+			return DEV_STATUS_WP;
+		}
+		#endif
+		#if defined(__MSDC_MS__)
+		if(gMS.is_wp)
+		{
+			return DEV_STATUS_WP;
+		}
+		#endif	
+		#if defined(__MSDC_MSPRO__)		
+		if(gMSP.is_wp)		
+		{			
+			//return USB_MS_LOCKED;		
+			return DEV_STATUS_WP;
+		}					
+		#endif
+		//return USB_MS_EXIST;
+
+		#if defined(__MSDC_SD_MMC__)
+		#if (defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+		// TFlash larger than 8GB is not support
+		
+		DclSD_Control(dclHandle, SD_CTRL_CMD_GET_CAPACITY, (DCL_CTRL_DATA_T*)&capacity);
+		if (*(capacity.pu8Capacity) > ((unsigned long long)FS_MAX_DISK_SIZE*1024*1024))
+		{
+			DclSD_Close(dclHandle);
+			return DEV_STATUS_NOMEDIA;
+		}
+		#endif //(LIPTON_BB) ||defined(ROSEMARY_BB))
+		#endif
+
+		DclSD_Close(dclHandle);
+		return DEV_STATUS_OK;
+	}
+
+	DclSD_Close(dclHandle);
+	
+	return DEV_STATUS_NOMEDIA;
+}
+
+#else
+
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type)
+{
+	kal_bool changed;
+	void *ID = NULL;
+
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+
+		default:
+			ID = NULL;
+			return DEV_STATUS_NOMEDIA;			
+	}	
+
+	changed = MSDC_GetMediaChanged((void*)ID);
+	if(changed)
+	{
+		//return USB_MS_CHANGED;
+		return DEV_STATUS_MEDIA_CHANGE;
+	}
+		
+	if(gMSDC_Handle->mIsPresent)
+	{
+		#if defined(__MSDC_SD_MMC__)
+		if(gSD->mWPEnabled)
+		{		
+			//return USB_MS_LOCKED;
+			return DEV_STATUS_WP;
+		}
+		#endif
+		#if defined(__MSDC_MS__)
+		if(gMS.is_wp)
+		{
+			//return USB_MS_LOCKED;
+			return DEV_STATUS_WP;
+		}
+		#endif	
+		#if defined(__MSDC_MSPRO__)		
+		if(gMSP.is_wp)		
+		{			
+			//return USB_MS_LOCKED;		
+			return DEV_STATUS_WP;
+		}					
+		#endif
+		//return USB_MS_EXIST;
+
+		#if defined(__MSDC_SD_MMC__)
+		#if (defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+		// TFlash larger than 8GB is not support
+		if (gSD->mCSD.capacity > ((unsigned long long)FS_MAX_DISK_SIZE*1024*1024))
+			return DEV_STATUS_NOMEDIA;
+		#endif //(LIPTON_BB) ||defined(ROSEMARY_BB))
+		#endif
+
+		return DEV_STATUS_OK;
+	}
+	
+	//return USB_MS_NOT_EXIST;   
+	return DEV_STATUS_NOMEDIA;
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+kal_bool usbms_format_all(MSDC_EXT_MEM_TYPE type)
+{
+	kal_uint32 status;
+	void *ID = NULL;
+
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+
+		default:
+			return KAL_FALSE;			
+	}	
+	
+	ASSERT(CardDrv != NULL);
+	status = CardDrv->MountDevice((void*)ID,0,0,0);
+	if(status != 512)
+		return KAL_FALSE;
+
+	return KAL_TRUE;  
+}
+
+kal_bool usbms_prevmedia_removal_all(kal_bool enable)
+{
+	return KAL_TRUE;
+}
+
+#if defined(DCL_MSDC_INTERFACE)
+
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type)
+{
+	kal_int32 status;
+	DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+	SD_CTRL_GET_CAPACITY_T capacity;
+	void *ID = NULL;
+//jinxing add for dual T-card.
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	sd_select_enum sel;
+	SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+	ASSERT(CardDrv != NULL);
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+
+		default:
+			return KAL_FALSE;			
+	}	
+
+	status = CardDrv->MountDevice((void*)ID, 0, 0, 0);
+	if(status != 512)
+		return KAL_FALSE;
+
+	#if defined(__MSDC_MS__)   	
+		*max_lba = gMS.TotalSectors-1;   
+	#elif defined(__MSDC_MSPRO__)   	
+		*max_lba = gMSP.user_block*gMSP.block_size-1;   
+	#elif defined(__MSDC_SD_MMC__)
+	#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+	if((MSDC_HANDLE *)ID == &MSDC_Blk[0])
+   {
+		sel = SD_EXT;
+	}
+	else
+   {
+#if defined(__SIM_PLUS__)
+		sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+		sel = SD_T_CARD_2;
+#endif
+	}
+
+   if(sel==SD_EXT)
+	{
+    	dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+		if (dclHandle == DCL_HANDLE_INVALID)
+			return KAL_FALSE;
+   }
+   else
+   {
+      #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+      dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+      if (dclHandle == DCL_HANDLE_INVALID)
+         return KAL_FALSE;
+      #else
+         ASSERT(0);
+      #endif
+   }
+	prSwitch.u4TargetInterface=sel; 
+   DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+   #else
+   dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+	if (dclHandle == DCL_HANDLE_INVALID)
+		return KAL_FALSE;
+#endif
+//jinxing add done
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+	
+		DclSD_Control(dclHandle, SD_CTRL_CMD_GET_CAPACITY, (DCL_CTRL_DATA_T*)&capacity);
+		DclSD_Close(dclHandle);
+		*max_lba =(capacity.pu8Capacity)/512 -1;
+	#endif
+	*sec_len =512;
+	return KAL_TRUE;
+}
+
+#else
+
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type)
+{
+	kal_int32 status;
+	void *ID = NULL;
+
+	ASSERT(CardDrv != NULL);
+	switch(type)
+	{
+		case MSDC_MEM_TYPE_EXT:
+			ID = EXT_MEM_ID;
+			break;
+#if defined(__SIM_PLUS__)
+		case MSDC_MEM_TYPE_SIMPLUS:
+			ID = SIMPLUS_MEM_ID;
+			break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+		case MSDC_MEM_TYPE_TCARD2:
+			ID = TCARD_2_MEM_ID;
+			break;
+#endif
+
+		default:
+			return KAL_FALSE;			
+	}	
+	status = CardDrv->MountDevice((void*)ID, 0, 0, 0);
+	if(status != 512)
+		return KAL_FALSE;
+
+	#if defined(__MSDC_MS__)   	
+		*max_lba = gMS.TotalSectors-1;   
+	#elif defined(__MSDC_MSPRO__)   	
+		*max_lba = gMSP.user_block*gMSP.block_size-1;   
+	#elif defined(__MSDC_SD_MMC__)
+		*max_lba = gSD->mCSD.capacity/512 -1;
+	#endif
+	*sec_len =512;
+	return KAL_TRUE;
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+#endif   /*__MSDC_MS__,__MSDC_SD_MMC__*/
+
+#endif /*__USB_MSD_SUPPORT__*/
+