Esempio n. 1
0
static int nand_read_page(
    uffs_Device *dev,
    u32 block, u32 page,
    u8 *data, int data_len,
    u8 * ecc,
    rt_uint8_t *spare, int spare_len)
{
	int res;

	page = block * dev->attr->pages_per_block + page;
	if (data == NULL && spare == NULL)
	{
#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON)
		RT_ASSERT(0); //should not be here
#else
		/* check block status: bad or good */
		rt_uint8_t spare[UFFS_MAX_SPARE_SIZE];

		rt_memset(spare, 0, UFFS_MAX_SPARE_SIZE);

		rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private),
		                 page, RT_NULL, 0,
		                 spare, dev->attr->spare_size);//dev->mem.spare_data_size

		res = spare[dev->attr->block_status_offs] == 0xFF ?
				               UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
		return res;
#endif
	}

	rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private),
	                   	   page, data, data_len, spare, spare_len);

	return UFFS_FLASH_NO_ERR;
}
Esempio n. 2
0
static int nand_mark_badblock(uffs_Device *dev, unsigned block)
{
    int res;

    res = rt_mtd_nand_mark_badblock(RT_MTD_NAND_DEVICE(dev->_private), block);

    return res == RT_EOK ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR;
}
Esempio n. 3
0
static int nand_write_page(uffs_Device *dev,
                           u32          block,
                           u32          page,
                           const u8    *data,
                           int          data_len,
                           const u8    *spare,
                           int          spare_len)
{
    int res;

    RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size);

    page = block * dev->attr->pages_per_block + page;

    if (data == NULL && spare == NULL)
    {
#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON)
        RT_ASSERT(0); //should not be here
#else
        /* mark bad block  */
        rt_uint8_t spare[UFFS_MAX_SPARE_SIZE];

        rt_memset(spare, 0xFF, UFFS_MAX_SPARE_SIZE);
        spare[dev->attr->block_status_offs] =  0x00;

        res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private),
                                page, RT_NULL, 0,
                                spare, dev->attr->spare_size);//dev->mem.spare_data_size
        if (res != RT_EOK)
            goto __error;
#endif
    }

    res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private),
                           page,  data, data_len, spare, spare_len);
    if (res != RT_EOK)
        goto __error;

    return UFFS_FLASH_NO_ERR;

__error:
    return UFFS_FLASH_IO_ERR;
}
Esempio n. 4
0
static int dfs_uffs_mount(
	struct dfs_filesystem* fs,
    unsigned long rwflag,
    const void* data)
{
	rt_base_t index;
	uffs_MountTable * mount_part;
	struct rt_mtd_nand_device * dev;
	
	RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX-1));
	dev = RT_MTD_NAND_DEVICE(fs->dev_id);

	/*1. find a empty entry in partition table */
	for (index = 0; index < UFFS_DEVICE_MAX ; index ++)
	{
		if (nand_part[index].dev == RT_NULL)
			break;
	}
	if (index == UFFS_DEVICE_MAX)
		return -DFS_STATUS_ENOENT;

	/*2. fill partition structure */
	nand_part[index].dev = dev;

	/* make a right mount path for uffs, end with '/' */
	rt_snprintf(nand_part[index].mount_path, UFFS_MOUNT_PATH_MAX, "%s/", fs->path);
	if (nand_part[index].mount_path[1] == '/')
		nand_part[index].mount_path[1] = 0;

	mount_part = &(nand_part[index].mount_table);
	mount_part->mount	= nand_part[index].mount_path;
	mount_part->dev = &(nand_part[index].uffs_dev);
	rt_memset(mount_part->dev, 0, sizeof(uffs_Device));//in order to make uffs happy.
	mount_part->dev->_private = dev;   /* save dev_id into uffs */
	mount_part->start_block = dev->block_start;
	mount_part->end_block = dev->block_end;
	/*3. mount uffs */
	if (init_uffs_fs(&nand_part[index]) < 0)
	{
		return uffs_result_to_dfs(uffs_get_error());
	}
	return 0;
}
Esempio n. 5
0
static int dfs_uffs_unmount(struct dfs_filesystem* fs)
{
	rt_base_t index;
	int result;

	/* find the device index and then unmount it */
	for (index = 0; index < UFFS_DEVICE_MAX; index++)
	{
		if (nand_part[index].dev == RT_MTD_NAND_DEVICE(fs->dev_id))
		{
			nand_part[index].dev = RT_NULL;
			result = uffs_UnMount(nand_part[index].mount_path);
			if (result != U_SUCC)
				break;

			result = uffs_UnRegisterMountTable(& nand_part[index].mount_table);
			return (result == U_SUCC) ? DFS_STATUS_OK : -1;
		}
	}
	return -DFS_STATUS_ENOENT;
}
Esempio n. 6
0
static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
{
	int result;
	struct uffs_stat s;
	struct rt_mtd_nand_device * mtd;

	result = uffs_stat(path, &s);
	if (result < 0)
		return uffs_result_to_dfs(uffs_get_error());

	/* convert uffs stat to dfs stat structure */
	/* FIXME, these field may not be the same */
	st->st_dev  = 0;
	st->st_mode = s.st_mode;
	st->st_size = s.st_size;
	st->st_mtime = s.st_mtime;

	mtd = RT_MTD_NAND_DEVICE(fs->dev_id);
	st->st_blksize = mtd->page_size;

	return 0;
}
Esempio n. 7
0
static int dfs_uffs_statfs(struct dfs_filesystem* fs,
                    struct statfs *buf)
{
    rt_base_t index;
    struct rt_mtd_nand_device * mtd = RT_MTD_NAND_DEVICE(fs->dev_id);

    RT_ASSERT(mtd != RT_NULL);

    /* find the device index */
    for (index = 0; index < UFFS_DEVICE_MAX; index++)
    {
        if (nand_part[index].dev == (void *)mtd)
            break;
    }
    if (index == UFFS_DEVICE_MAX)
        return -ENOENT;
    
    buf->f_bsize = mtd->page_size*mtd->pages_per_block;
    buf->f_blocks = (mtd->block_end - mtd->block_start + 1);
    buf->f_bfree = uffs_GetDeviceFree(&nand_part[index].uffs_dev)/buf->f_bsize ;
    
    return 0;
}
Esempio n. 8
0
static URET ReadPageWithLayout(uffs_Device   *dev,
                               u32            block,
                               u32            page,
                               u8            *data,
                               int            data_len,
                               u8            *ecc,              //NULL
                               uffs_TagStore *ts,
                               u8            *ecc_store)        //NULL
{
    int res = UFFS_FLASH_NO_ERR;
    int spare_len;
    rt_uint8_t spare[UFFS_MAX_SPARE_SIZE];

    RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size);

    page = block * dev->attr->pages_per_block + page;
    spare_len = dev->mem.spare_data_size;

    if (data == RT_NULL && ts == RT_NULL)
    {
#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON)
        RT_ASSERT(0); //should not be here
#else
        /* check block good or bad */

        rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private),
                         page, RT_NULL, 0,
                         spare, dev->attr->spare_size);//dev->mem.spare_data_size

        dev->st.io_read++;

        res = spare[dev->attr->block_status_offs] == 0xFF ?
                               UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
        return res;
#endif
    }

    if (data != RT_NULL)
    {
        dev->st.io_read += data_len;
        dev->st.page_read_count++;
    }

    res = rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private),
                           page, data, data_len, spare, spare_len);
    if (res == 0)
        res = UFFS_FLASH_NO_ERR;
    else if (res == -1)
    {
        //TODO ecc correct, add code to use hardware do ecc correct
        res = UFFS_FLASH_ECC_OK;
    }
    else
        res = UFFS_FLASH_ECC_FAIL;

    if (ts != RT_NULL)
    {
        // unload ts and ecc from spare, you can modify it if you like
        uffs_FlashUnloadSpare(dev, (const u8 *)spare, ts, RT_NULL);

        if ((spare[spare_len - 1] == 0xFF) && (res == UFFS_FLASH_NO_ERR))
            res = UFFS_FLASH_NOT_SEALED;

        dev->st.io_read += spare_len;
        dev->st.spare_read_count++;
    }

    return res;
}
Esempio n. 9
0
static int WritePageWithLayout(uffs_Device         *dev,
                               u32                  block,
                               u32                  page,
                               const u8            *data,
                               int                  data_len,
                               const u8            *ecc,  //NULL
                               const uffs_TagStore *ts)
{
    int res;
    int spare_len;
    rt_uint8_t spare[UFFS_MAX_SPARE_SIZE];

    RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size);

    page = block * dev->attr->pages_per_block + page;
    spare_len = dev->mem.spare_data_size;

    if (data == NULL && ts == NULL)
    {
#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON)
        RT_ASSERT(0); //should not be here
#else
        /* mark bad block  */
        rt_memset(spare, 0xFF, UFFS_MAX_SPARE_SIZE);
        spare[dev->attr->block_status_offs] =  0x00;

        res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private),
                                page, RT_NULL, 0,
                                spare, dev->attr->spare_size);//dev->mem.spare_data_size
        if (res != RT_EOK)
            goto __error;

        dev->st.io_write++;
        return UFFS_FLASH_NO_ERR;
#endif
    }

    if (data != NULL && data_len != 0)
    {
        RT_ASSERT(data_len == dev->attr->page_data_size);

        dev->st.page_write_count++;
        dev->st.io_write += data_len;
    }

    if (ts != RT_NULL)
    {
        uffs_FlashMakeSpare(dev, ts, RT_NULL, (u8 *)spare);
        dev->st.spare_write_count++;
        dev->st.io_write += spare_len;
    }

    res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private),
                            page, data, data_len, spare, spare_len);
    if (res != RT_EOK)
        goto __error;

    return UFFS_FLASH_NO_ERR;

__error:
    return UFFS_FLASH_IO_ERR;
}