X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_mtdif1_multi.c;h=3673891c3b4450f1f5dc5d9d37deafddcf579203;hp=c3ea8c9b90bdef21f7dff4c50bd05382e57527d5;hb=7715144e7d55b2854f907001c432348e4caa5954;hpb=5409719091c79983abc45bcc3070bce6786c8278 diff --git a/yaffs_mtdif1_multi.c b/yaffs_mtdif1_multi.c index c3ea8c9..3673891 100644 --- a/yaffs_mtdif1_multi.c +++ b/yaffs_mtdif1_multi.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 @@ -39,15 +39,10 @@ /* Don't compile this module if we don't have MTD's mtd_oob_ops interface */ #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) -#ifndef CONFIG_YAFFS_9BYTE_TAGS -# define YTAG1_SIZE 8 -#else -# define YTAG1_SIZE 9 -#endif #if 0 /* Use the following nand_ecclayout with MTD when using - * CONFIG_YAFFS_9BYTE_TAGS and the older on-NAND tags layout. + * 9 byte tags and the older on-NAND tags layout. * If you have existing Yaffs images and the byte order differs from this, * adjust 'oobfree' to match your existing Yaffs data. * @@ -64,7 +59,7 @@ static struct nand_ecclayout nand_oob_16 = { .eccbytes = 6, .eccpos = {8, 9, 10, 13, 14, 15}, .oobavail = 9, - .oobfree = {{0, 4}, {6, 2}, {11, 2}, {4, 1}} + .oobfree = {{0, 4}, {6, 2}, {11, 2}, {4, 1} } }; #endif @@ -90,7 +85,7 @@ static struct nand_ecclayout nand_oob_16 = { * Returns YAFFS_OK or YAFFS_FAIL. */ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, - int nand_chunk, const u8 * data, + int nand_chunk, const u8 *data, const struct yaffs_ext_tags *etags) { struct mtd_info *mtd = yaffs_dev_to_mtd(dev); @@ -113,33 +108,33 @@ 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; + 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; + } } -#endif 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 = (u8 *) data; - ops.oobbuf = (u8 *) & pt1; + 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; } @@ -169,7 +164,7 @@ 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, + int nand_chunk, u8 *data, struct yaffs_ext_tags *etags) { struct mtd_info *mtd = yaffs_dev_to_mtd(dev); @@ -184,9 +179,9 @@ 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; #if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20)) /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug; @@ -198,11 +193,10 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, * 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)); - } + if (retval) + yaffs_trace(YAFFS_TRACE_MTD, + "read_oob failed, chunk %d, mtd error %d", + nand_chunk, retval); switch (retval) { case 0: @@ -227,20 +221,21 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, /* 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 - * inverted. - */ - deleted = !pt1.deleted; - pt1.deleted = 1; -#else - deleted = (yaffs_count_bits(((u8 *) & pt1)[8]) < 7); -#endif + + if(dev->param.tags_9bytes) { + deleted = (hweight8(((u8 *) &pt1)[8]) < 7); + } else { + /* Read deleted status (bit) then return it to it's non-deleted + * state before performing tags mini-ECC check. pt1.deleted is + * inverted. + */ + deleted = !pt1.deleted; + pt1.deleted = 1; + } /* Check the packed tags mini-ECC and correct if necessary/possible. */ @@ -264,7 +259,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; @@ -286,8 +281,7 @@ 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); return (retval) ? YAFFS_FAIL : YAFFS_OK; @@ -297,17 +291,16 @@ int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no) * * Returns YAFFS_OK or YAFFS_FAIL. */ -static int nandmtd1_test_prerequists(struct mtd_info *mtd) +static int nandmtd1_test_prerequists(struct yaffs_dev *dev, struct mtd_info *mtd) { /* 2.6.18 has mtd->ecclayout->oobavail */ /* 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; @@ -317,7 +310,7 @@ 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. @@ -336,20 +329,21 @@ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no, /* We don't yet have a good place to test for MTD config prerequists. * Do it here as we are called during the initial scan. */ - if (nandmtd1_test_prerequists(mtd) != YAFFS_OK) + if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK) return YAFFS_FAIL; retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags); 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;