2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
3 * yaffs_fileem.c NAND emulation on top of files
5 * Copyright (C) 2002 Aleph One Ltd.
6 * for Toby Churchill Ltd and Brightstar Engineering
8 * Created by Charles Manning <charles@aleph1.co.uk>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
17 #include "yaffs_fileem.h"
18 #include "yaffs_guts.h"
19 #include "yaffsinterface.h"
24 #include <sys/types.h>
29 #define FILE_SIZE_IN_MEG 2
31 // #define YAFFS_ERROR_TESTING
33 #define BLOCK_SIZE (32 * 528)
34 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
35 #define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG)
36 #define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE)
40 static __u8 ffChunk[528];
42 static int eraseDisplayEnabled;
44 static int markedBadBlocks[] = { 1, 4, -1};
46 static int IsAMarkedBadBlock(int blk)
48 #if YAFFS_ERROR_TESTING
49 int *m = markedBadBlocks;
53 if(*m == blk) return 1;
61 static __u8 yaffs_WriteFailCorruption(int chunkInNAND)
63 #if YAFFS_ERROR_TESTING
65 // Whole blocks that fail
66 switch(chunkInNAND/YAFFS_CHUNKS_PER_BLOCK)
73 // Single blocks that fail
80 return 3;// ding two bits
86 case 3007: return 1;// ding one bit
94 static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data)
96 #if YAFFS_ERROR_TESTING
99 *data ^= yaffs_WriteFailCorruption(chunkInNAND);
104 static __u8 yaffs_ReadFailCorruption(int chunkInNAND)
108 #if YAFFS_ERROR_TESTING
110 return 3;// ding two bits
113 return 1;// ding one bit
121 static void yaffs_ModifyReadData(int chunkInNAND,__u8 *data)
123 #if YAFFS_ERROR_TESTING
126 *data ^= yaffs_ReadFailCorruption(chunkInNAND);
135 static void CheckInit(yaffs_Device *dev)
137 static int initialised = 0;
145 memset(ffChunk,0xFF,528);
148 // h = open("yaffs-em-file" , O_RDONLY);
150 h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
154 perror("Fatal error opening yaffs emulation file");
159 length = lseek(h,0,SEEK_END);
161 while(length < FILE_SIZE_IN_BYTES && nWritten == 528)
163 write(h,ffChunk,528);
164 length = lseek(h,0,SEEK_END);
168 perror("Fatal error expanding yaffs emulation file");
176 h = open("yaffs-em-file" , O_RDONLY);
178 h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
183 int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare)
189 pos = chunkInNAND * 528;
196 memcpy(localData,data,512);
197 yaffs_ModifyWriteData(chunkInNAND,localData);
198 lseek(h,pos,SEEK_SET);
199 write(h,localData,512);
206 lseek(h,pos,SEEK_SET);
214 int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
218 pos = chunkInNAND * 528;
225 lseek(h,pos,SEEK_SET);
227 yaffs_ModifyReadData(chunkInNAND,data);
234 lseek(h,pos,SEEK_SET);
242 int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND)
248 if(eraseDisplayEnabled)
250 printf("Erasing block %d\n",blockInNAND);
253 lseek(h,blockInNAND * BLOCK_SIZE,SEEK_SET);
254 for(i = 0; i < 32; i++)
256 write(h,ffChunk,528);
262 case 15: return YAFFS_FAIL;
268 int yaffs_FEInitialiseNAND(yaffs_Device *dev)