Consolidate with Android fixes
[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.9 2008-05-05 07:58:58 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         /* If there are no tags provided, use local tags to get prioritised gc working */
33         if(!tags)
34                 tags = &localTags;
35
36         if (dev->readChunkWithTagsFromNAND)
37                 result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
38                                                       tags);
39         else
40                 result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
41                                                                         realignedChunkInNAND,
42                                                                         buffer,
43                                                                         tags);
44         if(tags &&
45            tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
46
47                 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
48                 yaffs_HandleChunkError(dev,bi);
49         }
50
51         return result;
52 }
53
54 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
55                                                    int chunkInNAND,
56                                                    const __u8 * buffer,
57                                                    yaffs_ExtendedTags * tags)
58 {
59         chunkInNAND -= dev->chunkOffset;
60
61
62         if (tags) {
63                 tags->sequenceNumber = dev->sequenceNumber;
64                 tags->chunkUsed = 1;
65                 if (!yaffs_ValidateTags(tags)) {
66                         T(YAFFS_TRACE_ERROR,
67                           (TSTR("Writing uninitialised tags" TENDSTR)));
68                         YBUG();
69                 }
70                 T(YAFFS_TRACE_WRITE,
71                   (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
72                    tags->objectId, tags->chunkId));
73         } else {
74                 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
75                 YBUG();
76         }
77
78         if (dev->writeChunkWithTagsToNAND)
79                 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
80                                                      tags);
81         else
82                 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
83                                                                        chunkInNAND,
84                                                                        buffer,
85                                                                        tags);
86 }
87
88 int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
89 {
90         blockNo -= dev->blockOffset;
91
92 ;
93         if (dev->markNANDBlockBad)
94                 return dev->markNANDBlockBad(dev, blockNo);
95         else
96                 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
97 }
98
99 int yaffs_QueryInitialBlockState(yaffs_Device * dev,
100                                                  int blockNo,
101                                                  yaffs_BlockState * state,
102                                                  __u32 *sequenceNumber)
103 {
104         blockNo -= dev->blockOffset;
105
106         if (dev->queryNANDBlock)
107                 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
108         else
109                 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
110                                                              state,
111                                                              sequenceNumber);
112 }
113
114
115 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
116                                   int blockInNAND)
117 {
118         int result;
119
120         blockInNAND -= dev->blockOffset;
121
122
123         dev->nBlockErasures++;
124         result = dev->eraseBlockInNAND(dev, blockInNAND);
125
126         return result;
127 }
128
129 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
130 {
131         return dev->initialiseNAND(dev);
132 }
133
134
135