X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_tagscompat.c;h=14532b9483b600ca6f0a0c92c0d4a3ef476e608c;hp=e213a3114a48ef28dffef61365fe340987229bea;hb=HEAD;hpb=df88cf1097f3b7012fc1010cccd4e682fb13de97 diff --git a/yaffs_tagscompat.c b/yaffs_tagscompat.c index e213a31..14532b9 100644 --- a/yaffs_tagscompat.c +++ b/yaffs_tagscompat.c @@ -1,14 +1,16 @@ /* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering + * Copyright (C) 2002-2018 Aleph One Ltd. * * Created by Charles Manning * * 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 +18,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 +75,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 +106,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) @@ -263,7 +280,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 +320,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,6 +368,7 @@ static int yaffs_tags_compat_query_block(struct yaffs_dev *dev, *seq_number = 0; + /* 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, @@ -369,12 +388,12 @@ void yaffs_tags_compat_install(struct yaffs_dev *dev) { if(dev->param.is_yaffs2) return; - if(!dev->th.write_chunk_tags_fn) - dev->th.write_chunk_tags_fn = yaffs_tags_compat_wr; - if(!dev->th.read_chunk_tags_fn) - dev->th.read_chunk_tags_fn = yaffs_tags_compat_rd; - if(!dev->th.query_block_fn) - dev->th.query_block_fn = yaffs_tags_compat_query_block; - if(!dev->th.mark_bad_fn) - dev->th.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; }