Пример #1
0
void get_partition_badblock(struct ptentry *ptn, struct nand_spec *spec)
{
	unsigned i = 0;
    unsigned block_start = 0;
	unsigned block_end= 0;
    unsigned bad_flag;
    unsigned bad_block_num =0;
    unsigned ret;

    block_start = (ptn->start + spec->blocksize- 1) / spec->blocksize;
	block_end = (ptn->start + ptn->length + spec->blocksize - 1) / spec->blocksize;

	for (i = block_start; i < block_end; i++)
	{
	    ret = nand_isbad(i, &bad_flag);
        if(ret)
        {
            cprintf("ERROR: check flash bad failed\n");
            return;
        }

	    if(NANDC_BAD_BLOCK == bad_flag)
        {
            cprintf("\nBad block found, partition: %s, address: 0x%x", ptn->name, i * spec->blocksize);
            bad_block_num++;
        }
	}

    if(0 == bad_block_num)
    {
        cprintf("\nNo bad block found, partition: %s", ptn->name);
    }

    return;
}
Пример #2
0
/**
* 作用:nandc模块按分区名和分区相对偏移来确定此块是不是坏块
*
* 参数:
* @partition_name          		---查询数据块的分区名
* @partition_offset      	    ---查询数据块的分区相对偏移地址
*
* 描述:根据分区名和分区的偏移地址来确定Flash的地址,再来判断此block是不是坏块
返回值:
* 0表示此块是好块
* 1表示是坏块
* 其他的表示有错误
*/
int bsp_nand_isbad(const char *partition_name, u32 partition_offset)
{
    u32 flash_addr;
    u32 bad_flag;
    u32 ret = NANDC_ERROR;
	struct nandc_host  * host   = NULL;
    struct ST_PART_TBL * ptable = find_partition_by_name(partition_name);

    if(!ptable)
    {
        goto ERRO;
    }

    /*得到Flash地址*/
    flash_addr = ptable->offset + partition_offset;

    host = nandc_nand_host;
    if(!host)
    {
        NAND_TRACE(("ERROR: function %s, line %d\n", __FUNCTION__, __LINE__));
        goto ERRO;
    }
	/*判断此block是否是坏块*/
	ret = nand_isbad(flash_addr / host->nandchip->spec.blocksize, &bad_flag);
    if(ret == 1)
    {
        return -6;
    }
    else if(ret > 1)
    {
        return ret;
    }

    if(bad_flag == 1)  /* bad block */
    {
        return 1;
    }
    else               /* good block */
    {
        return 0;
    }

ERRO:
    return ret;
}
Пример #3
0
/**
* 作用:nandc模块按分区名和分区偏移地址来擦除flash操作
*
* 参数:
* @partition_name          		---要擦除的分区名
* @partition_offset      	    ---要擦除的相对偏移地址
*
*
* 描述:根据分区名和分区的偏移地址来确定Flash的地址,再来擦除一个block,注意是擦除一个block数据块
*/
int bsp_nand_erase(const char *partition_name, u32 partition_offset)
{
    u32 flash_addr;
    u32 block_id, bad_flag;
    u32 ret = NANDC_ERROR;
	struct nandc_host  * host   = NULL;
    struct ST_PART_TBL * ptable = find_partition_by_name(partition_name);
	/*参数不正确*/
    if(!ptable)
    {
        goto ERRO;
    }

    /*得到flash的地址信息*/
    flash_addr = ptable->offset + partition_offset;

    host = nandc_nand_host;
    if(!host)
    {
        NAND_TRACE(("ERROR: function %s, line %d\n", __FUNCTION__, __LINE__));
        goto ERRO;
    }

    /*得到块号并判断是否是坏块*/
    block_id = flash_addr / host->nandchip->spec.blocksize;
    ret = nand_isbad(block_id, &bad_flag);
    if(ret)
    {
        NAND_TRACE(("ERROR: nand quary bad failed, function %s, line %d\n", __FUNCTION__, __LINE__));
        goto ERRO;
    }

    if(NANDC_BAD_BLOCK == bad_flag)
    {
        NAND_TRACE(("ERROR: try to erase a bad block, function %s, line %d\n", __FUNCTION__, __LINE__));
        goto ERRO;
    }
	/*擦除flash操作*/
	return nand_erase(block_id);

ERRO:
    return ret;
}
Пример #4
0
/**
 * 作用:对nand标坏块
 *
 * 参数:
 * @blockid          ---block块的字符串
 *
 *
 * 描述:nand标坏块
 */
void bsp_nand_markbad(char *blockid)
{
    int ret = NANDC_ERROR;
    unsigned int id, bad_flag;
    char *blk_id = bsp_nand_argument_check(blockid);

    /* string to int  */
    ret= str2ul(blk_id, &id);
    if(ret)
    {
        NAND_TRACE(("ERROR: string to integer failed, ret = 0x%x.\n", ret));
        goto EXIT;
    }

    /* check block bad. if good, mark bad; else return */
    ret = nand_isbad(id, &bad_flag);
    if(ret)
    {
        NAND_TRACE(("[%s]ERROR: nand check bad failed, ret = 0x%x.\n", __FUNCTION__, ret));
        goto EXIT;
    }

    if(NANDC_GOOD_BLOCK == bad_flag)
    {
        ret = nand_bad(id);
        if(ret)
        {
            NAND_TRACE(("[%s]ERROR: nand mark bad failed, ret = 0x%x.\n", __FUNCTION__, ret));
            goto EXIT;
        }
    }
    else
    {
        NAND_TRACE(("[%s]WARNING: block 0x%x is already bad.\n", __FUNCTION__));
        goto EXIT;
    }

    return;

EXIT:
    return;
}
Пример #5
0
/*****************************************************************************
* name		: flash_erase
*
* description	: Erase nand block
*
* input		: ptentry *ptn: partition to be erase
*
* return		: NANDF_OK: erase OK
*			  NANDF_ERROR_INIT: Init failed
*			  NANDF_ERROR_ARGS: Input error
*			  NANDF_BAD_BLOCK: the block to be erase is a bad block
*			  NANDF_ERROR_ERASE: erase failed, and mark the block as a bad block
*			  NANDF_ERROR_ERASE_MARKBAD: erase failed, and mark bad block failed
*			  NANDF_ERROR_SEMTAKE: apply semphore failed
*			  NANDF_ERROR_SEMGIVE: release semphore failed
*
* other		: No
*****************************************************************************/
int flash_erase(ptentry *ptn)
{
	int ret = ERROR;
	unsigned i = 0;
	unsigned block_start = 0;
	unsigned block_end= 0;
    unsigned bad_flag;
    struct nand_spec spec;

    ret = nand_get_spec(&spec);
    if(ret)
    {
        cprintf("ERROR: nand get spec failed!\n");
        return ERROR;
    }

    /* coverity[uninit_use] */
	block_start = (ptn->start + spec.blocksize- 1) / spec.blocksize;
	block_end = (ptn->start + ptn->length + spec.blocksize - 1) / spec.blocksize;

	for (i = block_start; i < block_end; i++)
	{
	    ret = (s32)nand_isbad(i, &bad_flag);
        if(NANDC_OK != ret || NANDC_BAD_BLOCK == bad_flag)
        {
            cprintf("block %d is bad, not erase, ret=%x\n", i, ret);
            continue;
        }

        ret = (s32)nand_erase(i);
        if(ret)
        {
            cprintf("erase block %d failed, ret=%x\n", i, ret);
        }
	}

    return OK;
}
Пример #6
0
/**
 * 作用:nandc模块提供对外扫描坏块的函数接口
 *
 * 参数:
 * @start         ---flash开始的地址
 * @length        ---扫描的长度
 * @if_erase      ---如果检测是好块根据此参数来决定是否擦除此块
 * 描述:扫描flash是否是坏块,根据参数来决定是否擦除
 */
u32 nand_scan_bad(FSZ start, FSZ length, u32 if_erase)
{
	u32 addr_block_align;
	u32 length_block_align;
	u32 blk_id, is_bad, times, ret;
	struct nand_spec spec;
	/*因为是在fastboot中实现,内存的释放是没有实现的,使用静态变量表示一次分配以后都不分配了*/
	static u32 block_buf = 0 ;

	memset(&spec, 0, sizeof(struct nand_spec));
	/*通过此函数得到nandflash的规格参数,知道blocksize的大小*/
	if(NAND_OK != nand_get_spec(&spec))
	{
		NAND_TRACE(("nand_scan_bad: nand_get_spec failed\n"));
		return NAND_ERROR;
	}

	/*扫描块时要块对齐*/
	addr_block_align = start - start%(spec.blocksize);
	/*得到要扫描的块长度*/
	length_block_align = nandc_alige_size(start + length, spec.blocksize) - addr_block_align;
	/*如果没有分配内存就分配内存*/
	if(!block_buf)
	{
		block_buf = (u32)himalloc(spec.blocksize);
		if(NULL == (void*)block_buf)//pclint 58
		{
			NAND_TRACE(("nand_scan_bad: himalloc failed\n"));
			goto ERRO;
		}
	}
	/*还有块长度需要扫描*/
	while(length_block_align > 0)
	{
		/*得到块号地址*/
		blk_id = addr_block_align/spec.blocksize;
		if(NAND_OK != nand_isbad(blk_id, &is_bad))
		{
			NAND_TRACE(("nand_scan_bad: nand_isbad failed\n"));
			goto ERRO;
		}
		if(NANDC_GOOD_BLOCK == is_bad)
		{
			times = 1;
			/*读整块数据如果没有出错的话表示是好坏*/
			while((NANDC_E_READ == nand_read((FSZ)addr_block_align, block_buf, spec.blocksize, 0)) && (times))
			{
			    times--;
			}
			if(0 == times)
			{
			    NAND_TRACE(("nand_scan_bad: find and read error, address:0x%x\n",addr_block_align));

			    ret = nand_bad(blk_id);
			    if(ret)
			    {
			        NAND_TRACE(("nand_scan_bad:nand check bad failed, ret = 0x%x\n",ret));
			    }
			}
			/*是好块如果要擦除的话就擦除*/
			else if(NANDC_TRUE == if_erase)
			{
			    ret = nand_erase(blk_id);
			    if(ret)
			    {
			        NAND_TRACE(("nand_scan_bad:nand erase failed, ret = 0x%x\n",ret));
			    }
			}
			else
			{
			}
		}
		else
		{
			NAND_TRACE(("nand_scan_bad:find bad block: 0x%x\n",addr_block_align));
		}
		length_block_align -= spec.blocksize;
		addr_block_align   += spec.blocksize;
	}

	return NAND_OK;
ERRO:
	return NAND_ERROR;
}