tizen 2.4 release
[kernel/u-boot-tm1.git] / fs / yaffs2 / yaffscfg.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  * yaffscfg.c  The configuration for the "direct" use of yaffs.
16  *
17  * This file is intended to be modified to your requirements.
18  * There is no need to redistribute this file.
19  */
20
21 /* XXX U-BOOT XXX */
22 #include <common.h>
23
24 #include <config.h>
25 #include "nand.h"
26 #include "yaffscfg.h"
27 #include "yaffsfs.h"
28 #include "yaffs_packedtags2.h"
29 #include "yaffs_mtdif.h"
30 #include "yaffs_mtdif2.h"
31 #include "parsemtdparts.h"
32 #if 0
33 #include <errno.h>
34 #else
35 #include "malloc.h"
36 #endif
37
38 unsigned yaffs_traceMask = 0x0; /* Disable logging */
39 //unsigned yaffs_traceMask = 0xFFFFFFFF; /* Enable logging */
40 static int yaffs_errno = 0;
41
42 void yaffsfs_SetError(int err)
43 {
44         //Do whatever to set error
45         yaffs_errno = err;
46 }
47
48 int yaffsfs_GetError(void)
49 {
50         return yaffs_errno;
51 }
52
53 void yaffsfs_Lock(void)
54 {
55 }
56
57 void yaffsfs_Unlock(void)
58 {
59 }
60
61 __u32 yaffsfs_CurrentTime(void)
62 {
63         return 0;
64 }
65
66 void *yaffs_malloc(size_t size)
67 {
68         return malloc(size);
69 }
70
71 void yaffs_free(void *ptr)
72 {
73         free(ptr);
74 }
75
76 void yaffsfs_LocalInitialisation(void)
77 {
78         // Define locking semaphore.
79 }
80
81 // Configuration for:
82 // /ram  2MB ramdisk
83 // /boot 2MB boot disk (flash)
84 // /flash 14MB flash disk (flash)
85 // NB Though /boot and /flash occupy the same physical device they
86 // are still disticnt "yaffs_Devices. You may think of these as "partitions"
87 // using non-overlapping areas in the same device.
88 //
89
90 #include "yaffs_ramdisk.h"
91 #include "yaffs_flashif.h"
92
93 static int isMounted = 0;
94 #define MOUNT_POINT "/flash"
95
96 #define SPRD_MOUNT_PARTITION    1
97 #ifdef  SPRD_MOUNT_PARTITION
98 #define MOUNT_POINT1 "/backupfixnv"
99 #define MOUNT_POINT2 "/runtimenv"
100 #define MOUNT_POINT3 "/productinfo"
101 #define MOUNT_POINT4 "/fixnv"
102 #define MOUNT_POINT5 "/cache"
103 #endif
104
105
106 #define YAFFS_RESERVED_BLOCK_NUM     5
107
108 extern nand_info_t nand_info[];
109
110 /* XXX U-BOOT XXX */
111 #if 0
112 static yaffs_Device ramDev;
113 static yaffs_Device bootDev;
114 static yaffs_Device flashDev;
115 #endif
116
117 static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
118 /* XXX U-BOOT XXX */
119 #if 0
120         { "/ram", &ramDev},
121         { "/boot", &bootDev},
122         { "/flash", &flashDev},
123 #else
124         { MOUNT_POINT, 0},
125 #ifdef  SPRD_MOUNT_PARTITION
126         { MOUNT_POINT1, 0},
127         { MOUNT_POINT2, 0},
128         { MOUNT_POINT3, 0},
129         { MOUNT_POINT4, 0},
130         { MOUNT_POINT5, 0},
131 #endif
132 #endif
133         {(void *)0,(void *)0}
134 };
135
136 static void yaffs_dump_dev(yaffs_Device * dev)
137 {
138         printf("\n\n");
139         printf("startBlock......... %d\n", dev->startBlock);
140         printf("endBlock........... %d\n", dev->endBlock);
141         //printf("totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
142         printf("nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
143         printf("chunkGroupBits..... %d\n", dev->chunkGroupBits);
144         printf("chunkGroupSize..... %d\n", dev->chunkGroupSize);
145         printf("nErasedBlocks...... %d\n", dev->nErasedBlocks);
146         printf("nReservedBlocks.... %d\n", dev->nReservedBlocks);
147         printf("blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
148         printf("nTnodesCreated..... %d\n", dev->nTnodesCreated);
149         printf("nFreeTnodes........ %d\n", dev->nFreeTnodes);
150         printf("nObjectsCreated.... %d\n", dev->nObjectsCreated);
151         printf("nFreeObjects....... %d\n", dev->nFreeObjects);
152         printf("nFreeChunks........ %d\n", dev->nFreeChunks);
153         printf("nPageWrites........ %d\n", dev->nPageWrites);
154         printf("nPageReads......... %d\n", dev->nPageReads);
155         printf("nBlockErasures..... %d\n", dev->nBlockErasures);
156         printf("nGCCopies.......... %d\n", dev->nGCCopies);
157         printf("garbageCollections. %d\n", dev->garbageCollections);
158         printf("passiveGCs......... %d\n", dev->passiveGarbageCollections);
159         printf("nRetriedWrites..... %d\n", dev->nRetriedWrites);
160         printf("nShortOpCaches..... %d\n", dev->nShortOpCaches);
161         printf("nRetireBlocks...... %d\n", dev->nRetiredBlocks);
162         printf("eccFixed........... %d\n", dev->eccFixed);
163         printf("eccUnfixed......... %d\n", dev->eccUnfixed);
164         printf("tagsEccFixed....... %d\n", dev->tagsEccFixed);
165         printf("tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed);
166         printf("cacheHits.......... %d\n", dev->cacheHits);
167         printf("nDeletedFiles...... %d\n", dev->nDeletedFiles);
168         printf("nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles);
169         printf("nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
170         printf("useNANDECC......... %d\n", dev->useNANDECC);
171         printf("isYaffs2........... %d\n", dev->isYaffs2);
172         //printf("inbandTags......... %d\n", dev->inbandTags);
173         printf("\n\n");
174 }
175
176
177 int yaffs_StartUp(void)
178 {
179         struct mtd_info *mtd = &nand_info[0];
180         int yaffsVersion = 2;
181         int nBlocks;
182         struct mtd_partition cur_partition;
183         int aaa;
184         char partname[255];
185         static int already_start_up = 0;
186         if(already_start_up){
187                 return 0;
188         }
189
190         yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device));
191 #ifdef  SPRD_MOUNT_PARTITION
192         yaffs_Device *backupfixnvDev = calloc(1, sizeof(yaffs_Device));
193         yaffs_Device *runtimenvDev = calloc(1, sizeof(yaffs_Device));
194         yaffs_Device *productinfoDev = calloc(1, sizeof(yaffs_Device));
195         yaffs_Device *fixnvDev = calloc(1, sizeof(yaffs_Device));
196         yaffs_Device *dataDev= calloc(1, sizeof(yaffs_Device));
197 #endif
198
199         yaffsfs_config[0].dev = flashDev;
200 #ifdef  SPRD_MOUNT_PARTITION
201         yaffsfs_config[1].dev = backupfixnvDev;
202         yaffsfs_config[2].dev = runtimenvDev;
203         yaffsfs_config[3].dev = productinfoDev;
204         yaffsfs_config[4].dev = fixnvDev;
205         yaffsfs_config[5].dev = dataDev;
206 #endif
207
208         /* store the mtd device for later use */
209         flashDev->genericDevice = mtd;
210 #ifdef  SPRD_MOUNT_PARTITION
211         backupfixnvDev->genericDevice = mtd;
212         runtimenvDev->genericDevice = mtd;
213         productinfoDev->genericDevice = mtd;
214         fixnvDev->genericDevice = mtd;
215         dataDev->genericDevice = mtd;
216 #endif
217
218         // Stuff to configure YAFFS
219         // Stuff to initialise anything special (eg lock semaphore).
220         yaffsfs_LocalInitialisation();
221
222         // Set up devices
223
224 /* XXX U-BOOT XXX */
225 #if 0
226         // /ram
227         ramDev.nBytesPerChunk = 512;
228         ramDev.nChunksPerBlock = 32;
229         ramDev.nReservedBlocks = 2; // Set this smaller for RAM
230         ramDev.startBlock = 1; // Can't use block 0
231         ramDev.endBlock = 127; // Last block in 2MB.
232         ramDev.useNANDECC = 1;
233         ramDev.nShortOpCaches = 0;      // Disable caching on this device.
234         ramDev.genericDevice = (void *) 0;      // Used to identify the device in fstat.
235         ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
236         ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
237         ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
238         ramDev.initialiseNAND = yramdisk_InitialiseNAND;
239
240         // /boot
241         bootDev.nBytesPerChunk = 612;
242         bootDev.nChunksPerBlock = 32;
243         bootDev.nReservedBlocks = 5;
244         bootDev.startBlock = 1; // Can't use block 0
245         bootDev.endBlock = 127; // Last block in 2MB.
246         bootDev.useNANDECC = 0; // use YAFFS's ECC
247         bootDev.nShortOpCaches = 10; // Use caches
248         bootDev.genericDevice = (void *) 1;     // Used to identify the device in fstat.
249         bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
250         bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
251         bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
252         bootDev.initialiseNAND = yflash_InitialiseNAND;
253 #endif
254
255                 // /flash
256         flashDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
257         //flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10;
258         flashDev->nShortOpCaches = 10; // Use caches
259         flashDev->useNANDECC = 0; // use YAFFS's ECC
260         if (yaffsVersion == 2)
261         {
262                 flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
263                 flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
264                 flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
265                 flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
266                 flashDev->spareBuffer = YMALLOC(mtd->oobsize);
267                 flashDev->isYaffs2 = 1;
268 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
269                 flashDev->nDataBytesPerChunk = mtd->writesize;
270                 flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
271 #else
272                 flashDev->nDataBytesPerChunk = mtd->oobblock;
273                 flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
274 #endif
275                 nBlocks = mtd->size / mtd->erasesize;
276                 //printf("nBlocks = %d\n", nBlocks);
277
278                 flashDev->nCheckpointReservedBlocks = 10;
279
280 #if 0
281                 flashDev->startBlock = 0;
282                 flashDev->endBlock = nBlocks - 1;
283 #else
284                 flashDev->startBlock = 237;
285                 flashDev->endBlock = flashDev->startBlock + 800  - 1;   
286 #endif
287                 //printf("\n\nflash device from %d to %d\n\n", flashDev->startBlock, flashDev->endBlock);
288         }
289         else
290         {
291                 flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
292                 flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
293                 flashDev->isYaffs2 = 0;
294                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
295                 flashDev->startBlock = 320;
296                 flashDev->endBlock = nBlocks - 1;
297                 flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
298                 flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
299         }
300
301         /* ... and common functions */
302         flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
303         flashDev->initialiseNAND = nandmtd_InitialiseNAND;
304
305 #ifdef  SPRD_MOUNT_PARTITION
306         // /backupfixnv
307         backupfixnvDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
308         backupfixnvDev->nShortOpCaches = 10; // Use caches
309         backupfixnvDev->useNANDECC = 1; // use YAFFS's ECC
310
311         backupfixnvDev->skipCheckpointRead = 1;
312         backupfixnvDev->skipCheckpointWrite = 1;
313
314         if (yaffsVersion == 2)
315         {
316                 backupfixnvDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
317                 backupfixnvDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
318                 backupfixnvDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
319                 backupfixnvDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
320                 backupfixnvDev->spareBuffer = YMALLOC(mtd->oobsize);
321                 backupfixnvDev->isYaffs2 = 1;
322 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
323                 backupfixnvDev->nDataBytesPerChunk = mtd->writesize;
324                 backupfixnvDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
325 #else
326                 backupfixnvDev->nDataBytesPerChunk = mtd->oobblock;
327                 backupfixnvDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
328 #endif
329                 nBlocks = mtd->size / mtd->erasesize;
330                 //printf("size = 0x%016Lx  erasesize = 0x%016Lx  nBlocks = %d\n", (unsigned long long)mtd->size, (unsigned long long)mtd->erasesize, nBlocks);
331
332                 backupfixnvDev->nCheckpointReservedBlocks = 0;
333                 
334                 memset(&cur_partition, 0 , sizeof(struct mtd_partition));
335                 memset(partname, 0, 255);
336                 strcpy(partname, MOUNT_POINT1);
337                 cur_partition.name = (char *)(partname + 1); /* skip '/' charater */
338                 cur_partition.offset = 0xffffffff;
339                 yaffs_parse_cmdline_partitions(&cur_partition, (unsigned long long)mtd->size);
340                 //printf("offset = 0x%08x  size = 0x%08x\n", cur_partition.offset, cur_partition.size);
341                 backupfixnvDev->startBlock = cur_partition.offset / mtd->erasesize;
342                 backupfixnvDev->endBlock = backupfixnvDev->startBlock + cur_partition.size / mtd->erasesize  - 1;
343                 //printf("\nbackupfixnv device from %d to %d\n", backupfixnvDev->startBlock, backupfixnvDev->endBlock);
344         }
345         else
346         {
347                 backupfixnvDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
348                 backupfixnvDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
349                 backupfixnvDev->isYaffs2 = 0;
350                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
351                 backupfixnvDev->startBlock = 320;
352                 backupfixnvDev->endBlock = nBlocks - 1;
353                 backupfixnvDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
354                 backupfixnvDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
355         }
356
357         /* ... and common functions */
358         backupfixnvDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
359         backupfixnvDev->initialiseNAND = nandmtd_InitialiseNAND;
360
361         //yaffs_dump_dev(backupfixnvDev);
362
363
364         // /runtimenv
365         runtimenvDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
366         runtimenvDev->nShortOpCaches = 10; // Use caches
367         runtimenvDev->useNANDECC = 1; // use YAFFS's ECC
368
369         runtimenvDev->skipCheckpointRead = 1;
370         runtimenvDev->skipCheckpointWrite = 1;
371
372         if (yaffsVersion == 2)
373         {
374                 runtimenvDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
375                 runtimenvDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
376                 runtimenvDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
377                 runtimenvDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
378                 runtimenvDev->spareBuffer = YMALLOC(mtd->oobsize);
379                 runtimenvDev->isYaffs2 = 1;
380 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
381                 runtimenvDev->nDataBytesPerChunk = mtd->writesize;
382                 runtimenvDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
383 #else
384                 runtimenvDev->nDataBytesPerChunk = mtd->oobblock;
385                 runtimenvDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
386 #endif
387                 nBlocks = mtd->size / mtd->erasesize;
388                 //printf("size = 0x%016Lx  erasesize = 0x%016Lx  nBlocks = %d\n", (unsigned long long)mtd->size, (unsigned long long)mtd->erasesize, nBlocks);
389
390                 runtimenvDev->nCheckpointReservedBlocks = 0;
391                 
392                 memset(&cur_partition, 0 , sizeof(struct mtd_partition));
393                 memset(partname, 0, 255);
394                 strcpy(partname, MOUNT_POINT2);
395                 cur_partition.name = (char *)(partname + 1); /* skip '/' charater */
396                 cur_partition.offset = 0xffffffff;
397                 yaffs_parse_cmdline_partitions(&cur_partition, (unsigned long long)mtd->size);
398                 //printf("offset = 0x%08x  size = 0x%08x\n", cur_partition.offset, cur_partition.size);
399                 runtimenvDev->startBlock = cur_partition.offset / mtd->erasesize;
400                 runtimenvDev->endBlock = runtimenvDev->startBlock + cur_partition.size / mtd->erasesize  - 1;
401                 //printf("\nruntimenv device from %d to %d\n", runtimenvDev->startBlock, runtimenvDev->endBlock);
402         }
403         else
404         {
405                 runtimenvDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
406                 runtimenvDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
407                 runtimenvDev->isYaffs2 = 0;
408                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
409                 runtimenvDev->startBlock = 320;
410                 runtimenvDev->endBlock = nBlocks - 1;
411                 runtimenvDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
412                 runtimenvDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
413         }
414
415         /* ... and common functions */
416         runtimenvDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
417         runtimenvDev->initialiseNAND = nandmtd_InitialiseNAND;
418
419         //yaffs_dump_dev(runtimenvDev);
420
421
422         // /productinfo
423         productinfoDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
424         productinfoDev->nShortOpCaches = 10; // Use caches
425         productinfoDev->useNANDECC = 1; // use YAFFS's ECC
426
427         productinfoDev->skipCheckpointRead = 1;
428         productinfoDev->skipCheckpointWrite = 1;
429
430         if (yaffsVersion == 2)
431         {
432                 productinfoDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
433                 productinfoDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
434                 productinfoDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
435                 productinfoDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
436                 productinfoDev->spareBuffer = YMALLOC(mtd->oobsize);
437                 productinfoDev->isYaffs2 = 1;
438 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
439                 productinfoDev->nDataBytesPerChunk = mtd->writesize;
440                 productinfoDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
441 #else
442                 productinfoDev->nDataBytesPerChunk = mtd->oobblock;
443                 productinfoDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
444 #endif
445                 nBlocks = mtd->size / mtd->erasesize;
446                 //printf("size = 0x%016Lx  erasesize = 0x%016Lx  nBlocks = %d\n", (unsigned long long)mtd->size, (unsigned long long)mtd->erasesize, nBlocks);
447
448                 productinfoDev->nCheckpointReservedBlocks = 0;
449                 
450                 memset(&cur_partition, 0 , sizeof(struct mtd_partition));
451                 memset(partname, 0, 255);
452                 strcpy(partname, MOUNT_POINT3);
453                 cur_partition.name = (char *)(partname + 1); /* skip '/' charater */
454                 cur_partition.offset = 0xffffffff;
455                 yaffs_parse_cmdline_partitions(&cur_partition, (unsigned long long)mtd->size);
456                 //printf("offset = 0x%08x  size = 0x%08x\n", cur_partition.offset, cur_partition.size);
457                 productinfoDev->startBlock = cur_partition.offset / mtd->erasesize;
458                 productinfoDev->endBlock = productinfoDev->startBlock + cur_partition.size / mtd->erasesize  - 1;
459                 //printf("\productinfo device from %d to %d\n", productinfoDev->startBlock, productinfoDev->endBlock);
460         }
461         else
462         {
463                 productinfoDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
464                 productinfoDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
465                 productinfoDev->isYaffs2 = 0;
466                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
467                 productinfoDev->startBlock = 320;
468                 productinfoDev->endBlock = nBlocks - 1;
469                 productinfoDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
470                 productinfoDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
471         }
472
473         /* ... and common functions */
474         productinfoDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
475         productinfoDev->initialiseNAND = nandmtd_InitialiseNAND;
476
477         //yaffs_dump_dev(productinfoDev);
478
479         // /fixnv
480         fixnvDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
481         fixnvDev->nShortOpCaches = 10; // Use caches
482         fixnvDev->useNANDECC = 1; // use YAFFS's ECC
483
484         fixnvDev->skipCheckpointRead = 1;
485         fixnvDev->skipCheckpointWrite = 1;
486
487         if (yaffsVersion == 2)
488         {
489                 fixnvDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
490                 fixnvDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
491                 fixnvDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
492                 fixnvDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
493                 fixnvDev->spareBuffer = YMALLOC(mtd->oobsize);
494                 fixnvDev->isYaffs2 = 1;
495 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
496                 fixnvDev->nDataBytesPerChunk = mtd->writesize;
497                 fixnvDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
498 #else
499                 fixnvDev->nDataBytesPerChunk = mtd->oobblock;
500                 fixnvDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
501 #endif
502                 nBlocks = mtd->size / mtd->erasesize;
503                 //printf("size = 0x%016Lx  erasesize = 0x%016Lx  nBlocks = %d\n", (unsigned long long)mtd->size, (unsigned long long)mtd->erasesize, nBlocks);
504
505                 fixnvDev->nCheckpointReservedBlocks = 0;
506                 
507                 memset(&cur_partition, 0 , sizeof(struct mtd_partition));
508                 memset(partname, 0, 255);
509                 strcpy(partname, MOUNT_POINT4);
510                 cur_partition.name = (char *)(partname + 1); /* skip '/' charater */
511                 cur_partition.offset = 0xffffffff;
512                 yaffs_parse_cmdline_partitions(&cur_partition, (unsigned long long)mtd->size);
513                 //printf("offset = 0x%08x  size = 0x%08x\n", cur_partition.offset, cur_partition.size);
514                 fixnvDev->startBlock = cur_partition.offset / mtd->erasesize;
515                 fixnvDev->endBlock = fixnvDev->startBlock + cur_partition.size / mtd->erasesize  - 1;
516                 //printf("fixnv device from %d to %d\n", fixnvDev->startBlock, fixnvDev->endBlock);
517         }
518         else
519         {
520                 fixnvDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
521                 fixnvDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
522                 fixnvDev->isYaffs2 = 0;
523                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
524                 fixnvDev->startBlock = 320;
525                 fixnvDev->endBlock = nBlocks - 1;
526                 fixnvDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
527                 fixnvDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
528         }
529
530         /* ... and common functions */
531         fixnvDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
532         fixnvDev->initialiseNAND = nandmtd_InitialiseNAND;
533
534         //yaffs_dump_dev(fixnvDev);
535
536         //data partition 
537         dataDev->nReservedBlocks = YAFFS_RESERVED_BLOCK_NUM;
538         dataDev->nShortOpCaches = 10; // Use caches
539         dataDev->useNANDECC = 1; // use YAFFS's ECC
540
541         dataDev->skipCheckpointRead = 1;
542         dataDev->skipCheckpointWrite = 1;
543
544         if (yaffsVersion == 2)
545         {
546                 dataDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
547                 dataDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
548                 dataDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
549                 dataDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
550                 dataDev->spareBuffer = YMALLOC(mtd->oobsize);
551                 dataDev->isYaffs2 = 1;
552 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
553                 dataDev->nDataBytesPerChunk = mtd->writesize;
554                 dataDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
555 #else
556                 dataDev->nDataBytesPerChunk = mtd->oobblock;
557                 dataDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
558 #endif
559                 nBlocks = mtd->size / mtd->erasesize;
560                 //printf("size = 0x%016Lx  erasesize = 0x%016Lx  nBlocks = %d\n", (unsigned long long)mtd->size, (unsigned long long)mtd->erasesize, nBlocks);
561
562                 dataDev->nCheckpointReservedBlocks = 0;
563                 
564                 memset(&cur_partition, 0 , sizeof(struct mtd_partition));
565                 memset(partname, 0, 255);
566                 strcpy(partname, MOUNT_POINT5);
567                 cur_partition.name = (char *)(partname + 1); /* skip '/' charater */
568                 cur_partition.offset = 0xffffffff;
569                 yaffs_parse_cmdline_partitions(&cur_partition, (unsigned long long)mtd->size);
570                 //printf("offset = 0x%08x  size = 0x%08x\n", cur_partition.offset, cur_partition.size);
571                 dataDev->startBlock = cur_partition.offset / mtd->erasesize;
572                 dataDev->endBlock = dataDev->startBlock + cur_partition.size / mtd->erasesize  - 1;
573                 //printf("fixnv device from %d to %d\n", fixnvDev->startBlock, fixnvDev->endBlock);
574         }
575         else
576         {
577                 dataDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
578                 dataDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
579                 dataDev->isYaffs2 = 0;
580                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
581                 dataDev->startBlock = 320;
582                 dataDev->endBlock = nBlocks - 1;
583                 dataDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
584                 dataDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
585         }
586
587         /* ... and common functions */
588         dataDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
589         dataDev->initialiseNAND = nandmtd_InitialiseNAND;
590
591         //yaffs_dump_dev(dataDev);
592 #endif
593
594         yaffs_initialise(yaffsfs_config);
595
596         already_start_up = 1;
597         return 0;
598 }
599
600
601 //void make_a_file(char *yaffsName,char bval,int sizeOfFile)
602 void make_a_file(char *yaffsName,unsigned long bval,int sizeOfFile)
603 {
604         int outh;
605         int i;
606         unsigned char buffer[100];
607         int aaa;
608
609         outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
610         if (outh < 0)
611         {
612                 printf("Error opening file: %d\n", outh);
613                 return;
614         }
615
616 #if 1
617         memset(buffer,bval,100);
618         for (aaa = 0; aaa < 100; aaa ++) {
619                 //printf("buffer[%d] = 0x%x\n", aaa, buffer[aaa]);
620                 buffer[aaa] = aaa;
621         }
622
623         do{
624                 i = sizeOfFile;
625                 if(i > 100) i = 100;
626                 sizeOfFile -= i;
627                 yaffs_write(outh,buffer,i);
628         } while (sizeOfFile > 0);
629 #else
630         
631         printf("bval = 0x%08x\n", bval);
632         yaffs_write(outh,&bval,4);
633         
634 #endif
635
636
637         yaffs_close(outh);
638 }
639
640 void read_a_file(char *fn)
641 {
642         int h;
643         int i = 0;
644         unsigned char b;
645
646         h = yaffs_open(fn, O_RDWR,0);
647         if(h<0)
648         {
649                 printf("File not found\n");
650                 return;
651         }
652
653         while(yaffs_read(h,&b,1)> 0)
654         {
655                 printf(" %02x",b);
656                 i++;
657                 if(i > 15)
658                 {
659                    printf("\n");
660                    i = 0;
661                  }
662         }
663         printf("\n");
664         yaffs_close(h);
665 }
666
667 void cmd_yaffs_mount(char *mp)
668 {
669         yaffs_StartUp();
670         int retval = yaffs_mount(mp);
671         if( retval != -1)
672                 isMounted = 1;
673         else
674                 printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError());
675 }
676
677 static void checkMount(void)
678 {
679         if( !isMounted )
680         {
681                 cmd_yaffs_mount(MOUNT_POINT);
682         }
683 }
684
685 void cmd_yaffs_umount(char *mp)
686 {
687         checkMount();
688         if( yaffs_unmount(mp) == -1)
689                 printf("Error umounting %s, return value: %d\n", mp, yaffsfs_GetError());
690 }
691
692 //void cmd_yaffs_write_file(char *yaffsName,char bval,int sizeOfFile)
693 void cmd_yaffs_write_file(char *yaffsName,unsigned long bval,int sizeOfFile)
694 {
695         printf("bval = 0x%08x  sizeOfFile = %d\n", bval, sizeOfFile);
696         checkMount();
697         make_a_file(yaffsName,bval,sizeOfFile);
698 }
699
700
701 void cmd_yaffs_read_file(char *fn)
702 {
703         checkMount();
704         read_a_file(fn);
705 }
706
707
708 void cmd_yaffs_mread_file(char *fn, unsigned char *addr)
709 {
710         int h;
711         struct yaffs_stat s;
712
713         checkMount();
714
715         yaffs_stat(fn,&s);
716
717         printf ("Copy %s to 0x%08x... ", fn, addr);
718         h = yaffs_open(fn, O_RDWR,0);
719         if(h<0)
720         {
721                 printf("File not found\n");
722                 return;
723         }
724         printf("st_size = %d\n", (int)s.st_size);
725         yaffs_read(h,addr,(int)s.st_size);
726         //printf("\t[DONE]\n");
727
728         yaffs_close(h);
729 }
730 /*
731 read file no more than "max size"
732 to avoid the case : s.st_size is abnormal value, 
733 i don't know why s.st_size is so strange value !!!
734 */
735 void cmd_yaffs_mread_fileex(char *fn, unsigned char *addr, int size)
736 {
737         int h;
738         struct yaffs_stat s;
739
740         checkMount();
741
742         yaffs_stat(fn,&s);
743
744         printf ("Copy %s to 0x%08x... ", fn, addr);
745         h = yaffs_open(fn, O_RDWR,0);
746         if(h<0)
747         {
748                 printf("File not found\n");
749                 return;
750         }
751         printf("st_size = %d, size= %d \n", (int)s.st_size, size);
752
753         if(s.st_size > size)
754                 s.st_size = size;
755         
756         yaffs_read(h,addr,(int)s.st_size);
757         printf("\t[DONE]\n");
758
759         yaffs_close(h);
760 }
761
762 void cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
763 {
764         int outh;
765
766         checkMount();
767         outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
768         if (outh < 0)
769         {
770                 printf("Error opening file: %d\n", outh);
771         }
772
773         yaffs_write(outh,addr,size);
774
775         yaffs_close(outh);
776 }
777
778
779 void cmd_yaffs_ls(const char *mountpt, int longlist)
780 {
781         int i;
782         yaffs_DIR *d;
783         yaffs_dirent *de;
784         struct yaffs_stat stat;
785         char tempstr[255];
786         
787         checkMount();
788         d = yaffs_opendir(mountpt);
789
790         if(!d)
791         {
792                 printf("opendir failed\n");
793         }
794         else
795         {
796                 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
797                 {
798                         if (longlist)
799                         {
800                                 memset(tempstr, 0, 255);
801                                 sprintf(tempstr, "%s/%s", mountpt, de->d_name);
802                                 yaffs_stat(tempstr, &stat);
803                                 printf("%-25s\t%7d\n",de->d_name, stat.st_size);
804                         }
805                         else
806                         {
807                                 printf("%s\n",de->d_name);
808                         }
809                 }
810         }
811 }
812
813 /*
814 *  retval : -1 file is not here ;  > 0 file is here and return size of file
815 */
816 int cmd_yaffs_ls_chk(char *dirfilename)
817 {
818         int i;
819         yaffs_DIR *d;
820         yaffs_dirent *de;
821         struct yaffs_stat stat;
822         char tempstr[255];
823         int ret = -1;
824         char filename[255];
825         char mountpt[255];
826         char *ptr = NULL;
827
828         memset(tempstr, 0, 255);
829         memset(mountpt, 0, 255);
830         memset(filename, 0, 255);
831
832         strcpy(tempstr, dirfilename);
833         ptr = strrchr(tempstr, '/');
834         if (ptr == NULL)
835                 return ret;
836         *ptr = '\0'; 
837         strcpy(filename, (ptr + 1));
838         strcpy(mountpt, tempstr);
839
840         checkMount();
841         d = yaffs_opendir(mountpt);
842
843         if(!d)
844         {
845                 printf("opendir failed\n");
846         }
847         else
848         {
849                 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
850                 {
851                                 if (strcmp(filename, de->d_name) == 0) {
852                                         memset(tempstr, 0, 255);
853                                         sprintf(tempstr, "%s/%s", mountpt, de->d_name);
854                                         yaffs_stat(tempstr, &stat);
855                                         printf("%-25s\t%7d\n",de->d_name, stat.st_size);
856                                         printf("%-25s\t%7d\n",tempstr, stat.st_size);
857                                         ret = stat.st_size;
858                                         return ret;
859                                 }
860                 }
861         }
862
863         return ret;
864 }
865
866 void cmd_yaffs_mkdir(const char *dir)
867 {
868         checkMount();
869
870         int retval = yaffs_mkdir(dir, 0);
871
872         if ( retval < 0)
873                 printf("yaffs_mkdir returning error: %d\n", retval);
874 }
875
876 void cmd_yaffs_rmdir(const char *dir)
877 {
878         checkMount();
879
880         int retval = yaffs_rmdir(dir);
881
882         if ( retval < 0)
883                 printf("yaffs_rmdir returning error: %d\n", retval);
884 }
885
886 void cmd_yaffs_rm(const char *path)
887 {
888         checkMount();
889
890         int retval = yaffs_unlink(path);
891
892         if ( retval < 0)
893                 printf("yaffs_unlink returning error: %d\n", retval);
894 }
895
896 void cmd_yaffs_mv(const char *oldPath, const char *newPath)
897 {
898         checkMount();
899
900         int retval = yaffs_rename(newPath, oldPath);
901
902         if ( retval < 0)
903                 printf("yaffs_unlink returning error: %d\n", retval);
904 }
905
906
907 int yaffs_get_reserved_block_num(void)
908 {
909         return (int)YAFFS_RESERVED_BLOCK_NUM;
910 }
911
912 int cmd_yaffs_rm_chk(const char *path)
913 {
914         checkMount();
915         int retval = yaffs_unlink(path);
916         if ( retval < 0)
917                 printf("yaffs_unlink returning error: %d\n", retval);
918
919         return retval;
920 }
921
922