• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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