2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
3 * yaffs_mtdif.c NAND mtd wrapper functions.
5 * Copyright (C) 2002 Aleph One Ltd.
6 * for Toby Churchill Ltd and Brightstar Engineering
8 * Created by Charles Manning <charles@aleph1.co.uk>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
16 /* mtd interface for YAFFS2 */
18 const char *yaffs_mtdif2_c_version =
19 "$Id: yaffs_mtdif2.c,v 1.1 2006-05-25 01:37:27 charles Exp $";
24 #include "yaffs_mtdif2.h"
26 #include "linux/mtd/mtd.h"
27 #include "linux/types.h"
28 #include "linux/time.h"
30 #include "yaffs_packedtags2.h"
33 void nandmtd2_pt2buf(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw)
35 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
36 __u8 *ptab = (__u8 *)pt; /* packed tags as bytes */
40 /* Pack buffer with 0xff */
41 for (i = 0; i < mtd->oobsize; i++)
42 dev->spareBuffer[i] = 0xff;
45 memcpy(dev->spareBuffer,pt,sizeof(yaffs_PackedTags2));
48 k = mtd->oobinfo.oobfree[j][0];
49 n = mtd->oobinfo.oobfree[j][1];
52 T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR)));
56 for (i = 0; i < sizeof(yaffs_PackedTags2); i++) {
59 k = mtd->oobinfo.oobfree[j][0];
60 n = mtd->oobinfo.oobfree[j][1];
62 T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR)));
66 dev->spareBuffer[k] = ptab[i];
74 void nandmtd2_buf2pt(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw)
76 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
78 __u8 *ptab = (__u8 *)pt; /* packed tags as bytes */
83 memcpy(pt,dev->spareBuffer,sizeof(yaffs_PackedTags2));
86 k = mtd->oobinfo.oobfree[j][0];
87 n = mtd->oobinfo.oobfree[j][1];
90 T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR)));
94 for (i = 0; i < sizeof(yaffs_PackedTags2); i++) {
97 k = mtd->oobinfo.oobfree[j][0];
98 n = mtd->oobinfo.oobfree[j][1];
100 T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR)));
104 ptab[i] = dev->spareBuffer[k];
112 int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
114 const yaffs_ExtendedTags * tags)
116 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
120 loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk;
122 yaffs_PackedTags2 pt;
126 ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
127 TENDSTR), chunkInNAND, data, tags));
130 yaffs_PackTags2(&pt, tags);
134 nandmtd2_pt2buf(dev, &pt, 0);
136 mtd->write_ecc(mtd, addr, dev->nBytesPerChunk,
137 &dummy, data, dev->spareBuffer,
142 T(YAFFS_TRACE_ALWAYS,
144 ("Write chunk with null tags or data!" TENDSTR)));
154 int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
155 __u8 * data, yaffs_ExtendedTags * tags)
157 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
161 loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk;
163 yaffs_PackedTags2 pt;
167 ("nandmtd2_ReadChunkWithTagsToNAND chunk %d data %p tags %p"
168 TENDSTR), chunkInNAND, data, tags));
170 if (0 && data && tags) {
172 mtd->read_ecc(mtd, addr, dev->nBytesPerChunk,
173 &dummy, data, dev->spareBuffer,
175 nandmtd2_buf2pt(dev, &pt, 0);
179 mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy,
183 mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
185 nandmtd2_buf2pt(dev, &pt, 1);
190 yaffs_UnpackTags2(tags, &pt);
198 int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
200 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
203 (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo));
206 mtd->block_markbad(mtd,
207 blockNo * dev->nChunksPerBlock *
208 dev->nBytesPerChunk);
217 int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
218 yaffs_BlockState * state, int *sequenceNumber)
220 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
224 (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo));
226 mtd->block_isbad(mtd,
227 blockNo * dev->nChunksPerBlock *
228 dev->nBytesPerChunk);
231 T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
233 *state = YAFFS_BLOCK_STATE_DEAD;
236 yaffs_ExtendedTags t;
237 nandmtd2_ReadChunkWithTagsFromNAND(dev,
239 dev->nChunksPerBlock, NULL,
243 *sequenceNumber = t.sequenceNumber;
244 *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
247 *state = YAFFS_BLOCK_STATE_EMPTY;
251 (TSTR("block is OK seq %d state %d" TENDSTR), *sequenceNumber,