Change initnandsim to accept parameters to lauch different simulations
[yaffs2.git] / yaffs_nand.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 const char *yaffs_nand_c_version =
15         "$Id: yaffs_nand.c,v 1.11 2009-09-09 03:03:01 charles Exp $";
16
17 #include "yaffs_nand.h"
18 #include "yaffs_tagscompat.h"
19 #include "yaffs_tagsvalidity.h"
20
21 #include "yaffs_getblockinfo.h"
22
23 int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
24                                            __u8 *buffer,
25                                            yaffs_ExtendedTags *tags)
26 {
27         int result;
28         yaffs_ExtendedTags localTags;
29
30         int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
31
32         dev->nPageReads++;
33
34         /* If there are no tags provided, use local tags to get prioritised gc working */
35         if (!tags)
36                 tags = &localTags;
37
38         if (dev->readChunkWithTagsFromNAND)
39                 result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
40                                                       tags);
41         else
42                 result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
43                                                                         realignedChunkInNAND,
44                                                                         buffer,
45                                                                         tags);
46         if (tags &&
47            tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
48
49                 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
50                 yaffs_HandleChunkError(dev, bi);
51         }
52
53         return result;
54 }
55
56 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
57                                                    int chunkInNAND,
58                                                    const __u8 *buffer,
59                                                    yaffs_ExtendedTags *tags)
60 {
61
62         dev->nPageWrites++;
63
64         chunkInNAND -= dev->chunkOffset;
65
66
67         if (tags) {
68                 tags->sequenceNumber = dev->sequenceNumber;
69                 tags->chunkUsed = 1;
70                 if (!yaffs_ValidateTags(tags)) {
71                         T(YAFFS_TRACE_ERROR,
72                           (TSTR("Writing uninitialised tags" TENDSTR)));
73                         YBUG();
74                 }
75                 T(YAFFS_TRACE_WRITE,
76                   (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
77                    tags->objectId, tags->chunkId));
78         } else {
79                 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
80                 YBUG();
81         }
82
83         if (dev->writeChunkWithTagsToNAND)
84                 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
85                                                      tags);
86         else
87                 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
88                                                                        chunkInNAND,
89                                                                        buffer,
90                                                                        tags);
91 }
92
93 int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
94 {
95         blockNo -= dev->blockOffset;
96
97
98         if (dev->markNANDBlockBad)
99                 return dev->markNANDBlockBad(dev, blockNo);
100         else
101                 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
102 }
103
104 int yaffs_QueryInitialBlockState(yaffs_Device *dev,
105                                                  int blockNo,
106                                                  yaffs_BlockState *state,
107                                                  __u32 *sequenceNumber)
108 {
109         blockNo -= dev->blockOffset;
110
111         if (dev->queryNANDBlock)
112                 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
113         else
114                 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
115                                                              state,
116                                                              sequenceNumber);
117 }
118
119
120 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
121                                   int blockInNAND)
122 {
123         int result;
124
125         blockInNAND -= dev->blockOffset;
126
127         dev->nBlockErasures++;
128
129         result = dev->eraseBlockInNAND(dev, blockInNAND);
130
131         return result;
132 }
133
134 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
135 {
136         return dev->initialiseNAND(dev);
137 }
138
139
140