void yaffs_InitialiseRawTnodesAndObjects(yaffs_Device *dev) { yaffs_Allocator *allocator; unsigned mount_id = yaffs_DeviceToLC(dev)->mount_id; T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n"))); if(dev->allocator) YBUG(); else if(mount_id >= 10){ T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id)); } else { allocator = YMALLOC(sizeof(yaffs_Allocator)); memset(allocator,0,sizeof(yaffs_Allocator)); dev->allocator = allocator; if(!dev->allocator){ T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs allocator creation failed\n"))); YBUG(); return; } sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id); sprintf(allocator->object_name,"yaffs_o_%u",mount_id); allocator->tnode_cache = kmem_cache_create(allocator->tnode_name, dev->tnodeSize, 0, 0, fake_ctor_list[mount_id]); if(allocator->tnode_cache) T(YAFFS_TRACE_ALLOCATE, (TSTR("tnode cache \"%s\" %p\n"), allocator->tnode_name,allocator->tnode_cache)); else { T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs cache creation failed\n"))); YBUG(); } allocator->object_cache = kmem_cache_create(allocator->object_name, sizeof(yaffs_Object), 0, 0, fake_ctor_list[mount_id]); if(allocator->object_cache) T(YAFFS_TRACE_ALLOCATE, (TSTR("object cache \"%s\" %p\n"), allocator->object_name,allocator->object_cache)); else { T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs cache creation failed\n"))); YBUG(); } } }
int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags) { struct mtd_info *mtd = yaffs_DeviceToMtd(dev); #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) struct mtd_oob_ops ops; #endif size_t dummy; int retval = 0; int localData = 0; loff_t addr = ((loff_t) chunkInNAND) * dev->param.totalBytesPerChunk; yaffs_PackedTags2 pt; int packed_tags_size = dev->param.noTagsECC ? sizeof(pt.t) : sizeof(pt); void * packed_tags_ptr = dev->param.noTagsECC ? (void *) &pt.t: (void *)&pt; T(YAFFS_TRACE_MTD, (TSTR ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" TENDSTR), chunkInNAND, data, tags)); if (dev->param.inbandTags) { if (!data) { localData = 1; data = yaffs_GetTempBuffer(dev, __LINE__); } } #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) if (dev->param.inbandTags || (data && !tags)) retval = mtd->read(mtd, addr, dev->param.totalBytesPerChunk, &dummy, data); else if (tags) { ops.mode = MTD_OOB_AUTO; ops.ooblen = packed_tags_size; ops.len = data ? dev->nDataBytesPerChunk : packed_tags_size; ops.ooboffs = 0; ops.datbuf = data; ops.oobbuf = yaffs_DeviceToLC(dev)->spareBuffer; retval = mtd->read_oob(mtd, addr, &ops); } #else if (!dev->param.inbandTags && data && tags) { retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, &dummy, data, dev->spareBuffer, NULL); } else { if (data) retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy, data); if (!dev->param.inbandTags && tags) retval = mtd->read_oob(mtd, addr, mtd->oobsize, &dummy, dev->spareBuffer); } #endif if (dev->param.inbandTags) { if (tags) { yaffs_PackedTags2TagsPart *pt2tp; pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk]; yaffs_UnpackTags2TagsPart(tags, pt2tp); } } else { if (tags) { memcpy(packed_tags_ptr, yaffs_DeviceToLC(dev)->spareBuffer, packed_tags_size); yaffs_UnpackTags2(tags, &pt, !dev->param.noTagsECC); } } if (localData) yaffs_ReleaseTempBuffer(dev, data, __LINE__); if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) { tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; dev->eccUnfixed++; } if(tags && retval == -EUCLEAN && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) { tags->eccResult = YAFFS_ECC_RESULT_FIXED; dev->eccFixed++; } if (retval == 0) return YAFFS_OK; else return YAFFS_FAIL; }