]> git.sur5r.net Git - u-boot/blob - fs/yaffs2/direct/yaffs_ramdisk.c
Incorporate yaffs2 into U-boot
[u-boot] / fs / yaffs2 / direct / yaffs_ramdisk.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  * yaffs_ramdisk.c: yaffs ram disk component
16  * This provides a ram disk under yaffs.
17  * NB this is not intended for NAND emulation.
18  * Use this with dev->useNANDECC enabled, then ECC overheads are not required.
19  */
20
21 /* XXX U-BOOT XXX */
22 #include <common.h>
23
24 const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.4 2007/02/14 01:09:06 wookey Exp $";
25
26
27 #include "yportenv.h"
28
29 #include "yaffs_ramdisk.h"
30 #include "yaffs_guts.h"
31 #include "devextras.h"
32 #include "yaffs_packedtags1.h"
33
34
35
36 #define SIZE_IN_MB 2
37
38 #define BLOCK_SIZE (32 * 528)
39 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
40
41
42
43
44
45 typedef struct 
46 {
47         __u8 data[528]; // Data + spare
48 } yramdisk_Page;
49
50 typedef struct
51 {
52         yramdisk_Page page[32]; // The pages in the block
53         
54 } yramdisk_Block;
55
56
57
58 typedef struct
59 {
60         yramdisk_Block **block;
61         int nBlocks;
62 } yramdisk_Device;
63
64 static yramdisk_Device ramdisk;
65
66 static int  CheckInit(yaffs_Device *dev)
67 {
68         static int initialised = 0;
69         
70         int i;
71         int fail = 0;
72         //int nBlocks; 
73         int nAllocated = 0;
74         
75         if(initialised) 
76         {
77                 return YAFFS_OK;
78         }
79
80         initialised = 1;
81         
82         
83         ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024);
84         
85         ramdisk.block = YMALLOC(sizeof(yramdisk_Block *) * ramdisk.nBlocks);
86         
87         if(!ramdisk.block) return 0;
88         
89         for(i=0; i <ramdisk.nBlocks; i++)
90         {
91                 ramdisk.block[i] = NULL;
92         }
93         
94         for(i=0; i <ramdisk.nBlocks && !fail; i++)
95         {
96                 if((ramdisk.block[i] = YMALLOC(sizeof(yramdisk_Block))) == 0)
97                 {
98                         fail = 1;
99                 }
100                 else
101                 {
102                         yramdisk_EraseBlockInNAND(dev,i);
103                         nAllocated++;
104                 }
105         }
106         
107         if(fail)
108         {
109                 for(i = 0; i < nAllocated; i++)
110                 {
111                         YFREE(ramdisk.block[i]);
112                 }
113                 YFREE(ramdisk.block);
114                 
115                 T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n",
116                    nAllocated/64,ramdisk.nBlocks * 528));
117                 return 0;
118         }
119         
120         
121         return 1;
122 }
123
124 int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
125 {
126         int blk;
127         int pg;
128         
129
130         CheckInit(dev);
131         
132         blk = chunkInNAND/32;
133         pg = chunkInNAND%32;
134         
135         
136         if(data)
137         {
138                 memcpy(ramdisk.block[blk]->page[pg].data,data,512);
139         }
140         
141         
142         if(tags)
143         {
144                 yaffs_PackedTags1 pt;
145                 
146                 yaffs_PackTags1(&pt,tags);
147                 memcpy(&ramdisk.block[blk]->page[pg].data[512],&pt,sizeof(pt));
148         }
149
150         return YAFFS_OK;        
151
152 }
153
154
155 int yramdisk_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags)
156 {
157         int blk;
158         int pg;
159
160         
161         CheckInit(dev);
162         
163         blk = chunkInNAND/32;
164         pg = chunkInNAND%32;
165         
166         
167         if(data)
168         {
169                 memcpy(data,ramdisk.block[blk]->page[pg].data,512);
170         }
171         
172         
173         if(tags)
174         {
175                 yaffs_PackedTags1 pt;
176                 
177                 memcpy(&pt,&ramdisk.block[blk]->page[pg].data[512],sizeof(pt));
178                 yaffs_UnpackTags1(tags,&pt);
179                 
180         }
181
182         return YAFFS_OK;
183 }
184
185
186 int yramdisk_CheckChunkErased(yaffs_Device *dev,int chunkInNAND)
187 {
188         int blk;
189         int pg;
190         int i;
191
192         
193         CheckInit(dev);
194         
195         blk = chunkInNAND/32;
196         pg = chunkInNAND%32;
197         
198         
199         for(i = 0; i < 528; i++)
200         {
201                 if(ramdisk.block[blk]->page[pg].data[i] != 0xFF)
202                 {
203                         return YAFFS_FAIL;
204                 }
205         }
206
207         return YAFFS_OK;
208
209 }
210
211 int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
212 {
213         
214         CheckInit(dev);
215         
216         if(blockNumber < 0 || blockNumber >= ramdisk.nBlocks)
217         {
218                 T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber));
219                 return YAFFS_FAIL;
220         }
221         else
222         {
223                 memset(ramdisk.block[blockNumber],0xFF,sizeof(yramdisk_Block));
224                 return YAFFS_OK;
225         }
226         
227 }
228
229 int yramdisk_InitialiseNAND(yaffs_Device *dev)
230 {
231         //dev->useNANDECC = 1; // force on useNANDECC which gets faked. 
232                                                  // This saves us doing ECC checks.
233         
234         return YAFFS_OK;
235 }