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