⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2450_fil.c

📁 s3c2450 bsp for wince 5.0 PM_REL_0.04_080519 经验证,完全没问题
💻 C
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////
//
//	MODULE		: FIL
//	NAME		: S3C2450X Flash Interface Layer
//	FILE			: S3C2450_FIL.c
//	PURPOSE		:
//
///////////////////////////////////////////////////////////////
//
//		COPYRIGHT 2003-2006 SAMSUNG ELECTRONICS CO., LTD.
//					ALL RIGHTS RESERVED
//
//	Permission is hereby granted to licensees of Samsung Electronics
//	Co., Ltd. products to use or abstract this computer program for the
//	sole purpose of implementing a product based on Samsung
//	Electronics Co., Ltd. products. No other rights to reproduce, use,
//	or disseminate this computer program, whether in part or in whole,
//	are granted.
//
//	Samsung Electronics Co., Ltd. makes no representation or warranties
//	with respect to the performance of this computer program, and
//	specifically disclaims any responsibility for any damages,
//	special or consequential, connected with the use of this program.
//
///////////////////////////////////////////////////////////////
//
//	REVISION HISTORY
//
//	2006.10.19	dodan2(gabjoo.lim@samsung.com)
//				Draft Version
//	2007.03.25	ksk
//				Support 4KByte/Page NAND Flash Device
//
///////////////////////////////////////////////////////////////

///////////////////////////////////////////////
// Header File
///////////////////////////////////////////////
#include <WMRConfig.h>
#include <WMRTypes.h>
#include <OSLessWMROAM.h>
#include <FIL.h>
#include <string.h>
#include <S3C2450_FIL.h>
#include <s3c2450_dma.h>
#include <s3c2450_nand.h>
#include <s3c2450_matrix.h>

//#define USE_SETKMODE
#define USE_2CE_NAND

///////////////////////////////////////////////
// Transfer Mode
///////////////////////////////////////////////
#define ASM					(0)		// Assembly Code
#define DMA					(1)		// DMA Transfer
#define NAND_TRANS_MODE	ASM

///////////////////////////////////////////////
// NAND DMA Buffer
///////////////////////////////////////////////
//#define NAND_DMA_BUFFER_UA	(0xA0100000+0x25800)		// LCD Frame Buffer
//#define NAND_DMA_BUFFER_PA	(0x30100000+0x25800)
#define NAND_DMA_BUFFER_UA	(0xB0700000)		// Stepping Stone (Check Oemaddrtab_cgf.inc !!!!)
#define NAND_DMA_BUFFER_PA	(0x40000000)

///////////////////////////////////////////////
// Debug Print Macro
///////////////////////////////////////////////
#define RETAILMSG(cond, printf_exp)	((cond)?(NKDbgPrintfW printf_exp),1:0)
#define NAND_ERR(x)	RETAILMSG(TRUE, x)
//#define NAND_ERR(x)
//#define NAND_MSG(x)	RETAILMSG(TRUE, x)
#define NAND_MSG(x)
#define NAND_LOG(x)	RETAILMSG(TRUE, x)
//#define NAND_LOG(x)

///////////////////////////////////////////////
// Device type context definitions
///////////////////////////////////////////////
typedef struct
{
	UINT8	nDevID;				// Device ID
	UINT8	nHidID;				// Hidden ID
	UINT32	nNumOfBlocks;		// Number of Blocks
	UINT32	nPagesPerBlock;		// Pages per block
	UINT32	nSectorsPerPage;	// Sectors per page
	BOOL32	b2XProgram;		// 2 plane program
	BOOL32	b2XRead;						/* 2 plane read	 	 */	
	BOOL32	b2XReadStatus;						/* 2 plane read status	 	 */	
	BOOL32	bDualDie;			// internal interleaving
	BOOL32	bMLC;				// MLC
} DEVInfo;

PRIVATE const DEVInfo stDEVInfo[] = {
		/*****************************************************************************/
		/* Device ID																 */
		/*	   Hidden ID															 */
		/*			 Blocks															 */
		/*				   Pages per block											 */
		/*						Sectors per page									 */
		/*						   2X program										 */
		/*						   			2X read									 */
		/*											 2x status 						 */		
		/*											 		  internal Interleaving	 */		
		/*												               MLC			 */
		/*****************************************************************************/
#if (WMR_SLC_SUPPORT)
		/* SLC NAND ID TABLE */
		{0xF1, 0x80, 1024,  64, 4, FALSE32, FALSE32, FALSE32, FALSE32, FALSE32},	/* 1Gb SLC(K9F1G08) Mono */
		{0xF1, 0x00, 1024,  64, 4, FALSE32, FALSE32, FALSE32, FALSE32, FALSE32},	/* 1Gb SLC(K9F1G08) Mono B-die */
		{0xDA, 0x80, 2048,  64, 4, FALSE32, FALSE32, FALSE32, FALSE32, FALSE32},	/* 2Gb SLC(K9F2G08) Mono */
		{0xDA, 0x10, 2048,  64, 4, TRUE32,  FALSE32, FALSE32, FALSE32, FALSE32},	/* 2Gb SLC(K9F2G08) Mono A-die */
		{0xDA, 0xC1, 2048,  64, 4, FALSE32, FALSE32, FALSE32, FALSE32, FALSE32},	/* 2Gb SLC(K9K2G08) DDP  */
		{0xDC, 0x10, 4096,  64, 4, TRUE32,  FALSE32, FALSE32, FALSE32, FALSE32},	/* 4Gb SLC(K9F4G08) Mono */
		{0xDC, 0xC1, 4096,  64, 4, FALSE32, FALSE32, FALSE32, TRUE32,  FALSE32},	/* 4Gb SLC(K9K4G08) DDP  */
		{0xD3, 0x51, 8192,  64, 4, TRUE32,  FALSE32, FALSE32, TRUE32,  FALSE32},	/* 8Gb SLC(K9K8G08) DDP  */
		{0xD3, 0x10, 4096,  64, 8, TRUE32,  TRUE32,  TRUE32,  FALSE32, FALSE32},	/* 8Gb SLC(K9F8G08) Mono  */			
#endif
#if (WMR_MLC_SUPPORT)
		/* MLC NAND ID TABLE */
		{0xDC, 0x14, 2048, 128, 4, TRUE32,  FALSE32, FALSE32, FALSE32, TRUE32},	/* 4Gb MLC(K9G4G08) Mono */
		{0xD3, 0x55, 4096, 128, 4, TRUE32,  FALSE32, FALSE32, TRUE32,  TRUE32},	/* 8Gb MLC(K9L8G08) DDP  */
		{0xD3, 0x14, 4096, 128, 4, TRUE32,  FALSE32, FALSE32, FALSE32, TRUE32},	/* 8Gb MLC(K9G8G08) Mono */
		{0xD5, 0x55, 8192, 128, 4, TRUE32,  FALSE32, FALSE32, TRUE32,  TRUE32},	/* 16Gb MLC(K9LAG08) DDP  */
		{0xD5, 0x14, 4096, 128, 8, TRUE32,  TRUE32,  TRUE32,  FALSE32, TRUE32},	/* 16Gb MLC(K9GAG08) Mono */			
		{0xD7, 0x55, 8192, 128, 8, TRUE32,  TRUE32,  TRUE32,  TRUE32,  TRUE32},	/* 32Gb MLC(K9LBG08) DDP  */						
#endif			
};

///////////////////////////////////////////////
// PRIVATE variables definitions
///////////////////////////////////////////////
PRIVATE BOOL32 bInternalInterleaving	= FALSE32;
PRIVATE 	BOOL32 aNeedSync[WMR_MAX_DEVICE * 2];

PRIVATE volatile S3C2450_NAND_REG *pNANDFConReg = NULL;
PRIVATE volatile S3C2450_DMA_REG *pDMAConReg = NULL;
PRIVATE volatile S3C2450_MATRIX_REG *pMatrixConReg = NULL;

PRIVATE UINT8 aTempSBuf[NAND_SPAREPAGE_SIZE] =
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

///////////////////////////////////////////////
// Private Function Prototype
///////////////////////////////////////////////
PRIVATE INT32	Read_DeviceID(UINT32 nBank, UINT8 *pDID, UINT8 *pHID);
PRIVATE UINT32	Read_Sector(UINT32 nBank, UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf, pSECCCxt pSpareCxt, BOOL32 bCheckAllFF);
PRIVATE UINT32	Read_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt);
PRIVATE VOID	Write_Sector(UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf);
PRIVATE VOID	Write_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt);
PRIVATE UINT32	Decoding_MainECC(UINT8* pBuf);
PRIVATE UINT32	Decoding_SpareECC(UINT8* pBuf);
PRIVATE UINT32	_IsAllFF(UINT8* pBuf, UINT32 nSize);
PRIVATE UINT32	_TRDelay(UINT32 nNum);
PRIVATE UINT32	_TRDelay2(UINT32 nNum);


///////////////////////////////////////////////
// ECC Decoding Function Return Value
///////////////////////////////////////////////
#define ECC_CORRECTABLE_ERROR					(0x1)
#define ECC_UNCORRECTABLE_ERROR				(0x2)
#define ECC_ALL_FF								(0x4)
//#define PAGE_CORRECTABLE_ERROR_MASK			(0x11111)  // for 2KByte/Page
//#define PAGE_UNCORRECTABLE_ERROR_MASK		(0x22222)  // for 2KByte/Page
#define PAGE_CORRECTABLE_ERROR_MASK			(0x15555)  // for 4KByte/Page
#define PAGE_UNCORRECTABLE_ERROR_MASK		(0x2AAAA)  // for 4KByte/Page
#define PAGE_ALL_FF_MASK						(0x44444)
#define SPARE_ALL_FF_MASK						(0x40000)

///////////////////////////////////////////////
// ECC Decoding Value for All FF
///////////////////////////////////////////////
#define ECCVAL_ALLFF  (0xFFFFFFFF)

#if (NAND_TRANS_MODE == ASM)
extern void _Read_512Byte(UINT8* pBuf);
extern void _Read_512Byte_Unaligned(UINT8* pBuf);
extern void _Write_512Byte(UINT8* pBuf);
extern void _Write_512Byte_Unaligned(UINT8* pBuf);
extern void _Write_Dummy_468Byte_AllFF(void);
extern void _Write_Dummy_436Byte_AllFF(void);
#elif (NAND_TRANS_MODE == DMA)
PRIVATE VOID Read_512Byte_DMA(UINT8* pBuf);
PRIVATE VOID Write_512Byte_DMA(UINT8* pBuf);
PRIVATE VOID Write_Dummy_468Byte_AllFF_DMA(void);
#endif

///////////////////////////////////////////////
// Code Implementation
///////////////////////////////////////////////


/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      NAND_Init		                                                     */
/* DESCRIPTION                                                               */
/*      This function inits NAND device.							 		 */
/* PARAMETERS                                                                */
/*      None													             */
/* RETURN VALUES                                                             */
/*		FIL_SUCCESS															 */
/*					NAND_Init is success.									 */
/*		FIL_CRITICAL_ERROR													 */
/*					NAND_Init is failed.									 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
INT32
NAND_Init(VOID)
{
	UINT32 nDevIdx;
	UINT32 nScanIdx = 0, nCompIdx = 0;
	UINT8 nDevID, nHiddenID;
	UINT32 nDevCnt = 0;
	BOOL32 bComp = FALSE32;

	NAND_MSG((_T("[FIL]++NAND_MLC_Init()\r\n")));

#if (BSP_TYPE == BSP_SMDK2443)
	pNANDFConReg = (volatile S3C2450_NAND_REG *)0xB1400000;			// 0x4E000000
	pMatrixConReg = (volatile S3C2450_MATRIX_REG *)0xB1500000;			// 0x4E800000
#elif (BSP_TYPE == BSP_SMDK2450)
	pNANDFConReg = (volatile S3C2450_NAND_REG *)0xB1500000;			// 0x4E000000
	pMatrixConReg = (volatile S3C2450_MATRIX_REG *)0xB1600000;			// 0x4E800000
#endif
	pDMAConReg = (volatile S3C2450_DMA_REG *)0xB0E00000;				// 0x4B000000

	// Initialize NAND Flash Controller for SLC Large Block NAND Flash
	pNANDFConReg->NFCONF = NF_1BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
	pNANDFConReg->NFCONT = NF_MAIN_ECC_LOCK | NF_SPARE_ECC_LOCK | NF_INIT_MECC | NF_INIT_SECC | NF_NFCE1 | NF_NFCE0 | NF_NFCON_EN;
	pNANDFConReg->NFSTAT = NF_RNB_READY;	// Clear RnB Transition Detect Bit

	// Initialize EBICON for 2nd nCE pin (nFCE1)
#ifdef	USE_2CE_NAND
	pMatrixConReg->EBICON |= (0x1<<8);	// Bank1_Cfg -> NAND
#endif

	/* Device's ID must be available and equal to each other */
	for(nDevIdx = 0; nDevIdx < WMR_MAX_DEVICE; nDevIdx++)
	{
		nScanIdx = Read_DeviceID(nDevIdx, &nDevID, &nHiddenID);

		if (nScanIdx == FIL_CRITICAL_ERROR)
		{
			nScanIdx = nCompIdx;
			break;
		}
		if ((nCompIdx != nScanIdx) && (bComp))
		{
			return FIL_CRITICAL_ERROR;
		}

		nCompIdx = nScanIdx;
		bComp = TRUE32;
		nDevCnt++;
	}
	
	if(stDEVInfo[nScanIdx].bMLC)
	{
		SET_DevType(WMR_MLC);
	}
	else
	{
		SET_DevType(WMR_SLC);
	}

	if(stDEVInfo[nScanIdx].bDualDie && nDevCnt <= 2)
	{
		/* multi chip dual die (DDP) */
		BLOCKS_PER_BANK = stDEVInfo[nScanIdx].nNumOfBlocks >> 1;
		BANKS_TOTAL = nDevCnt * 2;
		bInternalInterleaving = TRUE32;
	}
	else
	{
		BLOCKS_PER_BANK = stDEVInfo[nScanIdx].nNumOfBlocks;
		BANKS_TOTAL = nDevCnt;
		bInternalInterleaving = FALSE32;
	}

	SECTORS_PER_PAGE = stDEVInfo[nScanIdx].nSectorsPerPage;

	TWO_PLANE_PROGRAM = stDEVInfo[nScanIdx].b2XProgram;

	if (TWO_PLANE_PROGRAM == TRUE32)
	{
		BLOCKS_PER_BANK /= 2;
	}

	TWO_PLANE_READ = stDEVInfo[nScanIdx].b2XRead;

	TWO_PLANE_READ_STATUS = stDEVInfo[nScanIdx].b2XReadStatus;

	PAGES_PER_BLOCK = stDEVInfo[nScanIdx].nPagesPerBlock;

	/* DDP */
	if (bInternalInterleaving)
	{
		for (nDevIdx = 0; nDevIdx < nDevCnt; nDevIdx++)
		{
			aNeedSync[nDevIdx * 2] = FALSE32;
			aNeedSync[nDevIdx * 2 + 1] = FALSE32;
		}
	}

	#if (WMR_MLC_LSB_RECOVERY)
	MLC_LSB_CLASS = GetMlcClass( stDEVInfo[nScanIdx].nDevID, 
								 stDEVInfo[nScanIdx].nHidID);
	#endif

	CalcGlobal(bInternalInterleaving);
	
	NAND_LOG((_T("[FIL] ##############################\r\n")));
	NAND_LOG((_T("[FIL]  FIL Global Information\r\n")));
	NAND_LOG((_T("[FIL]  BANKS_TOTAL = %d\r\n"), BANKS_TOTAL));
	NAND_LOG((_T("[FIL]  BLOCKS_PER_BANK = %d\r\n"), BLOCKS_PER_BANK));
	NAND_LOG((_T("[FIL]  TWO_PLANE_PROGRAM = %d\r\n"), TWO_PLANE_PROGRAM));
	NAND_LOG((_T("[FIL]  SUPPORT_INTERLEAVING = %d\r\n"), IS_SUPPORT_INTERLEAVING));
	NAND_LOG((_T("[FIL]  SUBLKS_TOTAL = %d\r\n"), SUBLKS_TOTAL));
	NAND_LOG((_T("[FIL]  PAGES_PER_SUBLK = %d\r\n"), PAGES_PER_SUBLK));
	NAND_LOG((_T("[FIL]  PAGES_PER_BANK = %d\r\n"), PAGES_PER_BANK));
	NAND_LOG((_T("[FIL]  SECTORS_PER_PAGE = %d\r\n"), SECTORS_PER_PAGE));
	NAND_LOG((_T("[FIL]  SECTORS_PER_SUPAGE = %d\r\n"), SECTORS_PER_SUPAGE));
	NAND_LOG((_T("[FIL]  SECTORS_PER_SUBLK = %d\r\n"), SECTORS_PER_SUBLK));
	NAND_LOG((_T("[FIL]  USER_SECTORS_TOTAL = %d\r\n"), USER_SECTORS_TOTAL));
	NAND_LOG((_T("[FIL]  ADDRESS_CYCLE = %d\r\n"), DEV_ADDR_CYCLE));
	NAND_LOG((_T("[FIL] ##############################\r\n\r\n")));
	NAND_LOG((_T("[INFO] WMR_AREA_SIZE = %d\n"), WMR_AREA_SIZE));
	NAND_LOG((_T("[INFO] SPECIAL_AREA_START = %d\n"), SPECIAL_AREA_START));
	NAND_LOG((_T("[INFO] SPECIAL_AREA_SIZE = %d\n"), SPECIAL_AREA_SIZE));
	NAND_LOG((_T("[INFO] VFL_AREA_START = %d\n"), VFL_AREA_START));
	NAND_LOG((_T("[INFO] VFL_AREA_SIZE = %d\n"), VFL_AREA_SIZE));
	NAND_LOG((_T("[INFO] VFL_INFO_SECTION_START = %d\n"), VFL_INFO_SECTION_START));
	NAND_LOG((_T("[INFO] VFL_INFO_SECTION_SIZE = %d\n"), VFL_INFO_SECTION_SIZE));
	NAND_LOG((_T("[INFO] RESERVED_SECTION_START = %d\n"), RESERVED_SECTION_START));
	NAND_LOG((_T("[INFO] RESERVED_SECTION_SIZE = %d\n"), RESERVED_SECTION_SIZE));
	NAND_LOG((_T("[INFO] FTL_INFO_SECTION_START = %d\n"), FTL_INFO_SECTION_START));
	NAND_LOG((_T("[INFO] FTL_INFO_SECTION_SIZE = %d\n"), FTL_INFO_SECTION_SIZE));
	NAND_LOG((_T("[INFO] LOG_SECTION_SIZE = %d\n"), LOG_SECTION_SIZE));
	NAND_LOG((_T("[INFO] FREE_SECTION_START = %d\n"), FREE_SECTION_START));
	NAND_LOG((_T("[INFO] FREE_SECTION_SIZE = %d\n"), FREE_SECTION_SIZE));
	NAND_LOG((_T("[INFO] FREE_LIST_SIZE = %d\n"), FREE_LIST_SIZE));
	NAND_LOG((_T("[INFO] DATA_SECTION_START = %d\n"), DATA_SECTION_START));
	NAND_LOG((_T("[INFO] DATA_SECTION_SIZE = %d\n"), DATA_SECTION_SIZE));
	NAND_LOG((_T("[INFO] FTL_AREA_START = %d\n"), FTL_AREA_START));
	NAND_LOG((_T("[INFO] FTL_AREA_SIZE = %d\n"), FTL_AREA_SIZE));
	NAND_LOG((_T("[FIL] ##############################\r\n")));
	NAND_LOG((_T("[INFO] IS_CHECK_SPARE_ECC = %d\n"), IS_CHECK_SPARE_ECC));
	NAND_LOG((_T("[INFO] IS_SUPPORT_INTERNAL_INTERLEAVING = %d\n"), IS_SUPPORT_INTERNAL_INTERLEAVING));
	NAND_LOG((_T("[INFO] PAGES_PER_BLOCK = %d\n"), PAGES_PER_BLOCK));

	NAND_MSG((_T("[FIL]--NAND_Init()\r\n")));

	return FIL_SUCCESS;
}

/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      NAND_Read		                                                     */
/* DESCRIPTION                                                               */
/*      This function reads NAND page area							 		 */
/* PARAMETERS                                                                */
/*      nBank    	[IN] 	Physical device number			               	 */
/*      nPpn     	[IN] 	Physical page number				         	 */
/*      nSctBitmap  [IN] 	Physical sector bitmap in a page area        	 */
/*      nPlaneBitmap[IN]    The indicator of the plane  					 */
/*      pDBuf		[OUT]	Buffer pointer of main area to read          	 */
/*      pSBuf		[OUT]	Buffer pointer of spare area to read         	 */
/*      bECCIn		[IN] 	Whether read page with ECC value or not      	 */
/*      bCleanCheck [IN] 	When it's TRUE, checks the clean status        	 */
/*							of the page if the data of spare area is all	 */
/*							0xFF, returns PAGE_CLEAN						 */
/* RETURN VALUES                                                             */
/*		FIL_SUCCESS															 */
/*					NAND_Read is success.									 */
/*		FIL_SUCCESS_CLEAN													 */
/*					NAND_Read is success and all data is 0xFF.				 */
/*		FIL_U_ECC_ERROR														 */
/*					ECC value is not correct.								 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
INT32
NAND_Read(UINT32 nBank, UINT32 nPpn, UINT32 nSctBitmap, UINT32 nPlaneBitmap,
				UINT8* pDBuf, UINT8* pSBuf, BOOL32 bECCIn, BOOL32 bCleanCheck)
{
	UINT32 nPbn;
	UINT32 nPOffset;

	UINT32 nPageReadStatus = 0;
	UINT32 nPageReadStatus1st = 0;
	UINT32 nPageReadStatus2nd = 0;
	UINT32 nCnt;
	UINT32 nRet = 0;

	BOOL32 bECCErr = FALSE32;
	BOOL32 bPageClean = TRUE32;		// When the data is all 0xFF, regard the page as clean
	BOOL32 bIsSBufNull = FALSE32;	// When the pSBuf is NULL, set to check whether the page is clean or not

	BOOL32 bSecondRead = FALSE32;	// In case of twice read
	BOOL32 bLoopNeed = FALSE32;		// Only for nSctOffset == 8
	BOOL32 bRetry = TRUE32;

	UINT32  nLoopCount;
	UINT32  nVBank;
	UINT32  nPairBank;

	UINT32  nSyncRet;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -