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();
		}
	} 
}
Beispiel #2
0
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;
}