/* NB For use with inband tags....
 * We assume that the data buffer is of size total_bytes_per_chunk so that we can also
 * use it to load the tags.
 */
int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
			      const u8 * data,
			      const struct yaffs_ext_tags *tags)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	struct mtd_oob_ops ops;
	int retval = 0;

	loff_t addr;

	struct yaffs_packed_tags2 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;

	yaffs_trace(YAFFS_TRACE_MTD,
		"nandmtd2_write_chunk_tags chunk %d data %p tags %p",
		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) {
		struct yaffs_packed_tags2_tags_only *pt2tp;
		pt2tp =
		    (struct yaffs_packed_tags2_tags_only *)(data +
							    dev->
							    data_bytes_per_chunk);
		yaffs_pack_tags2_tags_only(pt2tp, tags);
	} else {
		yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
        }

	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);

	if (retval == 0)
		return YAFFS_OK;
	else
		return YAFFS_FAIL;
}
Example #2
0
int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_ext_tags *tags)
{
	int blk;
	int pg;
	int i;
	
	u8 *x;

	
	blk = nand_chunk/PAGES_PER_BLOCK;
	pg = nand_chunk%PAGES_PER_BLOCK;
	
	
	if(data)
	{
		x = ned.block[blk]->page[pg]->data;
		
		for(i = 0; i < PAGE_DATA_SIZE; i++)
		{
			x[i] &=data[i];
		}

		ned.block[blk]->page[pg]->empty = 0;
	}
	
	
	if(tags)
	{
		x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
		
		yaffs_pack_tags2((struct yaffs_packed_tags2 *)x,tags, !dev->param.no_tags_ecc);
			
	}
	
	if(tags || data)
	{
		nandemul_yield(1);
	}

	return YAFFS_OK;
}
Example #3
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 ynandif_WriteChunkWithTagsToNAND(struct yaffs_dev *dev, int nand_chunk,
				      const u8 *data,
				      const struct yaffs_ext_tags *tags)
{

	int retval = 0;
	struct yaffs_packed_tags2 pt;
	void *spare;
	unsigned spareSize = 0;
	struct ynandif_Geometry *geometry = (struct ynandif_Geometry *)(dev->driver_context);

	yaffs_trace(YAFFS_TRACE_MTD,
		"nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p",
		nand_chunk, 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->param.inband_tags) {
		struct yaffs_packed_tags2_tags_only *pt2tp;

		pt2tp = (struct yaffs_packed_tags2_tags_only *)
			(data + dev->data_bytes_per_chunk);
		yaffs_pack_tags2_tags_only(pt2tp, tags);
		spare = NULL;
		spareSize = 0;
	} else {
		yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
		spare = &pt;
		spareSize = sizeof(struct yaffs_packed_tags2);
	}

	retval = geometry->writeChunk(dev, nand_chunk,
				data, dev->param.total_bytes_per_chunk,
				spare, spareSize);

	return retval;
}
static int yaffs_tags_marshall_write(struct yaffs_dev *dev,
				    int nand_chunk, const u8 *data,
				    const struct yaffs_ext_tags *tags)
{
	struct yaffs_packed_tags2 pt;
	int retval;

	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;

	yaffs_trace(YAFFS_TRACE_MTD,
		"yaffs_tags_marshall_write chunk %d data %p tags %p",
		nand_chunk, 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 (!data || !tags)
		BUG();
	else if (dev->param.inband_tags) {
		struct yaffs_packed_tags2_tags_only *pt2tp;
		pt2tp =
		    (struct yaffs_packed_tags2_tags_only *)(data +
							dev->
							data_bytes_per_chunk);
		yaffs_pack_tags2_tags_only(pt2tp, tags);
	} else {
		yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
	}

	retval = dev->drv.drv_write_chunk_fn(dev, nand_chunk,
			data, dev->param.total_bytes_per_chunk,
			(dev->param.inband_tags) ? NULL : packed_tags_ptr,
			(dev->param.inband_tags) ? 0 : packed_tags_size);

	return retval;
}
Example #5
0
bool YaffsControl::writePage(u32 objectId, u32 chunkId, u32 numBytes) {
    bool result = false;

    static yaffs_ext_tags t;
    memset(&t, 0, sizeof(yaffs_ext_tags));
    t.chunk_used = 1;
    t.obj_id = objectId;
    t.chunk_id = chunkId;
    t.n_bytes = numBytes;
    t.serial_number = 1;
    t.seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

    memset(mSpareData, 0xff, SPARE_SIZE);
    yaffs_packed_tags2* pt = reinterpret_cast<yaffs_packed_tags2*>(mSpareData);
    yaffs_pack_tags2(pt, &t, 1);

    if (fwrite(mPageData, PAGE_SIZE, 1, mImageFile) == 1) {
        result = true;
        mNumPages++;
    }

    return result;
}
Example #6
0
int yflash2_WriteChunkWithTagsToNAND(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_ext_tags *tags)
{
	int written;
	int pos;
	int h;
	int i;
	int nRead;
	int error;
	
	yaffs_trace(YAFFS_TRACE_MTD, "write chunk %d data %p tags %p",nand_chunk, data, tags);

	CheckInit();
	
	
	if(dev->param.inband_tags){
		
		struct yaffs_packed_tags2_tags_only * pt2tp;
		pt2tp = (struct yaffs_packed_tags2_tags_only *)&data[dev->data_bytes_per_chunk];
		yaffs_pack_tags2_tags_only(pt2tp,tags);
		
		pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
		h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
				  			
		lseek(h,pos,SEEK_SET);
		written = write(h,data,dev->param.total_bytes_per_chunk);

		
		if(yaffs_test_partial_write){
			close(h);
			exit(1);
		}
		
		if(written != dev->param.total_bytes_per_chunk) return YAFFS_FAIL;


	}
	
	else {
		/* First do a write of a partial page */
		int n_partials;
		int bpos;

		if(data)
		{
			pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
			h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
		
			
			memcpy(localBuffer,data, dev->data_bytes_per_chunk);
			
			n_partials = rand()%20;
			
			for(i = 0; i < n_partials; i++){
				bpos = rand() % dev->data_bytes_per_chunk;
				
				localBuffer[bpos] |= (1 << (rand() & 7));
			}
		  
			if(REPORT_ERROR && memcmp(localBuffer,data,dev->data_bytes_per_chunk))
				printf("nand simulator: data does not match\n");
			
			lseek(h,pos,SEEK_SET);
			written = write(h,localBuffer,dev->data_bytes_per_chunk);
		
			if(yaffs_test_partial_write){
				close(h);
				exit(1);
			}


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

			if( 0 && dev->param.is_yaffs2)
			{
			
				written = write(h,tags,sizeof(struct yaffs_ext_tags));
				if(written != sizeof(struct yaffs_ext_tags)) return YAFFS_FAIL;
			}
			else
			{
				struct yaffs_packed_tags2 pt;
				yaffs_pack_tags2(&pt,tags, !dev->param.no_tags_ecc);
				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",
							nand_chunk,i,localBuffer[i]);
							error = 1;
					}
				}
		
				for(i = 0; i < sizeof(pt); i++)
				localBuffer[i] &= ptab[i];
				
				n_partials = rand()% sizeof(pt);
			
				for(i = 0; i < n_partials; i++){
					bpos = rand() % sizeof(pt);
				
					localBuffer[bpos] |= (1 << (rand() & 7));
				}			
			 
				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;
			}
		}
		
		//yflash2_MaybePowerFail(nand_chunk,2);
		
		/* Next do the whole write */
		if(data)
		{
			pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
			h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
		
			
			memset(localBuffer,0xFF, PAGE_SIZE);		
			for(i = 0; i < dev->data_bytes_per_chunk; i++){
				localBuffer[i] &= data[i];
			}
		  
			if(REPORT_ERROR && memcmp(localBuffer,data,dev->data_bytes_per_chunk))
				printf("nand simulator: data does not match\n");
			
			lseek(h,pos,SEEK_SET);
			written = write(h,localBuffer,dev->data_bytes_per_chunk);
		
			if(yaffs_test_partial_write){
				close(h);
				exit(1);
			}


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

			if( 0 && dev->param.is_yaffs2)
			{
			
				written = write(h,tags,sizeof(struct yaffs_ext_tags));
				if(written != sizeof(struct yaffs_ext_tags)) return YAFFS_FAIL;
			}
			else
			{
				struct yaffs_packed_tags2 pt;
				yaffs_pack_tags2(&pt,tags,!dev->param.no_tags_ecc);
				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",
							nand_chunk,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;
			}
		}
		
		yflash2_MaybePowerFail(nand_chunk,3);
	
	}
	return YAFFS_OK;	

}
Example #7
0
/* NB For use with inband tags....
 * We assume that the data buffer is of size total_bytes_per_chunk so that we can also
 * use it to load the tags.
 */
int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
			      const u8 * data,
			      const struct 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;

	struct yaffs_packed_tags2 pt;

	u8 *encrypted_data = NULL;

	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;

	yaffs_trace(YAFFS_TRACE_MTD,
		"nandmtd2_write_chunk_tags chunk %d data %p tags %p",
		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) {
		struct yaffs_packed_tags2_tags_only *pt2tp;
		pt2tp =
		    (struct yaffs_packed_tags2_tags_only *)(data +
							    dev->
							    data_bytes_per_chunk);
		yaffs_pack_tags2_tags_only(pt2tp, tags);
	} else {
		yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
        }

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))

	if (dev->is_encrypted_fs) {
		if (dev->param.inband_tags)
			BUG();

		encrypted_data = yaffs_get_temp_buffer(dev, __LINE__);
		memcpy(encrypted_data, data, dev->param.total_bytes_per_chunk);

		AES_xts_encrypt(dev->cipher,
				encrypted_data, encrypted_data,
				nand_chunk * 2, dev->param.total_bytes_per_chunk,
				packed_tags_ptr+SEQUENCE_OFFSET,
				packed_tags_ptr+SEQUENCE_OFFSET,
				(nand_chunk * 2) + 1,
				packed_tags_size-SEQUENCE_OFFSET);
	}

	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 = dev->is_encrypted_fs ? encrypted_data : (u8 *) data;
	ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
	retval = mtd->write_oob(mtd, addr, &ops);

	if (dev->is_encrypted_fs && encrypted_data)
		yaffs_release_temp_buffer(dev, encrypted_data, __LINE__);

#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;
}
Example #8
0
/* NB For use with inband tags....
 * We assume that the data buffer is of size total_bytes_per_chunk so that we can also
 * use it to load the tags.
 */
int nandmtd2_write_chunk_tags(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_packed_tags2 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_write_chunk_tags 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_packed_tags2_tags_only *pt2tp;
		pt2tp = (yaffs_packed_tags2_tags_only *)(data + dev->data_bytes_per_chunk);
		yaffs_pack_tags2_tags_only(pt2tp, tags);
	} else
		yaffs_pack_tags2(&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;
}