aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/build.c69
-rw-r--r--drivers/mtd/ubi/eba.c15
-rw-r--r--drivers/mtd/ubi/ubi.h6
-rw-r--r--drivers/mtd/ubi/vmt.c2
-rw-r--r--drivers/mtd/ubi/vtbl.c11
-rw-r--r--drivers/mtd/ubi/wl.c1
6 files changed, 80 insertions, 24 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 8b4573559df..4e761e957de 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -366,9 +366,6 @@ static int uif_init(struct ubi_device *ubi)
366 int i, err; 366 int i, err;
367 dev_t dev; 367 dev_t dev;
368 368
369 mutex_init(&ubi->volumes_mutex);
370 spin_lock_init(&ubi->volumes_lock);
371
372 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); 369 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
373 370
374 /* 371 /*
@@ -624,6 +621,58 @@ static int io_init(struct ubi_device *ubi)
624} 621}
625 622
626/** 623/**
624 * autoresize - re-size the volume which has the "auto-resize" flag set.
625 * @ubi: UBI device description object
626 * @vol_id: ID of the volume to re-size
627 *
628 * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in
629 * the volume table to the largest possible size. See comments in ubi-header.h
630 * for more description of the flag. Returns zero in case of success and a
631 * negative error code in case of failure.
632 */
633static int autoresize(struct ubi_device *ubi, int vol_id)
634{
635 struct ubi_volume_desc desc;
636 struct ubi_volume *vol = ubi->volumes[vol_id];
637 int err, old_reserved_pebs = vol->reserved_pebs;
638
639 /*
640 * Clear the auto-resize flag in the volume in-memory copy of the
641 * volume table, and 'ubi_resize_volume()' will propogate this change
642 * to the flash.
643 */
644 ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG;
645
646 if (ubi->avail_pebs == 0) {
647 struct ubi_vtbl_record vtbl_rec;
648
649 /*
650 * No avalilable PEBs to re-size the volume, clear the flag on
651 * flash and exit.
652 */
653 memcpy(&vtbl_rec, &ubi->vtbl[vol_id],
654 sizeof(struct ubi_vtbl_record));
655 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
656 if (err)
657 ubi_err("cannot clean auto-resize flag for volume %d",
658 vol_id);
659 } else {
660 desc.vol = vol;
661 err = ubi_resize_volume(&desc,
662 old_reserved_pebs + ubi->avail_pebs);
663 if (err)
664 ubi_err("cannot auto-resize volume %d", vol_id);
665 }
666
667 if (err)
668 return err;
669
670 ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id,
671 vol->name, old_reserved_pebs, vol->reserved_pebs);
672 return 0;
673}
674
675/**
627 * ubi_attach_mtd_dev - attach an MTD device. 676 * ubi_attach_mtd_dev - attach an MTD device.
628 * @mtd_dev: MTD device description object 677 * @mtd_dev: MTD device description object
629 * @ubi_num: number to assign to the new UBI device 678 * @ubi_num: number to assign to the new UBI device
@@ -699,6 +748,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
699 ubi->mtd = mtd; 748 ubi->mtd = mtd;
700 ubi->ubi_num = ubi_num; 749 ubi->ubi_num = ubi_num;
701 ubi->vid_hdr_offset = vid_hdr_offset; 750 ubi->vid_hdr_offset = vid_hdr_offset;
751 ubi->autoresize_vol_id = -1;
752
753 mutex_init(&ubi->buf_mutex);
754 mutex_init(&ubi->ckvol_mutex);
755 mutex_init(&ubi->volumes_mutex);
756 spin_lock_init(&ubi->volumes_lock);
702 757
703 dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", 758 dbg_msg("attaching mtd%d to ubi%d: VID header offset %d",
704 mtd->index, ubi_num, vid_hdr_offset); 759 mtd->index, ubi_num, vid_hdr_offset);
@@ -707,8 +762,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
707 if (err) 762 if (err)
708 goto out_free; 763 goto out_free;
709 764
710 mutex_init(&ubi->buf_mutex);
711 mutex_init(&ubi->ckvol_mutex);
712 ubi->peb_buf1 = vmalloc(ubi->peb_size); 765 ubi->peb_buf1 = vmalloc(ubi->peb_size);
713 if (!ubi->peb_buf1) 766 if (!ubi->peb_buf1)
714 goto out_free; 767 goto out_free;
@@ -730,6 +783,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
730 goto out_free; 783 goto out_free;
731 } 784 }
732 785
786 if (ubi->autoresize_vol_id != -1) {
787 err = autoresize(ubi, ubi->autoresize_vol_id);
788 if (err)
789 goto out_detach;
790 }
791
733 err = uif_init(ubi); 792 err = uif_init(ubi);
734 if (err) 793 if (err)
735 goto out_detach; 794 goto out_detach;
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 7c05c6e1abc..1f951e39c53 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -341,9 +341,6 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
341{ 341{
342 int err, pnum, vol_id = vol->vol_id; 342 int err, pnum, vol_id = vol->vol_id;
343 343
344 ubi_assert(ubi->ref_count > 0);
345 ubi_assert(vol->ref_count > 0);
346
347 if (ubi->ro_mode) 344 if (ubi->ro_mode)
348 return -EROFS; 345 return -EROFS;
349 346
@@ -392,9 +389,6 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
392 struct ubi_vid_hdr *vid_hdr; 389 struct ubi_vid_hdr *vid_hdr;
393 uint32_t uninitialized_var(crc); 390 uint32_t uninitialized_var(crc);
394 391
395 ubi_assert(ubi->ref_count > 0);
396 ubi_assert(vol->ref_count > 0);
397
398 err = leb_read_lock(ubi, vol_id, lnum); 392 err = leb_read_lock(ubi, vol_id, lnum);
399 if (err) 393 if (err)
400 return err; 394 return err;
@@ -618,9 +612,6 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
618 int err, pnum, tries = 0, vol_id = vol->vol_id; 612 int err, pnum, tries = 0, vol_id = vol->vol_id;
619 struct ubi_vid_hdr *vid_hdr; 613 struct ubi_vid_hdr *vid_hdr;
620 614
621 ubi_assert(ubi->ref_count > 0);
622 ubi_assert(vol->ref_count > 0);
623
624 if (ubi->ro_mode) 615 if (ubi->ro_mode)
625 return -EROFS; 616 return -EROFS;
626 617
@@ -754,9 +745,6 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
754 struct ubi_vid_hdr *vid_hdr; 745 struct ubi_vid_hdr *vid_hdr;
755 uint32_t crc; 746 uint32_t crc;
756 747
757 ubi_assert(ubi->ref_count > 0);
758 ubi_assert(vol->ref_count > 0);
759
760 if (ubi->ro_mode) 748 if (ubi->ro_mode)
761 return -EROFS; 749 return -EROFS;
762 750
@@ -871,9 +859,6 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
871 struct ubi_vid_hdr *vid_hdr; 859 struct ubi_vid_hdr *vid_hdr;
872 uint32_t crc; 860 uint32_t crc;
873 861
874 ubi_assert(ubi->ref_count > 0);
875 ubi_assert(vol->ref_count > 0);
876
877 if (ubi->ro_mode) 862 if (ubi->ro_mode)
878 return -EROFS; 863 return -EROFS;
879 864
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 90cdcad83cb..a8cdbd0364f 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -250,9 +250,11 @@ struct ubi_wl_entry;
250 * @rsvd_pebs: count of reserved physical eraseblocks 250 * @rsvd_pebs: count of reserved physical eraseblocks
251 * @avail_pebs: count of available physical eraseblocks 251 * @avail_pebs: count of available physical eraseblocks
252 * @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB 252 * @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB
253 * handling 253 * handling
254 * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling 254 * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling
255 * 255 *
256 * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end
257 * of UBI ititializetion
256 * @vtbl_slots: how many slots are available in the volume table 258 * @vtbl_slots: how many slots are available in the volume table
257 * @vtbl_size: size of the volume table in bytes 259 * @vtbl_size: size of the volume table in bytes
258 * @vtbl: in-RAM volume table copy 260 * @vtbl: in-RAM volume table copy
@@ -333,12 +335,14 @@ struct ubi_device {
333 int beb_rsvd_pebs; 335 int beb_rsvd_pebs;
334 int beb_rsvd_level; 336 int beb_rsvd_level;
335 337
338 int autoresize_vol_id;
336 int vtbl_slots; 339 int vtbl_slots;
337 int vtbl_size; 340 int vtbl_size;
338 struct ubi_vtbl_record *vtbl; 341 struct ubi_vtbl_record *vtbl;
339 struct mutex volumes_mutex; 342 struct mutex volumes_mutex;
340 343
341 int max_ec; 344 int max_ec;
345 /* TODO: mean_ec is not updated run-time, fix */
342 int mean_ec; 346 int mean_ec;
343 347
344 /* EBA unit's stuff */ 348 /* EBA unit's stuff */
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 221ce70be56..a3ca2257e60 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -497,8 +497,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
497 497
498 dbg_msg("re-size volume %d to from %d to %d PEBs", 498 dbg_msg("re-size volume %d to from %d to %d PEBs",
499 vol_id, vol->reserved_pebs, reserved_pebs); 499 vol_id, vol->reserved_pebs, reserved_pebs);
500 ubi_assert(desc->mode == UBI_EXCLUSIVE);
501 ubi_assert(vol == ubi->volumes[vol_id]);
502 500
503 if (vol->vol_type == UBI_STATIC_VOLUME && 501 if (vol->vol_type == UBI_STATIC_VOLUME &&
504 reserved_pebs < vol->used_ebs) { 502 reserved_pebs < vol->used_ebs) {
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 7a1a8a1da61..2fd9cf4cea7 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -514,6 +514,17 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
514 vol->name[vol->name_len] = '\0'; 514 vol->name[vol->name_len] = '\0';
515 vol->vol_id = i; 515 vol->vol_id = i;
516 516
517 if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
518 /* Auto re-size flag may be set only for one volume */
519 if (ubi->autoresize_vol_id != -1) {
520 ubi_err("more then one auto-resize volume (%d "
521 "and %d)", ubi->autoresize_vol_id, i);
522 return -EINVAL;
523 }
524
525 ubi->autoresize_vol_id = i;
526 }
527
517 ubi_assert(!ubi->volumes[i]); 528 ubi_assert(!ubi->volumes[i]);
518 ubi->volumes[i] = vol; 529 ubi->volumes[i] = vol;
519 ubi->vol_count += 1; 530 ubi->vol_count += 1;
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 1142aabcfc8..8bfb7434c99 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1303,7 +1303,6 @@ int ubi_wl_flush(struct ubi_device *ubi)
1303 * Make sure all the works which have been done in parallel are 1303 * Make sure all the works which have been done in parallel are
1304 * finished. 1304 * finished.
1305 */ 1305 */
1306 ubi_assert(ubi->ref_count > 0);
1307 down_write(&ubi->work_sem); 1306 down_write(&ubi->work_sem);
1308 up_write(&ubi->work_sem); 1307 up_write(&ubi->work_sem);
1309 1308