diff options
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 161 |
1 files changed, 150 insertions, 11 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 4048db83aef6..286ed594e5a0 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
42 | #include <linux/log2.h> | 42 | #include <linux/log2.h> |
43 | #include <linux/kthread.h> | 43 | #include <linux/kthread.h> |
44 | #include <linux/reboot.h> | ||
44 | #include "ubi.h" | 45 | #include "ubi.h" |
45 | 46 | ||
46 | /* Maximum length of the 'mtd=' parameter */ | 47 | /* Maximum length of the 'mtd=' parameter */ |
@@ -122,6 +123,94 @@ static struct device_attribute dev_mtd_num = | |||
122 | __ATTR(mtd_num, S_IRUGO, dev_attribute_show, NULL); | 123 | __ATTR(mtd_num, S_IRUGO, dev_attribute_show, NULL); |
123 | 124 | ||
124 | /** | 125 | /** |
126 | * ubi_volume_notify - send a volume change notification. | ||
127 | * @ubi: UBI device description object | ||
128 | * @vol: volume description object of the changed volume | ||
129 | * @ntype: notification type to send (%UBI_VOLUME_ADDED, etc) | ||
130 | * | ||
131 | * This is a helper function which notifies all subscribers about a volume | ||
132 | * change event (creation, removal, re-sizing, re-naming, updating). Returns | ||
133 | * zero in case of success and a negative error code in case of failure. | ||
134 | */ | ||
135 | int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) | ||
136 | { | ||
137 | struct ubi_notification nt; | ||
138 | |||
139 | ubi_do_get_device_info(ubi, &nt.di); | ||
140 | ubi_do_get_volume_info(ubi, vol, &nt.vi); | ||
141 | return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * ubi_notify_all - send a notification to all volumes. | ||
146 | * @ubi: UBI device description object | ||
147 | * @ntype: notification type to send (%UBI_VOLUME_ADDED, etc) | ||
148 | * @nb: the notifier to call | ||
149 | * | ||
150 | * This function walks all volumes of UBI device @ubi and sends the @ntype | ||
151 | * notification for each volume. If @nb is %NULL, then all registered notifiers | ||
152 | * are called, otherwise only the @nb notifier is called. Returns the number of | ||
153 | * sent notifications. | ||
154 | */ | ||
155 | int ubi_notify_all(struct ubi_device *ubi, int ntype, struct notifier_block *nb) | ||
156 | { | ||
157 | struct ubi_notification nt; | ||
158 | int i, count = 0; | ||
159 | |||
160 | ubi_do_get_device_info(ubi, &nt.di); | ||
161 | |||
162 | mutex_lock(&ubi->device_mutex); | ||
163 | for (i = 0; i < ubi->vtbl_slots; i++) { | ||
164 | /* | ||
165 | * Since the @ubi->device is locked, and we are not going to | ||
166 | * change @ubi->volumes, we do not have to lock | ||
167 | * @ubi->volumes_lock. | ||
168 | */ | ||
169 | if (!ubi->volumes[i]) | ||
170 | continue; | ||
171 | |||
172 | ubi_do_get_volume_info(ubi, ubi->volumes[i], &nt.vi); | ||
173 | if (nb) | ||
174 | nb->notifier_call(nb, ntype, &nt); | ||
175 | else | ||
176 | blocking_notifier_call_chain(&ubi_notifiers, ntype, | ||
177 | &nt); | ||
178 | count += 1; | ||
179 | } | ||
180 | mutex_unlock(&ubi->device_mutex); | ||
181 | |||
182 | return count; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * ubi_enumerate_volumes - send "add" notification for all existing volumes. | ||
187 | * @nb: the notifier to call | ||
188 | * | ||
189 | * This function walks all UBI devices and volumes and sends the | ||
190 | * %UBI_VOLUME_ADDED notification for each volume. If @nb is %NULL, then all | ||
191 | * registered notifiers are called, otherwise only the @nb notifier is called. | ||
192 | * Returns the number of sent notifications. | ||
193 | */ | ||
194 | int ubi_enumerate_volumes(struct notifier_block *nb) | ||
195 | { | ||
196 | int i, count = 0; | ||
197 | |||
198 | /* | ||
199 | * Since the @ubi_devices_mutex is locked, and we are not going to | ||
200 | * change @ubi_devices, we do not have to lock @ubi_devices_lock. | ||
201 | */ | ||
202 | for (i = 0; i < UBI_MAX_DEVICES; i++) { | ||
203 | struct ubi_device *ubi = ubi_devices[i]; | ||
204 | |||
205 | if (!ubi) | ||
206 | continue; | ||
207 | count += ubi_notify_all(ubi, UBI_VOLUME_ADDED, nb); | ||
208 | } | ||
209 | |||
210 | return count; | ||
211 | } | ||
212 | |||
213 | /** | ||
125 | * ubi_get_device - get UBI device. | 214 | * ubi_get_device - get UBI device. |
126 | * @ubi_num: UBI device number | 215 | * @ubi_num: UBI device number |
127 | * | 216 | * |
@@ -380,7 +469,7 @@ static void free_user_volumes(struct ubi_device *ubi) | |||
380 | * @ubi: UBI device description object | 469 | * @ubi: UBI device description object |
381 | * | 470 | * |
382 | * This function returns zero in case of success and a negative error code in | 471 | * This function returns zero in case of success and a negative error code in |
383 | * case of failure. Note, this function destroys all volumes if it failes. | 472 | * case of failure. Note, this function destroys all volumes if it fails. |
384 | */ | 473 | */ |
385 | static int uif_init(struct ubi_device *ubi) | 474 | static int uif_init(struct ubi_device *ubi) |
386 | { | 475 | { |
@@ -633,6 +722,15 @@ static int io_init(struct ubi_device *ubi) | |||
633 | } | 722 | } |
634 | 723 | ||
635 | /* | 724 | /* |
725 | * Set maximum amount of physical erroneous eraseblocks to be 10%. | ||
726 | * Erroneous PEB are those which have read errors. | ||
727 | */ | ||
728 | ubi->max_erroneous = ubi->peb_count / 10; | ||
729 | if (ubi->max_erroneous < 16) | ||
730 | ubi->max_erroneous = 16; | ||
731 | dbg_msg("max_erroneous %d", ubi->max_erroneous); | ||
732 | |||
733 | /* | ||
636 | * It may happen that EC and VID headers are situated in one minimal | 734 | * It may happen that EC and VID headers are situated in one minimal |
637 | * I/O unit. In this case we can only accept this UBI image in | 735 | * I/O unit. In this case we can only accept this UBI image in |
638 | * read-only mode. | 736 | * read-only mode. |
@@ -726,6 +824,34 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
726 | } | 824 | } |
727 | 825 | ||
728 | /** | 826 | /** |
827 | * ubi_reboot_notifier - halt UBI transactions immediately prior to a reboot. | ||
828 | * @n: reboot notifier object | ||
829 | * @state: SYS_RESTART, SYS_HALT, or SYS_POWER_OFF | ||
830 | * @cmd: pointer to command string for RESTART2 | ||
831 | * | ||
832 | * This function stops the UBI background thread so that the flash device | ||
833 | * remains quiescent when Linux restarts the system. Any queued work will be | ||
834 | * discarded, but this function will block until do_work() finishes if an | ||
835 | * operation is already in progress. | ||
836 | * | ||
837 | * This function solves a real-life problem observed on NOR flashes when an | ||
838 | * PEB erase operation starts, then the system is rebooted before the erase is | ||
839 | * finishes, and the boot loader gets confused and dies. So we prefer to finish | ||
840 | * the ongoing operation before rebooting. | ||
841 | */ | ||
842 | static int ubi_reboot_notifier(struct notifier_block *n, unsigned long state, | ||
843 | void *cmd) | ||
844 | { | ||
845 | struct ubi_device *ubi; | ||
846 | |||
847 | ubi = container_of(n, struct ubi_device, reboot_notifier); | ||
848 | if (ubi->bgt_thread) | ||
849 | kthread_stop(ubi->bgt_thread); | ||
850 | ubi_sync(ubi->ubi_num); | ||
851 | return NOTIFY_DONE; | ||
852 | } | ||
853 | |||
854 | /** | ||
729 | * ubi_attach_mtd_dev - attach an MTD device. | 855 | * ubi_attach_mtd_dev - attach an MTD device. |
730 | * @mtd: MTD device description object | 856 | * @mtd: MTD device description object |
731 | * @ubi_num: number to assign to the new UBI device | 857 | * @ubi_num: number to assign to the new UBI device |
@@ -806,8 +932,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
806 | 932 | ||
807 | mutex_init(&ubi->buf_mutex); | 933 | mutex_init(&ubi->buf_mutex); |
808 | mutex_init(&ubi->ckvol_mutex); | 934 | mutex_init(&ubi->ckvol_mutex); |
809 | mutex_init(&ubi->mult_mutex); | 935 | mutex_init(&ubi->device_mutex); |
810 | mutex_init(&ubi->volumes_mutex); | ||
811 | spin_lock_init(&ubi->volumes_lock); | 936 | spin_lock_init(&ubi->volumes_lock); |
812 | 937 | ||
813 | ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); | 938 | ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); |
@@ -825,7 +950,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
825 | if (!ubi->peb_buf2) | 950 | if (!ubi->peb_buf2) |
826 | goto out_free; | 951 | goto out_free; |
827 | 952 | ||
828 | #ifdef CONFIG_MTD_UBI_DEBUG | 953 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
829 | mutex_init(&ubi->dbg_buf_mutex); | 954 | mutex_init(&ubi->dbg_buf_mutex); |
830 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); | 955 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); |
831 | if (!ubi->dbg_peb_buf) | 956 | if (!ubi->dbg_peb_buf) |
@@ -872,11 +997,23 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
872 | ubi->beb_rsvd_pebs); | 997 | ubi->beb_rsvd_pebs); |
873 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 998 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
874 | 999 | ||
1000 | /* | ||
1001 | * The below lock makes sure we do not race with 'ubi_thread()' which | ||
1002 | * checks @ubi->thread_enabled. Otherwise we may fail to wake it up. | ||
1003 | */ | ||
1004 | spin_lock(&ubi->wl_lock); | ||
875 | if (!DBG_DISABLE_BGT) | 1005 | if (!DBG_DISABLE_BGT) |
876 | ubi->thread_enabled = 1; | 1006 | ubi->thread_enabled = 1; |
877 | wake_up_process(ubi->bgt_thread); | 1007 | wake_up_process(ubi->bgt_thread); |
1008 | spin_unlock(&ubi->wl_lock); | ||
1009 | |||
1010 | /* Flash device priority is 0 - UBI needs to shut down first */ | ||
1011 | ubi->reboot_notifier.priority = 1; | ||
1012 | ubi->reboot_notifier.notifier_call = ubi_reboot_notifier; | ||
1013 | register_reboot_notifier(&ubi->reboot_notifier); | ||
878 | 1014 | ||
879 | ubi_devices[ubi_num] = ubi; | 1015 | ubi_devices[ubi_num] = ubi; |
1016 | ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); | ||
880 | return ubi_num; | 1017 | return ubi_num; |
881 | 1018 | ||
882 | out_uif: | 1019 | out_uif: |
@@ -892,7 +1029,7 @@ out_detach: | |||
892 | out_free: | 1029 | out_free: |
893 | vfree(ubi->peb_buf1); | 1030 | vfree(ubi->peb_buf1); |
894 | vfree(ubi->peb_buf2); | 1031 | vfree(ubi->peb_buf2); |
895 | #ifdef CONFIG_MTD_UBI_DEBUG | 1032 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
896 | vfree(ubi->dbg_peb_buf); | 1033 | vfree(ubi->dbg_peb_buf); |
897 | #endif | 1034 | #endif |
898 | kfree(ubi); | 1035 | kfree(ubi); |
@@ -919,13 +1056,13 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
919 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) | 1056 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) |
920 | return -EINVAL; | 1057 | return -EINVAL; |
921 | 1058 | ||
922 | spin_lock(&ubi_devices_lock); | 1059 | ubi = ubi_get_device(ubi_num); |
923 | ubi = ubi_devices[ubi_num]; | 1060 | if (!ubi) |
924 | if (!ubi) { | ||
925 | spin_unlock(&ubi_devices_lock); | ||
926 | return -EINVAL; | 1061 | return -EINVAL; |
927 | } | ||
928 | 1062 | ||
1063 | spin_lock(&ubi_devices_lock); | ||
1064 | put_device(&ubi->dev); | ||
1065 | ubi->ref_count -= 1; | ||
929 | if (ubi->ref_count) { | 1066 | if (ubi->ref_count) { |
930 | if (!anyway) { | 1067 | if (!anyway) { |
931 | spin_unlock(&ubi_devices_lock); | 1068 | spin_unlock(&ubi_devices_lock); |
@@ -939,12 +1076,14 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
939 | spin_unlock(&ubi_devices_lock); | 1076 | spin_unlock(&ubi_devices_lock); |
940 | 1077 | ||
941 | ubi_assert(ubi_num == ubi->ubi_num); | 1078 | ubi_assert(ubi_num == ubi->ubi_num); |
1079 | ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); | ||
942 | dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); | 1080 | dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); |
943 | 1081 | ||
944 | /* | 1082 | /* |
945 | * Before freeing anything, we have to stop the background thread to | 1083 | * Before freeing anything, we have to stop the background thread to |
946 | * prevent it from doing anything on this device while we are freeing. | 1084 | * prevent it from doing anything on this device while we are freeing. |
947 | */ | 1085 | */ |
1086 | unregister_reboot_notifier(&ubi->reboot_notifier); | ||
948 | if (ubi->bgt_thread) | 1087 | if (ubi->bgt_thread) |
949 | kthread_stop(ubi->bgt_thread); | 1088 | kthread_stop(ubi->bgt_thread); |
950 | 1089 | ||
@@ -961,7 +1100,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
961 | put_mtd_device(ubi->mtd); | 1100 | put_mtd_device(ubi->mtd); |
962 | vfree(ubi->peb_buf1); | 1101 | vfree(ubi->peb_buf1); |
963 | vfree(ubi->peb_buf2); | 1102 | vfree(ubi->peb_buf2); |
964 | #ifdef CONFIG_MTD_UBI_DEBUG | 1103 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
965 | vfree(ubi->dbg_peb_buf); | 1104 | vfree(ubi->dbg_peb_buf); |
966 | #endif | 1105 | #endif |
967 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 1106 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |