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 int *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