?? badblockmanagement.c
字號:
#include "OSModule_MemoryManagement.h"
#include "HardwareAdaptationLayer.h"
#include "LLD.h"
#include "BadBlockManagement.h"
#include "FalUserDirective.h"
/*number of bad block present on device*/
static UINT8 BadBlocksNumber = 0;
/*physical block number of block containing the BBT*/
static INT16 BootBlockNumber = -1;
/*head of bad blocks list*/
static BadBlockElem *BadBlockList = NULL;
/*pointer to the last elem of bad block list in ram*/
static BadBlockElem *last = NULL;
//static UINT8 BadBlockBuff[528];
//static UINT8 pageBuffer[528];
/*************************GetBadBlockTable ****************************
* Retrieve the BBT from flash (if exists). Return a concatenate list *
* of BadBlockElem *
*---------------------------------------------------------------------*
* startBlock : physical block number where start the searching *
* *
* bbt : the head of bad block list retrieved *
* *
***********************************************************************/
NFTL_Return GetBadBlockTable(BadBlockElem *bbt, UINT16 startBlock)
{
UINT16 i;
UINT32 k;
UINT8 searchRange;
UINT8 founded = 0;
BootStruct bootStruct;
UINT16 *bbtArray = NULL;
UINT8 *buffer = NULL;
UINT16 lenght;
//lenght = GetDeviceArchitecture().pageSize;
lenght = CHUNK_SIZE;
searchRange = 10;
last = NULL;
BadBlocksNumber = 0;
//buffer = OS_DRIVER_Malloc(GetDeviceArchitecture().pageSize);
buffer = (UINT8 *)OS_DRIVER_Malloc(CHUNK_SIZE);
if (buffer == NULL)
{
return FAILURE;
}
for (i = startBlock; i <= (startBlock + searchRange); i++)
{
if (!founded)
{
UINT32 targetAddress;
CalculateAddress(i,0,&targetAddress);
//if ((NAND_PageRead(targetAddress,(UINT8 *)(&BadBlockBuff[0]),lenght) != NAND_PASS))
if ((NAND_PageRead(targetAddress,buffer,lenght) != NAND_PASS))
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
OS_MemCopy(&bootStruct,buffer,sizeof(BootStruct));
//founded bootStruct
if (OS_SearchString((char *) bootStruct.bootStructId,"NANDBOOT") != NULL)
{
UINT8 *pageBuffer = NULL;
int c = 0;
UINT8 noOfPage = 0;
INT32 lastPageDim = 0;
UINT8 totalPage = 0;
founded = 1;
//set the physical block number of the block containing the bootstruct
SetBBMBootBlockNumber(i);
//allocate the list of Bad Blocks
if (bootStruct.noOfBadBlocks == 0)
{
bbt = NULL;
bbtArray = NULL;
OS_DRIVER_Free(buffer);
return SUCCESS;
}
bbtArray = (UINT16 *)
OS_DRIVER_Malloc(sizeof(UINT16) * bootStruct.noOfBadBlocks);
if (bbtArray == NULL)
{
SetBBMBootBlockNumber(-1);
OS_DRIVER_Free(buffer);
return FAILURE;
}
#if 0
noOfPage = ((bootStruct.noOfBadBlocks) * sizeof(UINT16)) /
GetDeviceArchitecture().mainSize;
lastPageDim = (bootStruct.noOfBadBlocks * sizeof(UINT16)) %
GetDeviceArchitecture().mainSize;
#endif
#if 1
noOfPage = ((UINT16)((bootStruct.noOfBadBlocks) * sizeof(UINT16))) >>9;
lastPageDim = (bootStruct.noOfBadBlocks * sizeof(UINT16)) &511 ;
#endif
totalPage = noOfPage;
if (lastPageDim != 0)
{
totalPage += 1;
}
//pageBuffer = OS_DRIVER_Malloc(GetDeviceArchitecture().pageSize);
pageBuffer = (UINT8 *)OS_DRIVER_Malloc(CHUNK_SIZE);
if (pageBuffer == NULL)
{
return FAILURE;
}
for (c = 1; c <= totalPage; c++)
{
UINT16 lenght;
//lenght = GetDeviceArchitecture().pageSize;
lenght = CHUNK_SIZE;
CalculateAddress(i,c,&targetAddress);
if (NAND_PageRead(targetAddress,pageBuffer,lenght) != NAND_PASS)
{
bbt = NULL;
if (bbtArray != NULL)
{
OS_DRIVER_Free(bbtArray);
bbtArray = NULL;
}
OS_DRIVER_Free(buffer);
OS_DRIVER_Free(pageBuffer);
SetBBMBootBlockNumber(-1);
return FAILURE;
}
if (c == totalPage && lastPageDim)
{
//OS_MemCopy((UINT8 *) bbtArray +
//((c - 1) * GetDeviceArchitecture().mainSize),
//pageBuffer,lastPageDim);
OS_MemCopy((UINT8 *) bbtArray +
((c - 1) * CHUNK_DATA_SIZE),
pageBuffer,lastPageDim);
}
else
{
//OS_MemCopy((UINT8 *) bbtArray +
// ((c - 1) * GetDeviceArchitecture().mainSize),
// pageBuffer,GetDeviceArchitecture().mainSize);
OS_MemCopy((UINT8 *) bbtArray +
((c - 1) * CHUNK_DATA_SIZE),
pageBuffer,CHUNK_DATA_SIZE);
}
}
OS_DRIVER_Free(pageBuffer);
}
}
}
OS_DRIVER_Free(buffer);
if (!founded)
{
return DEVICE_UNFORMATTED;
}
SetBBMBadBlocksNumber(bootStruct.noOfBadBlocks);
//create a list of badblockelem
SetBBMlast(BadBlockList);
for (k = 1; k <= bootStruct.noOfBadBlocks; k++)
{
BadBlockElem *temp = (BadBlockElem *) OS_DRIVER_Malloc(sizeof(BadBlockElem));
if (temp == NULL)
{
bbt = NULL;
if (bbtArray != NULL)
{
OS_DRIVER_Free(bbtArray);
bbtArray = NULL;
}
bbtArray = NULL;
SetBBMBootBlockNumber(-1);
return FAILURE;
}
temp->blockNumber = bbtArray[k - 1];
temp->next = NULL;
if (GetBBMlast() == NULL)
{
SetBBMlast(temp);
SetBBMBadBlockList(GetBBMlast());
}
else
{
GetBBMlast()->next = temp;
SetBBMlast(temp);
}
}
if (bbtArray != NULL)
{
OS_DRIVER_Free(bbtArray);
bbtArray = NULL;
}
bbtArray = NULL;
*bbt = *(GetBBMBadBlockList());
return SUCCESS;
}
/***************** MarkBadBlock ************************************
* Mark a block as bad *
*-------------------------------------------------------------------*
* blockNumber : physical block number of block to mark bad *
* *
* return values: *
* SUCCESS: no problem erasing block *
* FAILURE: error marking bad the block *
*********************************************************************/
NFTL_Return MarkBadBlock(UINT16 blockNumber)
{
//write the spare
UINT8 BadFlag = 0x00;
UINT32 returnAddress;
CalculateAddress(blockNumber,0,&returnAddress);
returnAddress += BLOCK_STATUS_BYTE;
if (NAND_SpareProgram(returnAddress,&BadFlag,1) == NAND_FAIL)
{
return FAILURE;
}
return SUCCESS;
}
/*********************** AddBadBlock *******************************
* Add an element at the tail of bad blocks list *
*-------------------------------------------------------------------*
* blockNumber : physical block number of block to add *
* *
* return values: *
* SUCCESS: no adding bad block *
* FAILURE: error marking bad the block *
*********************************************************************/
NFTL_Return AddBadBlock(UINT16 blockNumber)
{
/*if (blockNumber
>= GetDeviceArchitecture().numOfBlocks * GetDeviceArchitecture().devicesNumber)
return FAILURE;
*/
if (GetBBMBadBlockList() == NULL)
{
SetBBMBadBlockList((BadBlockElem *) OS_DRIVER_Malloc(sizeof(BadBlockElem)));
GetBBMBadBlockList()->blockNumber = blockNumber;
GetBBMBadBlockList()->next = NULL;
SetBBMlast(BadBlockList);
}
else
{
GetBBMlast()->next = (BadBlockElem *) OS_DRIVER_Malloc(sizeof(BadBlockElem));
GetBBMlast()->next->blockNumber = blockNumber;
GetBBMlast()->next->next = NULL;
SetBBMlast(GetBBMlast()->next);
}
SetBBMBadBlocksNumber(GetBBMBadBlocksNumber() + 1);
return SUCCESS;
}
/***************** FlushBadBlockTable ******************************
* write on flash the Bad Block List and OS_DRIVER_Free space on ram *
* occupied by BadBlockList *
*-------------------------------------------------------------------*
* firstGoodBlock : physical block number ehere write BBT *
* or -1 if BBT must be written *
* in the current block used for store BBT *
* *
* *
*********************************************************************/
NFTL_Return FlushBadBlockTable(UINT16 firstGoodBlock)
{
UINT8 pageNumber = 0;
UINT16 *table = NULL;
UINT8 i;
UINT32 lastPageSize;
BadBlockElem *temp;
BootStruct bootStruct;
//lastPageSize = GetDeviceArchitecture().mainSize;
lastPageSize = CHUNK_DATA_SIZE;
if (firstGoodBlock != 0xFFFF)
{
//if (firstGoodBlock >
// GetDeviceArchitecture().numOfBlocks * GetDeviceArchitecture().devicesNumber)
if (firstGoodBlock >
4096 * GetDeviceArchitecture().devicesNumber)
{
return FAILURE;
}
}
strcpy((char *) bootStruct.bootStructId,"NANDBOOT NANDBOOT NANDBOOT NANDBOOT");
bootStruct.noOfBadBlocks = GetBBMBadBlocksNumber();
//calculate the number of pages required to store BBT
// if ((((GetBBMBadBlocksNumber()) * sizeof(UINT16)) % GetDeviceArchitecture().mainSize) !=
// 0)
if ((((GetBBMBadBlocksNumber()) * sizeof(UINT16)) % CHUNK_DATA_SIZE) !=
0)
{
pageNumber = (((GetBBMBadBlocksNumber()) * sizeof(UINT16)) /
CHUNK_DATA_SIZE) +
1;
lastPageSize = (((GetBBMBadBlocksNumber()) * sizeof(UINT16)) %
CHUNK_DATA_SIZE);
}
else
{
pageNumber = (((GetBBMBadBlocksNumber()) * sizeof(UINT16)) /
CHUNK_DATA_SIZE);
}
if (GetBBMBadBlocksNumber() != 0)
{
//create BBT on ram
table = (UINT16 *)OS_DRIVER_Malloc(sizeof(UINT16) * GetBBMBadBlocksNumber());
if (table == NULL)
{
return FAILURE;
}
//fill the table with list elem
temp = GetBBMBadBlockList();
i = 0;
while (temp != NULL)
{
BadBlockElem *t;
table[i] = temp->blockNumber;
t = temp;
temp = temp->next;
if (t != NULL)
{
OS_DRIVER_Free(t);
t = NULL;
}
i++;
}
SetBBMBadBlockList(NULL);
}
//erase the block selected
//if there is a BBT on device
if (firstGoodBlock == 0xFFFF) /*exsit*/
{
UINT8 *buffer;
UINT32 returnAddress;
UINT16 lenght;
// lenght = GetDeviceArchitecture().pageSize;
// buffer = OS_DRIVER_Malloc(GetDeviceArchitecture().pageSize);
lenght = CHUNK_SIZE;
buffer = (UINT8 *)OS_DRIVER_Malloc(CHUNK_SIZE);
if (buffer == NULL)
{
return FAILURE;
}
//OS_MemSet(buffer,0xFF,GetDeviceArchitecture().pageSize);
OS_MemSet(buffer,0xFF,CHUNK_SIZE);
OS_MemCopy(buffer,&bootStruct,sizeof(bootStruct));
CalculateAddress(GetBBMBootBlockNumber(),0,&returnAddress) ;
if (NAND_BlockErase(returnAddress) != NAND_PASS)
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
//write the bootstruct
//if (NAND_PageProgram(returnAddress,buffer,GetDeviceArchitecture().pageSize) !=
// NAND_PASS)
if (NAND_PageProgram(returnAddress,buffer,CHUNK_SIZE) !=
NAND_PASS)
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
OS_DRIVER_Free(buffer);
}
else/*not exsit*/
{
//UINT8 *buffer = OS_DRIVER_Malloc(GetDeviceArchitecture().pageSize);
UINT8 *buffer = (UINT8 *)OS_DRIVER_Malloc(CHUNK_SIZE);
UINT32 returnAddress;
UINT16 lenght;
//lenght = GetDeviceArchitecture().pageSize;
lenght = CHUNK_SIZE;
//OS_MemSet(buffer,0xFF,GetDeviceArchitecture().pageSize);
OS_MemSet(buffer,0xFF,CHUNK_SIZE);
OS_MemCopy(buffer,&bootStruct,sizeof(bootStruct));
CalculateAddress(firstGoodBlock,0,&returnAddress);
if (NAND_BlockErase(returnAddress) != NAND_PASS)
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
if (NAND_PageProgram(returnAddress,buffer,lenght) != NAND_PASS)
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
OS_DRIVER_Free(buffer) ;
SetBBMBootBlockNumber(firstGoodBlock);
}
//write BBT in flash page after page
for (i = 1; i <= pageNumber; i++)
{
UINT16 lenght;
UINT32 returnAddress;
//UINT8 *buffer = OS_DRIVER_Malloc(GetDeviceArchitecture().pageSize);
UINT8 *buffer = (UINT8 *)OS_DRIVER_Malloc(CHUNK_SIZE);
if (buffer == NULL)
{
return FAILURE;
}
lenght = CHUNK_SIZE;
OS_MemSet(buffer,0xFF,CHUNK_SIZE);
OS_MemCopy(buffer,table,bootStruct.noOfBadBlocks * sizeof(UINT16));
CalculateAddress(GetBBMBootBlockNumber(),i,&returnAddress) ;
if (NAND_PageProgram(returnAddress,buffer,lenght) != NAND_PASS)
{
OS_DRIVER_Free(buffer);
return FAILURE;
}
OS_DRIVER_Free(buffer);
}
if (table != NULL)
{
OS_DRIVER_Free(table);
table = NULL;
}
return SUCCESS;
}
/***************** GetBadBlocksNumber ******************************
* Return the number of bad blocks present on flash *
* *
*-------------------------------------------------------------------*
* numOfBadBlocks : containt the number of bad blocks present on *
* flash *
* return value: SUCCESS no error is occured *
*********************************************************************/
NFTL_Return GetBadBlocksNumber(UINT16 *numOfBadBlocks)
{
*numOfBadBlocks = GetBBMBadBlocksNumber();
return SUCCESS;
}
/***************** GetBadBlocksNumber ******************************
* Save the number of bad blocks present on flash *
* *
*-------------------------------------------------------------------*
* numOfBadBlocks : containt the number of bad blocks present on *
* flash *
* return value: SUCCESS no error is occured *
*********************************************************************/
NFTL_Return SetBadBlocksNumber(UINT16 numOfBadBlocks)
{
SetBBMBadBlocksNumber(numOfBadBlocks);
return SUCCESS;
}
NFTL_Return Unmount_BBM()
{
BadBlockElem *temp;
/*number of bad block present on device*/
SetBBMBadBlocksNumber(0);
/*physical block number of block containing the BBT*/
SetBBMBootBlockNumber(-1);
/*pointer to the last elem of bad block list in ram*/
SetBBMlast(NULL);
while (GetBBMBadBlockList() != NULL)
{
temp = GetBBMBadBlockList();
SetBBMBadBlockList(GetBBMBadBlockList()->next);
if (temp != NULL)
{
OS_DRIVER_Free(temp);
temp = NULL;
}
}
return SUCCESS;
}
UINT8 GetBBMBadBlocksNumber()
{
return BadBlocksNumber;
}
void SetBBMBadBlocksNumber(UINT8 value)
{
BadBlocksNumber = value;
}
BadBlockElem * GetBBMBadBlockList()
{
return BadBlockList;
}
void SetBBMBadBlockList(BadBlockElem *value)
{
BadBlockList = value;
}
BadBlockElem * GetBBMlast()
{
return last;
}
void SetBBMlast(BadBlockElem *value)
{
last = value;
}
INT16 GetBBMBootBlockNumber()
{
return BootBlockNumber;
}
void SetBBMBootBlockNumber(INT16 value)
{
BootBlockNumber = value;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -