1a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org/* 2a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * YAFFS: Yet another FFS. A NAND-flash specific file system. 3a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * yaffs_mtdif.c NAND mtd wrapper functions. 4a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * 5a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * Copyright (C) 2002 Aleph One Ltd. 6a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * for Toby Churchill Ltd and Brightstar Engineering 7a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * 8a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * Created by Charles Manning <charles@aleph1.co.uk> 9a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * 10a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * This program is free software; you can redistribute it and/or modify 11a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * it under the terms of the GNU General Public License version 2 as 12a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * published by the Free Software Foundation. 13a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org * 14a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org */ 157e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 167e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org/* mtd interface for YAFFS2 */ 17a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 1874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.orgconst char *yaffs_mtdif2_c_version = 19a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org "$Id: yaffs_mtdif2.c,v 1.14 2006/10/03 10:13:03 charles Exp $"; 207e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 217e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org#include "yportenv.h" 227e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 237e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 247e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org#include "yaffs_mtdif2.h" 257e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 26a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org#include "linux/mtd/mtd.h" 27a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org#include "linux/types.h" 28a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org#include "linux/time.h" 2901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 3001d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org#include "yaffs_packedtags2.h" 317e87822cf6f75bb60c3d47cfb7d76c98b0ad6d6astefan@webrtc.org 3201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 3374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.orgvoid nandmtd2_pt2buf(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw) 3474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org{ 3574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 36a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org __u8 *ptab = (__u8 *)pt; /* packed tags as bytes */ 37c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org 3872cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org int i, j = 0, k, n; 3972cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org#ifdef CONFIG_YAFFS_DOES_ECC 4072cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org size_t packed_size = sizeof(yaffs_PackedTags2); 4172cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org#else 4272cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org size_t packed_size = sizeof(yaffs_PackedTags2TagsPart); 4372cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org#endif 4472cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org 45c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org /* Pack buffer with 0xff */ 46c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org for (i = 0; i < mtd->oobsize; i++) 47c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org dev->spareBuffer[i] = 0xff; 4872cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org 4972cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org if(!is_raw){ 5072cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org memcpy(dev->spareBuffer,pt,packed_size); 51a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org } else { 52a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org j = 0; 53a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org k = mtd->ecclayout->oobfree[j].offset; 5474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org n = mtd->ecclayout->oobfree[j].length; 5574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 5674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org //printk("nandmtd2_pt2buf: writing %d bytes of extra data into %d\n", packed_size, mtd->oobsize); 5774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 5874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (n == 0) { 5974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR))); 60a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org YBUG(); 6101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 6201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 63a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org for (i = 0; i < packed_size; i++) { 6401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (n == 0) { 65a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org j++; 66a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org k = mtd->ecclayout->oobfree[j].offset; 67a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org n = mtd->ecclayout->oobfree[j].length; 6874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (n == 0 || j >= (sizeof(mtd->ecclayout->oobfree) / sizeof(mtd->ecclayout->oobfree[0]))) { 6974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR))); 7074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org YBUG(); 7174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 7274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 7374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org dev->spareBuffer[k] = ptab[i]; 7474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org k++; 7574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org n--; 7674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 77a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org } 78a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 79a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org} 80a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 81a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.orgvoid nandmtd2_buf2pt(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw) 8201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org{ 8301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 84a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org int i, j = 0, k, n; 85a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org __u8 *ptab = (__u8 *)pt; /* packed tags as bytes */ 86a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org size_t packed_size = dev->useNANDECC ? sizeof(yaffs_PackedTags2TagsPart) : sizeof(yaffs_PackedTags2); 8701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 88a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org if (!is_raw) { 8901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 9074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org memcpy(pt,dev->spareBuffer,packed_size); 9174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } else { 9201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org j = 0; 9301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org k = mtd->ecclayout->oobfree[j].offset; 9401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org n = mtd->ecclayout->oobfree[j].length; 9501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 9601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (n == 0) { 9701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR))); 9801d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org YBUG(); 9901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 10001d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 10101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org for (i = 0; i < packed_size; i++) { 10201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (n == 0) { 10301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org j++; 10401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org k = mtd->ecclayout->oobfree[j].offset; 10501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org n = mtd->ecclayout->oobfree[j].length; 10601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (n == 0 || j >= (sizeof(mtd->ecclayout->oobfree) / sizeof(mtd->ecclayout->oobfree[0]))) { 10701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR))); 10801d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org YBUG(); 10901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 1104a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org } 1114a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org ptab[i] = dev->spareBuffer[k]; 1124a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org k++; 11301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org n--; 11401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 11501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 11601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 1174a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org} 1184a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org 1194a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.orgint nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, 1204a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org const __u8 * data, 1214a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org const yaffs_ExtendedTags * tags) 1224a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org{ 1234a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 1244a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) 1254a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org struct mtd_oob_ops ops; 12674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#else 12774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org size_t dummy; 12874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#endif 12974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org int retval = 0; 13074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 13174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; 132a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 133a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org yaffs_PackedTags2 pt; 134a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 135a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org T(YAFFS_TRACE_MTD, 136a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org (TSTR 137a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" 138a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org TENDSTR), chunkInNAND, data, tags)); 13901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 14001d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) 14101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (tags) 14201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org yaffs_PackTags2(&pt, tags); 14374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org else 144903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.org BUG(); /* both tags and data should always be present */ 14501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 14674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org nandmtd2_pt2buf(dev, &pt, 1); 14774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (data) { 14874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.mode = MTD_OOB_AUTO; 14974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.ooblen = mtd->oobsize; 15074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.len = dev->nDataBytesPerChunk; 15174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.ooboffs = 0; 15274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.datbuf = (__u8 *)data; 15374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.oobbuf = dev->spareBuffer; 15474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = mtd->write_oob(mtd, addr, &ops); 15574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } else 15601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org BUG(); /* both tags and data should always be present */ 15701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org#else 15874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (tags) { 159903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.org yaffs_PackTags2(&pt, tags); 16001d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 16101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 16201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (tags) { 16301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org nandmtd2_pt2buf(dev, &pt, 1); 164a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org retval = 165a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, 16601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org &dummy, data, dev->spareBuffer, NULL); 16701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } else if (data) { 16874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = 16974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy, 17074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org data); 17174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 17274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#endif 17374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 17474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (retval == 0) 17574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org return YAFFS_OK; 17674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org else 17774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org return YAFFS_FAIL; 17874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org} 17974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 18074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.orgint nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, 18174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org __u8 * data, yaffs_ExtendedTags * tags) 18274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org{ 18374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 18474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) 18574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org struct mtd_oob_ops ops; 18674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#endif 18774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org size_t dummy; 18874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org int retval = 0; 18974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 19074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; 19174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 19274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org yaffs_PackedTags2 pt; 19374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 19474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org T(YAFFS_TRACE_MTD, 19574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org (TSTR 19674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" 19774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org TENDSTR), chunkInNAND, data, tags)); 19874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 199a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) 200a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org if (data && !tags) 20174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk, 20274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org &dummy, data); 20374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org else if (tags) { 20474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.mode = MTD_OOB_AUTO; 20574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.ooblen = mtd->oobsize; 20674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.len = data ? dev->nDataBytesPerChunk : mtd->oobsize; 20774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.ooboffs = 0; 20874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.datbuf = data; 20974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org ops.oobbuf = dev->spareBuffer; 21074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = mtd->read_oob(mtd, addr, &ops); 21174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org nandmtd2_buf2pt(dev, &pt, 1); 21274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 21374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#else 21474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (data && tags) { 21574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = 21674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, 21774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org &dummy, data, dev->spareBuffer, 21874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org NULL); 21974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } else { 22074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = 22174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, 22274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org &dummy, data, dev->spareBuffer, 22374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org NULL); 22474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 22574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } else { 22674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (data) 22774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = 22874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy, 22974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org data); 23074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (tags) { 23174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org retval = 23274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org mtd->read_oob(mtd, addr, mtd->oobsize, &dummy, 23374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org dev->spareBuffer); 23474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org nandmtd2_buf2pt(dev, &pt, 1); 23574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 23674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org } 23774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org#endif 23874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 23974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (tags) 24074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org yaffs_UnpackTags2(tags, &pt); 24174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 24274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) 24374257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; 24474257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 24574257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org if (retval == 0) 24674257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org return YAFFS_OK; 24774257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org else 24874257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org return YAFFS_FAIL; 24974257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org} 25074257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org 25174257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.orgint nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) 25274257108b4a17f3aeff1756b1f5bf45f971b6caeasapersson@webrtc.org{ 253a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 254fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org int retval; 255a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org T(YAFFS_TRACE_MTD, 256a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo)); 25701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 258a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org retval = 25901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org mtd->block_markbad(mtd, 260a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org blockNo * dev->nChunksPerBlock * 26101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org dev->nDataBytesPerChunk); 26201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 263a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org if (retval == 0) 26401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org return YAFFS_OK; 265a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org else 26601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org return YAFFS_FAIL; 267a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 268a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org} 269a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org 270a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.orgint nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, 271a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org yaffs_BlockState * state, int *sequenceNumber) 272a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org{ 27301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); 27401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org int retval; 27501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 27601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org T(YAFFS_TRACE_MTD, 27701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo)); 27801d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org retval = 279a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org mtd->block_isbad(mtd, 280a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org blockNo * dev->nChunksPerBlock * 281a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org dev->nDataBytesPerChunk); 28201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 2835041831648212bfd5b68e91e1ff39e2b420f679easapersson@webrtc.org if (retval) { 2845041831648212bfd5b68e91e1ff39e2b420f679easapersson@webrtc.org T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR))); 28501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 28601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org *state = YAFFS_BLOCK_STATE_DEAD; 28701d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org *sequenceNumber = 0; 28801d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } else { 28901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org yaffs_ExtendedTags t; 290a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org nandmtd2_ReadChunkWithTagsFromNAND(dev, 291a2d942a1e99a150f42f23ef2d6342c91a756dbb0asapersson@webrtc.org blockNo * 2923dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org dev->nChunksPerBlock, NULL, 29301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org &t); 29401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 29501d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org if (t.chunkUsed) { 2963dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org *sequenceNumber = t.sequenceNumber; 2973dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; 29872cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org } else { 29901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org *sequenceNumber = 0; 30072cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org *state = YAFFS_BLOCK_STATE_EMPTY; 30101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 30201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 30372cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org T(YAFFS_TRACE_MTD, 30401d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org (TSTR("block is OK seq %d state %d" TENDSTR), *sequenceNumber, 30572cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org *state)); 30601d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org } 30772cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org 30872cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org if (retval == 0) 30901d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org return YAFFS_OK; 31001d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org else 31101d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org return YAFFS_FAIL; 31201d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org} 31301d06c859328f3fb8c8521eede87063b05583208asapersson@webrtc.org 31472cc32a68bcb9b2aa32f751dc6d120716d220a10asapersson@webrtc.org