1/* 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. 3 * 4 * Copyright (C) 2002-2010 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#include "yaffs_tagsvalidity.h" 17 18#include "yaffs_getblockinfo.h" 19 20int yaffs_rd_chunk_tags_nand(yaffs_dev_t *dev, int nand_chunk, 21 __u8 *buffer, 22 yaffs_ext_tags *tags) 23{ 24 int result; 25 yaffs_ext_tags localTags; 26 27 int realignedChunkInNAND = nand_chunk - dev->chunk_offset; 28 29 dev->n_page_reads++; 30 31 /* If there are no tags provided, use local tags to get prioritised gc working */ 32 if (!tags) 33 tags = &localTags; 34 35 if (dev->param.read_chunk_tags_fn) 36 result = dev->param.read_chunk_tags_fn(dev, realignedChunkInNAND, buffer, 37 tags); 38 else 39 result = yaffs_tags_compat_rd(dev, 40 realignedChunkInNAND, 41 buffer, 42 tags); 43 if (tags && 44 tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) { 45 46 yaffs_block_info_t *bi; 47 bi = yaffs_get_block_info(dev, nand_chunk/dev->param.chunks_per_block); 48 yaffs_handle_chunk_error(dev, bi); 49 } 50 51 return result; 52} 53 54int yaffs_wr_chunk_tags_nand(yaffs_dev_t *dev, 55 int nand_chunk, 56 const __u8 *buffer, 57 yaffs_ext_tags *tags) 58{ 59 60 dev->n_page_writes++; 61 62 nand_chunk -= dev->chunk_offset; 63 64 65 if (tags) { 66 tags->seq_number = dev->seq_number; 67 tags->chunk_used = 1; 68 if (!yaffs_validate_tags(tags)) { 69 T(YAFFS_TRACE_ERROR, 70 (TSTR("Writing uninitialised tags" TENDSTR))); 71 YBUG(); 72 } 73 T(YAFFS_TRACE_WRITE, 74 (TSTR("Writing chunk %d tags %d %d" TENDSTR), nand_chunk, 75 tags->obj_id, tags->chunk_id)); 76 } else { 77 T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR))); 78 YBUG(); 79 } 80 81 if (dev->param.write_chunk_tags_fn) 82 return dev->param.write_chunk_tags_fn(dev, nand_chunk, buffer, 83 tags); 84 else 85 return yaffs_tags_compat_wr(dev, 86 nand_chunk, 87 buffer, 88 tags); 89} 90 91int yaffs_mark_bad(yaffs_dev_t *dev, int block_no) 92{ 93 block_no -= dev->block_offset; 94 95 96 if (dev->param.bad_block_fn) 97 return dev->param.bad_block_fn(dev, block_no); 98 else 99 return yaffs_tags_compat_mark_bad(dev, block_no); 100} 101 102int yaffs_query_init_block_state(yaffs_dev_t *dev, 103 int block_no, 104 yaffs_block_state_t *state, 105 __u32 *seq_number) 106{ 107 block_no -= dev->block_offset; 108 109 if (dev->param.query_block_fn) 110 return dev->param.query_block_fn(dev, block_no, state, seq_number); 111 else 112 return yaffs_tags_compat_query_block(dev, block_no, 113 state, 114 seq_number); 115} 116 117 118int yaffs_erase_block(struct yaffs_dev_s *dev, 119 int flash_block) 120{ 121 int result; 122 123 flash_block -= dev->block_offset; 124 125 dev->n_erasures++; 126 127 result = dev->param.erase_fn(dev, flash_block); 128 129 return result; 130} 131 132int yaffs_init_nand(struct yaffs_dev_s *dev) 133{ 134 if(dev->param.initialise_flash_fn) 135 return dev->param.initialise_flash_fn(dev); 136 return YAFFS_OK; 137} 138 139 140 141