X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_tagscompat.c;h=e57c2d33f15f77e5ab1f001d64203cfdf3e8d21b;hp=3d72be4a3a1b87819ba59b501541c3cfbe03624d;hb=5bc32d099123b2e0e5f27f7421caa5413d3211f0;hpb=5587d9d89d5fb9c31fd723e85949f85da70ef3a9 diff --git a/yaffs_tagscompat.c b/yaffs_tagscompat.c index 3d72be4..e57c2d3 100644 --- a/yaffs_tagscompat.c +++ b/yaffs_tagscompat.c @@ -9,6 +9,9 @@ * 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. + * + * This file handles yaffs1-style tags to allow compatibility with Yaffs1 style + * flash layouts. */ #include "yaffs_guts.h" @@ -16,13 +19,13 @@ #include "yaffs_ecc.h" #include "yaffs_getblockinfo.h" #include "yaffs_trace.h" +#include "yaffs_endian.h" static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk); /********** Tags ECC calculations *********/ - void yaffs_calc_tags_ecc(struct yaffs_tags *tags) { /* Calculate an ecc */ @@ -73,21 +76,30 @@ int yaffs_check_tags_ecc(struct yaffs_tags *tags) /********** Tags **********/ -static void yaffs_load_tags_to_spare(struct yaffs_spare *spare_ptr, +/* + * During tags storing/retireval we use a copy of the tags so that + * we can modify the endian etc without damaging the previous structure. + */ +static void yaffs_load_tags_to_spare(struct yaffs_dev *dev, + struct yaffs_spare *spare_ptr, struct yaffs_tags *tags_ptr) { - union yaffs_tags_union *tu = (union yaffs_tags_union *)tags_ptr; - - yaffs_calc_tags_ecc(tags_ptr); - - spare_ptr->tb0 = tu->as_bytes[0]; - spare_ptr->tb1 = tu->as_bytes[1]; - spare_ptr->tb2 = tu->as_bytes[2]; - spare_ptr->tb3 = tu->as_bytes[3]; - spare_ptr->tb4 = tu->as_bytes[4]; - spare_ptr->tb5 = tu->as_bytes[5]; - spare_ptr->tb6 = tu->as_bytes[6]; - spare_ptr->tb7 = tu->as_bytes[7]; + union yaffs_tags_union *tu_ptr = (union yaffs_tags_union *)tags_ptr; + union yaffs_tags_union tags_stored = *tu_ptr; + + yaffs_calc_tags_ecc(&tags_stored.as_tags); + + yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); + yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); + + spare_ptr->tb0 = tags_stored.as_bytes[0]; + spare_ptr->tb1 = tags_stored.as_bytes[1]; + spare_ptr->tb2 = tags_stored.as_bytes[2]; + spare_ptr->tb3 = tags_stored.as_bytes[3]; + spare_ptr->tb4 = tags_stored.as_bytes[4]; + spare_ptr->tb5 = tags_stored.as_bytes[5]; + spare_ptr->tb6 = tags_stored.as_bytes[6]; + spare_ptr->tb7 = tags_stored.as_bytes[7]; } static void yaffs_get_tags_from_spare(struct yaffs_dev *dev, @@ -95,16 +107,22 @@ static void yaffs_get_tags_from_spare(struct yaffs_dev *dev, struct yaffs_tags *tags_ptr) { union yaffs_tags_union *tu = (union yaffs_tags_union *)tags_ptr; + union yaffs_tags_union tags_stored; int result; - tu->as_bytes[0] = spare_ptr->tb0; - tu->as_bytes[1] = spare_ptr->tb1; - tu->as_bytes[2] = spare_ptr->tb2; - tu->as_bytes[3] = spare_ptr->tb3; - tu->as_bytes[4] = spare_ptr->tb4; - tu->as_bytes[5] = spare_ptr->tb5; - tu->as_bytes[6] = spare_ptr->tb6; - tu->as_bytes[7] = spare_ptr->tb7; + tags_stored.as_bytes[0] = spare_ptr->tb0; + tags_stored.as_bytes[1] = spare_ptr->tb1; + tags_stored.as_bytes[2] = spare_ptr->tb2; + tags_stored.as_bytes[3] = spare_ptr->tb3; + tags_stored.as_bytes[4] = spare_ptr->tb4; + tags_stored.as_bytes[5] = spare_ptr->tb5; + tags_stored.as_bytes[6] = spare_ptr->tb6; + tags_stored.as_bytes[7] = spare_ptr->tb7; + + yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); + yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); + + *tu = tags_stored; result = yaffs_check_tags_ecc(tags_ptr); if (result > 0) @@ -124,7 +142,7 @@ static int yaffs_wr_nand(struct yaffs_dev *dev, { int data_size = dev->data_bytes_per_chunk; - return dev->param.drv_write_chunk_fn(dev, nand_chunk, + return dev->drv.drv_write_chunk_fn(dev, nand_chunk, data, data_size, (u8 *) spare, sizeof(*spare)); } @@ -152,7 +170,7 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, spare_size = sizeof(struct yaffs_spare); if (dev->param.use_nand_ecc) - return dev->param.drv_read_chunk_fn(dev, nand_chunk, + return dev->drv.drv_read_chunk_fn(dev, nand_chunk, data, data_size, (u8 *) spare, spare_size, ecc_result); @@ -160,7 +178,7 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, /* Handle the ECC at this level. */ - ret_val = dev->param.drv_read_chunk_fn(dev, nand_chunk, + ret_val = dev->drv.drv_read_chunk_fn(dev, nand_chunk, data, data_size, (u8 *)spare, spare_size, NULL); @@ -263,7 +281,7 @@ static int yaffs_tags_compat_wr(struct yaffs_dev *dev, yaffs_ecc_calc(&data[256], spare.ecc2); } - yaffs_load_tags_to_spare(&spare, &tags); + yaffs_load_tags_to_spare(dev, &spare, &tags); } return yaffs_wr_nand(dev, nand_chunk, data, &spare); } @@ -303,6 +321,7 @@ static int yaffs_tags_compat_rd(struct yaffs_dev *dev, 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; @@ -350,7 +369,8 @@ static int yaffs_tags_compat_query_block(struct yaffs_dev *dev, *seq_number = 0; - yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1, + /* Look for bad block markers in the first two chunks */ + yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block, NULL, &spare0, &dummy, 0); yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1, NULL, &spare1, &dummy, 0); @@ -369,12 +389,12 @@ 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.query_block_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; + if(!dev->tagger.write_chunk_tags_fn) + dev->tagger.write_chunk_tags_fn = yaffs_tags_compat_wr; + if(!dev->tagger.read_chunk_tags_fn) + dev->tagger.read_chunk_tags_fn = yaffs_tags_compat_rd; + if(!dev->tagger.query_block_fn) + dev->tagger.query_block_fn = yaffs_tags_compat_query_block; + if(!dev->tagger.mark_bad_fn) + dev->tagger.mark_bad_fn = yaffs_tags_compat_mark_bad; }