diff options
-rw-r--r-- | drivers/mtd/ubi/eba.c | 285 |
1 files changed, 115 insertions, 170 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index be59cfb81934..180eb006e966 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -693,6 +693,69 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, | |||
693 | } | 693 | } |
694 | 694 | ||
695 | /** | 695 | /** |
696 | * try_write_vid_and_data - try to write VID header and data to a new PEB. | ||
697 | * @vol: volume description object | ||
698 | * @lnum: logical eraseblock number | ||
699 | * @vid_hdr: VID header to write | ||
700 | * @buf: buffer containing the data | ||
701 | * @offset: where to start writing data | ||
702 | * @len: how many bytes should be written | ||
703 | * | ||
704 | * This function tries to write VID header and data belonging to logical | ||
705 | * eraseblock @lnum of volume @vol to a new physical eraseblock. Returns zero | ||
706 | * in case of success and a negative error code in case of failure. | ||
707 | * In case of error, it is possible that something was still written to the | ||
708 | * flash media, but may be some garbage. | ||
709 | */ | ||
710 | static int try_write_vid_and_data(struct ubi_volume *vol, int lnum, | ||
711 | struct ubi_vid_hdr *vid_hdr, const void *buf, | ||
712 | int offset, int len) | ||
713 | { | ||
714 | struct ubi_device *ubi = vol->ubi; | ||
715 | int pnum, opnum, err, vol_id = vol->vol_id; | ||
716 | |||
717 | pnum = ubi_wl_get_peb(ubi); | ||
718 | if (pnum < 0) { | ||
719 | err = pnum; | ||
720 | goto out_put; | ||
721 | } | ||
722 | |||
723 | opnum = vol->eba_tbl[lnum]; | ||
724 | |||
725 | dbg_eba("write VID hdr and %d bytes at offset %d of LEB %d:%d, PEB %d", | ||
726 | len, offset, vol_id, lnum, pnum); | ||
727 | |||
728 | err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); | ||
729 | if (err) { | ||
730 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | ||
731 | vol_id, lnum, pnum); | ||
732 | goto out_put; | ||
733 | } | ||
734 | |||
735 | if (len) { | ||
736 | err = ubi_io_write_data(ubi, buf, pnum, offset, len); | ||
737 | if (err) { | ||
738 | ubi_warn(ubi, | ||
739 | "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", | ||
740 | len, offset, vol_id, lnum, pnum); | ||
741 | goto out_put; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | vol->eba_tbl[lnum] = pnum; | ||
746 | |||
747 | out_put: | ||
748 | up_read(&ubi->fm_eba_sem); | ||
749 | |||
750 | if (err && pnum >= 0) | ||
751 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); | ||
752 | else if (!err && opnum >= 0) | ||
753 | err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); | ||
754 | |||
755 | return err; | ||
756 | } | ||
757 | |||
758 | /** | ||
696 | * ubi_eba_write_leb - write data to dynamic volume. | 759 | * ubi_eba_write_leb - write data to dynamic volume. |
697 | * @ubi: UBI device description object | 760 | * @ubi: UBI device description object |
698 | * @vol: volume description object | 761 | * @vol: volume description object |
@@ -705,11 +768,12 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, | |||
705 | * @vol. Returns zero in case of success and a negative error code in case | 768 | * @vol. Returns zero in case of success and a negative error code in case |
706 | * of failure. In case of error, it is possible that something was still | 769 | * of failure. In case of error, it is possible that something was still |
707 | * written to the flash media, but may be some garbage. | 770 | * written to the flash media, but may be some garbage. |
771 | * This function retries %UBI_IO_RETRIES times before giving up. | ||
708 | */ | 772 | */ |
709 | int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | 773 | int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, |
710 | const void *buf, int offset, int len) | 774 | const void *buf, int offset, int len) |
711 | { | 775 | { |
712 | int err, pnum, tries = 0, vol_id = vol->vol_id; | 776 | int err, pnum, tries, vol_id = vol->vol_id; |
713 | struct ubi_vid_hdr *vid_hdr; | 777 | struct ubi_vid_hdr *vid_hdr; |
714 | 778 | ||
715 | if (ubi->ro_mode) | 779 | if (ubi->ro_mode) |
@@ -730,11 +794,9 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
730 | if (err == -EIO && ubi->bad_allowed) | 794 | if (err == -EIO && ubi->bad_allowed) |
731 | err = recover_peb(ubi, pnum, vol_id, lnum, buf, | 795 | err = recover_peb(ubi, pnum, vol_id, lnum, buf, |
732 | offset, len); | 796 | offset, len); |
733 | if (err) | ||
734 | ubi_ro_mode(ubi); | ||
735 | } | 797 | } |
736 | leb_write_unlock(ubi, vol_id, lnum); | 798 | |
737 | return err; | 799 | goto out; |
738 | } | 800 | } |
739 | 801 | ||
740 | /* | 802 | /* |
@@ -754,67 +816,31 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
754 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); | 816 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); |
755 | vid_hdr->data_pad = cpu_to_be32(vol->data_pad); | 817 | vid_hdr->data_pad = cpu_to_be32(vol->data_pad); |
756 | 818 | ||
757 | retry: | 819 | for (tries = 0; tries <= UBI_IO_RETRIES; tries++) { |
758 | pnum = ubi_wl_get_peb(ubi); | 820 | err = try_write_vid_and_data(vol, lnum, vid_hdr, buf, offset, |
759 | if (pnum < 0) { | 821 | len); |
760 | ubi_free_vid_hdr(ubi, vid_hdr); | 822 | if (err != -EIO || !ubi->bad_allowed) |
761 | leb_write_unlock(ubi, vol_id, lnum); | 823 | break; |
762 | up_read(&ubi->fm_eba_sem); | ||
763 | return pnum; | ||
764 | } | ||
765 | |||
766 | dbg_eba("write VID hdr and %d bytes at offset %d of LEB %d:%d, PEB %d", | ||
767 | len, offset, vol_id, lnum, pnum); | ||
768 | |||
769 | err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); | ||
770 | if (err) { | ||
771 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | ||
772 | vol_id, lnum, pnum); | ||
773 | up_read(&ubi->fm_eba_sem); | ||
774 | goto write_error; | ||
775 | } | ||
776 | 824 | ||
777 | if (len) { | 825 | /* |
778 | err = ubi_io_write_data(ubi, buf, pnum, offset, len); | 826 | * Fortunately, this is the first write operation to this |
779 | if (err) { | 827 | * physical eraseblock, so just put it and request a new one. |
780 | ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", | 828 | * We assume that if this physical eraseblock went bad, the |
781 | len, offset, vol_id, lnum, pnum); | 829 | * erase code will handle that. |
782 | up_read(&ubi->fm_eba_sem); | 830 | */ |
783 | goto write_error; | 831 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); |
784 | } | 832 | ubi_msg(ubi, "try another PEB"); |
785 | } | 833 | } |
786 | 834 | ||
787 | vol->eba_tbl[lnum] = pnum; | ||
788 | up_read(&ubi->fm_eba_sem); | ||
789 | |||
790 | leb_write_unlock(ubi, vol_id, lnum); | ||
791 | ubi_free_vid_hdr(ubi, vid_hdr); | 835 | ubi_free_vid_hdr(ubi, vid_hdr); |
792 | return 0; | ||
793 | 836 | ||
794 | write_error: | 837 | out: |
795 | if (err != -EIO || !ubi->bad_allowed) { | 838 | if (err) |
796 | ubi_ro_mode(ubi); | 839 | ubi_ro_mode(ubi); |
797 | leb_write_unlock(ubi, vol_id, lnum); | ||
798 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
799 | return err; | ||
800 | } | ||
801 | 840 | ||
802 | /* | 841 | leb_write_unlock(ubi, vol_id, lnum); |
803 | * Fortunately, this is the first write operation to this physical | ||
804 | * eraseblock, so just put it and request a new one. We assume that if | ||
805 | * this physical eraseblock went bad, the erase code will handle that. | ||
806 | */ | ||
807 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); | ||
808 | if (err || ++tries > UBI_IO_RETRIES) { | ||
809 | ubi_ro_mode(ubi); | ||
810 | leb_write_unlock(ubi, vol_id, lnum); | ||
811 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
812 | return err; | ||
813 | } | ||
814 | 842 | ||
815 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); | 843 | return err; |
816 | ubi_msg(ubi, "try another PEB"); | ||
817 | goto retry; | ||
818 | } | 844 | } |
819 | 845 | ||
820 | /** | 846 | /** |
@@ -842,7 +868,7 @@ write_error: | |||
842 | int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, | 868 | int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, |
843 | int lnum, const void *buf, int len, int used_ebs) | 869 | int lnum, const void *buf, int len, int used_ebs) |
844 | { | 870 | { |
845 | int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id; | 871 | int err, tries, data_size = len, vol_id = vol->vol_id; |
846 | struct ubi_vid_hdr *vid_hdr; | 872 | struct ubi_vid_hdr *vid_hdr; |
847 | uint32_t crc; | 873 | uint32_t crc; |
848 | 874 | ||
@@ -860,10 +886,8 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, | |||
860 | return -ENOMEM; | 886 | return -ENOMEM; |
861 | 887 | ||
862 | err = leb_write_lock(ubi, vol_id, lnum); | 888 | err = leb_write_lock(ubi, vol_id, lnum); |
863 | if (err) { | 889 | if (err) |
864 | ubi_free_vid_hdr(ubi, vid_hdr); | 890 | goto out; |
865 | return err; | ||
866 | } | ||
867 | 891 | ||
868 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); | 892 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); |
869 | vid_hdr->vol_id = cpu_to_be32(vol_id); | 893 | vid_hdr->vol_id = cpu_to_be32(vol_id); |
@@ -877,66 +901,26 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, | |||
877 | vid_hdr->used_ebs = cpu_to_be32(used_ebs); | 901 | vid_hdr->used_ebs = cpu_to_be32(used_ebs); |
878 | vid_hdr->data_crc = cpu_to_be32(crc); | 902 | vid_hdr->data_crc = cpu_to_be32(crc); |
879 | 903 | ||
880 | retry: | 904 | ubi_assert(vol->eba_tbl[lnum] < 0); |
881 | pnum = ubi_wl_get_peb(ubi); | ||
882 | if (pnum < 0) { | ||
883 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
884 | leb_write_unlock(ubi, vol_id, lnum); | ||
885 | up_read(&ubi->fm_eba_sem); | ||
886 | return pnum; | ||
887 | } | ||
888 | |||
889 | dbg_eba("write VID hdr and %d bytes at LEB %d:%d, PEB %d, used_ebs %d", | ||
890 | len, vol_id, lnum, pnum, used_ebs); | ||
891 | 905 | ||
892 | err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); | 906 | for (tries = 0; tries <= UBI_IO_RETRIES; tries++) { |
893 | if (err) { | 907 | err = try_write_vid_and_data(vol, lnum, vid_hdr, buf, 0, len); |
894 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | 908 | if (err != -EIO || !ubi->bad_allowed) |
895 | vol_id, lnum, pnum); | 909 | break; |
896 | up_read(&ubi->fm_eba_sem); | ||
897 | goto write_error; | ||
898 | } | ||
899 | 910 | ||
900 | err = ubi_io_write_data(ubi, buf, pnum, 0, len); | 911 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); |
901 | if (err) { | 912 | ubi_msg(ubi, "try another PEB"); |
902 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", | ||
903 | len, pnum); | ||
904 | up_read(&ubi->fm_eba_sem); | ||
905 | goto write_error; | ||
906 | } | 913 | } |
907 | 914 | ||
908 | ubi_assert(vol->eba_tbl[lnum] < 0); | 915 | if (err) |
909 | vol->eba_tbl[lnum] = pnum; | 916 | ubi_ro_mode(ubi); |
910 | up_read(&ubi->fm_eba_sem); | ||
911 | 917 | ||
912 | leb_write_unlock(ubi, vol_id, lnum); | 918 | leb_write_unlock(ubi, vol_id, lnum); |
913 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
914 | return 0; | ||
915 | |||
916 | write_error: | ||
917 | if (err != -EIO || !ubi->bad_allowed) { | ||
918 | /* | ||
919 | * This flash device does not admit of bad eraseblocks or | ||
920 | * something nasty and unexpected happened. Switch to read-only | ||
921 | * mode just in case. | ||
922 | */ | ||
923 | ubi_ro_mode(ubi); | ||
924 | leb_write_unlock(ubi, vol_id, lnum); | ||
925 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
926 | return err; | ||
927 | } | ||
928 | 919 | ||
929 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); | 920 | out: |
930 | if (err || ++tries > UBI_IO_RETRIES) { | 921 | ubi_free_vid_hdr(ubi, vid_hdr); |
931 | ubi_ro_mode(ubi); | ||
932 | leb_write_unlock(ubi, vol_id, lnum); | ||
933 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
934 | return err; | ||
935 | } | ||
936 | 922 | ||
937 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); | 923 | return err; |
938 | ubi_msg(ubi, "try another PEB"); | ||
939 | goto retry; | ||
940 | } | 924 | } |
941 | 925 | ||
942 | /* | 926 | /* |
@@ -959,7 +943,7 @@ write_error: | |||
959 | int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, | 943 | int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, |
960 | int lnum, const void *buf, int len) | 944 | int lnum, const void *buf, int len) |
961 | { | 945 | { |
962 | int err, pnum, old_pnum, tries = 0, vol_id = vol->vol_id; | 946 | int err, tries, vol_id = vol->vol_id; |
963 | struct ubi_vid_hdr *vid_hdr; | 947 | struct ubi_vid_hdr *vid_hdr; |
964 | uint32_t crc; | 948 | uint32_t crc; |
965 | 949 | ||
@@ -998,70 +982,31 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, | |||
998 | vid_hdr->copy_flag = 1; | 982 | vid_hdr->copy_flag = 1; |
999 | vid_hdr->data_crc = cpu_to_be32(crc); | 983 | vid_hdr->data_crc = cpu_to_be32(crc); |
1000 | 984 | ||
1001 | retry: | 985 | dbg_eba("change LEB %d:%d", vol_id, lnum); |
1002 | pnum = ubi_wl_get_peb(ubi); | ||
1003 | if (pnum < 0) { | ||
1004 | err = pnum; | ||
1005 | up_read(&ubi->fm_eba_sem); | ||
1006 | goto out_leb_unlock; | ||
1007 | } | ||
1008 | |||
1009 | dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", | ||
1010 | vol_id, lnum, vol->eba_tbl[lnum], pnum); | ||
1011 | 986 | ||
1012 | err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); | 987 | for (tries = 0; tries <= UBI_IO_RETRIES; tries++) { |
1013 | if (err) { | 988 | err = try_write_vid_and_data(vol, lnum, vid_hdr, buf, 0, len); |
1014 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | 989 | if (err != -EIO || !ubi->bad_allowed) |
1015 | vol_id, lnum, pnum); | 990 | break; |
1016 | up_read(&ubi->fm_eba_sem); | ||
1017 | goto write_error; | ||
1018 | } | ||
1019 | 991 | ||
1020 | err = ubi_io_write_data(ubi, buf, pnum, 0, len); | 992 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); |
1021 | if (err) { | 993 | ubi_msg(ubi, "try another PEB"); |
1022 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", | ||
1023 | len, pnum); | ||
1024 | up_read(&ubi->fm_eba_sem); | ||
1025 | goto write_error; | ||
1026 | } | 994 | } |
1027 | 995 | ||
1028 | old_pnum = vol->eba_tbl[lnum]; | 996 | /* |
1029 | vol->eba_tbl[lnum] = pnum; | 997 | * This flash device does not admit of bad eraseblocks or |
1030 | up_read(&ubi->fm_eba_sem); | 998 | * something nasty and unexpected happened. Switch to read-only |
1031 | 999 | * mode just in case. | |
1032 | if (old_pnum >= 0) { | 1000 | */ |
1033 | err = ubi_wl_put_peb(ubi, vol_id, lnum, old_pnum, 0); | 1001 | if (err) |
1034 | if (err) | 1002 | ubi_ro_mode(ubi); |
1035 | goto out_leb_unlock; | ||
1036 | } | ||
1037 | 1003 | ||
1038 | out_leb_unlock: | ||
1039 | leb_write_unlock(ubi, vol_id, lnum); | 1004 | leb_write_unlock(ubi, vol_id, lnum); |
1005 | |||
1040 | out_mutex: | 1006 | out_mutex: |
1041 | mutex_unlock(&ubi->alc_mutex); | 1007 | mutex_unlock(&ubi->alc_mutex); |
1042 | ubi_free_vid_hdr(ubi, vid_hdr); | 1008 | ubi_free_vid_hdr(ubi, vid_hdr); |
1043 | return err; | 1009 | return err; |
1044 | |||
1045 | write_error: | ||
1046 | if (err != -EIO || !ubi->bad_allowed) { | ||
1047 | /* | ||
1048 | * This flash device does not admit of bad eraseblocks or | ||
1049 | * something nasty and unexpected happened. Switch to read-only | ||
1050 | * mode just in case. | ||
1051 | */ | ||
1052 | ubi_ro_mode(ubi); | ||
1053 | goto out_leb_unlock; | ||
1054 | } | ||
1055 | |||
1056 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); | ||
1057 | if (err || ++tries > UBI_IO_RETRIES) { | ||
1058 | ubi_ro_mode(ubi); | ||
1059 | goto out_leb_unlock; | ||
1060 | } | ||
1061 | |||
1062 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); | ||
1063 | ubi_msg(ubi, "try another PEB"); | ||
1064 | goto retry; | ||
1065 | } | 1010 | } |
1066 | 1011 | ||
1067 | /** | 1012 | /** |