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