Fix copyright
[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-2018 Aleph One Ltd.
5  *
6  * Created by Charles Manning <charles@aleph1.co.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 /*
14  * yaffs_ramdisk.c: yaffs ram disk component
15  * This provides a ram disk under yaffs.
16  * NB this is not intended for NAND emulation.
17  * Use this with dev->use_nand_ecc enabled, then ECC overheads are not required.
18  */
19
20 #include "yportenv.h"
21 #include "yaffs_trace.h"
22
23 #include "yaffs_ramdisk.h"
24 #include "yaffs_guts.h"
25 #include "yaffs_packedtags1.h"
26
27
28
29 #define SIZE_IN_MB 2
30
31 #define BLOCK_SIZE (32 * 528)
32 #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512))
33
34
35
36
37
38 typedef struct
39 {
40         u8 data[528]; // Data + spare
41 } yramdisk_page;
42
43 typedef struct
44 {
45         yramdisk_page page[32]; // The pages in the block
46
47 } yramdisk_block;
48
49
50
51 typedef struct
52 {
53         yramdisk_block **block;
54         int nBlocks;
55 } yramdisk_device;
56
57 static yramdisk_device ramdisk;
58
59 static int  CheckInit(struct yaffs_dev *dev)
60 {
61         static int initialised = 0;
62
63         int i;
64         int fail = 0;
65         //int nBlocks;
66         int nAllocated = 0;
67
68         if(initialised)
69         {
70                 return YAFFS_OK;
71         }
72
73         initialised = 1;
74
75
76         ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024);
77
78         ramdisk.block = malloc(sizeof(yramdisk_block *) * ramdisk.nBlocks);
79
80         if(!ramdisk.block) return 0;
81
82         for(i=0; i <ramdisk.nBlocks; i++)
83         {
84                 ramdisk.block[i] = NULL;
85         }
86
87         for(i=0; i <ramdisk.nBlocks && !fail; i++)
88         {
89                 if((ramdisk.block[i] = malloc(sizeof(yramdisk_block))) == 0)
90                 {
91                         fail = 1;
92                 }
93                 else
94                 {
95                         yramdisk_erase(dev,i);
96                         nAllocated++;
97                 }
98         }
99
100         if(fail)
101         {
102                 for(i = 0; i < nAllocated; i++)
103                 {
104                         kfree(ramdisk.block[i]);
105                 }
106                 kfree(ramdisk.block);
107
108                 yaffs_trace(YAFFS_TRACE_ALWAYS,
109                         "Allocation failed, could only allocate %dMB of %dMB requested.\n",
110                         nAllocated/64,ramdisk.nBlocks * 528);
111                 return 0;
112         }
113
114
115         return 1;
116 }
117
118 int yramdisk_wr_chunk(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_ext_tags *tags)
119 {
120         int blk;
121         int pg;
122
123
124         CheckInit(dev);
125
126         blk = nand_chunk/32;
127         pg = nand_chunk%32;
128
129
130         if(data)
131         {
132                 memcpy(ramdisk.block[blk]->page[pg].data,data,512);
133         }
134
135
136         if(tags)
137         {
138                 struct yaffs_packed_tags1 pt;
139
140                 yaffs_pack_tags1(&pt,tags);
141                 memcpy(&ramdisk.block[blk]->page[pg].data[512],&pt,sizeof(pt));
142         }
143
144         return YAFFS_OK;
145
146 }
147
148
149 int yramdisk_rd_chunk(struct yaffs_dev *dev,int nand_chunk, u8 *data, struct yaffs_ext_tags *tags)
150 {
151         int blk;
152         int pg;
153
154
155         CheckInit(dev);
156
157         blk = nand_chunk/32;
158         pg = nand_chunk%32;
159
160
161         if(data)
162         {
163                 memcpy(data,ramdisk.block[blk]->page[pg].data,512);
164         }
165
166
167         if(tags)
168         {
169                 struct yaffs_packed_tags1 pt;
170
171                 memcpy(&pt,&ramdisk.block[blk]->page[pg].data[512],sizeof(pt));
172                 yaffs_unpack_tags1(tags,&pt);
173
174         }
175
176         return YAFFS_OK;
177 }
178
179
180 int yramdisk_check_chunk_erased(struct yaffs_dev *dev,int nand_chunk)
181 {
182         int blk;
183         int pg;
184         int i;
185
186
187         CheckInit(dev);
188
189         blk = nand_chunk/32;
190         pg = nand_chunk%32;
191
192
193         for(i = 0; i < 528; i++)
194         {
195                 if(ramdisk.block[blk]->page[pg].data[i] != 0xFF)
196                 {
197                         return YAFFS_FAIL;
198                 }
199         }
200
201         return YAFFS_OK;
202
203 }
204
205 int yramdisk_erase(struct yaffs_dev *dev, int blockNumber)
206 {
207
208         CheckInit(dev);
209
210         if(blockNumber < 0 || blockNumber >= ramdisk.nBlocks)
211         {
212                 yaffs_trace(YAFFS_TRACE_ALWAYS,
213                         "Attempt to erase non-existant block %d\n",
214                         blockNumber);
215                 return YAFFS_FAIL;
216         }
217         else
218         {
219                 memset(ramdisk.block[blockNumber],0xFF,sizeof(yramdisk_block));
220                 return YAFFS_OK;
221         }
222
223 }
224
225 int yramdisk_initialise(struct yaffs_dev *dev)
226 {
227         (void) dev;
228
229         //dev->use_nand_ecc = 1; // force on use_nand_ecc which gets faked.
230                                                  // This saves us doing ECC checks.
231
232         return YAFFS_OK;
233 }
234