aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdpart.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2012-03-03 16:13:06 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-03-26 19:44:29 -0400
commit994c8409c4591983898182bfb5a0368d3daf1fc1 (patch)
tree610844d80a3433b1dd6b2031cd838b1e7689ee9f /drivers/mtd/mtdpart.c
parent31716a5ad32771be8339832b62aa030c263c6dac (diff)
mtd: fix partition wrapper functions
This patch reverts a change that may have been mistakenly included with the set of patches that introduced the new mtd api entry functions. Or perhaps I am mistaken :) The problem is in the partition wrapper functions, where the calls to the driver methods were replaced with calls to the new mtd api functions. This causes the api function to be called a second time, further down the call stack. This is not only unnecessary and redundant - because the sanity checking code and (more restrictive) bounds checks for the partition were done in the first call - but is potentially problematic and confusing. For example, the call stack for a call to mtd_read() on a partitioned device currently looks like this: mtd_read() gets struct mtd_info for the partition | +-> part_read() via the pointer assigned when the partition was created | +->mtd_read() this time gets struct mtd_info for the master | +->xyz_driver_read() via the pointer asigned by the driver It seems that this can cause a variety of problems. For example, if you want to add code to the api function that tests a value in mtd_info that is relevant only to the partition. Or (in my case) you want the driver to return a value that may be different from that returned by the mtd api function. This patch eliminates the second call to the mtd api function. It was tested on the docg4 nand driver with a subset of the api functions, but I inspected the rest and don't see any problems. Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/mtdpart.c')
-rw-r--r--drivers/mtd/mtdpart.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 33d32c6f4f58..226d28a618d8 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -65,7 +65,8 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
65 int res; 65 int res;
66 66
67 stats = part->master->ecc_stats; 67 stats = part->master->ecc_stats;
68 res = mtd_read(part->master, from + part->offset, len, retlen, buf); 68 res = part->master->_read(part->master, from + part->offset, len,
69 retlen, buf);
69 if (unlikely(res)) { 70 if (unlikely(res)) {
70 if (mtd_is_bitflip(res)) 71 if (mtd_is_bitflip(res))
71 mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected; 72 mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
@@ -80,15 +81,15 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
80{ 81{
81 struct mtd_part *part = PART(mtd); 82 struct mtd_part *part = PART(mtd);
82 83
83 return mtd_point(part->master, from + part->offset, len, retlen, 84 return part->master->_point(part->master, from + part->offset, len,
84 virt, phys); 85 retlen, virt, phys);
85} 86}
86 87
87static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 88static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
88{ 89{
89 struct mtd_part *part = PART(mtd); 90 struct mtd_part *part = PART(mtd);
90 91
91 return mtd_unpoint(part->master, from + part->offset, len); 92 return part->master->_unpoint(part->master, from + part->offset, len);
92} 93}
93 94
94static unsigned long part_get_unmapped_area(struct mtd_info *mtd, 95static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
@@ -99,7 +100,8 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
99 struct mtd_part *part = PART(mtd); 100 struct mtd_part *part = PART(mtd);
100 101
101 offset += part->offset; 102 offset += part->offset;
102 return mtd_get_unmapped_area(part->master, len, offset, flags); 103 return part->master->_get_unmapped_area(part->master, len, offset,
104 flags);
103} 105}
104 106
105static int part_read_oob(struct mtd_info *mtd, loff_t from, 107static int part_read_oob(struct mtd_info *mtd, loff_t from,
@@ -130,7 +132,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
130 return -EINVAL; 132 return -EINVAL;
131 } 133 }
132 134
133 res = mtd_read_oob(part->master, from + part->offset, ops); 135 res = part->master->_read_oob(part->master, from + part->offset, ops);
134 if (unlikely(res)) { 136 if (unlikely(res)) {
135 if (mtd_is_bitflip(res)) 137 if (mtd_is_bitflip(res))
136 mtd->ecc_stats.corrected++; 138 mtd->ecc_stats.corrected++;
@@ -144,43 +146,46 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
144 size_t len, size_t *retlen, u_char *buf) 146 size_t len, size_t *retlen, u_char *buf)
145{ 147{
146 struct mtd_part *part = PART(mtd); 148 struct mtd_part *part = PART(mtd);
147 return mtd_read_user_prot_reg(part->master, from, len, retlen, buf); 149 return part->master->_read_user_prot_reg(part->master, from, len,
150 retlen, buf);
148} 151}
149 152
150static int part_get_user_prot_info(struct mtd_info *mtd, 153static int part_get_user_prot_info(struct mtd_info *mtd,
151 struct otp_info *buf, size_t len) 154 struct otp_info *buf, size_t len)
152{ 155{
153 struct mtd_part *part = PART(mtd); 156 struct mtd_part *part = PART(mtd);
154 return mtd_get_user_prot_info(part->master, buf, len); 157 return part->master->_get_user_prot_info(part->master, buf, len);
155} 158}
156 159
157static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, 160static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
158 size_t len, size_t *retlen, u_char *buf) 161 size_t len, size_t *retlen, u_char *buf)
159{ 162{
160 struct mtd_part *part = PART(mtd); 163 struct mtd_part *part = PART(mtd);
161 return mtd_read_fact_prot_reg(part->master, from, len, retlen, buf); 164 return part->master->_read_fact_prot_reg(part->master, from, len,
165 retlen, buf);
162} 166}
163 167
164static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, 168static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
165 size_t len) 169 size_t len)
166{ 170{
167 struct mtd_part *part = PART(mtd); 171 struct mtd_part *part = PART(mtd);
168 return mtd_get_fact_prot_info(part->master, buf, len); 172 return part->master->_get_fact_prot_info(part->master, buf, len);
169} 173}
170 174
171static int part_write(struct mtd_info *mtd, loff_t to, size_t len, 175static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
172 size_t *retlen, const u_char *buf) 176 size_t *retlen, const u_char *buf)
173{ 177{
174 struct mtd_part *part = PART(mtd); 178 struct mtd_part *part = PART(mtd);
175 return mtd_write(part->master, to + part->offset, len, retlen, buf); 179 return part->master->_write(part->master, to + part->offset, len,
180 retlen, buf);
176} 181}
177 182
178static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, 183static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
179 size_t *retlen, const u_char *buf) 184 size_t *retlen, const u_char *buf)
180{ 185{
181 struct mtd_part *part = PART(mtd); 186 struct mtd_part *part = PART(mtd);
182 return mtd_panic_write(part->master, to + part->offset, len, retlen, 187 return part->master->_panic_write(part->master, to + part->offset, len,
183 buf); 188 retlen, buf);
184} 189}
185 190
186static int part_write_oob(struct mtd_info *mtd, loff_t to, 191static int part_write_oob(struct mtd_info *mtd, loff_t to,
@@ -192,29 +197,30 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
192 return -EINVAL; 197 return -EINVAL;
193 if (ops->datbuf && to + ops->len > mtd->size) 198 if (ops->datbuf && to + ops->len > mtd->size)
194 return -EINVAL; 199 return -EINVAL;
195 return mtd_write_oob(part->master, to + part->offset, ops); 200 return part->master->_write_oob(part->master, to + part->offset, ops);
196} 201}
197 202
198static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, 203static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
199 size_t len, size_t *retlen, u_char *buf) 204 size_t len, size_t *retlen, u_char *buf)
200{ 205{
201 struct mtd_part *part = PART(mtd); 206 struct mtd_part *part = PART(mtd);
202 return mtd_write_user_prot_reg(part->master, from, len, retlen, buf); 207 return part->master->_write_user_prot_reg(part->master, from, len,
208 retlen, buf);
203} 209}
204 210
205static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, 211static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
206 size_t len) 212 size_t len)
207{ 213{
208 struct mtd_part *part = PART(mtd); 214 struct mtd_part *part = PART(mtd);
209 return mtd_lock_user_prot_reg(part->master, from, len); 215 return part->master->_lock_user_prot_reg(part->master, from, len);
210} 216}
211 217
212static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, 218static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
213 unsigned long count, loff_t to, size_t *retlen) 219 unsigned long count, loff_t to, size_t *retlen)
214{ 220{
215 struct mtd_part *part = PART(mtd); 221 struct mtd_part *part = PART(mtd);
216 return mtd_writev(part->master, vecs, count, to + part->offset, 222 return part->master->_writev(part->master, vecs, count,
217 retlen); 223 to + part->offset, retlen);
218} 224}
219 225
220static int part_erase(struct mtd_info *mtd, struct erase_info *instr) 226static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
@@ -223,7 +229,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
223 int ret; 229 int ret;
224 230
225 instr->addr += part->offset; 231 instr->addr += part->offset;
226 ret = mtd_erase(part->master, instr); 232 ret = part->master->_erase(part->master, instr);
227 if (ret) { 233 if (ret) {
228 if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) 234 if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
229 instr->fail_addr -= part->offset; 235 instr->fail_addr -= part->offset;
@@ -249,44 +255,44 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
249static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 255static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
250{ 256{
251 struct mtd_part *part = PART(mtd); 257 struct mtd_part *part = PART(mtd);
252 return mtd_lock(part->master, ofs + part->offset, len); 258 return part->master->_lock(part->master, ofs + part->offset, len);
253} 259}
254 260
255static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 261static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
256{ 262{
257 struct mtd_part *part = PART(mtd); 263 struct mtd_part *part = PART(mtd);
258 return mtd_unlock(part->master, ofs + part->offset, len); 264 return part->master->_unlock(part->master, ofs + part->offset, len);
259} 265}
260 266
261static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) 267static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
262{ 268{
263 struct mtd_part *part = PART(mtd); 269 struct mtd_part *part = PART(mtd);
264 return mtd_is_locked(part->master, ofs + part->offset, len); 270 return part->master->_is_locked(part->master, ofs + part->offset, len);
265} 271}
266 272
267static void part_sync(struct mtd_info *mtd) 273static void part_sync(struct mtd_info *mtd)
268{ 274{
269 struct mtd_part *part = PART(mtd); 275 struct mtd_part *part = PART(mtd);
270 mtd_sync(part->master); 276 part->master->_sync(part->master);
271} 277}
272 278
273static int part_suspend(struct mtd_info *mtd) 279static int part_suspend(struct mtd_info *mtd)
274{ 280{
275 struct mtd_part *part = PART(mtd); 281 struct mtd_part *part = PART(mtd);
276 return mtd_suspend(part->master); 282 return part->master->_suspend(part->master);
277} 283}
278 284
279static void part_resume(struct mtd_info *mtd) 285static void part_resume(struct mtd_info *mtd)
280{ 286{
281 struct mtd_part *part = PART(mtd); 287 struct mtd_part *part = PART(mtd);
282 mtd_resume(part->master); 288 part->master->_resume(part->master);
283} 289}
284 290
285static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) 291static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
286{ 292{
287 struct mtd_part *part = PART(mtd); 293 struct mtd_part *part = PART(mtd);
288 ofs += part->offset; 294 ofs += part->offset;
289 return mtd_block_isbad(part->master, ofs); 295 return part->master->_block_isbad(part->master, ofs);
290} 296}
291 297
292static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) 298static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
@@ -295,7 +301,7 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
295 int res; 301 int res;
296 302
297 ofs += part->offset; 303 ofs += part->offset;
298 res = mtd_block_markbad(part->master, ofs); 304 res = part->master->_block_markbad(part->master, ofs);
299 if (!res) 305 if (!res)
300 mtd->ecc_stats.badblocks++; 306 mtd->ecc_stats.badblocks++;
301 return res; 307 return res;