blob: ce048cc1851d363206297bbcf9ff1cc5f9493a47 [file] [log] [blame]
William Juul0e8cc8b2007-11-15 11:13:05 +01001/*
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 */
Wolfgang Denk4b070802008-08-14 14:41:06 +020013
William Juul90ef1172007-11-15 12:23:57 +010014/* XXX U-BOOT XXX */
15#include <common.h>
16
William Juul0e8cc8b2007-11-15 11:13:05 +010017const char *yaffs_nand_c_version =
18 "$Id: yaffs_nand.c,v 1.7 2007/02/14 01:09:06 wookey Exp $";
19
20#include "yaffs_nand.h"
21#include "yaffs_tagscompat.h"
22#include "yaffs_tagsvalidity.h"
23
24
25int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
26 __u8 * buffer,
27 yaffs_ExtendedTags * tags)
28{
29 int result;
30 yaffs_ExtendedTags localTags;
Wolfgang Denk4b070802008-08-14 14:41:06 +020031
William Juul0e8cc8b2007-11-15 11:13:05 +010032 int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
Wolfgang Denk4b070802008-08-14 14:41:06 +020033
William Juul0e8cc8b2007-11-15 11:13:05 +010034 /* 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,
Wolfgang Denk4b070802008-08-14 14:41:06 +020045 tags);
46 if(tags &&
William Juul0e8cc8b2007-11-15 11:13:05 +010047 tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
Wolfgang Denk4b070802008-08-14 14:41:06 +020048
William Juul0e8cc8b2007-11-15 11:13:05 +010049 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
Wolfgang Denk4b070802008-08-14 14:41:06 +020050 yaffs_HandleChunkError(dev,bi);
William Juul0e8cc8b2007-11-15 11:13:05 +010051 }
Wolfgang Denk4b070802008-08-14 14:41:06 +020052
William Juul0e8cc8b2007-11-15 11:13:05 +010053 return result;
54}
55
56int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
57 int chunkInNAND,
58 const __u8 * buffer,
59 yaffs_ExtendedTags * tags)
60{
61 chunkInNAND -= dev->chunkOffset;
62
Wolfgang Denk4b070802008-08-14 14:41:06 +020063
William Juul0e8cc8b2007-11-15 11:13:05 +010064 if (tags) {
65 tags->sequenceNumber = dev->sequenceNumber;
66 tags->chunkUsed = 1;
67 if (!yaffs_ValidateTags(tags)) {
68 T(YAFFS_TRACE_ERROR,
69 (TSTR("Writing uninitialised tags" TENDSTR)));
70 YBUG();
71 }
72 T(YAFFS_TRACE_WRITE,
73 (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
74 tags->objectId, tags->chunkId));
75 } else {
76 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
77 YBUG();
78 }
79
80 if (dev->writeChunkWithTagsToNAND)
81 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
82 tags);
83 else
84 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
85 chunkInNAND,
86 buffer,
87 tags);
88}
89
90int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
91{
92 blockNo -= dev->blockOffset;
93
94;
95 if (dev->markNANDBlockBad)
96 return dev->markNANDBlockBad(dev, blockNo);
97 else
98 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
99}
100
101int yaffs_QueryInitialBlockState(yaffs_Device * dev,
102 int blockNo,
103 yaffs_BlockState * state,
Wolfgang Denkfa00e032011-09-08 02:10:20 +0000104 int *sequenceNumber)
William Juul0e8cc8b2007-11-15 11:13:05 +0100105{
106 blockNo -= dev->blockOffset;
107
108 if (dev->queryNANDBlock)
109 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
110 else
111 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
112 state,
113 sequenceNumber);
114}
115
116
117int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
118 int blockInNAND)
119{
120 int result;
121
122 blockInNAND -= dev->blockOffset;
123
124
125 dev->nBlockErasures++;
126 result = dev->eraseBlockInNAND(dev, blockInNAND);
127
128 return result;
129}
130
131int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
132{
133 return dev->initialiseNAND(dev);
134}