X-Git-Url: https://yaffs.net/gitweb/?a=blobdiff_plain;f=yaffs_tagscompat.c;h=78781e638346f37d7138d7b87f366e5009ed95e0;hb=9c99932eb16ba64c6d3ba69145fe8c5d5b04274d;hp=35d33c91fcee285ec557bac232e909a5faee31e4;hpb=46eb953ecab322d3385ccf84c75d969de8542317;p=yaffs2.git diff --git a/yaffs_tagscompat.c b/yaffs_tagscompat.c index 35d33c9..78781e6 100644 --- a/yaffs_tagscompat.c +++ b/yaffs_tagscompat.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 @@ -22,10 +22,10 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk); /********** Tags ECC calculations *********/ -void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare) +static void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare) { - yaffs_ecc_cacl(data, spare->ecc1); - yaffs_ecc_cacl(&data[256], spare->ecc2); + yaffs_ecc_calc(data, spare->ecc1); + yaffs_ecc_calc(&data[256], spare->ecc2); } void yaffs_calc_tags_ecc(struct yaffs_tags *tags) @@ -120,13 +120,17 @@ static void yaffs_get_tags_from_spare(struct yaffs_dev *dev, static void yaffs_spare_init(struct yaffs_spare *spare) { - memset(spare, 0xFF, sizeof(struct yaffs_spare)); + memset(spare, 0xff, sizeof(struct yaffs_spare)); } static int yaffs_wr_nand(struct yaffs_dev *dev, int nand_chunk, const u8 *data, struct yaffs_spare *spare) { + int data_size; + int spare_size; + u8 spare_buffer[100]; + if (nand_chunk < dev->param.start_block * dev->param.chunks_per_block) { yaffs_trace(YAFFS_TRACE_ERROR, "**>> yaffs chunk %d is not valid", @@ -134,7 +138,11 @@ static int yaffs_wr_nand(struct yaffs_dev *dev, return YAFFS_FAIL; } - return dev->param.write_chunk_fn(dev, nand_chunk, data, spare); + /* Format up the spare */ + + return dev->param.drv_write_chunk_fn(dev, nand_chunk, + data, data_size, + spare_buffer, spare_size); } static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, @@ -146,6 +154,8 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, { int ret_val; struct yaffs_spare local_spare; + int data_size; + int spare_size; if (!spare) { /* If we don't have a real spare, then we use a local one. */ @@ -155,17 +165,20 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, if (!dev->param.use_nand_ecc) { ret_val = - dev->param.read_chunk_fn(dev, nand_chunk, data, spare); + dev->param.drv_read_chunk_fn(dev, nand_chunk, + data, data_size, + (u8 *)spare, spare_size, + ecc_result); if (data && correct_errors) { /* Do ECC correction */ /* Todo handle any errors */ int ecc_result1, ecc_result2; u8 calc_ecc[3]; - yaffs_ecc_cacl(data, calc_ecc); + yaffs_ecc_calc(data, calc_ecc); ecc_result1 = yaffs_ecc_correct(data, spare->ecc1, calc_ecc); - yaffs_ecc_cacl(&data[256], calc_ecc); + yaffs_ecc_calc(&data[256], calc_ecc); ecc_result2 = yaffs_ecc_correct(&data[256], spare->ecc2, calc_ecc); @@ -213,9 +226,10 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, memset(&nspare, 0, sizeof(nspare)); - ret_val = dev->param.read_chunk_fn(dev, nand_chunk, data, - (struct yaffs_spare *) - &nspare); + ret_val = dev->param.drv_read_chunk_fn(dev, nand_chunk, + data, data_size, + (u8 *) &nspare, sizeof(nspare), + NULL); memcpy(spare, &nspare, sizeof(struct yaffs_spare)); if (data && correct_errors) { if (nspare.eccres1 > 0) { @@ -277,7 +291,7 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk) */ } -int yaffs_tags_compat_wr(struct yaffs_dev *dev, +static int yaffs_tags_compat_wr(struct yaffs_dev *dev, int nand_chunk, const u8 *data, const struct yaffs_ext_tags *ext_tags) { @@ -292,7 +306,7 @@ int yaffs_tags_compat_wr(struct yaffs_dev *dev, tags.obj_id = ext_tags->obj_id; tags.chunk_id = ext_tags->chunk_id; - tags.n_bytes_lsb = ext_tags->n_bytes & 0x3ff; + tags.n_bytes_lsb = ext_tags->n_bytes & (1024 - 1); if (dev->data_bytes_per_chunk >= 1024) tags.n_bytes_msb = (ext_tags->n_bytes >> 10) & 3; @@ -305,13 +319,11 @@ int yaffs_tags_compat_wr(struct yaffs_dev *dev, yaffs_calc_ecc(data, &spare); yaffs_load_tags_to_spare(&spare, &tags); - } - return yaffs_wr_nand(dev, nand_chunk, data, &spare); } -int yaffs_tags_compat_rd(struct yaffs_dev *dev, +static int yaffs_tags_compat_rd(struct yaffs_dev *dev, int nand_chunk, u8 *data, struct yaffs_ext_tags *ext_tags) { @@ -320,51 +332,47 @@ int yaffs_tags_compat_rd(struct yaffs_dev *dev, enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN; static struct yaffs_spare spare_ff; static int init; + int deleted; if (!init) { - memset(&spare_ff, 0xFF, sizeof(spare_ff)); + memset(&spare_ff, 0xff, sizeof(spare_ff)); init = 1; } - if (yaffs_rd_chunk_nand(dev, nand_chunk, - data, &spare, &ecc_result, 1)) { - /* ext_tags may be NULL */ - if (ext_tags) { - - int deleted = - (hweight8(spare.page_status) < 7) ? 1 : 0; + if (!yaffs_rd_chunk_nand(dev, nand_chunk, + data, &spare, &ecc_result, 1)) + return YAFFS_FAIL; - ext_tags->is_deleted = deleted; - ext_tags->ecc_result = ecc_result; - ext_tags->block_bad = 0; /* We're reading it */ - /* therefore it is not a bad block */ - ext_tags->chunk_used = - (memcmp(&spare_ff, &spare, sizeof(spare_ff)) != - 0) ? 1 : 0; + /* ext_tags may be NULL */ + if (!ext_tags) + return YAFFS_OK; - if (ext_tags->chunk_used) { - yaffs_get_tags_from_spare(dev, &spare, &tags); + deleted = (hweight8(spare.page_status) < 7) ? 1 : 0; - ext_tags->obj_id = tags.obj_id; - ext_tags->chunk_id = tags.chunk_id; - ext_tags->n_bytes = tags.n_bytes_lsb; + ext_tags->is_deleted = deleted; + ext_tags->ecc_result = ecc_result; + ext_tags->block_bad = 0; /* We're reading it */ + /* therefore it is not a bad block */ + ext_tags->chunk_used = + memcmp(&spare_ff, &spare, sizeof(spare_ff)) ? 1 : 0; - if (dev->data_bytes_per_chunk >= 1024) - ext_tags->n_bytes |= - (((unsigned)tags. - n_bytes_msb) << 10); + if (ext_tags->chunk_used) { + yaffs_get_tags_from_spare(dev, &spare, &tags); + ext_tags->obj_id = tags.obj_id; + ext_tags->chunk_id = tags.chunk_id; + ext_tags->n_bytes = tags.n_bytes_lsb; - ext_tags->serial_number = tags.serial_number; - } - } + if (dev->data_bytes_per_chunk >= 1024) + ext_tags->n_bytes |= + (((unsigned)tags.n_bytes_msb) << 10); - return YAFFS_OK; - } else { - return YAFFS_FAIL; + ext_tags->serial_number = tags.serial_number; } + + return YAFFS_OK; } -int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block) +static int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block) { struct yaffs_spare spare; @@ -380,7 +388,7 @@ int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block) return YAFFS_OK; } -int yaffs_tags_compat_query_block(struct yaffs_dev *dev, +static int yaffs_tags_compat_query_block(struct yaffs_dev *dev, int block_no, enum yaffs_block_state *state, u32 *seq_number) @@ -391,7 +399,7 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev, enum yaffs_ecc_result dummy; if (!init) { - memset(&spare_ff, 0xFF, sizeof(spare_ff)); + memset(&spare_ff, 0xff, sizeof(spare_ff)); init = 1; } @@ -407,7 +415,21 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev, else if (memcmp(&spare_ff, &spare0, sizeof(spare_ff)) == 0) *state = YAFFS_BLOCK_STATE_EMPTY; else - *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + *state = YAFFS_BLOCK_STATE_NEEDS_SCAN; return YAFFS_OK; } + +void yaffs_tags_compat_install(struct yaffs_dev *dev) +{ + if(dev->param.is_yaffs2) + return; + if(!dev->param.write_chunk_tags_fn) + dev->param.write_chunk_tags_fn = yaffs_tags_compat_wr; + if(!dev->param.read_chunk_tags_fn) + dev->param.read_chunk_tags_fn = yaffs_tags_compat_rd; + if(!dev->param.read_chunk_tags_fn) + dev->param.query_block_fn = yaffs_tags_compat_query_block; + if(!dev->param.mark_bad_fn) + dev->param.mark_bad_fn = yaffs_tags_compat_mark_bad; +}