1 /* 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. 3 * 4 * Copyright (C) 2002-2011 Aleph One Ltd. 5 * for Toby Churchill Ltd and Brightstar Engineering 6 * 7 * Created by Charles Manning <charles@aleph1.co.uk> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14 #include "yaffs_nand.h" 15 #include "yaffs_tagscompat.h" 16 17 #include "yaffs_getblockinfo.h" 18 #include "yaffs_summary.h" 19 20 int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, 21 u8 *buffer, struct yaffs_ext_tags *tags) 22 { 23 int result; 24 struct yaffs_ext_tags local_tags; 25 int flash_chunk = nand_chunk - dev->chunk_offset; 26 27 dev->n_page_reads++; 28 29 /* If there are no tags provided use local tags. */ 30 if (!tags) 31 tags = &local_tags; 32 33 if (dev->param.read_chunk_tags_fn) 34 result = 35 dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer, 36 tags); 37 else 38 result = yaffs_tags_compat_rd(dev, 39 flash_chunk, buffer, tags); 40 if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) { 41 42 struct yaffs_block_info *bi; 43 bi = yaffs_get_block_info(dev, 44 nand_chunk / 45 dev->param.chunks_per_block); 46 yaffs_handle_chunk_error(dev, bi); 47 } 48 return result; 49 } 50 51 int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, 52 int nand_chunk, 53 const u8 *buffer, struct yaffs_ext_tags *tags) 54 { 55 int result; 56 int flash_chunk = nand_chunk - dev->chunk_offset; 57 58 dev->n_page_writes++; 59 60 if (tags) { 61 tags->seq_number = dev->seq_number; 62 tags->chunk_used = 1; 63 yaffs_trace(YAFFS_TRACE_WRITE, 64 "Writing chunk %d tags %d %d", 65 nand_chunk, tags->obj_id, tags->chunk_id); 66 } else { 67 yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags"); 68 BUG(); 69 return YAFFS_FAIL; 70 } 71 72 if (dev->param.write_chunk_tags_fn) 73 result = dev->param.write_chunk_tags_fn(dev, flash_chunk, 74 buffer, tags); 75 else 76 result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags); 77 78 yaffs_summary_add(dev, tags, nand_chunk); 79 80 return result; 81 } 82 83 int yaffs_mark_bad(struct yaffs_dev *dev, int block_no) 84 { 85 block_no -= dev->block_offset; 86 if (dev->param.bad_block_fn) 87 return dev->param.bad_block_fn(dev, block_no); 88 89 return yaffs_tags_compat_mark_bad(dev, block_no); 90 } 91 92 int yaffs_query_init_block_state(struct yaffs_dev *dev, 93 int block_no, 94 enum yaffs_block_state *state, 95 u32 *seq_number) 96 { 97 block_no -= dev->block_offset; 98 if (dev->param.query_block_fn) 99 return dev->param.query_block_fn(dev, block_no, state, 100 seq_number); 101 102 return yaffs_tags_compat_query_block(dev, block_no, state, seq_number); 103 } 104 105 int yaffs_erase_block(struct yaffs_dev *dev, int flash_block) 106 { 107 int result; 108 109 flash_block -= dev->block_offset; 110 dev->n_erasures++; 111 result = dev->param.erase_fn(dev, flash_block); 112 return result; 113 } 114 115 int yaffs_init_nand(struct yaffs_dev *dev) 116 { 117 if (dev->param.initialise_flash_fn) 118 return dev->param.initialise_flash_fn(dev); 119 return YAFFS_OK; 120 } 121