Interworking with 2.6.18 kernel enabled
[yaffs2.git] / yaffs_nand.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  *
4  * Copyright (C) 2002 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 const char *yaffs_nand_c_version =
16     "$Id: yaffs_nand.c,v 1.2 2006-09-21 08:13:59 charles Exp $";
17
18 #include "yaffs_nand.h"
19 #include "yaffs_tagscompat.h"
20 #include "yaffs_tagsvalidity.h"
21
22
23 int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
24                                            __u8 * buffer,
25                                            yaffs_ExtendedTags * tags)
26 {
27         int result;
28         
29         int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
30
31         if (dev->readChunkWithTagsFromNAND)
32                 result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
33                                                       tags);
34         else
35                 result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
36                                                                         realignedChunkInNAND,
37                                                                         buffer,
38                                                                         tags);  
39         if(tags && 
40            tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
41         
42                 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
43                 bi->gcPrioritise = 1;
44         }
45                                                                 
46         return result;
47 }
48
49 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
50                                                    int chunkInNAND,
51                                                    const __u8 * buffer,
52                                                    yaffs_ExtendedTags * tags)
53 {
54         chunkInNAND -= dev->chunkOffset;
55
56         
57         if (tags) {
58                 tags->sequenceNumber = dev->sequenceNumber;
59                 tags->chunkUsed = 1;
60                 if (!yaffs_ValidateTags(tags)) {
61                         T(YAFFS_TRACE_ERROR,
62                           (TSTR("Writing uninitialised tags" TENDSTR)));
63                         YBUG();
64                 }
65                 T(YAFFS_TRACE_WRITE,
66                   (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
67                    tags->objectId, tags->chunkId));
68         } else {
69                 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
70                 YBUG();
71         }
72
73         if (dev->writeChunkWithTagsToNAND)
74                 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
75                                                      tags);
76         else
77                 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
78                                                                        chunkInNAND,
79                                                                        buffer,
80                                                                        tags);
81 }
82
83 int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
84 {
85         blockNo -= dev->blockOffset;
86
87 ;
88         if (dev->markNANDBlockBad)
89                 return dev->markNANDBlockBad(dev, blockNo);
90         else
91                 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
92 }
93
94 int yaffs_QueryInitialBlockState(yaffs_Device * dev,
95                                                  int blockNo,
96                                                  yaffs_BlockState * state,
97                                                  unsigned *sequenceNumber)
98 {
99         blockNo -= dev->blockOffset;
100
101         if (dev->queryNANDBlock)
102                 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
103         else
104                 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
105                                                              state,
106                                                              sequenceNumber);
107 }
108
109
110 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
111                                   int blockInNAND)
112 {
113         int result;
114
115         blockInNAND -= dev->blockOffset;
116
117
118         dev->nBlockErasures++;
119         result = dev->eraseBlockInNAND(dev, blockInNAND);
120
121         /* If at first we don't succeed, try again *once*.*/
122         if (!result)
123                 result = dev->eraseBlockInNAND(dev, blockInNAND);       
124         return result;
125 }
126
127 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
128 {
129         return dev->initialiseNAND(dev);
130 }
131
132
133