292 lines
11 KiB
C
292 lines
11 KiB
C
/* ftlBm.h - FTL BM/BBM Head File */
|
|
|
|
/*
|
|
* Copyright (c) 2012, 2013 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute, modify or otherwise make use
|
|
* of this software may be licensed only pursuant to the terms
|
|
* of an applicable Wind River license agreement.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01e,11oct13,ghs Correct compile error (WIND00438400)
|
|
01d,08jun13,jxu added ftlBmCopy to help copy pages for gc/wl/bbm
|
|
added a block mark for bbm to identify runtime bad blocks
|
|
01c,08nov12,jxu added more device geometry info to bm identity.
|
|
01b,01sep12,jxu rewritten for conceptual integrity.
|
|
01a,15may12,x_z created.
|
|
*/
|
|
|
|
#ifndef __INCftlBmh
|
|
#define __INCftlBmh
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* includes */
|
|
|
|
#include <private/ftl/ftlLibP.h>
|
|
#include <drv/mtd/mtd.h>
|
|
|
|
/* defines */
|
|
|
|
#define BM_STATUS_NOTIFIED 0x0
|
|
#define BM_STATUS_FORMATTING 0x1
|
|
#define BM_STATUS_MOUNTED 0x2
|
|
|
|
#define AVL_NODE_TO_BBMT_ENTRY(pNode) \
|
|
CONTAINER_OF(pNode, struct bbmt_entry_ram, avlNode)
|
|
|
|
/* erase options */
|
|
|
|
#define BM_ERASE_OPT 0x01
|
|
|
|
#define BM_MAGIC 0x42424d54 /* 'B' 'B' 'M' 'T' */
|
|
|
|
#define BBMT_TYPE_INIT 0
|
|
#define BBMT_TYPE_ID 0x11
|
|
#define BBMT_TYPE_START_REPL 0x22
|
|
#define BBMT_TYPE_CANCEL_REPL 0x33 /* cancel the on-going replacement */
|
|
#define BBMT_TYPE_FINISH_REPL 0x44 /* runtime bad block table */
|
|
#define BBMT_TYPE_UNDO_REPL 0x55 /* undo the finished replacement */
|
|
|
|
#define BBMT_NUM_COPY 2
|
|
#define BM_NUM_ID_BLKS 2
|
|
#define BBMT_NUM_BLK_MARK 8
|
|
|
|
#define BBM_FLAG_CHECK_BAD_BLK 0x1 /* check if the error block is bad */
|
|
|
|
/* block copy related definitions */
|
|
|
|
struct copy_info;
|
|
typedef int (*COPY_FUNC) (FTL_DESC * pFtl, struct copy_info * pCopyInfo);
|
|
typedef struct copy_info
|
|
{
|
|
FTL_ADDR srcAddr;
|
|
BOOL multiSrc; /* pages from multiple blocks */
|
|
FTL_ADDR destAddr;
|
|
MAP_BLK_INFO destBlkInfo;
|
|
fpage_t nPages;
|
|
char * pPageBuf;
|
|
int flags;
|
|
COPY_FUNC start; /* callback before read the src page */
|
|
COPY_FUNC check; /* callback before write to the dest page */
|
|
long priv; /* private to caller */
|
|
BOOL stopped; /* stop copy */
|
|
BOOL skipped; /* TRUE if not copy current page */
|
|
fpage_t curPageNo; /* last page copied well */
|
|
fpage_t copiedLast; /* last page copied well */
|
|
fpage_t copiedPages; /* # of copied pages */
|
|
fpage_t stopBlankPage; /* stop blank starting from this page */
|
|
}COPY_INFO;
|
|
|
|
#define DECLARE_COPY_INFO(name) \
|
|
COPY_INFO name = {INVALID_ADDR, FALSE, INVALID_ADDR, INVALID_BLKINFO, \
|
|
0, NULL, 0, NULL, NULL, 0, FALSE, FALSE, FTL_INVALID_PPN, \
|
|
FTL_INVALID_PPN, 0, FTL_INVALID_PPN};
|
|
|
|
#define ERASE_MARK 0 /* bitflip safe */
|
|
#define BAD_MARK 0 /* bitflip safe */
|
|
|
|
/* typedefs */
|
|
|
|
typedef struct blk_mark
|
|
{
|
|
UINT8 erase;
|
|
UINT8 bad;
|
|
}_FTL_PACK_ALIGN(1) BLK_MARK;
|
|
|
|
/* bad block check parameter */
|
|
|
|
typedef struct bbmt_blk_mark /* block mark for bbmt blocks */
|
|
{
|
|
UINT32 bbmtId; /* bbmt identity */
|
|
UINT32 crc32; /* checksum of this block mark */
|
|
}_FTL_PACK_ALIGN(4) BBMT_BLK_MARK;
|
|
|
|
typedef struct bbmt_entry /* bad block replacement entry */
|
|
{
|
|
UINT32 badBlkNo; /* bad block */
|
|
UINT32 replBlkNo; /* replacement block */
|
|
}_FTL_PACK_ALIGN(4) BBMT_ENTRY;
|
|
|
|
typedef struct bbmt_header /* bbmt header */
|
|
{
|
|
UINT32 magic; /* bbmt magic number */
|
|
UINT8 extFlags; /* set to 0 if no extension flag is set */
|
|
UINT8 type; /* replacement or undo-replacement */
|
|
UINT8 nPagesPerBbmt; /* currently not used */
|
|
UINT8 copyNo; /* copy number */
|
|
UINT32 seqNo; /* sequence number */
|
|
INT32 error; /* error type */
|
|
UINT32 nBbmtEntry; /* # of bbmt entries */
|
|
UINT32 bbmtOff; /* offset of the bbmt entries */
|
|
UINT32 bbmtLen; /* length of the bbmt entries */
|
|
BBMT_ENTRY newEntry; /* new bbmt entry to be added */
|
|
UINT8 reserved[4]; /* reserved for future */
|
|
UINT32 dataChksum; /* checksum of bbmt data */
|
|
UINT32 hdrChksum; /* checksum of bbmt header */
|
|
}_FTL_PACK_ALIGN(4) BBMT_HEADER; /* 48 bytes in total */
|
|
|
|
typedef struct bbmt_entry_ram /* bbmt entry in ram */
|
|
{
|
|
AVL_NODE avlNode; /* node in tree */
|
|
UINT32 badBlkNo; /* bad block number */
|
|
UINT32 replBlkNo; /* replacement block number */
|
|
}BBMT_ENTRY_RAM;
|
|
|
|
/* ftl BM (block management) desc */
|
|
|
|
typedef struct ftl_bm_desc
|
|
{
|
|
DL_NODE bmNode; /* linked to BM list */
|
|
|
|
/* FTL information */
|
|
|
|
char devName[FTL_DEV_NAME_LEN_MAX + 1];
|
|
FTL_DESC * pFtlDesc; /* related FTL descriptor */
|
|
void * pDevDesc; /* descriptor of flash devices */
|
|
|
|
UINT32 bmFlag; /* flag for BM and FTL core */
|
|
UINT32 status; /* BM status */
|
|
char * pPageBuf; /* page buffer (OOB included) */
|
|
|
|
/* geometry information */
|
|
|
|
FLASH_TYPE_T flashType; /* flash type */
|
|
FLASH_CELL_T cellType; /* for nand flash only */
|
|
|
|
UINT64 totalSize; /* total size of this device */
|
|
fpsize_t pageSize; /* page size in bytes */
|
|
fpsize_t pageSizeShift; /* page size in bytes */
|
|
fbsize_t blkSize; /* block size in bytes */
|
|
fpage_t pagesPerBlk; /* number of pages per block */
|
|
fblock_t blkStart; /* starting block number */
|
|
fblock_t nBlks; /* total number of flash blocks */
|
|
fpsize_t oobSize; /* oob size */
|
|
fpsize_t oobSizeAvail; /* available oob size to FTL */
|
|
fpsize_t pageOobSize; /* page size plus oob available size */
|
|
|
|
fpage_t blkMarkPageNo; /* the page for writting bad mark */
|
|
fpsize_t blkMarkOffset; /* bad mark offset in the page */
|
|
|
|
/* BBM stuff */
|
|
|
|
FTL_LOCK_T bbmLock; /* bad block management lock */
|
|
FTL_LOCK_T bbmTrLock; /* bad block management tree lock */
|
|
|
|
fblock_t replBlkStart; /* start block of consecutive */
|
|
/* replacement blocks */
|
|
fblock_t nReplBlks; /* number of good replacement blocks */
|
|
/* in bbm area */
|
|
|
|
fblock_t freeReplBlkStart; /* first free block in bbm area */
|
|
fblock_t freeReplBlkEnd; /* last free block in bbm area */
|
|
|
|
fblock_t bbmtBlkStart; /* start block of saving bbmt */
|
|
|
|
fblock_t * pStBbt; /* static bad block table */
|
|
size_t stBadBlkCnt; /* # of bad blocks in bbm area */
|
|
BBMT_ENTRY * pStBbmt; /* static bad block map table */
|
|
size_t stBadBlkMapCnt; /* # of bad blocks in non-bbm area */
|
|
|
|
AVL_TREE badBlkTree; /* bad block replacment search tree */
|
|
|
|
/* address of next bbmt for each copy */
|
|
|
|
FTL_ADDR copyInfo[BBMT_NUM_COPY];
|
|
|
|
UINT32 seqNo; /* sequence number to track the */
|
|
/* latest bbmt */
|
|
|
|
char * pBbmtBuf; /* buffer */
|
|
size_t bbmtSize; /* current size of bbmt data */
|
|
size_t bbmtSizeAl; /* aligned size of bbmt data */
|
|
|
|
#ifdef FTL_DEBUG
|
|
struct {
|
|
FTL_ATOMIC32_T errorCnt;
|
|
FTL_ATOMIC32_T writeErrorCnt;
|
|
FTL_ATOMIC32_T eraseErrorCnt;
|
|
FTL_ATOMIC32_T eccRecvErrorCnt;
|
|
FTL_ATOMIC32_T eccIrrecvErrorCnt;
|
|
FTL_ATOMIC32_T knownEccIrrecvErrorCnt;
|
|
FTL_ATOMIC32_T unknownErrorCnt;
|
|
FTL_ATOMIC32_T stBadBlkCnt; /* static bad block */
|
|
FTL_ATOMIC32_T rtBadBlkCnt; /* run-time bad block */
|
|
|
|
FTL_ATOMIC32_T memUseHigh;
|
|
FTL_ATOMIC32_T memUseCur;
|
|
}dbgStat;
|
|
#endif
|
|
}FTL_BM_DESC;
|
|
|
|
/* function declarations */
|
|
|
|
STATUS ftlBmSaveId (FTL_DESC * pFtl, FTL_DEV_ID * pFtlId);
|
|
int ftlFormatBm (void * pBm, size_t sizeBBM, BOOL bPreserve);
|
|
int ftlMountBm (void * pBm, FTL_DEV_ID * pFtlId);
|
|
int ftlUnmountBm (FTL_BM_DESC * pBm);
|
|
int ftlBmNotify (MTD_DESC * pMtdDesc, void * pArg);
|
|
int ftlBmCleanup (FTL_BM_DESC * pBm);
|
|
FTL_BM_DESC * ftlBmFind (const char * pFtlDevName);
|
|
int ftlBmRead (FTL_DESC * pFtl, FTL_ADDR * pFromAddr,
|
|
size_t dataLen, char * pBuf, int rwFlags);
|
|
int ftlBmWrite (FTL_DESC * pFtl, FTL_ADDR * pFromAddr,
|
|
size_t dataLen, char * pBuf, int rwFlags);
|
|
int ftlBmRW (FTL_DESC * pBm, FTL_ADDR * pFromAddr,
|
|
size_t dataLen, char * pBuf, int rwFlags);
|
|
#ifdef obsolete
|
|
int ftlBmEraseBlk (FTL_DESC * pFtl, fblock_t blkNo, int option);
|
|
#endif
|
|
int ftlBmErase (FTL_DESC * pFtl, fblock_t blkNo,
|
|
fblock_t nBlks, int flags);
|
|
int ftlBmIsBadBlk (FTL_DESC * pFtl, fblock_t blkNo, int option);
|
|
int ftlBmFillBlankPages (FTL_DESC * pFtl, FTL_ADDR * pFromAddr,
|
|
fpage_t nPages, MAP_BLK_INFO * pBlkInfo);
|
|
int ftlBmIsBlankBlk (FTL_DESC * pFtl, fblock_t blkNo, int flags);
|
|
int ftlBmIsBlankPage (FTL_DESC * pFtl, FTL_ADDR * pAddr, int option);
|
|
int ftlBmIsFilledBlankPage (FTL_DESC * pFtl, FTL_ADDR * pAddr, int option);
|
|
int ftlBmScanPages (FTL_DESC * pFtl, FTL_ADDR * pFromAddr,
|
|
fpage_t nPages, char * pBuf, FTL_ADDR * pOkAddr,
|
|
FTL_ADDR * pBlankAddr, int flags);
|
|
int ftlBmCopyPages (FTL_DESC * pFtl, FTL_ADDR * pDestAddr,
|
|
FTL_ADDR * pSrcAddr, fpage_t nPages, int flags);
|
|
int ftlBmCopyBlk (FTL_DESC * pFtl, fblock_t destBlk,
|
|
fblock_t srcBlk, int flags);
|
|
UINT16 ftlBmBlkNextFpn (FTL_DESC * pFtl, fblock_t blkNo);
|
|
|
|
extern __inline__ MTD_DESC * ftlFindMtd (FTL_BM_DESC * pBm, fblock_t blkNo);
|
|
int bmIsBlankPage (FTL_BM_DESC * pBm, fblock_t blkNo,
|
|
fpage_t pageNo);
|
|
int ftlBbmCleanup (FTL_BM_DESC * pBm);
|
|
int bbmReplace (FTL_BM_DESC * pBm, BBMT_ENTRY * pBbmtEntry, int error);
|
|
int bbmBadBlkMap (FTL_BM_DESC * pBm, fblock_t blkNo,
|
|
fblock_t * pReplBlkNo);
|
|
int bbmUndoReplace (FTL_BM_DESC * pBm, BBMT_ENTRY * pBbmtEntry, int error);
|
|
int copyCheckFunc (FTL_DESC * pFtl, COPY_INFO * pInfo);
|
|
int ftlBmCopy (FTL_DESC * pFtl, COPY_INFO * pInfo);
|
|
int ftlBmWriteRaw (FTL_BM_DESC * pBm, FTL_ADDR * pFromAddr,
|
|
size_t dataLen, char * pBuf, int flags);
|
|
int ftlBmReadRaw (FTL_BM_DESC * pBm, FTL_ADDR * pFromAddr,
|
|
size_t dataLen, char * pBuf, int flags);
|
|
int ftlBmCheckSeqPgMap (FTL_DESC * pFtl, fblock_t blkNo, fpage_t pageNo,
|
|
int nPages);
|
|
int checkBlank (FTL_BM_DESC * pBm, const char * pBuf, size_t len, int flags);
|
|
#ifdef FTL_DEBUG
|
|
int ftlBmCheckBlankPages (FTL_DESC * pFtl, fblock_t blkNo, fpage_t pageNo,
|
|
int nPages);
|
|
int ftlBmCheckAnyBlankPages (FTL_DESC * pFtl, fblock_t blkNo, fpage_t pageNo,
|
|
int nPages);
|
|
#endif /* FTL_DEBUG */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __INCftlBmh */
|
|
|