]>
Commit | Line | Data |
---|---|---|
0e8cc8bd WJ |
1 | /* |
2 | * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. | |
3 | * | |
753ac610 | 4 | * Copyright (C) 2002-2011 Aleph One Ltd. |
0e8cc8bd WJ |
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 | */ | |
4b070809 | 13 | |
0e8cc8bd WJ |
14 | #include "yaffs_nand.h" |
15 | #include "yaffs_tagscompat.h" | |
0e8cc8bd | 16 | |
753ac610 CM |
17 | #include "yaffs_getblockinfo.h" |
18 | #include "yaffs_summary.h" | |
0e8cc8bd | 19 | |
753ac610 CM |
20 | int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, |
21 | u8 *buffer, struct yaffs_ext_tags *tags) | |
0e8cc8bd WJ |
22 | { |
23 | int result; | |
753ac610 CM |
24 | struct yaffs_ext_tags local_tags; |
25 | int flash_chunk = nand_chunk - dev->chunk_offset; | |
4b070809 | 26 | |
753ac610 | 27 | dev->n_page_reads++; |
4b070809 | 28 | |
753ac610 CM |
29 | /* If there are no tags provided use local tags. */ |
30 | if (!tags) | |
31 | tags = &local_tags; | |
0e8cc8bd | 32 | |
753ac610 CM |
33 | if (dev->param.read_chunk_tags_fn) |
34 | result = | |
35 | dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer, | |
36 | tags); | |
0e8cc8bd | 37 | else |
753ac610 CM |
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); | |
0e8cc8bd | 47 | } |
0e8cc8bd WJ |
48 | return result; |
49 | } | |
50 | ||
753ac610 CM |
51 | int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, |
52 | int nand_chunk, | |
53 | const u8 *buffer, struct yaffs_ext_tags *tags) | |
0e8cc8bd | 54 | { |
753ac610 CM |
55 | int result; |
56 | int flash_chunk = nand_chunk - dev->chunk_offset; | |
0e8cc8bd | 57 | |
753ac610 | 58 | dev->n_page_writes++; |
4b070809 | 59 | |
0e8cc8bd | 60 | if (tags) { |
753ac610 CM |
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); | |
0e8cc8bd | 66 | } else { |
753ac610 CM |
67 | yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags"); |
68 | BUG(); | |
69 | return YAFFS_FAIL; | |
0e8cc8bd WJ |
70 | } |
71 | ||
753ac610 CM |
72 | if (dev->param.write_chunk_tags_fn) |
73 | result = dev->param.write_chunk_tags_fn(dev, flash_chunk, | |
74 | buffer, tags); | |
0e8cc8bd | 75 | else |
753ac610 CM |
76 | result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags); |
77 | ||
78 | yaffs_summary_add(dev, tags, nand_chunk); | |
79 | ||
80 | return result; | |
0e8cc8bd WJ |
81 | } |
82 | ||
753ac610 | 83 | int yaffs_mark_bad(struct yaffs_dev *dev, int block_no) |
0e8cc8bd | 84 | { |
753ac610 CM |
85 | block_no -= dev->block_offset; |
86 | if (dev->param.bad_block_fn) | |
87 | return dev->param.bad_block_fn(dev, block_no); | |
0e8cc8bd | 88 | |
753ac610 | 89 | return yaffs_tags_compat_mark_bad(dev, block_no); |
0e8cc8bd WJ |
90 | } |
91 | ||
753ac610 CM |
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) | |
0e8cc8bd | 96 | { |
753ac610 CM |
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); | |
0e8cc8bd | 101 | |
753ac610 | 102 | return yaffs_tags_compat_query_block(dev, block_no, state, seq_number); |
0e8cc8bd WJ |
103 | } |
104 | ||
753ac610 | 105 | int yaffs_erase_block(struct yaffs_dev *dev, int flash_block) |
0e8cc8bd WJ |
106 | { |
107 | int result; | |
108 | ||
753ac610 CM |
109 | flash_block -= dev->block_offset; |
110 | dev->n_erasures++; | |
111 | result = dev->param.erase_fn(dev, flash_block); | |
0e8cc8bd WJ |
112 | return result; |
113 | } | |
114 | ||
753ac610 | 115 | int yaffs_init_nand(struct yaffs_dev *dev) |
0e8cc8bd | 116 | { |
753ac610 CM |
117 | if (dev->param.initialise_flash_fn) |
118 | return dev->param.initialise_flash_fn(dev); | |
119 | return YAFFS_OK; | |
0e8cc8bd | 120 | } |