X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_mtdif1_single.c;h=467a0319f74ff4d8fda305d159539e86d589ba14;hp=02281fdb3d568fe71e18fdf11ca52e401b1d50a8;hb=8e0281ff8c5904d1dbb5b41f3cfadfb05f139437;hpb=757a553001be4016e9c5d8880648d3703f34b10e diff --git a/yaffs_mtdif1_single.c b/yaffs_mtdif1_single.c index 02281fd..467a031 100644 --- a/yaffs_mtdif1_single.c +++ b/yaffs_mtdif1_single.c @@ -1,7 +1,7 @@ /* * YAFFS: Yet another FFS. 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 @@ -30,19 +30,11 @@ #include "yaffs_packedtags1.h" #include "yaffs_tagscompat.h" /* for yaffs_calc_tags_ecc */ #include "yaffs_linux.h" - #include "linux/kernel.h" #include "linux/version.h" #include "linux/types.h" #include "linux/mtd/mtd.h" -#ifndef CONFIG_YAFFS_9BYTE_TAGS -# define YTAG1_SIZE 8 -#else -# define YTAG1_SIZE 9 -#endif - - /* Write a chunk (page) of data to NAND. * * Caller always provides ExtendedTags data which are converted to a more @@ -65,11 +57,12 @@ * Returns YAFFS_OK or YAFFS_FAIL. */ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, - int nand_chunk, const u8 *data, const struct yaffs_ext_tags *etags) + int nand_chunk, const u8 *data, + const struct yaffs_ext_tags *etags) { struct mtd_info *mtd = yaffs_dev_to_mtd(dev); int chunk_bytes = dev->data_bytes_per_chunk; - loff_t addr = ((loff_t)nand_chunk) * chunk_bytes; + loff_t addr = ((loff_t) nand_chunk) * chunk_bytes; struct mtd_oob_ops ops; struct yaffs_packed_tags1 pt1; int retval; @@ -87,33 +80,34 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, * that only zeroed-bits stick and set tag bytes to all-ones and * zero just the (not) deleted bit. */ -#ifndef CONFIG_YAFFS_9BYTE_TAGS - if (etags->is_deleted) { - memset(&pt1, 0xff, 8); - /* clear delete status bit to indicate deleted */ - pt1.deleted = 0; - } -#else - ((u8 *)&pt1)[8] = 0xff; - if (etags->is_deleted) { - memset(&pt1, 0xff, 8); - /* zero page_status byte to indicate deleted */ - ((u8 *)&pt1)[8] = 0; - } -#endif + + if(dev->param.tags_9bytes) { + ((u8 *) &pt1)[8] = 0xff; + if (etags->is_deleted) { + memset(&pt1, 0xff, 8); + /* zero page_status byte to indicate deleted */ + ((u8 *) &pt1)[8] = 0; + } + } else { + if (etags->is_deleted) { + memset(&pt1, 0xff, 8); + /* clear delete status bit to indicate deleted */ + pt1.deleted = 0; + } + } memset(&ops, 0, sizeof(ops)); ops.mode = MTD_OOB_AUTO; ops.len = (data) ? chunk_bytes : 0; - ops.ooblen = YTAG1_SIZE; - ops.datbuf = (u8 *)data; - ops.oobbuf = (u8 *)&pt1; + ops.ooblen = dev->param.tags_9bytes ? 9 : 8; + ops.datbuf = (u8 *) data; + ops.oobbuf = (u8 *) &pt1; retval = mtd->write_oob(mtd, addr, &ops); if (retval) { - T(YAFFS_TRACE_MTD, - (TSTR("write_oob failed, chunk %d, mtd error %d"TENDSTR), - nand_chunk, retval)); + yaffs_trace(YAFFS_TRACE_MTD, + "write_oob failed, chunk %d, mtd error %d", + nand_chunk, retval); } return retval ? YAFFS_FAIL : YAFFS_OK; } @@ -143,11 +137,12 @@ static int rettags(struct yaffs_ext_tags *etags, int ecc_result, int retval) * Returns YAFFS_OK or YAFFS_FAIL. */ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, - int nand_chunk, u8 *data, struct yaffs_ext_tags *etags) + int nand_chunk, u8 *data, + struct yaffs_ext_tags *etags) { struct mtd_info *mtd = yaffs_dev_to_mtd(dev); int chunk_bytes = dev->data_bytes_per_chunk; - loff_t addr = ((loff_t)nand_chunk) * chunk_bytes; + loff_t addr = ((loff_t) nand_chunk) * chunk_bytes; int eccres = YAFFS_ECC_RESULT_NO_ERROR; struct mtd_oob_ops ops; struct yaffs_packed_tags1 pt1; @@ -157,18 +152,18 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, memset(&ops, 0, sizeof(ops)); ops.mode = MTD_OOB_AUTO; ops.len = (data) ? chunk_bytes : 0; - ops.ooblen = YTAG1_SIZE; + ops.ooblen = dev->param.tags_9bytes ? 9 : 8; ops.datbuf = data; - ops.oobbuf = (u8 *)&pt1; + ops.oobbuf = (u8 *) &pt1; /* Read page and oob using MTD. * Check status and determine ECC result. */ retval = mtd->read_oob(mtd, addr, &ops); if (retval) { - T(YAFFS_TRACE_MTD, - (TSTR("read_oob failed, chunk %d, mtd error %d"TENDSTR), - nand_chunk, retval)); + yaffs_trace(YAFFS_TRACE_MTD, + "read_oob failed, chunk %d, mtd error %d", + nand_chunk, retval); } switch (retval) { @@ -188,17 +183,16 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, /* fall into... */ default: rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0); - etags->block_bad = (mtd->block_isbad)(mtd, addr); + etags->block_bad = (mtd->block_isbad) (mtd, addr); return YAFFS_FAIL; } /* Check for a blank/erased chunk. */ - if (yaffs_check_ff((u8 *)&pt1, 8)) { + if (yaffs_check_ff((u8 *) &pt1, 8)) { /* when blank, upper layers want ecc_result to be <= NO_ERROR */ return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK); } - #ifndef CONFIG_YAFFS_9BYTE_TAGS /* Read deleted status (bit) then return it to it's non-deleted * state before performing tags mini-ECC check. pt1.deleted is @@ -207,7 +201,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, deleted = !pt1.deleted; pt1.deleted = 1; #else - deleted = (yaffs_count_bits(((u8 *)&pt1)[8]) < 7); + deleted = (hweight8(((u8 *) &pt1)[8]) < 7); #endif /* Check the packed tags mini-ECC and correct if necessary/possible. @@ -232,7 +226,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, /* Unpack the tags to extended form and set ECC result. * [set should_be_ff just to keep yaffs_unpack_tags1 happy] */ - pt1.should_be_ff = 0xFFFFFFFF; + pt1.should_be_ff = 0xffffffff; yaffs_unpack_tags1(etags, &pt1); etags->ecc_result = eccres; @@ -254,9 +248,10 @@ int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no) int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk; int retval; - T(YAFFS_TRACE_BAD_BLOCKS,(TSTR("marking block %d bad"TENDSTR), block_no)); + yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, + "marking block %d bad", block_no); - retval = mtd->block_markbad(mtd, (loff_t)blocksize * block_no); + retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no); return (retval) ? YAFFS_FAIL : YAFFS_OK; } @@ -270,10 +265,10 @@ static int nandmtd1_test_prerequists(struct mtd_info *mtd) /* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */ int oobavail = mtd->ecclayout->oobavail; - if (oobavail < YTAG1_SIZE) { - T(YAFFS_TRACE_ERROR, - (TSTR("mtd device has only %d bytes for tags, need %d"TENDSTR), - oobavail, YTAG1_SIZE)); + if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) { + yaffs_trace(YAFFS_TRACE_ERROR, + "mtd device has only %d bytes for tags, need %d", + oobavail, (dev->param.tags_9bytes ? 9 : 8); return YAFFS_FAIL; } return YAFFS_OK; @@ -283,17 +278,17 @@ static int nandmtd1_test_prerequists(struct mtd_info *mtd) * * Examine the tags of the first chunk of the block and return the state: * - YAFFS_BLOCK_STATE_DEAD, the block is marked bad - * - YAFFS_BLOCK_STATE_NEEDS_SCANNING, the block is in use + * - YAFFS_BLOCK_STATE_NEEDS_SCAN, the block is in use * - YAFFS_BLOCK_STATE_EMPTY, the block is clean * * Always returns YAFFS_OK. */ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no, - enum yaffs_block_state *state_ptr, u32 *seq_ptr) + enum yaffs_block_state *state_ptr, u32 * seq_ptr) { struct mtd_info *mtd = yaffs_dev_to_mtd(dev); int chunk_num = block_no * dev->param.chunks_per_block; - loff_t addr = (loff_t)chunk_num * dev->data_bytes_per_chunk; + loff_t addr = (loff_t) chunk_num * dev->data_bytes_per_chunk; struct yaffs_ext_tags etags; int state = YAFFS_BLOCK_STATE_DEAD; int seqnum = 0; @@ -306,16 +301,16 @@ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no, return YAFFS_FAIL; retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags); - etags.block_bad = (mtd->block_isbad)(mtd, addr); + etags.block_bad = (mtd->block_isbad) (mtd, addr); if (etags.block_bad) { - T(YAFFS_TRACE_BAD_BLOCKS, - (TSTR("block %d is marked bad"TENDSTR), block_no)); + yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, + "block %d is marked bad", block_no); state = YAFFS_BLOCK_STATE_DEAD; } else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) { /* bad tags, need to look more closely */ - state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + state = YAFFS_BLOCK_STATE_NEEDS_SCAN; } else if (etags.chunk_used) { - state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + state = YAFFS_BLOCK_STATE_NEEDS_SCAN; seqnum = etags.seq_number; } else { state = YAFFS_BLOCK_STATE_EMPTY;