140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/*
240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * YAFFS: Yet another FFS. A NAND-flash specific file system.
340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * yaffs_ramdisk.c: yaffs ram disk component
440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Copyright (C) 2002 Aleph One Ltd.
640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Created by Charles Manning <charles@aleph1.co.uk>
840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * This program is free software; you can redistribute it and/or modify
1040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * it under the terms of the GNU General Public License version 2 as
1140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * published by the Free Software Foundation.
1240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
1440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
1540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// This provides a YAFFS nand emulation on a file for emulating 2kB pages.
1640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// THis is only intended as test code to test persistence etc.
1740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
1840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectconst char *yaffs_flashif_c_version = "$Id: yaffs_fileem2k.c,v 1.7 2006/10/13 08:52:49 charles Exp $";
1940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yportenv.h"
2240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_flashif.h"
2440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_guts.h"
2540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "devextras.h"
2640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/types.h>
2840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/stat.h>
2940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <fcntl.h>
3040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <unistd.h>
3140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_fileem2k.h"
3340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_packedtags2.h"
3440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
3840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
3940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8 data[PAGE_SIZE]; // Data + spare
4040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} yflash_Page;
4140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
4340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
4440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yflash_Page page[PAGES_PER_BLOCK]; // The pages in the block
4540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} yflash_Block;
4740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define MAX_HANDLES 20
5140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define BLOCKS_PER_HANDLE 8000
5240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
5440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
5540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int handle[MAX_HANDLES];
5640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int nBlocks;
5740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} yflash_Device;
5840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yflash_Device filedisk;
6040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_testPartialWrite = 0;
6240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic char *NToName(char *buf,int n)
6540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
6640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sprintf(buf,"emfile%d",n);
6740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return buf;
6840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
6940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic char dummyBuffer[BLOCK_SIZE];
7140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int GetBlockFileHandle(int n)
7340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
7440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
7540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int requiredSize;
7640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char name[40];
7840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	NToName(name,n);
7940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int fSize;
8040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
8140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h =  open(name, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
8340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(h >= 0){
8440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		fSize = lseek(h,0,SEEK_END);
8540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		requiredSize = BLOCKS_PER_HANDLE * BLOCK_SIZE;
8640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(fSize < requiredSize){
8740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   for(i = 0; i < BLOCKS_PER_HANDLE; i++)
8840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   	if(write(h,dummyBuffer,BLOCK_SIZE) != BLOCK_SIZE)
8940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				return -1;
9040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
9240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
9340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return h;
9540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
9740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int  CheckInit(void)
9940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
10040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	static int initialised = 0;
10140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
10240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
10340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	off_t fSize;
10640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	off_t requiredSize;
10740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int written;
10840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int blk;
10940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yflash_Page p;
11140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(initialised)
11340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
11440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return YAFFS_OK;
11540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	initialised = 1;
11840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(dummyBuffer,0xff,sizeof(dummyBuffer));
12040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	filedisk.nBlocks = SIZE_IN_MB * BLOCKS_PER_MB;
12340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	for(i = 0; i <  MAX_HANDLES; i++)
12540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		filedisk.handle[i] = -1;
12640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	for(i = 0,blk = 0; blk < filedisk.nBlocks; blk+=BLOCKS_PER_HANDLE,i++)
12840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		filedisk.handle[i] = GetBlockFileHandle(i);
12940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 1;
13240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
13340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_GetNumberOfBlocks(void)
13640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
13740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
13840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return filedisk.nBlocks;
14040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
14140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
14340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
14440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int written;
14540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int pos;
14640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
14740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
14940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(data)
15340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
15440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
15540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
15640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		lseek(h,pos,SEEK_SET);
15840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		written = write(h,data,dev->nDataBytesPerChunk);
15940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
16040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(yaffs_testPartialWrite){
16140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			close(h);
16240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			exit(1);
16340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
16440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
16540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL;
16640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
16740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
16840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(tags)
16940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
17040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
17140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
17240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
17340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		lseek(h,pos,SEEK_SET);
17440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if( 0 && dev->isYaffs2)
17540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
17640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
17740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			written = write(h,tags,sizeof(yaffs_ExtendedTags));
17840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(written != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
17940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
18040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
18140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
18240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_PackedTags2 pt;
18340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_PackTags2(&pt,tags);
18440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
18540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			written = write(h,&pt,sizeof(pt));
18640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(written != sizeof(pt)) return YAFFS_FAIL;
18740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
18840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
18940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return YAFFS_OK;
19240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
19440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_CheckAllFF(const __u8 *ptr, int n)
19640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
19740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while(n)
19840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
19940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		n--;
20040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(*ptr!=0xFF) return 0;
20140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		ptr++;
20240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
20340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 1;
20440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
20540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int fail300 = 1;
20840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int fail320 = 1;
20940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags)
21140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
21240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int nread;
21340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int pos;
21440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
21540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
21740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(data)
22140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
22240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
22440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
22540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		lseek(h,pos,SEEK_SET);
22640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		nread = read(h,data,dev->nDataBytesPerChunk);
22740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(nread != dev->nDataBytesPerChunk) return YAFFS_FAIL;
22940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
23040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(tags)
23240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
23340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
23440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
23540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		lseek(h,pos,SEEK_SET);
23640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(0 && dev->isYaffs2)
23840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
23940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			nread= read(h,tags,sizeof(yaffs_ExtendedTags));
24040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(nread != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
24140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(yaffs_CheckAllFF((__u8 *)tags,sizeof(yaffs_ExtendedTags)))
24240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
24340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffs_InitialiseTags(tags);
24440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
24540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
24640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
24740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				tags->chunkUsed = 1;
24840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
24940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
25040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
25140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
25240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_PackedTags2 pt;
25340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			nread= read(h,&pt,sizeof(pt));
25440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_UnpackTags2(tags,&pt);
25540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if((chunkInNAND >> 6) == 300) {
25640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			    if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
25740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			       tags->eccResult = YAFFS_ECC_RESULT_FIXED;
25840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			       fail300 = 0;
25940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			    }
26040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
26240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if((chunkInNAND >> 6) == 320) {
26340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			    if(fail320 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
26440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			       tags->eccResult = YAFFS_ECC_RESULT_FIXED;
26540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			       fail320 = 0;
26640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			    }
26740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
26840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(nread != sizeof(pt)) return YAFFS_FAIL;
26940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
27040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
27140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return YAFFS_OK;
27440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
27640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
27940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
28040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int written;
28140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
28240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
28340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_PackedTags2 pt;
28440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
28540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
28640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
28740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(&pt,0,sizeof(pt));
28840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = filedisk.handle[(blockNo / ( BLOCKS_PER_HANDLE))];
28940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	lseek(h,((blockNo % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET);
29040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	written = write(h,&pt,sizeof(pt));
29140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(written != sizeof(pt)) return YAFFS_FAIL;
29340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return YAFFS_OK;
29640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
29840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
30040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
30140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
30340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int h;
30440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
30640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(blockNumber == 320)
30840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		fail320 = 1;
30940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(blockNumber < 0 || blockNumber >= filedisk.nBlocks)
31140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
31240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber));
31340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return YAFFS_FAIL;
31440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
31540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
31640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
31740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		__u8 pg[PAGE_SIZE];
31940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		int syz = PAGE_SIZE;
32040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		int pos;
32140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		memset(pg,0xff,syz);
32340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = filedisk.handle[(blockNumber / ( BLOCKS_PER_HANDLE))];
32640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		lseek(h,((blockNumber % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE,SEEK_SET);
32740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		for(i = 0; i < dev->nChunksPerBlock; i++)
32840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
32940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			write(h,pg,PAGE_SIZE);
33040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
33140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos = lseek(h, 0,SEEK_CUR);
33240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return YAFFS_OK;
33440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
33540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
33740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_InitialiseNAND(yaffs_Device *dev)
33940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
34040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	CheckInit();
34140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return YAFFS_OK;
34340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
34440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber)
34940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
35040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ExtendedTags tags;
35140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int chunkNo;
35240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	*sequenceNumber = 0;
35440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	chunkNo = blockNo * dev->nChunksPerBlock;
35640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yflash_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
35840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(tags.blockBad)
35940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		*state = YAFFS_BLOCK_STATE_DEAD;
36140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
36240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(!tags.chunkUsed)
36340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		*state = YAFFS_BLOCK_STATE_EMPTY;
36540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
36640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(tags.chunkUsed)
36740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
36940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		*sequenceNumber = tags.sequenceNumber;
37040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
37140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return YAFFS_OK;
37240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
37340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
374