*** empty log message ***
[yaffs/.git] / yaffs_fileem.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  * yaffs_fileem.c  NAND emulation on top of files
4  *
5  * Copyright (C) 2002 Aleph One Ltd.
6  *   for Toby Churchill Ltd and Brightstar Engineering
7  *
8  * Created by Charles Manning <charles@aleph1.co.uk>
9  *
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.
13  *
14  */
15  //yaffs_fileem.c
16
17 #include "yaffs_fileem.h"
18 #include "yaffs_guts.h"
19 #include "yaffsinterface.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <string.h>
28
29 #define FILE_SIZE_IN_MEG 32
30
31 #define BLOCK_SIZE (32 * 528)
32 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
33 #define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG)
34 #define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE)
35
36
37 static int h;
38 static __u8 ffChunk[528];
39
40 static int eraseDisplayEnabled;
41
42 static int markedBadBlocks[] = { 1, 4, -1};
43
44 static int IsAMarkedBadBlock(int blk)
45 {
46         int *m = markedBadBlocks;
47         
48         while(*m >= 0)
49         {
50                 if(*m == blk) return 1;
51                 m++;
52         }
53         return 0;
54 }
55
56
57 static void  CheckInit(yaffs_Device *dev)
58 {
59         static int initialised = 0;
60
61         int length;
62
63         
64         if(!initialised)
65         {
66                 memset(ffChunk,0xFF,528);
67                 
68                 h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
69                 if(h < 0)
70                 {
71                         perror("Fatal error opening yaffs emulation file");
72                         exit(1);
73                 }
74                 initialised = 1;
75                 
76                 length = lseek(h,0,SEEK_END);
77                 if(length !=  FILE_SIZE_IN_BYTES)
78                 {
79                         // Create file contents
80                         int i;
81                         
82                         printf("Creating emulation file...\n");
83                         for(i = 0; i < FILE_SIZE_IN_BLOCKS; i++)
84                         {
85                                 yaffs_FEEraseBlockInNAND(dev,i);
86                                 
87                                 if(IsAMarkedBadBlock(i))
88                                 {
89                                         yaffs_Spare spare;
90                                         memset(&spare,0xff,sizeof(spare));
91                                         spare.blockStatus = 1;
92                                         
93                                         yaffs_FEWriteChunkToNAND(dev, i * 32,NULL,&spare);
94                                 }
95                         }
96                 }
97                 eraseDisplayEnabled = 1;
98         }
99 }
100
101 int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare)
102 {
103         int pos;
104         
105         pos = chunkInNAND * 528;
106         
107         CheckInit(dev);
108         
109         
110         if(data)
111         {
112                 lseek(h,pos,SEEK_SET);
113                 write(h,data,512);
114         }
115         
116         pos += 512;
117         
118         if(spare)
119         {
120                 lseek(h,pos,SEEK_SET);
121                 write(h,spare,16);      
122         }
123
124         return YAFFS_OK;
125 }
126
127
128 int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
129 {
130         int pos;
131
132         pos = chunkInNAND * 528;
133         
134         
135         CheckInit(dev);
136         
137         if(data)
138         {
139                 lseek(h,pos,SEEK_SET);
140                 read(h,data,512);
141         }
142         
143         pos += 512;
144         
145         if(spare)
146         {
147                 lseek(h,pos,SEEK_SET);
148                 read(h,spare,16);       
149         }
150
151         return YAFFS_OK;
152 }
153
154
155 int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND)
156 {
157         int i;
158         
159         CheckInit(dev);
160         
161         if(eraseDisplayEnabled)
162         {
163                 printf("Erasing block %d\n",blockInNAND);
164         }
165         
166         lseek(h,blockInNAND * BLOCK_SIZE,SEEK_SET);
167         for(i = 0; i < 32; i++)
168         {
169                 write(h,ffChunk,528);
170         }
171         return YAFFS_OK;
172 }
173
174 int yaffs_FEInitialiseNAND(yaffs_Device *dev)
175 {
176         return YAFFS_OK;
177 }