diff options
| author | Richard Weinberger <richard@nod.at> | 2012-09-26 11:51:42 -0400 |
|---|---|---|
| committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-10-03 05:29:37 -0400 |
| commit | 5638b33abffd967dda4f984a247925b7af38b23d (patch) | |
| tree | 1df7dfde3faec82ce76e169c425c936625cfe017 /drivers/mtd/ubi | |
| parent | 1c865749999efdae63ddfb73b911ee04e1d4e1c8 (diff) | |
UBI: Add fastmap stuff to ubi.h
This patch adds fastmap specific data structures to ubi.h.
It moves also struct ubi_work to ubi.h as it is now needed
for more than one c file.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd/ubi')
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 116 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 24 |
2 files changed, 115 insertions, 25 deletions
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 383ee43d2425..b0d3ba2a3dea 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -133,6 +133,17 @@ enum { | |||
| 133 | MOVE_RETRY, | 133 | MOVE_RETRY, |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | /* | ||
| 137 | * Return codes of the fastmap sub-system | ||
| 138 | * | ||
| 139 | * UBI_NO_FASTMAP: No fastmap super block was found | ||
| 140 | * UBI_BAD_FASTMAP: A fastmap was found but it's unusable | ||
| 141 | */ | ||
| 142 | enum { | ||
| 143 | UBI_NO_FASTMAP = 1, | ||
| 144 | UBI_BAD_FASTMAP, | ||
| 145 | }; | ||
| 146 | |||
| 136 | /** | 147 | /** |
| 137 | * struct ubi_wl_entry - wear-leveling entry. | 148 | * struct ubi_wl_entry - wear-leveling entry. |
| 138 | * @u.rb: link in the corresponding (free/used) RB-tree | 149 | * @u.rb: link in the corresponding (free/used) RB-tree |
| @@ -199,6 +210,41 @@ struct ubi_rename_entry { | |||
| 199 | struct ubi_volume_desc; | 210 | struct ubi_volume_desc; |
| 200 | 211 | ||
| 201 | /** | 212 | /** |
| 213 | * struct ubi_fastmap_layout - in-memory fastmap data structure. | ||
| 214 | * @e: PEBs used by the current fastmap | ||
| 215 | * @to_be_tortured: if non-zero tortured this PEB | ||
| 216 | * @used_blocks: number of used PEBs | ||
| 217 | * @max_pool_size: maximal size of the user pool | ||
| 218 | * @max_wl_pool_size: maximal size of the pool used by the WL sub-system | ||
| 219 | */ | ||
| 220 | struct ubi_fastmap_layout { | ||
| 221 | struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS]; | ||
| 222 | int to_be_tortured[UBI_FM_MAX_BLOCKS]; | ||
| 223 | int used_blocks; | ||
| 224 | int max_pool_size; | ||
| 225 | int max_wl_pool_size; | ||
| 226 | }; | ||
| 227 | |||
| 228 | /** | ||
| 229 | * struct ubi_fm_pool - in-memory fastmap pool | ||
| 230 | * @pebs: PEBs in this pool | ||
| 231 | * @used: number of used PEBs | ||
| 232 | * @size: total number of PEBs in this pool | ||
| 233 | * @max_size: maximal size of the pool | ||
| 234 | * | ||
| 235 | * A pool gets filled with up to max_size. | ||
| 236 | * If all PEBs within the pool are used a new fastmap will be written | ||
| 237 | * to the flash and the pool gets refilled with empty PEBs. | ||
| 238 | * | ||
| 239 | */ | ||
| 240 | struct ubi_fm_pool { | ||
| 241 | int pebs[UBI_FM_MAX_POOL_SIZE]; | ||
| 242 | int used; | ||
| 243 | int size; | ||
| 244 | int max_size; | ||
| 245 | }; | ||
| 246 | |||
| 247 | /** | ||
| 202 | * struct ubi_volume - UBI volume description data structure. | 248 | * struct ubi_volume - UBI volume description data structure. |
| 203 | * @dev: device object to make use of the the Linux device model | 249 | * @dev: device object to make use of the the Linux device model |
| 204 | * @cdev: character device object to create character device | 250 | * @cdev: character device object to create character device |
| @@ -333,9 +379,21 @@ struct ubi_wl_entry; | |||
| 333 | * @ltree: the lock tree | 379 | * @ltree: the lock tree |
| 334 | * @alc_mutex: serializes "atomic LEB change" operations | 380 | * @alc_mutex: serializes "atomic LEB change" operations |
| 335 | * | 381 | * |
| 382 | * @fm_disabled: non-zero if fastmap is disabled (default) | ||
| 383 | * @fm: in-memory data structure of the currently used fastmap | ||
| 384 | * @fm_pool: in-memory data structure of the fastmap pool | ||
| 385 | * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL | ||
| 386 | * sub-system | ||
| 387 | * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf | ||
| 388 | * @fm_buf: vmalloc()'d buffer which holds the raw fastmap | ||
| 389 | * @fm_size: fastmap size in bytes | ||
| 390 | * @fm_sem: allows ubi_update_fastmap() to block EBA table changes | ||
| 391 | * @fm_work: fastmap work queue | ||
| 392 | * | ||
| 336 | * @used: RB-tree of used physical eraseblocks | 393 | * @used: RB-tree of used physical eraseblocks |
| 337 | * @erroneous: RB-tree of erroneous used physical eraseblocks | 394 | * @erroneous: RB-tree of erroneous used physical eraseblocks |
| 338 | * @free: RB-tree of free physical eraseblocks | 395 | * @free: RB-tree of free physical eraseblocks |
| 396 | * @free_count: Contains the number of elements in @free | ||
| 339 | * @scrub: RB-tree of physical eraseblocks which need scrubbing | 397 | * @scrub: RB-tree of physical eraseblocks which need scrubbing |
| 340 | * @pq: protection queue (contain physical eraseblocks which are temporarily | 398 | * @pq: protection queue (contain physical eraseblocks which are temporarily |
| 341 | * protected from the wear-leveling worker) | 399 | * protected from the wear-leveling worker) |
| @@ -426,10 +484,22 @@ struct ubi_device { | |||
| 426 | struct rb_root ltree; | 484 | struct rb_root ltree; |
| 427 | struct mutex alc_mutex; | 485 | struct mutex alc_mutex; |
| 428 | 486 | ||
| 487 | /* Fastmap stuff */ | ||
| 488 | int fm_disabled; | ||
| 489 | struct ubi_fastmap_layout *fm; | ||
| 490 | struct ubi_fm_pool fm_pool; | ||
| 491 | struct ubi_fm_pool fm_wl_pool; | ||
| 492 | struct rw_semaphore fm_sem; | ||
| 493 | struct mutex fm_mutex; | ||
| 494 | void *fm_buf; | ||
| 495 | size_t fm_size; | ||
| 496 | struct work_struct fm_work; | ||
| 497 | |||
| 429 | /* Wear-leveling sub-system's stuff */ | 498 | /* Wear-leveling sub-system's stuff */ |
| 430 | struct rb_root used; | 499 | struct rb_root used; |
| 431 | struct rb_root erroneous; | 500 | struct rb_root erroneous; |
| 432 | struct rb_root free; | 501 | struct rb_root free; |
| 502 | int free_count; | ||
| 433 | struct rb_root scrub; | 503 | struct rb_root scrub; |
| 434 | struct list_head pq[UBI_PROT_QUEUE_LEN]; | 504 | struct list_head pq[UBI_PROT_QUEUE_LEN]; |
| 435 | int pq_head; | 505 | int pq_head; |
| @@ -596,6 +666,32 @@ struct ubi_attach_info { | |||
| 596 | struct kmem_cache *aeb_slab_cache; | 666 | struct kmem_cache *aeb_slab_cache; |
| 597 | }; | 667 | }; |
| 598 | 668 | ||
| 669 | /** | ||
| 670 | * struct ubi_work - UBI work description data structure. | ||
| 671 | * @list: a link in the list of pending works | ||
| 672 | * @func: worker function | ||
| 673 | * @e: physical eraseblock to erase | ||
| 674 | * @vol_id: the volume ID on which this erasure is being performed | ||
| 675 | * @lnum: the logical eraseblock number | ||
| 676 | * @torture: if the physical eraseblock has to be tortured | ||
| 677 | * @anchor: produce a anchor PEB to by used by fastmap | ||
| 678 | * | ||
| 679 | * The @func pointer points to the worker function. If the @cancel argument is | ||
| 680 | * not zero, the worker has to free the resources and exit immediately. The | ||
| 681 | * worker has to return zero in case of success and a negative error code in | ||
| 682 | * case of failure. | ||
| 683 | */ | ||
| 684 | struct ubi_work { | ||
| 685 | struct list_head list; | ||
| 686 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | ||
| 687 | /* The below fields are only relevant to erasure works */ | ||
| 688 | struct ubi_wl_entry *e; | ||
| 689 | int vol_id; | ||
| 690 | int lnum; | ||
| 691 | int torture; | ||
| 692 | int anchor; | ||
| 693 | }; | ||
| 694 | |||
| 599 | #include "debug.h" | 695 | #include "debug.h" |
| 600 | 696 | ||
| 601 | extern struct kmem_cache *ubi_wl_entry_slab; | 697 | extern struct kmem_cache *ubi_wl_entry_slab; |
| @@ -606,7 +702,7 @@ extern struct class *ubi_class; | |||
| 606 | extern struct mutex ubi_devices_mutex; | 702 | extern struct mutex ubi_devices_mutex; |
| 607 | extern struct blocking_notifier_head ubi_notifiers; | 703 | extern struct blocking_notifier_head ubi_notifiers; |
| 608 | 704 | ||
| 609 | /* scan.c */ | 705 | /* attach.c */ |
| 610 | int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, | 706 | int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, |
| 611 | int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); | 707 | int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); |
| 612 | struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, | 708 | struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, |
| @@ -664,6 +760,9 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, | |||
| 664 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 760 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
| 665 | struct ubi_vid_hdr *vid_hdr); | 761 | struct ubi_vid_hdr *vid_hdr); |
| 666 | int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | 762 | int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); |
| 763 | unsigned long long ubi_next_sqnum(struct ubi_device *ubi); | ||
| 764 | int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, | ||
| 765 | struct ubi_attach_info *ai_scan); | ||
| 667 | 766 | ||
| 668 | /* wl.c */ | 767 | /* wl.c */ |
| 669 | int ubi_wl_get_peb(struct ubi_device *ubi); | 768 | int ubi_wl_get_peb(struct ubi_device *ubi); |
| @@ -674,6 +773,12 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); | |||
| 674 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | 773 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); |
| 675 | void ubi_wl_close(struct ubi_device *ubi); | 774 | void ubi_wl_close(struct ubi_device *ubi); |
| 676 | int ubi_thread(void *u); | 775 | int ubi_thread(void *u); |
| 776 | struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor); | ||
| 777 | int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e, | ||
| 778 | int lnum, int torture); | ||
| 779 | int ubi_is_erase_work(struct ubi_work *wrk); | ||
| 780 | void ubi_refill_pools(struct ubi_device *ubi); | ||
| 781 | int ubi_ensure_anchor_pebs(struct ubi_device *ubi); | ||
| 677 | 782 | ||
| 678 | /* io.c */ | 783 | /* io.c */ |
| 679 | int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, | 784 | int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, |
| @@ -711,6 +816,15 @@ void ubi_free_internal_volumes(struct ubi_device *ubi); | |||
| 711 | void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); | 816 | void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); |
| 712 | void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, | 817 | void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, |
| 713 | struct ubi_volume_info *vi); | 818 | struct ubi_volume_info *vi); |
| 819 | /* scan.c */ | ||
| 820 | int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | ||
| 821 | int pnum, const struct ubi_vid_hdr *vid_hdr); | ||
| 822 | |||
| 823 | /* fastmap.c */ | ||
| 824 | size_t ubi_calc_fm_size(struct ubi_device *ubi); | ||
| 825 | int ubi_update_fastmap(struct ubi_device *ubi); | ||
| 826 | int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | ||
| 827 | int fm_anchor); | ||
| 714 | 828 | ||
| 715 | /* | 829 | /* |
| 716 | * ubi_rb_for_each_entry - walk an RB-tree. | 830 | * ubi_rb_for_each_entry - walk an RB-tree. |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 032fc57f1090..f4d06dbdb2a9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -135,30 +135,6 @@ | |||
| 135 | */ | 135 | */ |
| 136 | #define WL_MAX_FAILURES 32 | 136 | #define WL_MAX_FAILURES 32 |
| 137 | 137 | ||
| 138 | /** | ||
| 139 | * struct ubi_work - UBI work description data structure. | ||
| 140 | * @list: a link in the list of pending works | ||
| 141 | * @func: worker function | ||
| 142 | * @e: physical eraseblock to erase | ||
| 143 | * @vol_id: the volume ID on which this erasure is being performed | ||
| 144 | * @lnum: the logical eraseblock number | ||
| 145 | * @torture: if the physical eraseblock has to be tortured | ||
| 146 | * | ||
| 147 | * The @func pointer points to the worker function. If the @cancel argument is | ||
| 148 | * not zero, the worker has to free the resources and exit immediately. The | ||
| 149 | * worker has to return zero in case of success and a negative error code in | ||
| 150 | * case of failure. | ||
| 151 | */ | ||
| 152 | struct ubi_work { | ||
| 153 | struct list_head list; | ||
| 154 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | ||
| 155 | /* The below fields are only relevant to erasure works */ | ||
| 156 | struct ubi_wl_entry *e; | ||
| 157 | int vol_id; | ||
| 158 | int lnum; | ||
| 159 | int torture; | ||
| 160 | }; | ||
| 161 | |||
| 162 | static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); | 138 | static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); |
| 163 | static int self_check_in_wl_tree(const struct ubi_device *ubi, | 139 | static int self_check_in_wl_tree(const struct ubi_device *ubi, |
| 164 | struct ubi_wl_entry *e, struct rb_root *root); | 140 | struct ubi_wl_entry *e, struct rb_root *root); |
