struct yaffs_dev *yflash2_install_drv(const char *name) { struct yaffs_dev *dev = NULL; struct yaffs_param *param; struct yaffs_driver *drv; dev = malloc(sizeof(*dev)); if(!dev) return NULL; memset(dev, 0, sizeof(*dev)); dev->param.name = strdup(name); if(!dev->param.name) { free(dev); return NULL; } drv = &dev->drv; drv->drv_write_chunk_fn = yflash2_WriteChunk; drv->drv_read_chunk_fn = yflash2_ReadChunk; drv->drv_erase_fn = yflash2_EraseBlock; drv->drv_mark_bad_fn = yflash2_MarkBad; drv->drv_check_bad_fn = yflash2_CheckBad; drv->drv_initialise_fn = yflash2_Initialise; param = &dev->param; param->total_bytes_per_chunk = 2048; param->chunks_per_block = 64; param->start_block = 0; param->end_block = yflash2_GetNumberOfBlocks()-1; param->is_yaffs2 = 1; param->use_nand_ecc=1; param->n_reserved_blocks = 5; param->wide_tnodes_disabled=0; param->refresh_period = 1000; param->n_caches = 10; // Use caches param->enable_xattr = 1; /* dev->driver_context is not used by this simulator */ yaffs_add_device(dev); return dev; }
struct yaffs_dev *yaffs_m18_install_drv(const char *name) { struct yaffs_dev *dev = malloc(sizeof(struct yaffs_dev)); char *name_copy = strdup(name); struct yaffs_param *param; struct yaffs_driver *drv; if(!dev || !name_copy) { free(name_copy); free(dev); return NULL; } param = &dev->param; drv = &dev->drv; memset(dev, 0, sizeof(*dev)); param->name = name_copy; param->total_bytes_per_chunk = 1024; param->chunks_per_block =248; param->n_reserved_blocks = 2; param->start_block = 0; // Can use block 0 param->end_block = 31; // Last block param->use_nand_ecc = 0; // use YAFFS's ECC drv->drv_write_chunk_fn = m18_drv_WriteChunkToNAND; drv->drv_read_chunk_fn = m18_drv_ReadChunkFromNAND; drv->drv_erase_fn = m18_drv_EraseBlockInNAND; drv->drv_initialise_fn = m18_drv_InitialiseNAND; drv->drv_deinitialise_fn = m18_drv_Deinitialise_flash_fn; param->n_caches = 10; param->disable_soft_del = 1; dev->driver_context = (void *) 1; // Used to identify the device in fstat. yaffs_add_device(dev); return NULL; }
struct yaffs_dev * yaffs_add_dev_from_geometry(const YCHAR *name, const struct ynandif_Geometry *geometry) { YCHAR *clonedName = malloc(sizeof(YCHAR) * (strnlen(name, YAFFS_MAX_NAME_LENGTH)+1)); struct yaffs_dev *dev = malloc(sizeof(struct yaffs_dev)); struct yaffs_param *param; if (dev && clonedName) { memset(dev, 0, sizeof(struct yaffs_dev)); strcpy(clonedName, name); param = &dev->param; param->name = clonedName; param->write_chunk_tags_fn = ynandif_WriteChunkWithTagsToNAND; param->read_chunk_tags_fn = ynandif_ReadChunkWithTagsFromNAND; param->erase_fn = ynandif_EraseBlockInNAND; param->initialise_flash_fn = ynandif_InitialiseNAND; param->query_block_fn = ynandif_QueryNANDBlock; param->bad_block_fn = ynandif_MarkNANDBlockBad; param->n_caches = 20; param->start_block = geometry->start_block; param->end_block = geometry->end_block; param->total_bytes_per_chunk = geometry->dataSize; param->spare_bytes_per_chunk = geometry->spareSize; param->inband_tags = geometry->inband_tags; param->chunks_per_block = geometry->pagesPerBlock; param->use_nand_ecc = geometry->hasECC; param->is_yaffs2 = geometry->useYaffs2; param->n_reserved_blocks = 5; dev->driver_context = (void *)geometry; yaffs_add_device(dev); return dev; } free(dev); free(clonedName); return NULL; }
void cmd_yaffs_devconfig(char *_mp, int flash_dev, int start_block, int end_block) { struct mtd_info *mtd = NULL; struct yaffs_dev *dev = NULL; struct yaffs_dev *chk; char *mp = NULL; struct nand_chip *chip; dev = calloc(1, sizeof(*dev)); mp = strdup(_mp); mtd = &nand_info[flash_dev]; if (!dev || !mp) { /* Alloc error */ printf("Failed to allocate memory\n"); goto err; } if (flash_dev >= CONFIG_SYS_MAX_NAND_DEVICE) { printf("Flash device invalid\n"); goto err; } if (end_block == 0) end_block = mtd->size / mtd->erasesize - 1; if (end_block < start_block) { printf("Bad start/end\n"); goto err; } chip = mtd->priv; /* Check for any conflicts */ yaffs_dev_rewind(); while (1) { chk = yaffs_next_dev(); if (!chk) break; if (strcmp(chk->param.name, mp) == 0) { printf("Mount point name already used\n"); goto err; } if (chk->driver_context == mtd && yaffs_regions_overlap( chk->param.start_block, chk->param.end_block, start_block, end_block)) { printf("Region overlaps with partition %s\n", chk->param.name); goto err; } } /* Seems sane, so configure */ memset(dev, 0, sizeof(*dev)); dev->param.name = mp; dev->driver_context = mtd; dev->param.start_block = start_block; dev->param.end_block = end_block; dev->param.chunks_per_block = mtd->erasesize / mtd->writesize; dev->param.total_bytes_per_chunk = mtd->writesize; dev->param.is_yaffs2 = 1; dev->param.use_nand_ecc = 1; dev->param.n_reserved_blocks = 5; if (chip->ecc.layout->oobavail < sizeof(struct yaffs_packed_tags2)) dev->param.inband_tags = 1; dev->param.n_caches = 10; dev->param.write_chunk_tags_fn = nandmtd2_write_chunk_tags; dev->param.read_chunk_tags_fn = nandmtd2_read_chunk_tags; dev->param.erase_fn = nandmtd_EraseBlockInNAND; dev->param.initialise_flash_fn = nandmtd_InitialiseNAND; dev->param.bad_block_fn = nandmtd2_MarkNANDBlockBad; dev->param.query_block_fn = nandmtd2_QueryNANDBlock; yaffs_add_device(dev); printf("Configures yaffs mount %s: dev %d start block %d, end block %d %s\n", mp, flash_dev, start_block, end_block, dev->param.inband_tags ? "using inband tags" : ""); return; err: free(dev); free(mp); }
void fs_init(void) { yaffs_add_device(&flash_dev); yaffs_mount("/"); }