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$";
16
17 #include "yaffs_nand.h"
18 #include "yaffs_tagscompat.h"
19 #include "yaffs_tagsvalidity.h"
20
21 #include "yaffs_getblockinfo.h"
22
yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev,int chunkInNAND,__u8 * buffer,yaffs_ExtendedTags * tags)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
yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,int chunkInNAND,const __u8 * buffer,yaffs_ExtendedTags * tags)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
yaffs_MarkBlockBad(yaffs_Device * dev,int blockNo)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
yaffs_QueryInitialBlockState(yaffs_Device * dev,int blockNo,yaffs_BlockState * state,__u32 * sequenceNumber)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
yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct * dev,int blockInNAND)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
yaffs_InitialiseNAND(struct yaffs_DeviceStruct * dev)134 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
135 {
136 return dev->initialiseNAND(dev);
137 }
138
139
140
141