Ejemplo n.º 1
0
/** 
 * \brief initialize tree buffers
 * \param[in] dev uffs device
 */
URET uffs_TreeInit(uffs_Device *dev)
{
	int size;
	int num;
	uffs_Pool *pool;
	int i;

	size = sizeof(TreeNode);
	num = dev->par.end - dev->par.start + 1;
	
	pool = &(dev->mem.tree_pool);

	if (dev->mem.tree_nodes_pool_size == 0) {
		if (dev->mem.malloc) {
			dev->mem.tree_nodes_pool_buf = dev->mem.malloc(dev, size * num);
			if (dev->mem.tree_nodes_pool_buf)
				dev->mem.tree_nodes_pool_size = size * num;
		}
	}
	if (size * num > dev->mem.tree_nodes_pool_size) {
		uffs_Perror(UFFS_MSG_DEAD,
					"Tree buffer require %d but only %d available.",
					size * num, dev->mem.tree_nodes_pool_size);
		memset(pool, 0, sizeof(uffs_Pool));
		return U_FAIL;
	}
	uffs_Perror(UFFS_MSG_NOISY, "alloc tree nodes %d bytes.", size * num);
	
	uffs_PoolInit(pool, dev->mem.tree_nodes_pool_buf,
					dev->mem.tree_nodes_pool_size, size, num, U_FALSE);

	dev->tree.erased = NULL;
	dev->tree.erased_tail = NULL;
	dev->tree.erased_count = 0;
	dev->tree.bad = NULL;
	dev->tree.bad_count = 0;

	for (i = 0; i < DIR_NODE_ENTRY_LEN; i++) {
		dev->tree.dir_entry[i] = EMPTY_NODE;
	}

	for (i = 0; i < FILE_NODE_ENTRY_LEN; i++) {
		dev->tree.file_entry[i] = EMPTY_NODE;
	}

	for (i = 0; i < DATA_NODE_ENTRY_LEN; i++) {
		dev->tree.data_entry[i] = EMPTY_NODE;
	}

	dev->tree.max_serial = ROOT_DIR_SERIAL;
	
	return U_SUCC;
}
Ejemplo n.º 2
0
/**
 * initialise uffs_DIR buffers, called by UFFS internal
 */
URET uffs_InitDirEntryBuf(void)
{
return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
                     sizeof(uffs_DIR), MAX_DIR_HANDLE);
}
Ejemplo n.º 3
0
Archivo: uffs_fs.c Proyecto: mazj/uffs
/**
 * initialise object buffers, called by UFFS internal
 */
URET uffs_InitObjectBuf(void)
{
	return uffs_PoolInit(&_object_pool, _object_data, sizeof(_object_data),
			sizeof(uffs_Object), MAX_OBJECT_HANDLE, U_FALSE);
}
/**
 * Initialize UFFS flash interface
 */
URET uffs_FlashInterfaceInit(uffs_Device *dev)
{
	URET ret = U_FAIL;
	struct uffs_StorageAttrSt *attr = dev->attr;
	uffs_Pool *pool = SPOOL(dev);

	if (dev->mem.spare_pool_size == 0) {
		if (dev->mem.malloc) {
			dev->mem.spare_pool_buf = dev->mem.malloc(dev, UFFS_SPARE_BUFFER_SIZE);
			if (dev->mem.spare_pool_buf)
				dev->mem.spare_pool_size = UFFS_SPARE_BUFFER_SIZE;
		}
	}

	if (UFFS_SPARE_BUFFER_SIZE > dev->mem.spare_pool_size) {
		uffs_Perror(UFFS_MSG_DEAD,
					"Spare buffer require %d but only %d available.",
					UFFS_SPARE_BUFFER_SIZE, dev->mem.spare_pool_size);
		memset(pool, 0, sizeof(uffs_Pool));
		goto ext;
	}

	uffs_Perror(UFFS_MSG_NOISY,
					"alloc spare buffers %d bytes.",
					UFFS_SPARE_BUFFER_SIZE);
	uffs_PoolInit(pool, dev->mem.spare_pool_buf,
					dev->mem.spare_pool_size,
					UFFS_MAX_SPARE_SIZE, MAX_SPARE_BUFFERS);

	// init flash driver
	if (dev->ops->InitFlash) {
		if (dev->ops->InitFlash(dev) < 0)
			goto ext;
	}

	if (dev->ops->WritePage == NULL && dev->ops->WritePageWithLayout == NULL) {
		uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver must provide 'WritePage' or 'WritePageWithLayout' function!");
		goto ext;
	}

	if (dev->ops->ReadPage == NULL && dev->ops->ReadPageWithLayout == NULL) {
		uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver must provide 'ReadPage' or 'ReadPageWithLayout' function!");
		goto ext;
	}

	if (dev->attr->layout_opt == UFFS_LAYOUT_UFFS) {
		/* sanity check */

		if (dev->attr->ecc_size == 0 && dev->attr->ecc_opt != UFFS_ECC_NONE) {
			dev->attr->ecc_size = NOMINAL_ECC_SIZE(dev);
		}

		uffs_Perror(UFFS_MSG_NORMAL, "ECC size %d", dev->attr->ecc_size);

		if ((dev->attr->data_layout && !dev->attr->ecc_layout) ||
			(!dev->attr->data_layout && dev->attr->ecc_layout)) {
			uffs_Perror(UFFS_MSG_SERIOUS,
						"Please setup data_layout and ecc_layout, "
						"or leave them all NULL !");
			goto ext;
		}

		if (!attr->data_layout && !attr->ecc_layout) {
#if defined(CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME)
			switch(attr->page_data_size) {
			case 512:
				attr->ecc_layout = MTD512_LAYOUT_ECC;
				attr->data_layout = MTD512_LAYOUT_DATA;
				break;
			case 2048:
				attr->ecc_layout = MTD2K_LAYOUT_ECC;
				attr->data_layout = MTD2K_LAYOUT_DATA;
				break;
			default:
				InitSpareLayout(dev);
				break;
			}
#else
			InitSpareLayout(dev);
#endif
		}
	}
	else if (dev->attr->layout_opt == UFFS_LAYOUT_FLASH) {
		if (dev->ops->WritePageWithLayout == NULL || dev->ops->ReadPageWithLayout == NULL) {
			uffs_Perror(UFFS_MSG_SERIOUS, "When using UFFS_LAYOUT_FLASH option, "
				"flash driver must provide 'WritePageWithLayout' and 'ReadPageWithLayout' function!");
			goto ext;
		}
	}
	else {
		uffs_Perror(UFFS_MSG_SERIOUS, "Invalid layout_opt: %d", dev->attr->layout_opt);
		goto ext;
	}

	if (dev->ops->EraseBlock == NULL) {
		uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver MUST implement 'EraseBlock()' function !");
		goto ext;
	}

	dev->mem.spare_data_size = CalculateSpareDataSize(dev);
	uffs_Perror(UFFS_MSG_NORMAL, "UFFS consume spare data size %d", dev->mem.spare_data_size);

	if (dev->mem.spare_data_size > dev->attr->spare_size) {
		uffs_Perror(UFFS_MSG_SERIOUS, "NAND spare(%dB) can't hold UFFS spare data(%dB) !",
						dev->attr->spare_size, dev->mem.spare_data_size);
		goto ext;
	}

	ret = U_SUCC;
ext:
	return ret;
}