aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/mtdpart.c129
1 files changed, 65 insertions, 64 deletions
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 45c6f32b0bf1..9cf73d360e78 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -44,8 +44,8 @@ struct mtd_part {
44 * to the _real_ device. 44 * to the _real_ device.
45 */ 45 */
46 46
47static int part_read (struct mtd_info *mtd, loff_t from, size_t len, 47static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
48 size_t *retlen, u_char *buf) 48 size_t *retlen, u_char *buf)
49{ 49{
50 struct mtd_part *part = PART(mtd); 50 struct mtd_part *part = PART(mtd);
51 int res; 51 int res;
@@ -54,7 +54,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
54 len = 0; 54 len = 0;
55 else if (from + len > mtd->size) 55 else if (from + len > mtd->size)
56 len = mtd->size - from; 56 len = mtd->size - from;
57 res = part->master->read (part->master, from + part->offset, 57 res = part->master->read(part->master, from + part->offset,
58 len, retlen, buf); 58 len, retlen, buf);
59 if (unlikely(res)) { 59 if (unlikely(res)) {
60 if (res == -EUCLEAN) 60 if (res == -EUCLEAN)
@@ -65,8 +65,8 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
65 return res; 65 return res;
66} 66}
67 67
68static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 68static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
69 size_t *retlen, void **virt, resource_size_t *phys) 69 size_t *retlen, void **virt, resource_size_t *phys)
70{ 70{
71 struct mtd_part *part = PART(mtd); 71 struct mtd_part *part = PART(mtd);
72 if (from >= mtd->size) 72 if (from >= mtd->size)
@@ -85,7 +85,7 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
85} 85}
86 86
87static int part_read_oob(struct mtd_info *mtd, loff_t from, 87static int part_read_oob(struct mtd_info *mtd, loff_t from,
88 struct mtd_oob_ops *ops) 88 struct mtd_oob_ops *ops)
89{ 89{
90 struct mtd_part *part = PART(mtd); 90 struct mtd_part *part = PART(mtd);
91 int res; 91 int res;
@@ -105,38 +105,38 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
105 return res; 105 return res;
106} 106}
107 107
108static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 108static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
109 size_t *retlen, u_char *buf) 109 size_t len, size_t *retlen, u_char *buf)
110{ 110{
111 struct mtd_part *part = PART(mtd); 111 struct mtd_part *part = PART(mtd);
112 return part->master->read_user_prot_reg (part->master, from, 112 return part->master->read_user_prot_reg(part->master, from,
113 len, retlen, buf); 113 len, retlen, buf);
114} 114}
115 115
116static int part_get_user_prot_info (struct mtd_info *mtd, 116static int part_get_user_prot_info(struct mtd_info *mtd,
117 struct otp_info *buf, size_t len) 117 struct otp_info *buf, size_t len)
118{ 118{
119 struct mtd_part *part = PART(mtd); 119 struct mtd_part *part = PART(mtd);
120 return part->master->get_user_prot_info (part->master, buf, len); 120 return part->master->get_user_prot_info(part->master, buf, len);
121} 121}
122 122
123static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 123static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
124 size_t *retlen, u_char *buf) 124 size_t len, size_t *retlen, u_char *buf)
125{ 125{
126 struct mtd_part *part = PART(mtd); 126 struct mtd_part *part = PART(mtd);
127 return part->master->read_fact_prot_reg (part->master, from, 127 return part->master->read_fact_prot_reg(part->master, from,
128 len, retlen, buf); 128 len, retlen, buf);
129} 129}
130 130
131static int part_get_fact_prot_info (struct mtd_info *mtd, 131static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
132 struct otp_info *buf, size_t len) 132 size_t len)
133{ 133{
134 struct mtd_part *part = PART(mtd); 134 struct mtd_part *part = PART(mtd);
135 return part->master->get_fact_prot_info (part->master, buf, len); 135 return part->master->get_fact_prot_info(part->master, buf, len);
136} 136}
137 137
138static int part_write (struct mtd_info *mtd, loff_t to, size_t len, 138static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
139 size_t *retlen, const u_char *buf) 139 size_t *retlen, const u_char *buf)
140{ 140{
141 struct mtd_part *part = PART(mtd); 141 struct mtd_part *part = PART(mtd);
142 if (!(mtd->flags & MTD_WRITEABLE)) 142 if (!(mtd->flags & MTD_WRITEABLE))
@@ -145,12 +145,12 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
145 len = 0; 145 len = 0;
146 else if (to + len > mtd->size) 146 else if (to + len > mtd->size)
147 len = mtd->size - to; 147 len = mtd->size - to;
148 return part->master->write (part->master, to + part->offset, 148 return part->master->write(part->master, to + part->offset,
149 len, retlen, buf); 149 len, retlen, buf);
150} 150}
151 151
152static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len, 152static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
153 size_t *retlen, const u_char *buf) 153 size_t *retlen, const u_char *buf)
154{ 154{
155 struct mtd_part *part = PART(mtd); 155 struct mtd_part *part = PART(mtd);
156 if (!(mtd->flags & MTD_WRITEABLE)) 156 if (!(mtd->flags & MTD_WRITEABLE))
@@ -159,12 +159,12 @@ static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len,
159 len = 0; 159 len = 0;
160 else if (to + len > mtd->size) 160 else if (to + len > mtd->size)
161 len = mtd->size - to; 161 len = mtd->size - to;
162 return part->master->panic_write (part->master, to + part->offset, 162 return part->master->panic_write(part->master, to + part->offset,
163 len, retlen, buf); 163 len, retlen, buf);
164} 164}
165 165
166static int part_write_oob(struct mtd_info *mtd, loff_t to, 166static int part_write_oob(struct mtd_info *mtd, loff_t to,
167 struct mtd_oob_ops *ops) 167 struct mtd_oob_ops *ops)
168{ 168{
169 struct mtd_part *part = PART(mtd); 169 struct mtd_part *part = PART(mtd);
170 170
@@ -178,31 +178,32 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
178 return part->master->write_oob(part->master, to + part->offset, ops); 178 return part->master->write_oob(part->master, to + part->offset, ops);
179} 179}
180 180
181static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 181static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
182 size_t *retlen, u_char *buf) 182 size_t len, size_t *retlen, u_char *buf)
183{ 183{
184 struct mtd_part *part = PART(mtd); 184 struct mtd_part *part = PART(mtd);
185 return part->master->write_user_prot_reg (part->master, from, 185 return part->master->write_user_prot_reg(part->master, from,
186 len, retlen, buf); 186 len, retlen, buf);
187} 187}
188 188
189static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) 189static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
190 size_t len)
190{ 191{
191 struct mtd_part *part = PART(mtd); 192 struct mtd_part *part = PART(mtd);
192 return part->master->lock_user_prot_reg (part->master, from, len); 193 return part->master->lock_user_prot_reg(part->master, from, len);
193} 194}
194 195
195static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, 196static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
196 unsigned long count, loff_t to, size_t *retlen) 197 unsigned long count, loff_t to, size_t *retlen)
197{ 198{
198 struct mtd_part *part = PART(mtd); 199 struct mtd_part *part = PART(mtd);
199 if (!(mtd->flags & MTD_WRITEABLE)) 200 if (!(mtd->flags & MTD_WRITEABLE))
200 return -EROFS; 201 return -EROFS;
201 return part->master->writev (part->master, vecs, count, 202 return part->master->writev(part->master, vecs, count,
202 to + part->offset, retlen); 203 to + part->offset, retlen);
203} 204}
204 205
205static int part_erase (struct mtd_info *mtd, struct erase_info *instr) 206static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
206{ 207{
207 struct mtd_part *part = PART(mtd); 208 struct mtd_part *part = PART(mtd);
208 int ret; 209 int ret;
@@ -234,7 +235,7 @@ void mtd_erase_callback(struct erase_info *instr)
234} 235}
235EXPORT_SYMBOL_GPL(mtd_erase_callback); 236EXPORT_SYMBOL_GPL(mtd_erase_callback);
236 237
237static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) 238static int part_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
238{ 239{
239 struct mtd_part *part = PART(mtd); 240 struct mtd_part *part = PART(mtd);
240 if ((len + ofs) > mtd->size) 241 if ((len + ofs) > mtd->size)
@@ -242,7 +243,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
242 return part->master->lock(part->master, ofs + part->offset, len); 243 return part->master->lock(part->master, ofs + part->offset, len);
243} 244}
244 245
245static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) 246static int part_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
246{ 247{
247 struct mtd_part *part = PART(mtd); 248 struct mtd_part *part = PART(mtd);
248 if ((len + ofs) > mtd->size) 249 if ((len + ofs) > mtd->size)
@@ -268,7 +269,7 @@ static void part_resume(struct mtd_info *mtd)
268 part->master->resume(part->master); 269 part->master->resume(part->master);
269} 270}
270 271
271static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) 272static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
272{ 273{
273 struct mtd_part *part = PART(mtd); 274 struct mtd_part *part = PART(mtd);
274 if (ofs >= mtd->size) 275 if (ofs >= mtd->size)
@@ -277,7 +278,7 @@ static int part_block_isbad (struct mtd_info *mtd, loff_t ofs)
277 return part->master->block_isbad(part->master, ofs); 278 return part->master->block_isbad(part->master, ofs);
278} 279}
279 280
280static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) 281static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
281{ 282{
282 struct mtd_part *part = PART(mtd); 283 struct mtd_part *part = PART(mtd);
283 int res; 284 int res;
@@ -305,13 +306,14 @@ int del_mtd_partitions(struct mtd_info *master)
305 list_for_each_entry_safe(slave, next, &mtd_partitions, list) 306 list_for_each_entry_safe(slave, next, &mtd_partitions, list)
306 if (slave->master == master) { 307 if (slave->master == master) {
307 list_del(&slave->list); 308 list_del(&slave->list);
308 if(slave->registered) 309 if (slave->registered)
309 del_mtd_device(&slave->mtd); 310 del_mtd_device(&slave->mtd);
310 kfree(slave); 311 kfree(slave);
311 } 312 }
312 313
313 return 0; 314 return 0;
314} 315}
316EXPORT_SYMBOL(del_mtd_partitions);
315 317
316static struct mtd_part *add_one_partition(struct mtd_info *master, 318static struct mtd_part *add_one_partition(struct mtd_info *master,
317 const struct mtd_partition *part, int partno, 319 const struct mtd_partition *part, int partno,
@@ -320,9 +322,9 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
320 struct mtd_part *slave; 322 struct mtd_part *slave;
321 323
322 /* allocate the partition structure */ 324 /* allocate the partition structure */
323 slave = kzalloc (sizeof(*slave), GFP_KERNEL); 325 slave = kzalloc(sizeof(*slave), GFP_KERNEL);
324 if (!slave) { 326 if (!slave) {
325 printk("memory allocation error while creating partitions for \"%s\"\n", 327 printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",
326 master->name); 328 master->name);
327 del_mtd_partitions(master); 329 del_mtd_partitions(master);
328 return NULL; 330 return NULL;
@@ -347,7 +349,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
347 if (master->panic_write) 349 if (master->panic_write)
348 slave->mtd.panic_write = part_panic_write; 350 slave->mtd.panic_write = part_panic_write;
349 351
350 if(master->point && master->unpoint){ 352 if (master->point && master->unpoint) {
351 slave->mtd.point = part_point; 353 slave->mtd.point = part_point;
352 slave->mtd.unpoint = part_unpoint; 354 slave->mtd.unpoint = part_unpoint;
353 } 355 }
@@ -356,17 +358,17 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
356 slave->mtd.read_oob = part_read_oob; 358 slave->mtd.read_oob = part_read_oob;
357 if (master->write_oob) 359 if (master->write_oob)
358 slave->mtd.write_oob = part_write_oob; 360 slave->mtd.write_oob = part_write_oob;
359 if(master->read_user_prot_reg) 361 if (master->read_user_prot_reg)
360 slave->mtd.read_user_prot_reg = part_read_user_prot_reg; 362 slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
361 if(master->read_fact_prot_reg) 363 if (master->read_fact_prot_reg)
362 slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; 364 slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
363 if(master->write_user_prot_reg) 365 if (master->write_user_prot_reg)
364 slave->mtd.write_user_prot_reg = part_write_user_prot_reg; 366 slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
365 if(master->lock_user_prot_reg) 367 if (master->lock_user_prot_reg)
366 slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; 368 slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
367 if(master->get_user_prot_info) 369 if (master->get_user_prot_info)
368 slave->mtd.get_user_prot_info = part_get_user_prot_info; 370 slave->mtd.get_user_prot_info = part_get_user_prot_info;
369 if(master->get_fact_prot_info) 371 if (master->get_fact_prot_info)
370 slave->mtd.get_fact_prot_info = part_get_fact_prot_info; 372 slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
371 if (master->sync) 373 if (master->sync)
372 slave->mtd.sync = part_sync; 374 slave->mtd.sync = part_sync;
@@ -404,7 +406,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
404 if (slave->mtd.size == MTDPART_SIZ_FULL) 406 if (slave->mtd.size == MTDPART_SIZ_FULL)
405 slave->mtd.size = master->size - slave->offset; 407 slave->mtd.size = master->size - slave->offset;
406 408
407 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 409 printk(KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
408 slave->offset + slave->mtd.size, slave->mtd.name); 410 slave->offset + slave->mtd.size, slave->mtd.name);
409 411
410 /* let's do some sanity checks */ 412 /* let's do some sanity checks */
@@ -412,21 +414,21 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
412 /* let's register it anyway to preserve ordering */ 414 /* let's register it anyway to preserve ordering */
413 slave->offset = 0; 415 slave->offset = 0;
414 slave->mtd.size = 0; 416 slave->mtd.size = 0;
415 printk ("mtd: partition \"%s\" is out of reach -- disabled\n", 417 printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n",
416 part->name); 418 part->name);
417 } 419 }
418 if (slave->offset + slave->mtd.size > master->size) { 420 if (slave->offset + slave->mtd.size > master->size) {
419 slave->mtd.size = master->size - slave->offset; 421 slave->mtd.size = master->size - slave->offset;
420 printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", 422 printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
421 part->name, master->name, slave->mtd.size); 423 part->name, master->name, slave->mtd.size);
422 } 424 }
423 if (master->numeraseregions>1) { 425 if (master->numeraseregions > 1) {
424 /* Deal with variable erase size stuff */ 426 /* Deal with variable erase size stuff */
425 int i; 427 int i;
426 struct mtd_erase_region_info *regions = master->eraseregions; 428 struct mtd_erase_region_info *regions = master->eraseregions;
427 429
428 /* Find the first erase regions which is part of this partition. */ 430 /* Find the first erase regions which is part of this partition. */
429 for (i=0; i < master->numeraseregions && regions[i].offset <= slave->offset; i++) 431 for (i = 0; i < master->numeraseregions && regions[i].offset <= slave->offset; i++)
430 ; 432 ;
431 433
432 for (i--; i < master->numeraseregions && regions[i].offset < slave->offset + slave->mtd.size; i++) { 434 for (i--; i < master->numeraseregions && regions[i].offset < slave->offset + slave->mtd.size; i++) {
@@ -442,15 +444,16 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
442 if ((slave->mtd.flags & MTD_WRITEABLE) && 444 if ((slave->mtd.flags & MTD_WRITEABLE) &&
443 (slave->offset % slave->mtd.erasesize)) { 445 (slave->offset % slave->mtd.erasesize)) {
444 /* Doesn't start on a boundary of major erase size */ 446 /* Doesn't start on a boundary of major erase size */
445 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ 447 /* FIXME: Let it be writable if it is on a boundary of
448 * _minor_ erase size though */
446 slave->mtd.flags &= ~MTD_WRITEABLE; 449 slave->mtd.flags &= ~MTD_WRITEABLE;
447 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", 450 printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
448 part->name); 451 part->name);
449 } 452 }
450 if ((slave->mtd.flags & MTD_WRITEABLE) && 453 if ((slave->mtd.flags & MTD_WRITEABLE) &&
451 (slave->mtd.size % slave->mtd.erasesize)) { 454 (slave->mtd.size % slave->mtd.erasesize)) {
452 slave->mtd.flags &= ~MTD_WRITEABLE; 455 slave->mtd.flags &= ~MTD_WRITEABLE;
453 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", 456 printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
454 part->name); 457 part->name);
455 } 458 }
456 459
@@ -458,7 +461,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
458 if (master->block_isbad) { 461 if (master->block_isbad) {
459 uint32_t offs = 0; 462 uint32_t offs = 0;
460 463
461 while(offs < slave->mtd.size) { 464 while (offs < slave->mtd.size) {
462 if (master->block_isbad(master, 465 if (master->block_isbad(master,
463 offs + slave->offset)) 466 offs + slave->offset))
464 slave->mtd.ecc_stats.badblocks++; 467 slave->mtd.ecc_stats.badblocks++;
@@ -466,7 +469,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
466 } 469 }
467 } 470 }
468 471
469 if(part->mtdp) { /* store the object pointer (caller may or may not register it */ 472 if (part->mtdp) {
473 /* store the object pointer (caller may or may not register it*/
470 *part->mtdp = &slave->mtd; 474 *part->mtdp = &slave->mtd;
471 slave->registered = 0; 475 slave->registered = 0;
472 } else { 476 } else {
@@ -492,7 +496,7 @@ int add_mtd_partitions(struct mtd_info *master,
492 u_int32_t cur_offset = 0; 496 u_int32_t cur_offset = 0;
493 int i; 497 int i;
494 498
495 printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); 499 printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
496 500
497 for (i = 0; i < nbparts; i++) { 501 for (i = 0; i < nbparts; i++) {
498 slave = add_one_partition(master, parts + i, i, cur_offset); 502 slave = add_one_partition(master, parts + i, i, cur_offset);
@@ -503,9 +507,7 @@ int add_mtd_partitions(struct mtd_info *master,
503 507
504 return 0; 508 return 0;
505} 509}
506
507EXPORT_SYMBOL(add_mtd_partitions); 510EXPORT_SYMBOL(add_mtd_partitions);
508EXPORT_SYMBOL(del_mtd_partitions);
509 511
510static DEFINE_SPINLOCK(part_parser_lock); 512static DEFINE_SPINLOCK(part_parser_lock);
511static LIST_HEAD(part_parsers); 513static LIST_HEAD(part_parsers);
@@ -535,6 +537,7 @@ int register_mtd_parser(struct mtd_part_parser *p)
535 537
536 return 0; 538 return 0;
537} 539}
540EXPORT_SYMBOL_GPL(register_mtd_parser);
538 541
539int deregister_mtd_parser(struct mtd_part_parser *p) 542int deregister_mtd_parser(struct mtd_part_parser *p)
540{ 543{
@@ -543,6 +546,7 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
543 spin_unlock(&part_parser_lock); 546 spin_unlock(&part_parser_lock);
544 return 0; 547 return 0;
545} 548}
549EXPORT_SYMBOL_GPL(deregister_mtd_parser);
546 550
547int parse_mtd_partitions(struct mtd_info *master, const char **types, 551int parse_mtd_partitions(struct mtd_info *master, const char **types,
548 struct mtd_partition **pparts, unsigned long origin) 552 struct mtd_partition **pparts, unsigned long origin)
@@ -570,7 +574,4 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
570 } 574 }
571 return ret; 575 return ret;
572} 576}
573
574EXPORT_SYMBOL_GPL(parse_mtd_partitions); 577EXPORT_SYMBOL_GPL(parse_mtd_partitions);
575EXPORT_SYMBOL_GPL(register_mtd_parser);
576EXPORT_SYMBOL_GPL(deregister_mtd_parser);