Fix M18 driver for 64-bit systems
[yaffs2.git] / direct / test-framework / yaffs_ramdisk.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2011 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->use_nand_ecc enabled, then ECC overheads are not required.
19  */
20
21 #include "yportenv.h"
22 #include "yaffs_trace.h"
23
24 #include "yaffs_ramdisk.h"
25 #include "yaffs_guts.h"
26 #include "yaffs_packedtags1.h"
27
28
29
30 #define SIZE_IN_MB 2
31
32 #define BLOCK_SIZE (32 * 528)
33 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
34
35
36
37
38
39 typedef struct 
40 {
41         u8 data[528]; // Data + spare
42 } yramdisk_page;
43
44 typedef struct
45 {
46         yramdisk_page page[32]; // The pages in the block
47         
48 } yramdisk_block;
49
50
51
52 typedef struct
53 {
54         yramdisk_block **block;
55         int nBlocks;
56 } yramdisk_device;
57
58 static yramdisk_device ramdisk;
59
60 static int  CheckInit(struct yaffs_dev *dev)
61 {
62         static int initialised = 0;
63         
64         int i;
65         int fail = 0;
66         //int nBlocks; 
67         int nAllocated = 0;
68         
69         if(initialised) 
70         {
71                 return YAFFS_OK;
72         }
73
74         initialised = 1;
75         
76         
77         ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024);
78         
79         ramdisk.block = malloc(sizeof(yramdisk_block *) * ramdisk.nBlocks);
80         
81         if(!ramdisk.block) return 0;
82         
83         for(i=0; i <ramdisk.nBlocks; i++)
84         {
85                 ramdisk.block[i] = NULL;
86         }
87         
88         for(i=0; i <ramdisk.nBlocks && !fail; i++)
89         {
90                 if((ramdisk.block[i] = malloc(sizeof(yramdisk_block))) == 0)
91                 {
92                         fail = 1;
93                 }
94                 else
95                 {
96                         yramdisk_erase(dev,i);
97                         nAllocated++;
98                 }
99         }
100         
101         if(fail)
102         {
103                 for(i = 0; i < nAllocated; i++)
104                 {
105                         kfree(ramdisk.block[i]);
106                 }
107                 kfree(ramdisk.block);
108                 
109                 yaffs_trace(YAFFS_TRACE_ALWAYS,
110                         "Allocation failed, could only allocate %dMB of %dMB requested.\n",
111                         nAllocated/64,ramdisk.nBlocks * 528);
112                 return 0;
113         }
114         
115         
116         return 1;
117 }
118
119 int yramdisk_wr_chunk(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_ext_tags *tags)
120 {
121         int blk;
122         int pg;
123         
124
125         CheckInit(dev);
126         
127         blk = nand_chunk/32;
128         pg = nand_chunk%32;
129         
130         
131         if(data)
132         {
133                 memcpy(ramdisk.block[blk]->page[pg].data,data,512);
134         }
135         
136         
137         if(tags)
138         {
139                 struct yaffs_packed_tags1 pt;
140                 
141                 yaffs_pack_tags1(&pt,tags);
142                 memcpy(&ramdisk.block[blk]->page[pg].data[512],&pt,sizeof(pt));
143         }
144
145         return YAFFS_OK;        
146
147 }
148
149
150 int yramdisk_rd_chunk(struct yaffs_dev *dev,int nand_chunk, u8 *data, struct yaffs_ext_tags *tags)
151 {
152         int blk;
153         int pg;
154
155         
156         CheckInit(dev);
157         
158         blk = nand_chunk/32;
159         pg = nand_chunk%32;
160         
161         
162         if(data)
163         {
164                 memcpy(data,ramdisk.block[blk]->page[pg].data,512);
165         }
166         
167         
168         if(tags)
169         {
170                 struct yaffs_packed_tags1 pt;
171                 
172                 memcpy(&pt,&ramdisk.block[blk]->page[pg].data[512],sizeof(pt));
173                 yaffs_unpack_tags1(tags,&pt);
174                 
175         }
176
177         return YAFFS_OK;
178 }
179
180
181 int yramdisk_check_chunk_erased(struct yaffs_dev *dev,int nand_chunk)
182 {
183         int blk;
184         int pg;
185         int i;
186
187         
188         CheckInit(dev);
189         
190         blk = nand_chunk/32;
191         pg = nand_chunk%32;
192         
193         
194         for(i = 0; i < 528; i++)
195         {
196                 if(ramdisk.block[blk]->page[pg].data[i] != 0xFF)
197                 {
198                         return YAFFS_FAIL;
199                 }
200         }
201
202         return YAFFS_OK;
203
204 }
205
206 int yramdisk_erase(struct yaffs_dev *dev, int blockNumber)
207 {
208         
209         CheckInit(dev);
210         
211         if(blockNumber < 0 || blockNumber >= ramdisk.nBlocks)
212         {
213                 yaffs_trace(YAFFS_TRACE_ALWAYS,
214                         "Attempt to erase non-existant block %d\n",
215                         blockNumber);
216                 return YAFFS_FAIL;
217         }
218         else
219         {
220                 memset(ramdisk.block[blockNumber],0xFF,sizeof(yramdisk_block));
221                 return YAFFS_OK;
222         }
223         
224 }
225
226 int yramdisk_initialise(struct yaffs_dev *dev)
227 {
228         //dev->use_nand_ecc = 1; // force on use_nand_ecc which gets faked. 
229                                                  // This saves us doing ECC checks.
230         
231         return YAFFS_OK;
232 }
233