Adding fsx test to yaffs direct
[yaffs2.git] / direct / yaffs_fileem.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2007 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 /*
15  * This provides a YAFFS nand emulation on a file.
16  * This is only intended as test code to test persistence etc.
17  */
18
19 const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.3 2007-02-14 01:09:06 wookey Exp $";
20
21
22 #include "yportenv.h"
23
24 #include "yaffs_flashif.h"
25 #include "yaffs_guts.h"
26
27 #include "devextras.h"
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <unistd.h> 
33
34
35
36 #define SIZE_IN_MB 16
37
38 #define BLOCK_SIZE (32 * 528)
39 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
40
41
42
43 typedef struct 
44 {
45         __u8 data[528]; // Data + spare
46 } yflash_Page;
47
48 typedef struct
49 {
50         yflash_Page page[32]; // The pages in the block
51         
52 } yflash_Block;
53
54
55
56 typedef struct
57 {
58         int handle;
59         int nBlocks;
60 } yflash_Device;
61
62 static yflash_Device filedisk;
63
64 static int  CheckInit(yaffs_Device *dev)
65 {
66         static int initialised = 0;
67         
68         int i;
69
70         
71         int fSize;
72         int written;
73         
74         yflash_Page p;
75         
76         if(initialised) 
77         {
78                 return YAFFS_OK;
79         }
80
81         initialised = 1;
82         
83         
84         filedisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024);
85         
86         filedisk.handle = open("yaffsemfile", O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
87         
88         if(filedisk.handle < 0)
89         {
90                 perror("Failed to open yaffs emulation file");
91                 return YAFFS_FAIL;
92         }
93         
94         
95         fSize = lseek(filedisk.handle,0,SEEK_END);
96         
97         if(fSize < SIZE_IN_MB * 1024 * 1024)
98         {
99                 printf("Creating yaffs emulation file\n");
100                 
101                 lseek(filedisk.handle,0,SEEK_SET);
102                 
103                 memset(&p,0xff,sizeof(yflash_Page));
104                 
105                 for(i = 0; i < SIZE_IN_MB * 1024 * 1024; i+= 512)
106                 {
107                         written = write(filedisk.handle,&p,sizeof(yflash_Page));
108                         
109                         if(written != sizeof(yflash_Page))
110                         {
111                                 printf("Write failed\n");
112                                 return YAFFS_FAIL;
113                         }
114                 }               
115         }
116         
117         return 1;
118 }
119
120 int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare)
121 {
122         int written;
123
124         CheckInit(dev);
125         
126         
127         
128         if(data)
129         {
130                 lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET);
131                 written = write(filedisk.handle,data,512);
132                 
133                 if(written != 512) return YAFFS_FAIL;
134         }
135         
136         if(spare)
137         {
138                 lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET);
139                 written = write(filedisk.handle,spare,16);
140                 
141                 if(written != 16) return YAFFS_FAIL;
142         }
143         
144
145         return YAFFS_OK;        
146
147 }
148
149
150 int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
151 {
152         int nread;
153
154         CheckInit(dev);
155         
156         
157         
158         if(data)
159         {
160                 lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET);
161                 nread = read(filedisk.handle,data,512);
162                 
163                 if(nread != 512) return YAFFS_FAIL;
164         }
165         
166         if(spare)
167         {
168                 lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET);
169                 nread= read(filedisk.handle,spare,16);
170                 
171                 if(nread != 16) return YAFFS_FAIL;
172         }
173         
174
175         return YAFFS_OK;        
176
177 }
178
179
180 int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
181 {
182
183         int i;
184                 
185         CheckInit(dev);
186         
187         if(blockNumber < 0 || blockNumber >= filedisk.nBlocks)
188         {
189                 T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber));
190                 return YAFFS_FAIL;
191         }
192         else
193         {
194         
195                 yflash_Page pg;
196                 
197                 memset(&pg,0xff,sizeof(yflash_Page));
198                 
199                 lseek(filedisk.handle, blockNumber * 32 * 528, SEEK_SET);
200                 
201                 for(i = 0; i < 32; i++)
202                 {
203                         write(filedisk.handle,&pg,528);
204                 }
205                 return YAFFS_OK;
206         }
207         
208 }
209
210 int yflash_InitialiseNAND(yaffs_Device *dev)
211 {
212         dev->useNANDECC = 1; // force on useNANDECC which gets faked. 
213                                                  // This saves us doing ECC checks.
214         
215         return YAFFS_OK;
216 }
217
218