X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_nand.c;h=9afd5ec8e1c6cdf2233fc81264a69cf79cae4d28;hp=cb2a1629f2008e65a7efc176edc918cb712f14b5;hb=b813666977c08c925a4b62cee860470e7f4bc302;hpb=0333f489a25b05a4c0176258204eee1db9e8c9e0 diff --git a/yaffs_nand.c b/yaffs_nand.c index cb2a162..9afd5ec 100644 --- a/yaffs_nand.c +++ b/yaffs_nand.c @@ -1,7 +1,7 @@ /* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * - * Copyright (C) 2002-2010 Aleph One Ltd. + * Copyright (C) 2002-2011 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning @@ -13,127 +13,106 @@ #include "yaffs_nand.h" #include "yaffs_tagscompat.h" -#include "yaffs_tagsvalidity.h" #include "yaffs_getblockinfo.h" +#include "yaffs_summary.h" -int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, - __u8 *buffer, - yaffs_ExtendedTags *tags) +static int apply_chunk_offset(struct yaffs_dev *dev, int chunk) { - int result; - yaffs_ExtendedTags localTags; + return chunk - dev->chunk_offset; +} - int realignedChunkInNAND = chunkInNAND - dev->chunkOffset; +int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, + u8 *buffer, struct yaffs_ext_tags *tags) +{ + int result; + struct yaffs_ext_tags local_tags; + int flash_chunk = apply_chunk_offset(dev, nand_chunk); - dev->nPageReads++; + dev->n_page_reads++; - /* If there are no tags provided, use local tags to get prioritised gc working */ + /* If there are no tags provided use local tags. */ if (!tags) - tags = &localTags; - - if (dev->param.readChunkWithTagsFromNAND) - result = dev->param.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->param.nChunksPerBlock); - yaffs_HandleChunkError(dev, bi); - } + tags = &local_tags; + + result = dev->tagger.read_chunk_tags_fn(dev, flash_chunk, buffer, tags); + if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) { + struct yaffs_block_info *bi; + bi = yaffs_get_block_info(dev, + nand_chunk / + dev->param.chunks_per_block); + yaffs_handle_chunk_error(dev, bi); + } return result; } -int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev, - int chunkInNAND, - const __u8 *buffer, - yaffs_ExtendedTags *tags) +int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, + int nand_chunk, + const u8 *buffer, struct yaffs_ext_tags *tags) { + int result; + int flash_chunk = apply_chunk_offset(dev, nand_chunk); + + dev->n_page_writes++; - dev->nPageWrites++; - - 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 (!tags) { + yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags"); + BUG(); + return YAFFS_FAIL; } - if (dev->param.writeChunkWithTagsToNAND) - return dev->param.writeChunkWithTagsToNAND(dev, chunkInNAND, buffer, - tags); - else - return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev, - chunkInNAND, - buffer, - tags); -} + tags->seq_number = dev->seq_number; + tags->chunk_used = 1; + yaffs_trace(YAFFS_TRACE_WRITE, + "Writing chunk %d tags %d %d", + nand_chunk, tags->obj_id, tags->chunk_id); -int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo) -{ - blockNo -= dev->blockOffset; + result = dev->tagger.write_chunk_tags_fn(dev, flash_chunk, + buffer, tags); + yaffs_summary_add(dev, tags, nand_chunk); - if (dev->param.markNANDBlockBad) - return dev->param.markNANDBlockBad(dev, blockNo); - else - return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo); + return result; } -int yaffs_QueryInitialBlockState(yaffs_Device *dev, - int blockNo, - yaffs_BlockState *state, - __u32 *sequenceNumber) +int yaffs_mark_bad(struct yaffs_dev *dev, int block_no) { - blockNo -= dev->blockOffset; - - if (dev->param.queryNANDBlock) - return dev->param.queryNANDBlock(dev, blockNo, state, sequenceNumber); - else - return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo, - state, - sequenceNumber); + block_no -= dev->block_offset; + dev->n_bad_markings++; + return dev->tagger.mark_bad_fn(dev, block_no); } -int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, - int blockInNAND) +int yaffs_query_init_block_state(struct yaffs_dev *dev, + int block_no, + enum yaffs_block_state *state, + u32 *seq_number) { - int result; - - blockInNAND -= dev->blockOffset; - - dev->nBlockErasures++; + block_no -= dev->block_offset; + return dev->tagger.query_block_fn(dev, block_no, state, seq_number); +} - result = dev->param.eraseBlockInNAND(dev, blockInNAND); +int yaffs_erase_block(struct yaffs_dev *dev, int block_no) +{ + int result; + block_no -= dev->block_offset; + dev->n_erasures++; + result = dev->drv.drv_erase_fn(dev, block_no); return result; } -int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) +int yaffs_init_nand(struct yaffs_dev *dev) { - if(dev->param.initialiseNAND) - return dev->param.initialiseNAND(dev); + if (dev->drv.drv_initialise_fn) + return dev->drv.drv_initialise_fn(dev); return YAFFS_OK; } - - +int yaffs_deinit_nand(struct yaffs_dev *dev) +{ + if (dev->drv.drv_deinitialise_fn) + return dev->drv.drv_deinitialise_fn(dev); + return YAFFS_OK; +}