cd39d516066564bd452bafd9e48e2a7da82e67c6
[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.1 2006-05-08 10:13:34 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         chunkInNAND -= dev->chunkOffset;
28
29         if (dev->readChunkWithTagsFromNAND)
30                 return dev->readChunkWithTagsFromNAND(dev, chunkInNAND, buffer,
31                                                       tags);
32         else
33                 return yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
34                                                                         chunkInNAND,
35                                                                         buffer,
36                                                                         tags);
37 }
38
39 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
40                                                    int chunkInNAND,
41                                                    const __u8 * buffer,
42                                                    yaffs_ExtendedTags * tags)
43 {
44         chunkInNAND -= dev->chunkOffset;
45
46         
47         if (tags) {
48                 tags->sequenceNumber = dev->sequenceNumber;
49                 tags->chunkUsed = 1;
50                 if (!yaffs_ValidateTags(tags)) {
51                         T(YAFFS_TRACE_ERROR,
52                           (TSTR("Writing uninitialised tags" TENDSTR)));
53                         YBUG();
54                 }
55                 T(YAFFS_TRACE_WRITE,
56                   (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
57                    tags->objectId, tags->chunkId));
58         } else {
59                 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
60                 YBUG();
61         }
62
63         if (dev->writeChunkWithTagsToNAND)
64                 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
65                                                      tags);
66         else
67                 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
68                                                                        chunkInNAND,
69                                                                        buffer,
70                                                                        tags);
71 }
72
73 int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
74 {
75         blockNo -= dev->blockOffset;
76
77 ;
78         if (dev->markNANDBlockBad)
79                 return dev->markNANDBlockBad(dev, blockNo);
80         else
81                 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
82 }
83
84 int yaffs_QueryInitialBlockState(yaffs_Device * dev,
85                                                  int blockNo,
86                                                  yaffs_BlockState * state,
87                                                  unsigned *sequenceNumber)
88 {
89         blockNo -= dev->blockOffset;
90
91         if (dev->queryNANDBlock)
92                 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
93         else
94                 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
95                                                              state,
96                                                              sequenceNumber);
97 }
98
99
100 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
101                                   int blockInNAND)
102 {
103         int result;
104
105         blockInNAND -= dev->blockOffset;
106
107
108         dev->nBlockErasures++;
109         result = dev->eraseBlockInNAND(dev, blockInNAND);
110
111         /* If at first we don't succeed, try again *once*.*/
112         if (!result)
113                 result = dev->eraseBlockInNAND(dev, blockInNAND);       
114         return result;
115 }
116
117 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
118 {
119         return dev->initialiseNAND(dev);
120 }
121
122
123