Exemple #1
0
/* NB For use with inband tags....
 * We assume that the data buffer is of size totalBytersPerChunk so that we can also
 * use it to load the tags.
 */
int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
				      const __u8 * data,
				      const yaffs_ExtendedTags * tags)
{
	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
	struct mtd_oob_ops ops;
#else
	size_t dummy;
#endif
	int retval = 0;

	loff_t addr;

	yaffs_PackedTags2 pt;

	T(YAFFS_TRACE_MTD,
	  (TSTR
	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
	    TENDSTR), chunkInNAND, data, tags));
	 
	addr  = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
	
	/* For yaffs2 writing there must be both data and tags.
	 * If we're using inband tags, then the tags are stuffed into
	 * the end of the data buffer.
	 */
	if(!data || !tags)
		BUG();	
	else if(dev->inbandTags){
		yaffs_PackedTags2TagsPart *pt2tp;
		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
		yaffs_PackTags2TagsPart(pt2tp,tags);
	}else
		yaffs_PackTags2(&pt, tags);

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
	ops.mode = MTD_OOB_AUTO;
	ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
	ops.len = dev->totalBytesPerChunk;
	ops.ooboffs = 0;
	ops.datbuf = (__u8 *)data;
	ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
	retval = mtd->write_oob(mtd, addr, &ops);
#else
	if (!dev->inbandTags) {
		retval = mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
				     &dummy, data, (__u8 *) &pt, NULL);
	} else {
		retval = mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy, data);
	}
#endif

	if (retval == 0)
		return YAFFS_OK;
	else
		return YAFFS_FAIL;
}
void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t, int tagsECC)
{
	yaffs_PackTags2TagsPart(&pt->t, t);

	if(tagsECC)
		yaffs_ECCCalculateOther((unsigned char *)&pt->t,
					sizeof(yaffs_PackedTags2TagsPart),
					&pt->ecc);
}
void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
{
	yaffs_PackTags2TagsPart(&pt->t,t);

#ifndef YAFFS_IGNORE_TAGS_ECC
	{
		printk("YAFFS_IGNORE_TAGS_ECC\n");
		yaffs_ECCCalculateOther((unsigned char *)&pt->t,
					sizeof(yaffs_PackedTags2TagsPart),&pt->ecc);
	}
#endif
}
/* NB For use with inband tags....
 * We assume that the data buffer is of size totalBytersPerChunk so that we can also
 * use it to load the tags.
 */
int ynandif_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
				      const __u8 * data,
				      const yaffs_ExtendedTags * tags)
{

	int retval = 0;
	yaffs_PackedTags2 pt;
	void *spare;
	unsigned spareSize = 0;

	unsigned char *bufferIn   = DevBufferIn(dev);
	unsigned char *bufferOut  = DevBufferOut(dev);
	unsigned       bufferSize = DevBufferSize(dev);

	T(YAFFS_TRACE_MTD,
	  (TSTR
	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
	    TENDSTR), chunkInNAND, data, tags));
	    

	/* For yaffs2 writing there must be both data and tags.
	 * If we're using inband tags, then the tags are stuffed into
	 * the end of the data buffer.
	 */

	if(dev->inbandTags){
		yaffs_PackedTags2TagsPart *pt2tp;
		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
		yaffs_PackTags2TagsPart(pt2tp,tags);
		spare = NULL;
		spareSize = 0;
	}
	else{
		yaffs_PackTags2(&pt, tags);
		spare = &pt;
		spareSize = sizeof(yaffs_PackedTags2);
	}
	
	yramsim_WritePage(chunkInNAND,
					  data, dev->totalBytesPerChunk, spare, spareSize);

	return YAFFS_OK;
}
Exemple #5
0
/* NB For use with inband tags....
 * We assume that the data buffer is of size totalBytersPerChunk so that we can also
 * use it to load the tags.
 */
int nandmtd2_WriteChunkWithTagsToNAND(yaffs_dev_t *dev, int nand_chunk,
				      const __u8 *data,
				      const yaffs_ext_tags *tags)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
	struct mtd_oob_ops ops;
#else
	size_t dummy;
#endif
	int retval = 0;

	loff_t addr;

	yaffs_PackedTags2 pt;

	int packed_tags_size = dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
	void * packed_tags_ptr = dev->param.no_tags_ecc ? (void *) &pt.t : (void *)&pt;

	T(YAFFS_TRACE_MTD,
	  (TSTR
	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
	    TENDSTR), nand_chunk, data, tags));


	addr  = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;

	/* For yaffs2 writing there must be both data and tags.
	 * If we're using inband tags, then the tags are stuffed into
	 * the end of the data buffer.
	 */
	if (!data || !tags)
		BUG();
	else if (dev->param.inband_tags) {
		yaffs_PackedTags2TagsPart *pt2tp;
		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->data_bytes_per_chunk);
		yaffs_PackTags2TagsPart(pt2tp, tags);
	} else
		yaffs_PackTags2(&pt, tags, !dev->param.no_tags_ecc);

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
	ops.mode = MTD_OOB_AUTO;
	ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
	ops.len = dev->param.total_bytes_per_chunk;
	ops.ooboffs = 0;
	ops.datbuf = (__u8 *)data;
	ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
	retval = mtd->write_oob(mtd, addr, &ops);

#else
	if (!dev->param.inband_tags) {
		retval =
		    mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
				   &dummy, data, (__u8 *) packed_tags_ptr, NULL);
	} else {
		retval =
		    mtd->write(mtd, addr, dev->param.total_bytes_per_chunk, &dummy,
			       data);
	}
#endif

	if (retval == 0)
		return YAFFS_OK;
	else
		return YAFFS_FAIL;
}
int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags)
{
	int written;
	int pos;
	int h;
	int i;
	int nRead;
	int error;
	
	T(YAFFS_TRACE_MTD,(TSTR("write chunk %d data %x tags %x" TENDSTR),chunkInNAND,(unsigned)data, (unsigned)tags));

	CheckInit();
	
	
	if(dev->inbandTags){
		
		yaffs_PackedTags2TagsPart * pt2tp;
		pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
		yaffs_PackTags2TagsPart(pt2tp,tags);
		
		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
				  			
		lseek(h,pos,SEEK_SET);
		written = write(h,data,dev->totalBytesPerChunk);

		
		if(yaffs_testPartialWrite){
			close(h);
			exit(1);
		}
		
		if(written != dev->totalBytesPerChunk) return YAFFS_FAIL;


	}
	
	else {
	
		if(data)
		{
			pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
			h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
		
			lseek(h,pos,SEEK_SET);
			nRead =  read(h, localBuffer,dev->nDataBytesPerChunk);
			for(i = error = 0; i < dev->nDataBytesPerChunk && !error; i++){
				if(REPORT_ERROR && localBuffer[i] != 0xFF){
					printf("nand simulation: chunk %d data byte %d was %0x2\n",
						chunkInNAND,i,localBuffer[i]);
					error = 1;
				}
			}
		
			for(i = 0; i < dev->nDataBytesPerChunk; i++)
			localBuffer[i] &= data[i];
		  
			if(REPORT_ERROR && memcmp(localBuffer,data,dev->nDataBytesPerChunk))
				printf("nand simulator: data does not match\n");
			
			lseek(h,pos,SEEK_SET);
			written = write(h,localBuffer,dev->nDataBytesPerChunk);
		
			if(yaffs_testPartialWrite){
				close(h);
				exit(1);
			}
		
#ifdef SIMULATE_FAILURES
				if((chunkInNAND >> 6) == 100) 
				written = 0;

				if((chunkInNAND >> 6) == 110) 
				written = 0;
#endif


			if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL;
		}
	
		if(tags)
		{
			pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
			h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
		
			lseek(h,pos,SEEK_SET);

			if( 0 && dev->isYaffs2)
			{
			
				written = write(h,tags,sizeof(yaffs_ExtendedTags));
				if(written != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
			}
			else
			{
				yaffs_PackedTags2 pt;
				yaffs_PackTags2(&pt,tags);
				__u8 * ptab = (__u8 *)&pt;

				nRead = read(h,localBuffer,sizeof(pt));
				for(i = error = 0; REPORT_ERROR && i < sizeof(pt) && !error; i++){
					if(localBuffer[i] != 0xFF){
						printf("nand simulation: chunk %d oob byte %d was %0x2\n",
							chunkInNAND,i,localBuffer[i]);
							error = 1;
					}
				}
		
				for(i = 0; i < sizeof(pt); i++)
				localBuffer[i] &= ptab[i];
			 
				if(REPORT_ERROR && memcmp(localBuffer,&pt,sizeof(pt)))
					printf("nand sim: tags corruption\n");
				
				lseek(h,pos,SEEK_SET);
			
				written = write(h,localBuffer,sizeof(pt));
				if(written != sizeof(pt)) return YAFFS_FAIL;
			}
		}
	
	}
	return YAFFS_OK;	

}