xref: /openbmc/u-boot/fs/yaffs2/yaffs_nand.c (revision 74d9c16a)
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 /* XXX U-BOOT XXX */
15 #include <common.h>
16 
17 const 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 
25 int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
26 					   __u8 * buffer,
27 					   yaffs_ExtendedTags * tags)
28 {
29 	int result;
30 	yaffs_ExtendedTags localTags;
31 
32 	int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
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 
56 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
57 						   int chunkInNAND,
58 						   const __u8 * buffer,
59 						   yaffs_ExtendedTags * tags)
60 {
61 	chunkInNAND -= dev->chunkOffset;
62 
63 
64 	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 
90 int 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 
101 int yaffs_QueryInitialBlockState(yaffs_Device * dev,
102 						 int blockNo,
103 						 yaffs_BlockState * state,
104 						 unsigned *sequenceNumber)
105 {
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 
117 int 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 
131 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
132 {
133 	return dev->initialiseNAND(dev);
134 }
135