示例#1
0
/* returns 0 if block containing pos is OK:
 *		valid erase block and
 *		not marked bad, or no bad mark position is specified
 * returns 1 if marked bad or otherwise invalid
 */
static int check_block (struct nand_chip *nand, unsigned long pos)
{
	size_t retlen;
	uint8_t oob_data;
	uint16_t oob_data16[6];
	int page0 = pos & (-nand->erasesize);
	int page1 = page0 + nand->oobblock;
	int badpos = oob_config.badblock_pos;

	if (pos >= nand->totlen)
		return 1;

	if (badpos < 0)
		return 0;	/* no way to check, assume OK */

	if (nand->bus16) {
		if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
		    || (oob_data16[2] & 0xff00) != 0xff00)
			return 1;
		if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
		    || (oob_data16[2] & 0xff00) != 0xff00)
			return 1;
	} else {
		/* Note - bad block marker can be on first or second page */
		if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data)
		    || oob_data != 0xff
		    || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data)
		    || oob_data != 0xff)
			return 1;
	}

	return 0;
}
示例#2
0
static int
nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset,
    uint32_t len, uint8_t *data, uint8_t write)
{
	struct chip_geom *cg;
	uint8_t *buf = NULL;
	int ret = 0;

	cg = &chip->chip_geom;

	buf = malloc(cg->oob_size, M_NAND, M_WAITOK);
	if (!buf)
		return (ENOMEM);

	memset(buf, 0xff, cg->oob_size);

	if (!write) {
		ret = nand_read_oob(chip, page, buf, cg->oob_size);
		copyout(buf, data, len);
	} else {
		copyin(data, buf, len);
		ret = nand_prog_oob(chip, page, buf, cg->oob_size);
	}

	free(buf, M_NAND);

	return (ret);
}
示例#3
0
/*****************************************************************************
* name		: flash_read_ext
*
* description	: Read data from nand
*
* input		: ptentry *ptn: flash partition to read
*			: unsigned extra_per_page:
*			: unsigned offset: offset from partition start address
*			: void *data: buffer to save data
*             		: unsigned bytes: number of bytes to read
*
* return		: NANDF_ERROR_INIT: Init error
*			  NANDF_ERROR_ARGS: Input error
*			  NANDF_ERROR_READ: Read error
*			  NANDF_OK: Read successful
*
* other		: No
*****************************************************************************/
int flash_read_ext(ptentry *ptn, unsigned extra_per_page, unsigned offset, void *data, unsigned bytes, unsigned int *skip_len)
{
    int ret = 0;
    u64 src_addr = 0;

    src_addr = ptn->start + offset;

    ret = nand_read_oob((u64)src_addr, (u32)data, bytes, extra_per_page, skip_len);

    return ret;
}
示例#4
0
/**
* 作用:读取分区相对偏移地址的标志值,主要是为NV模块用,查询此分区的偏移地址的标志位的值
*
* 参数:
* @partition_name         	---分区名
* @partition_offset         ---分区的相对偏移
* @flag                     ---把检测的分区的标志值存放在此flag中
* 描述:NV模块把一个分区的一个block的最后一页的OOB中存放特定标记值,读此标记值存放在flag中
*/
u32 bsp_nand_read_flag_nv(const char *partition_name, u32 partition_offset, unsigned char *flag)
{
    u32 flash_addr;
    u32 ret = NANDC_ERROR;
    static unsigned char *buffer = NULL;
    struct nand_spec spec;
    struct ST_PART_TBL * ptable = find_partition_by_name((char *)partition_name);
	/*参数不对*/
    if(!ptable)
    {
        goto ERRO;
    }
    if(!flag)
    {
        NAND_TRACE(("argu error.\n"));
        goto ERRO;
    }
	/*得到此分区的nandflash的规格参数*/
    ret = bsp_get_nand_info(&spec);
    if(ret)
    {
        goto ERRO;
    }
	/*没有内存时分配内存*/
    if(!buffer)
    {
        buffer = (unsigned char *)himalloc(spec.pagesize + YAFFS_BYTES_PER_SPARE);
        if(!buffer)
        {
    		NAND_TRACE(("get ram buffer failed!\n"));
    		goto ERRO;
        }
    }

    memset(buffer, 0xFF, spec.pagesize + YAFFS_BYTES_PER_SPARE);

    flash_addr = ptable->offset + partition_offset;
	/*使能ECC功能的带OOB读数据功能*/
    ret = nand_read_oob((flash_addr + spec.blocksize - spec.pagesize),
          (unsigned int)buffer, (spec.pagesize + YAFFS_BYTES_PER_SPARE),YAFFS_BYTES_PER_SPARE ,NULL);
    if(ret)
    {
		NAND_TRACE(("nand read oob failed!\n"));
		goto ERRO;
    }
    *flag = (*(buffer + spec.pagesize) == NV_WRITE_SUCCESS) ? NV_WRITE_SUCCESS : (~NV_WRITE_SUCCESS);

    return NANDC_OK;
ERRO:
    return ret;
}
示例#5
0
static int
nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset,
    uint32_t len, uint8_t *data, uint8_t write)
{
	struct chip_geom *cg;
	int ret = 0;

	cg = &chip->chip_geom;

	if (!write)
		ret = nand_read_oob(chip, page, data, cg->oob_size);
	else
		ret = nand_prog_oob(chip, page, data, cg->oob_size);

	return (ret);
}
示例#6
0
/* read a block data to buf
 * return 1 if the block is bad or ECC error can't be corrected for any page
 * return 0 on sucess
 */ 
int nand_read_block(unsigned char *buf, ulong block_addr)
{
	int i, offset = 0;
	uchar oob_buf[16];
 	
	/* check bad block */
	/* 0th and 5th words need be 0xffff */
	if (nand_read_oob(oob_buf, block_addr) ||
//		oob_buf[0] != 0xff || oob_buf[1] != 0xff ||
//		oob_buf[10] != 0xff || oob_buf[11] != 0xff ){
		oob_buf[5] != 0xff){
		printf("Skipped bad block at 0x%x\n", block_addr);
 		return NAND_READ_SKIPPED_BAD_BLOCK;    /* skip bad block */
	}

	/* read the block page by page*/
	for (i=0; i<32; i++){
		if (nand_read_page(buf+offset, block_addr + offset))
			return NAND_READ_ECC_FAILURE;
		offset += PAGE_SIZE;
	}

	return NAND_READ_SUCCESS;
}