|  | /* | 
|  | * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. | 
|  | * | 
|  | * Copyright (C) 2002-2007 Aleph One Ltd. | 
|  | *   for Toby Churchill Ltd and Brightstar Engineering | 
|  | * | 
|  | * Created by Charles Manning <charles@aleph1.co.uk> | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or modify | 
|  | * it under the terms of the GNU General Public License version 2 as | 
|  | * published by the Free Software Foundation. | 
|  | */ | 
|  |  | 
|  | /* XXX U-BOOT XXX */ | 
|  | #include <common.h> | 
|  |  | 
|  | const char *yaffs_nand_c_version = | 
|  | "$Id: yaffs_nand.c,v 1.7 2007/02/14 01:09:06 wookey Exp $"; | 
|  |  | 
|  | #include "yaffs_nand.h" | 
|  | #include "yaffs_tagscompat.h" | 
|  | #include "yaffs_tagsvalidity.h" | 
|  |  | 
|  |  | 
|  | int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, | 
|  | __u8 * buffer, | 
|  | yaffs_ExtendedTags * tags) | 
|  | { | 
|  | int result; | 
|  | yaffs_ExtendedTags localTags; | 
|  |  | 
|  | int realignedChunkInNAND = chunkInNAND - dev->chunkOffset; | 
|  |  | 
|  | /* If there are no tags provided, use local tags to get prioritised gc working */ | 
|  | if(!tags) | 
|  | tags = &localTags; | 
|  |  | 
|  | if (dev->readChunkWithTagsFromNAND) | 
|  | result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer, | 
|  | tags); | 
|  | else | 
|  | result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev, | 
|  | realignedChunkInNAND, | 
|  | buffer, | 
|  | tags); | 
|  | if(tags && | 
|  | tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){ | 
|  |  | 
|  | yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock); | 
|  | yaffs_HandleChunkError(dev,bi); | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev, | 
|  | int chunkInNAND, | 
|  | const __u8 * buffer, | 
|  | yaffs_ExtendedTags * tags) | 
|  | { | 
|  | chunkInNAND -= dev->chunkOffset; | 
|  |  | 
|  |  | 
|  | if (tags) { | 
|  | tags->sequenceNumber = dev->sequenceNumber; | 
|  | tags->chunkUsed = 1; | 
|  | if (!yaffs_ValidateTags(tags)) { | 
|  | T(YAFFS_TRACE_ERROR, | 
|  | (TSTR("Writing uninitialised tags" TENDSTR))); | 
|  | YBUG(); | 
|  | } | 
|  | T(YAFFS_TRACE_WRITE, | 
|  | (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND, | 
|  | tags->objectId, tags->chunkId)); | 
|  | } else { | 
|  | T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR))); | 
|  | YBUG(); | 
|  | } | 
|  |  | 
|  | if (dev->writeChunkWithTagsToNAND) | 
|  | return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer, | 
|  | tags); | 
|  | else | 
|  | return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev, | 
|  | chunkInNAND, | 
|  | buffer, | 
|  | tags); | 
|  | } | 
|  |  | 
|  | int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo) | 
|  | { | 
|  | blockNo -= dev->blockOffset; | 
|  |  | 
|  | ; | 
|  | if (dev->markNANDBlockBad) | 
|  | return dev->markNANDBlockBad(dev, blockNo); | 
|  | else | 
|  | return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo); | 
|  | } | 
|  |  | 
|  | int yaffs_QueryInitialBlockState(yaffs_Device * dev, | 
|  | int blockNo, | 
|  | yaffs_BlockState * state, | 
|  | unsigned *sequenceNumber) | 
|  | { | 
|  | blockNo -= dev->blockOffset; | 
|  |  | 
|  | if (dev->queryNANDBlock) | 
|  | return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber); | 
|  | else | 
|  | return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo, | 
|  | state, | 
|  | sequenceNumber); | 
|  | } | 
|  |  | 
|  |  | 
|  | int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, | 
|  | int blockInNAND) | 
|  | { | 
|  | int result; | 
|  |  | 
|  | blockInNAND -= dev->blockOffset; | 
|  |  | 
|  |  | 
|  | dev->nBlockErasures++; | 
|  | result = dev->eraseBlockInNAND(dev, blockInNAND); | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) | 
|  | { | 
|  | return dev->initialiseNAND(dev); | 
|  | } |