aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdconcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdconcat.c')
-rw-r--r--drivers/mtd/mtdconcat.c106
1 files changed, 24 insertions, 82 deletions
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 1ed5103b219b..b9000563b9f4 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -72,8 +72,6 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
72 int ret = 0, err; 72 int ret = 0, err;
73 int i; 73 int i;
74 74
75 *retlen = 0;
76
77 for (i = 0; i < concat->num_subdev; i++) { 75 for (i = 0; i < concat->num_subdev; i++) {
78 struct mtd_info *subdev = concat->subdev[i]; 76 struct mtd_info *subdev = concat->subdev[i];
79 size_t size, retsize; 77 size_t size, retsize;
@@ -126,11 +124,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
126 int err = -EINVAL; 124 int err = -EINVAL;
127 int i; 125 int i;
128 126
129 if (!(mtd->flags & MTD_WRITEABLE))
130 return -EROFS;
131
132 *retlen = 0;
133
134 for (i = 0; i < concat->num_subdev; i++) { 127 for (i = 0; i < concat->num_subdev; i++) {
135 struct mtd_info *subdev = concat->subdev[i]; 128 struct mtd_info *subdev = concat->subdev[i];
136 size_t size, retsize; 129 size_t size, retsize;
@@ -145,11 +138,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
145 else 138 else
146 size = len; 139 size = len;
147 140
148 if (!(subdev->flags & MTD_WRITEABLE)) 141 err = mtd_write(subdev, to, size, &retsize, buf);
149 err = -EROFS;
150 else
151 err = mtd_write(subdev, to, size, &retsize, buf);
152
153 if (err) 142 if (err)
154 break; 143 break;
155 144
@@ -176,19 +165,10 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
176 int i; 165 int i;
177 int err = -EINVAL; 166 int err = -EINVAL;
178 167
179 if (!(mtd->flags & MTD_WRITEABLE))
180 return -EROFS;
181
182 *retlen = 0;
183
184 /* Calculate total length of data */ 168 /* Calculate total length of data */
185 for (i = 0; i < count; i++) 169 for (i = 0; i < count; i++)
186 total_len += vecs[i].iov_len; 170 total_len += vecs[i].iov_len;
187 171
188 /* Do not allow write past end of device */
189 if ((to + total_len) > mtd->size)
190 return -EINVAL;
191
192 /* Check alignment */ 172 /* Check alignment */
193 if (mtd->writesize > 1) { 173 if (mtd->writesize > 1) {
194 uint64_t __to = to; 174 uint64_t __to = to;
@@ -224,12 +204,8 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
224 old_iov_len = vecs_copy[entry_high].iov_len; 204 old_iov_len = vecs_copy[entry_high].iov_len;
225 vecs_copy[entry_high].iov_len = size; 205 vecs_copy[entry_high].iov_len = size;
226 206
227 if (!(subdev->flags & MTD_WRITEABLE)) 207 err = mtd_writev(subdev, &vecs_copy[entry_low],
228 err = -EROFS; 208 entry_high - entry_low + 1, to, &retsize);
229 else
230 err = mtd_writev(subdev, &vecs_copy[entry_low],
231 entry_high - entry_low + 1, to,
232 &retsize);
233 209
234 vecs_copy[entry_high].iov_len = old_iov_len - size; 210 vecs_copy[entry_high].iov_len = old_iov_len - size;
235 vecs_copy[entry_high].iov_base += size; 211 vecs_copy[entry_high].iov_base += size;
@@ -403,15 +379,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
403 uint64_t length, offset = 0; 379 uint64_t length, offset = 0;
404 struct erase_info *erase; 380 struct erase_info *erase;
405 381
406 if (!(mtd->flags & MTD_WRITEABLE))
407 return -EROFS;
408
409 if (instr->addr > concat->mtd.size)
410 return -EINVAL;
411
412 if (instr->len + instr->addr > concat->mtd.size)
413 return -EINVAL;
414
415 /* 382 /*
416 * Check for proper erase block alignment of the to-be-erased area. 383 * Check for proper erase block alignment of the to-be-erased area.
417 * It is easier to do this based on the super device's erase 384 * It is easier to do this based on the super device's erase
@@ -459,8 +426,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
459 return -EINVAL; 426 return -EINVAL;
460 } 427 }
461 428
462 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
463
464 /* make a local copy of instr to avoid modifying the caller's struct */ 429 /* make a local copy of instr to avoid modifying the caller's struct */
465 erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); 430 erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
466 431
@@ -499,10 +464,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
499 else 464 else
500 erase->len = length; 465 erase->len = length;
501 466
502 if (!(subdev->flags & MTD_WRITEABLE)) {
503 err = -EROFS;
504 break;
505 }
506 length -= erase->len; 467 length -= erase->len;
507 if ((err = concat_dev_erase(subdev, erase))) { 468 if ((err = concat_dev_erase(subdev, erase))) {
508 /* sanity check: should never happen since 469 /* sanity check: should never happen since
@@ -538,9 +499,6 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
538 struct mtd_concat *concat = CONCAT(mtd); 499 struct mtd_concat *concat = CONCAT(mtd);
539 int i, err = -EINVAL; 500 int i, err = -EINVAL;
540 501
541 if ((len + ofs) > mtd->size)
542 return -EINVAL;
543
544 for (i = 0; i < concat->num_subdev; i++) { 502 for (i = 0; i < concat->num_subdev; i++) {
545 struct mtd_info *subdev = concat->subdev[i]; 503 struct mtd_info *subdev = concat->subdev[i];
546 uint64_t size; 504 uint64_t size;
@@ -575,9 +533,6 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
575 struct mtd_concat *concat = CONCAT(mtd); 533 struct mtd_concat *concat = CONCAT(mtd);
576 int i, err = 0; 534 int i, err = 0;
577 535
578 if ((len + ofs) > mtd->size)
579 return -EINVAL;
580
581 for (i = 0; i < concat->num_subdev; i++) { 536 for (i = 0; i < concat->num_subdev; i++) {
582 struct mtd_info *subdev = concat->subdev[i]; 537 struct mtd_info *subdev = concat->subdev[i];
583 uint64_t size; 538 uint64_t size;
@@ -650,9 +605,6 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
650 if (!mtd_can_have_bb(concat->subdev[0])) 605 if (!mtd_can_have_bb(concat->subdev[0]))
651 return res; 606 return res;
652 607
653 if (ofs > mtd->size)
654 return -EINVAL;
655
656 for (i = 0; i < concat->num_subdev; i++) { 608 for (i = 0; i < concat->num_subdev; i++) {
657 struct mtd_info *subdev = concat->subdev[i]; 609 struct mtd_info *subdev = concat->subdev[i];
658 610
@@ -673,12 +625,6 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
673 struct mtd_concat *concat = CONCAT(mtd); 625 struct mtd_concat *concat = CONCAT(mtd);
674 int i, err = -EINVAL; 626 int i, err = -EINVAL;
675 627
676 if (!mtd_can_have_bb(concat->subdev[0]))
677 return 0;
678
679 if (ofs > mtd->size)
680 return -EINVAL;
681
682 for (i = 0; i < concat->num_subdev; i++) { 628 for (i = 0; i < concat->num_subdev; i++) {
683 struct mtd_info *subdev = concat->subdev[i]; 629 struct mtd_info *subdev = concat->subdev[i];
684 630
@@ -716,10 +662,6 @@ static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
716 continue; 662 continue;
717 } 663 }
718 664
719 /* we've found the subdev over which the mapping will reside */
720 if (offset + len > subdev->size)
721 return (unsigned long) -EINVAL;
722
723 return mtd_get_unmapped_area(subdev, len, offset, flags); 665 return mtd_get_unmapped_area(subdev, len, offset, flags);
724 } 666 }
725 667
@@ -777,16 +719,16 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
777 concat->mtd.subpage_sft = subdev[0]->subpage_sft; 719 concat->mtd.subpage_sft = subdev[0]->subpage_sft;
778 concat->mtd.oobsize = subdev[0]->oobsize; 720 concat->mtd.oobsize = subdev[0]->oobsize;
779 concat->mtd.oobavail = subdev[0]->oobavail; 721 concat->mtd.oobavail = subdev[0]->oobavail;
780 if (subdev[0]->writev) 722 if (subdev[0]->_writev)
781 concat->mtd.writev = concat_writev; 723 concat->mtd._writev = concat_writev;
782 if (subdev[0]->read_oob) 724 if (subdev[0]->_read_oob)
783 concat->mtd.read_oob = concat_read_oob; 725 concat->mtd._read_oob = concat_read_oob;
784 if (subdev[0]->write_oob) 726 if (subdev[0]->_write_oob)
785 concat->mtd.write_oob = concat_write_oob; 727 concat->mtd._write_oob = concat_write_oob;
786 if (subdev[0]->block_isbad) 728 if (subdev[0]->_block_isbad)
787 concat->mtd.block_isbad = concat_block_isbad; 729 concat->mtd._block_isbad = concat_block_isbad;
788 if (subdev[0]->block_markbad) 730 if (subdev[0]->_block_markbad)
789 concat->mtd.block_markbad = concat_block_markbad; 731 concat->mtd._block_markbad = concat_block_markbad;
790 732
791 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; 733 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
792 734
@@ -833,8 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
833 if (concat->mtd.writesize != subdev[i]->writesize || 775 if (concat->mtd.writesize != subdev[i]->writesize ||
834 concat->mtd.subpage_sft != subdev[i]->subpage_sft || 776 concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
835 concat->mtd.oobsize != subdev[i]->oobsize || 777 concat->mtd.oobsize != subdev[i]->oobsize ||
836 !concat->mtd.read_oob != !subdev[i]->read_oob || 778 !concat->mtd._read_oob != !subdev[i]->_read_oob ||
837 !concat->mtd.write_oob != !subdev[i]->write_oob) { 779 !concat->mtd._write_oob != !subdev[i]->_write_oob) {
838 kfree(concat); 780 kfree(concat);
839 printk("Incompatible OOB or ECC data on \"%s\"\n", 781 printk("Incompatible OOB or ECC data on \"%s\"\n",
840 subdev[i]->name); 782 subdev[i]->name);
@@ -849,15 +791,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
849 concat->num_subdev = num_devs; 791 concat->num_subdev = num_devs;
850 concat->mtd.name = name; 792 concat->mtd.name = name;
851 793
852 concat->mtd.erase = concat_erase; 794 concat->mtd._erase = concat_erase;
853 concat->mtd.read = concat_read; 795 concat->mtd._read = concat_read;
854 concat->mtd.write = concat_write; 796 concat->mtd._write = concat_write;
855 concat->mtd.sync = concat_sync; 797 concat->mtd._sync = concat_sync;
856 concat->mtd.lock = concat_lock; 798 concat->mtd._lock = concat_lock;
857 concat->mtd.unlock = concat_unlock; 799 concat->mtd._unlock = concat_unlock;
858 concat->mtd.suspend = concat_suspend; 800 concat->mtd._suspend = concat_suspend;
859 concat->mtd.resume = concat_resume; 801 concat->mtd._resume = concat_resume;
860 concat->mtd.get_unmapped_area = concat_get_unmapped_area; 802 concat->mtd._get_unmapped_area = concat_get_unmapped_area;
861 803
862 /* 804 /*
863 * Combine the erase block size info of the subdevices: 805 * Combine the erase block size info of the subdevices: