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