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: yaffs_nand.c,v 1.7 2007/02/14 01:09:06 wookey Exp $"; 16 17 #include "yaffs_nand.h" 18 #include "yaffs_tagscompat.h" 19 #include "yaffs_tagsvalidity.h" 20 21 22 int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, 23 __u8 * buffer, 24 yaffs_ExtendedTags * tags) 25 { 26 int result; 27 yaffs_ExtendedTags localTags; 28 29 int realignedChunkInNAND = chunkInNAND - dev->chunkOffset; 30 31 /* If there are no tags provided, use local tags to get prioritised gc working */ 32 if(!tags) 33 tags = &localTags; 34 35 if (dev->readChunkWithTagsFromNAND) 36 result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer, 37 tags); 38 else 39 result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev, 40 realignedChunkInNAND, 41 buffer, 42 tags); 43 if(tags && 44 tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){ 45 46 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock); 47 yaffs_HandleChunkError(dev,bi); 48 } 49 50 return result; 51 } 52 53 int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev, 54 int chunkInNAND, 55 const __u8 * buffer, 56 yaffs_ExtendedTags * tags) 57 { 58 chunkInNAND -= dev->chunkOffset; 59 60 61 if (tags) { 62 tags->sequenceNumber = dev->sequenceNumber; 63 tags->chunkUsed = 1; 64 if (!yaffs_ValidateTags(tags)) { 65 T(YAFFS_TRACE_ERROR, 66 (TSTR("Writing uninitialised tags" TENDSTR))); 67 YBUG(); 68 } 69 T(YAFFS_TRACE_WRITE, 70 (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND, 71 tags->objectId, tags->chunkId)); 72 } else { 73 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR))); 74 YBUG(); 75 } 76 77 if (dev->writeChunkWithTagsToNAND) 78 return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer, 79 tags); 80 else 81 return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev, 82 chunkInNAND, 83 buffer, 84 tags); 85 } 86 87 int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo) 88 { 89 blockNo -= dev->blockOffset; 90 91 ; 92 if (dev->markNANDBlockBad) 93 return dev->markNANDBlockBad(dev, blockNo); 94 else 95 return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo); 96 } 97 98 int yaffs_QueryInitialBlockState(yaffs_Device * dev, 99 int blockNo, 100 yaffs_BlockState * state, 101 unsigned *sequenceNumber) 102 { 103 blockNo -= dev->blockOffset; 104 105 if (dev->queryNANDBlock) 106 return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber); 107 else 108 return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo, 109 state, 110 sequenceNumber); 111 } 112 113 114 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, 115 int blockInNAND) 116 { 117 int result; 118 119 blockInNAND -= dev->blockOffset; 120 121 122 dev->nBlockErasures++; 123 result = dev->eraseBlockInNAND(dev, blockInNAND); 124 125 return result; 126 } 127 128 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) 129 { 130 return dev->initialiseNAND(dev); 131 } 132 133 134 135