1ff94bc40SHeiko Schocher /* 2ff94bc40SHeiko Schocher * Copyright (c) 2012 Linutronix GmbH 30195a7bbSHeiko Schocher * Copyright (c) 2014 sigma star gmbh 4ff94bc40SHeiko Schocher * Author: Richard Weinberger <richard@nod.at> 5ff94bc40SHeiko Schocher * 6ff94bc40SHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 7ff94bc40SHeiko Schocher * 8ff94bc40SHeiko Schocher */ 9ff94bc40SHeiko Schocher 10ff94bc40SHeiko Schocher #ifndef __UBOOT__ 11ff94bc40SHeiko Schocher #include <linux/crc32.h> 12ff94bc40SHeiko Schocher #else 13ff94bc40SHeiko Schocher #include <div64.h> 14ff94bc40SHeiko Schocher #include <malloc.h> 15ff94bc40SHeiko Schocher #include <ubi_uboot.h> 16ff94bc40SHeiko Schocher #endif 17ff94bc40SHeiko Schocher 18ff94bc40SHeiko Schocher #include <linux/compat.h> 19ff94bc40SHeiko Schocher #include <linux/math64.h> 20ff94bc40SHeiko Schocher #include "ubi.h" 21ff94bc40SHeiko Schocher 22ff94bc40SHeiko Schocher /** 230195a7bbSHeiko Schocher * init_seen - allocate memory for used for debugging. 240195a7bbSHeiko Schocher * @ubi: UBI device description object 250195a7bbSHeiko Schocher */ 260195a7bbSHeiko Schocher static inline int *init_seen(struct ubi_device *ubi) 270195a7bbSHeiko Schocher { 280195a7bbSHeiko Schocher int *ret; 290195a7bbSHeiko Schocher 300195a7bbSHeiko Schocher if (!ubi_dbg_chk_fastmap(ubi)) 310195a7bbSHeiko Schocher return NULL; 320195a7bbSHeiko Schocher 330195a7bbSHeiko Schocher ret = kcalloc(ubi->peb_count, sizeof(int), GFP_KERNEL); 340195a7bbSHeiko Schocher if (!ret) 350195a7bbSHeiko Schocher return ERR_PTR(-ENOMEM); 360195a7bbSHeiko Schocher 370195a7bbSHeiko Schocher return ret; 380195a7bbSHeiko Schocher } 390195a7bbSHeiko Schocher 400195a7bbSHeiko Schocher /** 410195a7bbSHeiko Schocher * free_seen - free the seen logic integer array. 420195a7bbSHeiko Schocher * @seen: integer array of @ubi->peb_count size 430195a7bbSHeiko Schocher */ 440195a7bbSHeiko Schocher static inline void free_seen(int *seen) 450195a7bbSHeiko Schocher { 460195a7bbSHeiko Schocher kfree(seen); 470195a7bbSHeiko Schocher } 480195a7bbSHeiko Schocher 490195a7bbSHeiko Schocher /** 500195a7bbSHeiko Schocher * set_seen - mark a PEB as seen. 510195a7bbSHeiko Schocher * @ubi: UBI device description object 520195a7bbSHeiko Schocher * @pnum: The PEB to be makred as seen 530195a7bbSHeiko Schocher * @seen: integer array of @ubi->peb_count size 540195a7bbSHeiko Schocher */ 550195a7bbSHeiko Schocher static inline void set_seen(struct ubi_device *ubi, int pnum, int *seen) 560195a7bbSHeiko Schocher { 570195a7bbSHeiko Schocher if (!ubi_dbg_chk_fastmap(ubi) || !seen) 580195a7bbSHeiko Schocher return; 590195a7bbSHeiko Schocher 600195a7bbSHeiko Schocher seen[pnum] = 1; 610195a7bbSHeiko Schocher } 620195a7bbSHeiko Schocher 630195a7bbSHeiko Schocher /** 640195a7bbSHeiko Schocher * self_check_seen - check whether all PEB have been seen by fastmap. 650195a7bbSHeiko Schocher * @ubi: UBI device description object 660195a7bbSHeiko Schocher * @seen: integer array of @ubi->peb_count size 670195a7bbSHeiko Schocher */ 680195a7bbSHeiko Schocher static int self_check_seen(struct ubi_device *ubi, int *seen) 690195a7bbSHeiko Schocher { 700195a7bbSHeiko Schocher int pnum, ret = 0; 710195a7bbSHeiko Schocher 720195a7bbSHeiko Schocher if (!ubi_dbg_chk_fastmap(ubi) || !seen) 730195a7bbSHeiko Schocher return 0; 740195a7bbSHeiko Schocher 750195a7bbSHeiko Schocher for (pnum = 0; pnum < ubi->peb_count; pnum++) { 760195a7bbSHeiko Schocher if (!seen[pnum] && ubi->lookuptbl[pnum]) { 770195a7bbSHeiko Schocher ubi_err(ubi, "self-check failed for PEB %d, fastmap didn't see it", pnum); 780195a7bbSHeiko Schocher ret = -EINVAL; 790195a7bbSHeiko Schocher } 800195a7bbSHeiko Schocher } 810195a7bbSHeiko Schocher 820195a7bbSHeiko Schocher return ret; 830195a7bbSHeiko Schocher } 840195a7bbSHeiko Schocher 850195a7bbSHeiko Schocher /** 86ff94bc40SHeiko Schocher * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device. 87ff94bc40SHeiko Schocher * @ubi: UBI device description object 88ff94bc40SHeiko Schocher */ 89ff94bc40SHeiko Schocher size_t ubi_calc_fm_size(struct ubi_device *ubi) 90ff94bc40SHeiko Schocher { 91ff94bc40SHeiko Schocher size_t size; 92ff94bc40SHeiko Schocher 930195a7bbSHeiko Schocher size = sizeof(struct ubi_fm_sb) + 940195a7bbSHeiko Schocher sizeof(struct ubi_fm_hdr) + 950195a7bbSHeiko Schocher sizeof(struct ubi_fm_scan_pool) + 960195a7bbSHeiko Schocher sizeof(struct ubi_fm_scan_pool) + 970195a7bbSHeiko Schocher (ubi->peb_count * sizeof(struct ubi_fm_ec)) + 980195a7bbSHeiko Schocher (sizeof(struct ubi_fm_eba) + 990195a7bbSHeiko Schocher (ubi->peb_count * sizeof(__be32))) + 100ff94bc40SHeiko Schocher sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES; 101ff94bc40SHeiko Schocher return roundup(size, ubi->leb_size); 102ff94bc40SHeiko Schocher } 103ff94bc40SHeiko Schocher 104ff94bc40SHeiko Schocher 105ff94bc40SHeiko Schocher /** 106ff94bc40SHeiko Schocher * new_fm_vhdr - allocate a new volume header for fastmap usage. 107ff94bc40SHeiko Schocher * @ubi: UBI device description object 108ff94bc40SHeiko Schocher * @vol_id: the VID of the new header 109ff94bc40SHeiko Schocher * 110ff94bc40SHeiko Schocher * Returns a new struct ubi_vid_hdr on success. 111ff94bc40SHeiko Schocher * NULL indicates out of memory. 112ff94bc40SHeiko Schocher */ 113ff94bc40SHeiko Schocher static struct ubi_vid_hdr *new_fm_vhdr(struct ubi_device *ubi, int vol_id) 114ff94bc40SHeiko Schocher { 115ff94bc40SHeiko Schocher struct ubi_vid_hdr *new; 116ff94bc40SHeiko Schocher 117ff94bc40SHeiko Schocher new = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 118ff94bc40SHeiko Schocher if (!new) 119ff94bc40SHeiko Schocher goto out; 120ff94bc40SHeiko Schocher 121ff94bc40SHeiko Schocher new->vol_type = UBI_VID_DYNAMIC; 122ff94bc40SHeiko Schocher new->vol_id = cpu_to_be32(vol_id); 123ff94bc40SHeiko Schocher 124ff94bc40SHeiko Schocher /* UBI implementations without fastmap support have to delete the 125ff94bc40SHeiko Schocher * fastmap. 126ff94bc40SHeiko Schocher */ 127ff94bc40SHeiko Schocher new->compat = UBI_COMPAT_DELETE; 128ff94bc40SHeiko Schocher 129ff94bc40SHeiko Schocher out: 130ff94bc40SHeiko Schocher return new; 131ff94bc40SHeiko Schocher } 132ff94bc40SHeiko Schocher 133ff94bc40SHeiko Schocher /** 134ff94bc40SHeiko Schocher * add_aeb - create and add a attach erase block to a given list. 135ff94bc40SHeiko Schocher * @ai: UBI attach info object 136ff94bc40SHeiko Schocher * @list: the target list 137ff94bc40SHeiko Schocher * @pnum: PEB number of the new attach erase block 138ff94bc40SHeiko Schocher * @ec: erease counter of the new LEB 139ff94bc40SHeiko Schocher * @scrub: scrub this PEB after attaching 140ff94bc40SHeiko Schocher * 141ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 142ff94bc40SHeiko Schocher */ 143ff94bc40SHeiko Schocher static int add_aeb(struct ubi_attach_info *ai, struct list_head *list, 144ff94bc40SHeiko Schocher int pnum, int ec, int scrub) 145ff94bc40SHeiko Schocher { 146ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb; 147ff94bc40SHeiko Schocher 148ff94bc40SHeiko Schocher aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); 149ff94bc40SHeiko Schocher if (!aeb) 150ff94bc40SHeiko Schocher return -ENOMEM; 151ff94bc40SHeiko Schocher 152ff94bc40SHeiko Schocher aeb->pnum = pnum; 153ff94bc40SHeiko Schocher aeb->ec = ec; 154ff94bc40SHeiko Schocher aeb->lnum = -1; 155ff94bc40SHeiko Schocher aeb->scrub = scrub; 156ff94bc40SHeiko Schocher aeb->copy_flag = aeb->sqnum = 0; 157ff94bc40SHeiko Schocher 158ff94bc40SHeiko Schocher ai->ec_sum += aeb->ec; 159ff94bc40SHeiko Schocher ai->ec_count++; 160ff94bc40SHeiko Schocher 161ff94bc40SHeiko Schocher if (ai->max_ec < aeb->ec) 162ff94bc40SHeiko Schocher ai->max_ec = aeb->ec; 163ff94bc40SHeiko Schocher 164ff94bc40SHeiko Schocher if (ai->min_ec > aeb->ec) 165ff94bc40SHeiko Schocher ai->min_ec = aeb->ec; 166ff94bc40SHeiko Schocher 167ff94bc40SHeiko Schocher list_add_tail(&aeb->u.list, list); 168ff94bc40SHeiko Schocher 169ff94bc40SHeiko Schocher return 0; 170ff94bc40SHeiko Schocher } 171ff94bc40SHeiko Schocher 172ff94bc40SHeiko Schocher /** 173ff94bc40SHeiko Schocher * add_vol - create and add a new volume to ubi_attach_info. 174ff94bc40SHeiko Schocher * @ai: ubi_attach_info object 175ff94bc40SHeiko Schocher * @vol_id: VID of the new volume 176ff94bc40SHeiko Schocher * @used_ebs: number of used EBS 177ff94bc40SHeiko Schocher * @data_pad: data padding value of the new volume 178ff94bc40SHeiko Schocher * @vol_type: volume type 179ff94bc40SHeiko Schocher * @last_eb_bytes: number of bytes in the last LEB 180ff94bc40SHeiko Schocher * 181ff94bc40SHeiko Schocher * Returns the new struct ubi_ainf_volume on success. 182ff94bc40SHeiko Schocher * NULL indicates an error. 183ff94bc40SHeiko Schocher */ 184ff94bc40SHeiko Schocher static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id, 185ff94bc40SHeiko Schocher int used_ebs, int data_pad, u8 vol_type, 186ff94bc40SHeiko Schocher int last_eb_bytes) 187ff94bc40SHeiko Schocher { 188ff94bc40SHeiko Schocher struct ubi_ainf_volume *av; 189ff94bc40SHeiko Schocher struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; 190ff94bc40SHeiko Schocher 191ff94bc40SHeiko Schocher while (*p) { 192ff94bc40SHeiko Schocher parent = *p; 193ff94bc40SHeiko Schocher av = rb_entry(parent, struct ubi_ainf_volume, rb); 194ff94bc40SHeiko Schocher 195ff94bc40SHeiko Schocher if (vol_id > av->vol_id) 196ff94bc40SHeiko Schocher p = &(*p)->rb_left; 1970195a7bbSHeiko Schocher else if (vol_id < av->vol_id) 198ff94bc40SHeiko Schocher p = &(*p)->rb_right; 1990195a7bbSHeiko Schocher else 2000195a7bbSHeiko Schocher return ERR_PTR(-EINVAL); 201ff94bc40SHeiko Schocher } 202ff94bc40SHeiko Schocher 203ff94bc40SHeiko Schocher av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); 204ff94bc40SHeiko Schocher if (!av) 205ff94bc40SHeiko Schocher goto out; 206ff94bc40SHeiko Schocher 2070195a7bbSHeiko Schocher av->highest_lnum = av->leb_count = av->used_ebs = 0; 208ff94bc40SHeiko Schocher av->vol_id = vol_id; 209ff94bc40SHeiko Schocher av->data_pad = data_pad; 210ff94bc40SHeiko Schocher av->last_data_size = last_eb_bytes; 211ff94bc40SHeiko Schocher av->compat = 0; 212ff94bc40SHeiko Schocher av->vol_type = vol_type; 213ff94bc40SHeiko Schocher av->root = RB_ROOT; 2140195a7bbSHeiko Schocher if (av->vol_type == UBI_STATIC_VOLUME) 2150195a7bbSHeiko Schocher av->used_ebs = used_ebs; 216ff94bc40SHeiko Schocher 217ff94bc40SHeiko Schocher dbg_bld("found volume (ID %i)", vol_id); 218ff94bc40SHeiko Schocher 219ff94bc40SHeiko Schocher rb_link_node(&av->rb, parent, p); 220ff94bc40SHeiko Schocher rb_insert_color(&av->rb, &ai->volumes); 221ff94bc40SHeiko Schocher 222ff94bc40SHeiko Schocher out: 223ff94bc40SHeiko Schocher return av; 224ff94bc40SHeiko Schocher } 225ff94bc40SHeiko Schocher 226ff94bc40SHeiko Schocher /** 227ff94bc40SHeiko Schocher * assign_aeb_to_av - assigns a SEB to a given ainf_volume and removes it 228ff94bc40SHeiko Schocher * from it's original list. 229ff94bc40SHeiko Schocher * @ai: ubi_attach_info object 230ff94bc40SHeiko Schocher * @aeb: the to be assigned SEB 231ff94bc40SHeiko Schocher * @av: target scan volume 232ff94bc40SHeiko Schocher */ 233ff94bc40SHeiko Schocher static void assign_aeb_to_av(struct ubi_attach_info *ai, 234ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb, 235ff94bc40SHeiko Schocher struct ubi_ainf_volume *av) 236ff94bc40SHeiko Schocher { 237ff94bc40SHeiko Schocher struct ubi_ainf_peb *tmp_aeb; 238ff94bc40SHeiko Schocher struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; 239ff94bc40SHeiko Schocher 240ff94bc40SHeiko Schocher p = &av->root.rb_node; 241ff94bc40SHeiko Schocher while (*p) { 242ff94bc40SHeiko Schocher parent = *p; 243ff94bc40SHeiko Schocher 244ff94bc40SHeiko Schocher tmp_aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); 245ff94bc40SHeiko Schocher if (aeb->lnum != tmp_aeb->lnum) { 246ff94bc40SHeiko Schocher if (aeb->lnum < tmp_aeb->lnum) 247ff94bc40SHeiko Schocher p = &(*p)->rb_left; 248ff94bc40SHeiko Schocher else 249ff94bc40SHeiko Schocher p = &(*p)->rb_right; 250ff94bc40SHeiko Schocher 251ff94bc40SHeiko Schocher continue; 252ff94bc40SHeiko Schocher } else 253ff94bc40SHeiko Schocher break; 254ff94bc40SHeiko Schocher } 255ff94bc40SHeiko Schocher 256ff94bc40SHeiko Schocher list_del(&aeb->u.list); 257ff94bc40SHeiko Schocher av->leb_count++; 258ff94bc40SHeiko Schocher 259ff94bc40SHeiko Schocher rb_link_node(&aeb->u.rb, parent, p); 260ff94bc40SHeiko Schocher rb_insert_color(&aeb->u.rb, &av->root); 261ff94bc40SHeiko Schocher } 262ff94bc40SHeiko Schocher 263ff94bc40SHeiko Schocher /** 264ff94bc40SHeiko Schocher * update_vol - inserts or updates a LEB which was found a pool. 265ff94bc40SHeiko Schocher * @ubi: the UBI device object 266ff94bc40SHeiko Schocher * @ai: attach info object 267ff94bc40SHeiko Schocher * @av: the volume this LEB belongs to 268ff94bc40SHeiko Schocher * @new_vh: the volume header derived from new_aeb 269ff94bc40SHeiko Schocher * @new_aeb: the AEB to be examined 270ff94bc40SHeiko Schocher * 271ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 272ff94bc40SHeiko Schocher */ 273ff94bc40SHeiko Schocher static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai, 274ff94bc40SHeiko Schocher struct ubi_ainf_volume *av, struct ubi_vid_hdr *new_vh, 275ff94bc40SHeiko Schocher struct ubi_ainf_peb *new_aeb) 276ff94bc40SHeiko Schocher { 277ff94bc40SHeiko Schocher struct rb_node **p = &av->root.rb_node, *parent = NULL; 278ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb, *victim; 279ff94bc40SHeiko Schocher int cmp_res; 280ff94bc40SHeiko Schocher 281ff94bc40SHeiko Schocher while (*p) { 282ff94bc40SHeiko Schocher parent = *p; 283ff94bc40SHeiko Schocher aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); 284ff94bc40SHeiko Schocher 285ff94bc40SHeiko Schocher if (be32_to_cpu(new_vh->lnum) != aeb->lnum) { 286ff94bc40SHeiko Schocher if (be32_to_cpu(new_vh->lnum) < aeb->lnum) 287ff94bc40SHeiko Schocher p = &(*p)->rb_left; 288ff94bc40SHeiko Schocher else 289ff94bc40SHeiko Schocher p = &(*p)->rb_right; 290ff94bc40SHeiko Schocher 291ff94bc40SHeiko Schocher continue; 292ff94bc40SHeiko Schocher } 293ff94bc40SHeiko Schocher 294ff94bc40SHeiko Schocher /* This case can happen if the fastmap gets written 295ff94bc40SHeiko Schocher * because of a volume change (creation, deletion, ..). 296ff94bc40SHeiko Schocher * Then a PEB can be within the persistent EBA and the pool. 297ff94bc40SHeiko Schocher */ 298ff94bc40SHeiko Schocher if (aeb->pnum == new_aeb->pnum) { 299ff94bc40SHeiko Schocher ubi_assert(aeb->lnum == new_aeb->lnum); 300ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, new_aeb); 301ff94bc40SHeiko Schocher 302ff94bc40SHeiko Schocher return 0; 303ff94bc40SHeiko Schocher } 304ff94bc40SHeiko Schocher 305ff94bc40SHeiko Schocher cmp_res = ubi_compare_lebs(ubi, aeb, new_aeb->pnum, new_vh); 306ff94bc40SHeiko Schocher if (cmp_res < 0) 307ff94bc40SHeiko Schocher return cmp_res; 308ff94bc40SHeiko Schocher 309ff94bc40SHeiko Schocher /* new_aeb is newer */ 310ff94bc40SHeiko Schocher if (cmp_res & 1) { 311ff94bc40SHeiko Schocher victim = kmem_cache_alloc(ai->aeb_slab_cache, 312ff94bc40SHeiko Schocher GFP_KERNEL); 313ff94bc40SHeiko Schocher if (!victim) 314ff94bc40SHeiko Schocher return -ENOMEM; 315ff94bc40SHeiko Schocher 316ff94bc40SHeiko Schocher victim->ec = aeb->ec; 317ff94bc40SHeiko Schocher victim->pnum = aeb->pnum; 318ff94bc40SHeiko Schocher list_add_tail(&victim->u.list, &ai->erase); 319ff94bc40SHeiko Schocher 320ff94bc40SHeiko Schocher if (av->highest_lnum == be32_to_cpu(new_vh->lnum)) 3210195a7bbSHeiko Schocher av->last_data_size = 322ff94bc40SHeiko Schocher be32_to_cpu(new_vh->data_size); 323ff94bc40SHeiko Schocher 324ff94bc40SHeiko Schocher dbg_bld("vol %i: AEB %i's PEB %i is the newer", 325ff94bc40SHeiko Schocher av->vol_id, aeb->lnum, new_aeb->pnum); 326ff94bc40SHeiko Schocher 327ff94bc40SHeiko Schocher aeb->ec = new_aeb->ec; 328ff94bc40SHeiko Schocher aeb->pnum = new_aeb->pnum; 329ff94bc40SHeiko Schocher aeb->copy_flag = new_vh->copy_flag; 330ff94bc40SHeiko Schocher aeb->scrub = new_aeb->scrub; 331ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, new_aeb); 332ff94bc40SHeiko Schocher 333ff94bc40SHeiko Schocher /* new_aeb is older */ 334ff94bc40SHeiko Schocher } else { 335ff94bc40SHeiko Schocher dbg_bld("vol %i: AEB %i's PEB %i is old, dropping it", 336ff94bc40SHeiko Schocher av->vol_id, aeb->lnum, new_aeb->pnum); 337ff94bc40SHeiko Schocher list_add_tail(&new_aeb->u.list, &ai->erase); 338ff94bc40SHeiko Schocher } 339ff94bc40SHeiko Schocher 340ff94bc40SHeiko Schocher return 0; 341ff94bc40SHeiko Schocher } 342ff94bc40SHeiko Schocher /* This LEB is new, let's add it to the volume */ 343ff94bc40SHeiko Schocher 344ff94bc40SHeiko Schocher if (av->highest_lnum <= be32_to_cpu(new_vh->lnum)) { 345ff94bc40SHeiko Schocher av->highest_lnum = be32_to_cpu(new_vh->lnum); 346ff94bc40SHeiko Schocher av->last_data_size = be32_to_cpu(new_vh->data_size); 347ff94bc40SHeiko Schocher } 348ff94bc40SHeiko Schocher 349ff94bc40SHeiko Schocher if (av->vol_type == UBI_STATIC_VOLUME) 350ff94bc40SHeiko Schocher av->used_ebs = be32_to_cpu(new_vh->used_ebs); 351ff94bc40SHeiko Schocher 352ff94bc40SHeiko Schocher av->leb_count++; 353ff94bc40SHeiko Schocher 354ff94bc40SHeiko Schocher rb_link_node(&new_aeb->u.rb, parent, p); 355ff94bc40SHeiko Schocher rb_insert_color(&new_aeb->u.rb, &av->root); 356ff94bc40SHeiko Schocher 357ff94bc40SHeiko Schocher return 0; 358ff94bc40SHeiko Schocher } 359ff94bc40SHeiko Schocher 360ff94bc40SHeiko Schocher /** 361ff94bc40SHeiko Schocher * process_pool_aeb - we found a non-empty PEB in a pool. 362ff94bc40SHeiko Schocher * @ubi: UBI device object 363ff94bc40SHeiko Schocher * @ai: attach info object 364ff94bc40SHeiko Schocher * @new_vh: the volume header derived from new_aeb 365ff94bc40SHeiko Schocher * @new_aeb: the AEB to be examined 366ff94bc40SHeiko Schocher * 367ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 368ff94bc40SHeiko Schocher */ 369ff94bc40SHeiko Schocher static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai, 370ff94bc40SHeiko Schocher struct ubi_vid_hdr *new_vh, 371ff94bc40SHeiko Schocher struct ubi_ainf_peb *new_aeb) 372ff94bc40SHeiko Schocher { 373ff94bc40SHeiko Schocher struct ubi_ainf_volume *av, *tmp_av = NULL; 374ff94bc40SHeiko Schocher struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; 375ff94bc40SHeiko Schocher int found = 0; 376ff94bc40SHeiko Schocher 377ff94bc40SHeiko Schocher if (be32_to_cpu(new_vh->vol_id) == UBI_FM_SB_VOLUME_ID || 378ff94bc40SHeiko Schocher be32_to_cpu(new_vh->vol_id) == UBI_FM_DATA_VOLUME_ID) { 379ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, new_aeb); 380ff94bc40SHeiko Schocher 381ff94bc40SHeiko Schocher return 0; 382ff94bc40SHeiko Schocher } 383ff94bc40SHeiko Schocher 384ff94bc40SHeiko Schocher /* Find the volume this SEB belongs to */ 385ff94bc40SHeiko Schocher while (*p) { 386ff94bc40SHeiko Schocher parent = *p; 387ff94bc40SHeiko Schocher tmp_av = rb_entry(parent, struct ubi_ainf_volume, rb); 388ff94bc40SHeiko Schocher 389ff94bc40SHeiko Schocher if (be32_to_cpu(new_vh->vol_id) > tmp_av->vol_id) 390ff94bc40SHeiko Schocher p = &(*p)->rb_left; 391ff94bc40SHeiko Schocher else if (be32_to_cpu(new_vh->vol_id) < tmp_av->vol_id) 392ff94bc40SHeiko Schocher p = &(*p)->rb_right; 393ff94bc40SHeiko Schocher else { 394ff94bc40SHeiko Schocher found = 1; 395ff94bc40SHeiko Schocher break; 396ff94bc40SHeiko Schocher } 397ff94bc40SHeiko Schocher } 398ff94bc40SHeiko Schocher 399ff94bc40SHeiko Schocher if (found) 400ff94bc40SHeiko Schocher av = tmp_av; 401ff94bc40SHeiko Schocher else { 4020195a7bbSHeiko Schocher ubi_err(ubi, "orphaned volume in fastmap pool!"); 4030195a7bbSHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, new_aeb); 404ff94bc40SHeiko Schocher return UBI_BAD_FASTMAP; 405ff94bc40SHeiko Schocher } 406ff94bc40SHeiko Schocher 407ff94bc40SHeiko Schocher ubi_assert(be32_to_cpu(new_vh->vol_id) == av->vol_id); 408ff94bc40SHeiko Schocher 409ff94bc40SHeiko Schocher return update_vol(ubi, ai, av, new_vh, new_aeb); 410ff94bc40SHeiko Schocher } 411ff94bc40SHeiko Schocher 412ff94bc40SHeiko Schocher /** 413ff94bc40SHeiko Schocher * unmap_peb - unmap a PEB. 414ff94bc40SHeiko Schocher * If fastmap detects a free PEB in the pool it has to check whether 415ff94bc40SHeiko Schocher * this PEB has been unmapped after writing the fastmap. 416ff94bc40SHeiko Schocher * 417ff94bc40SHeiko Schocher * @ai: UBI attach info object 418ff94bc40SHeiko Schocher * @pnum: The PEB to be unmapped 419ff94bc40SHeiko Schocher */ 420ff94bc40SHeiko Schocher static void unmap_peb(struct ubi_attach_info *ai, int pnum) 421ff94bc40SHeiko Schocher { 422ff94bc40SHeiko Schocher struct ubi_ainf_volume *av; 423ff94bc40SHeiko Schocher struct rb_node *node, *node2; 424ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb; 425ff94bc40SHeiko Schocher 426ff94bc40SHeiko Schocher for (node = rb_first(&ai->volumes); node; node = rb_next(node)) { 427ff94bc40SHeiko Schocher av = rb_entry(node, struct ubi_ainf_volume, rb); 428ff94bc40SHeiko Schocher 429ff94bc40SHeiko Schocher for (node2 = rb_first(&av->root); node2; 430ff94bc40SHeiko Schocher node2 = rb_next(node2)) { 431ff94bc40SHeiko Schocher aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb); 432ff94bc40SHeiko Schocher if (aeb->pnum == pnum) { 433ff94bc40SHeiko Schocher rb_erase(&aeb->u.rb, &av->root); 4340195a7bbSHeiko Schocher av->leb_count--; 435ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, aeb); 436ff94bc40SHeiko Schocher return; 437ff94bc40SHeiko Schocher } 438ff94bc40SHeiko Schocher } 439ff94bc40SHeiko Schocher } 440ff94bc40SHeiko Schocher } 441ff94bc40SHeiko Schocher 442ff94bc40SHeiko Schocher /** 443ff94bc40SHeiko Schocher * scan_pool - scans a pool for changed (no longer empty PEBs). 444ff94bc40SHeiko Schocher * @ubi: UBI device object 445ff94bc40SHeiko Schocher * @ai: attach info object 446ff94bc40SHeiko Schocher * @pebs: an array of all PEB numbers in the to be scanned pool 447ff94bc40SHeiko Schocher * @pool_size: size of the pool (number of entries in @pebs) 448ff94bc40SHeiko Schocher * @max_sqnum: pointer to the maximal sequence number 449ff94bc40SHeiko Schocher * @free: list of PEBs which are most likely free (and go into @ai->free) 450ff94bc40SHeiko Schocher * 451ff94bc40SHeiko Schocher * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned. 452ff94bc40SHeiko Schocher * < 0 indicates an internal error. 453ff94bc40SHeiko Schocher */ 454ff94bc40SHeiko Schocher #ifndef __UBOOT__ 455ff94bc40SHeiko Schocher static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, 456*248f260cSHeiko Schocher __be32 *pebs, int pool_size, unsigned long long *max_sqnum, 4570195a7bbSHeiko Schocher struct list_head *free) 458ff94bc40SHeiko Schocher #else 459ff94bc40SHeiko Schocher static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, 460*248f260cSHeiko Schocher __be32 *pebs, int pool_size, unsigned long long *max_sqnum, 4610195a7bbSHeiko Schocher struct list_head *free) 462ff94bc40SHeiko Schocher #endif 463ff94bc40SHeiko Schocher { 464ff94bc40SHeiko Schocher struct ubi_vid_hdr *vh; 465ff94bc40SHeiko Schocher struct ubi_ec_hdr *ech; 4660195a7bbSHeiko Schocher struct ubi_ainf_peb *new_aeb; 4670195a7bbSHeiko Schocher int i, pnum, err, ret = 0; 468ff94bc40SHeiko Schocher 469ff94bc40SHeiko Schocher ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 470ff94bc40SHeiko Schocher if (!ech) 471ff94bc40SHeiko Schocher return -ENOMEM; 472ff94bc40SHeiko Schocher 473ff94bc40SHeiko Schocher vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 474ff94bc40SHeiko Schocher if (!vh) { 475ff94bc40SHeiko Schocher kfree(ech); 476ff94bc40SHeiko Schocher return -ENOMEM; 477ff94bc40SHeiko Schocher } 478ff94bc40SHeiko Schocher 479ff94bc40SHeiko Schocher dbg_bld("scanning fastmap pool: size = %i", pool_size); 480ff94bc40SHeiko Schocher 481ff94bc40SHeiko Schocher /* 482ff94bc40SHeiko Schocher * Now scan all PEBs in the pool to find changes which have been made 483ff94bc40SHeiko Schocher * after the creation of the fastmap 484ff94bc40SHeiko Schocher */ 485ff94bc40SHeiko Schocher for (i = 0; i < pool_size; i++) { 486ff94bc40SHeiko Schocher int scrub = 0; 487ff94bc40SHeiko Schocher int image_seq; 488ff94bc40SHeiko Schocher 489ff94bc40SHeiko Schocher pnum = be32_to_cpu(pebs[i]); 490ff94bc40SHeiko Schocher 491ff94bc40SHeiko Schocher if (ubi_io_is_bad(ubi, pnum)) { 4920195a7bbSHeiko Schocher ubi_err(ubi, "bad PEB in fastmap pool!"); 493ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 494ff94bc40SHeiko Schocher goto out; 495ff94bc40SHeiko Schocher } 496ff94bc40SHeiko Schocher 497ff94bc40SHeiko Schocher err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); 498ff94bc40SHeiko Schocher if (err && err != UBI_IO_BITFLIPS) { 4990195a7bbSHeiko Schocher ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", 500ff94bc40SHeiko Schocher pnum, err); 501ff94bc40SHeiko Schocher ret = err > 0 ? UBI_BAD_FASTMAP : err; 502ff94bc40SHeiko Schocher goto out; 5030195a7bbSHeiko Schocher } else if (err == UBI_IO_BITFLIPS) 504ff94bc40SHeiko Schocher scrub = 1; 505ff94bc40SHeiko Schocher 506ff94bc40SHeiko Schocher /* 507ff94bc40SHeiko Schocher * Older UBI implementations have image_seq set to zero, so 508ff94bc40SHeiko Schocher * we shouldn't fail if image_seq == 0. 509ff94bc40SHeiko Schocher */ 510ff94bc40SHeiko Schocher image_seq = be32_to_cpu(ech->image_seq); 511ff94bc40SHeiko Schocher 512ff94bc40SHeiko Schocher if (image_seq && (image_seq != ubi->image_seq)) { 5130195a7bbSHeiko Schocher ubi_err(ubi, "bad image seq: 0x%x, expected: 0x%x", 514ff94bc40SHeiko Schocher be32_to_cpu(ech->image_seq), ubi->image_seq); 515ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 516ff94bc40SHeiko Schocher goto out; 517ff94bc40SHeiko Schocher } 518ff94bc40SHeiko Schocher 519ff94bc40SHeiko Schocher err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); 520ff94bc40SHeiko Schocher if (err == UBI_IO_FF || err == UBI_IO_FF_BITFLIPS) { 521ff94bc40SHeiko Schocher unsigned long long ec = be64_to_cpu(ech->ec); 522ff94bc40SHeiko Schocher unmap_peb(ai, pnum); 523ff94bc40SHeiko Schocher dbg_bld("Adding PEB to free: %i", pnum); 524ff94bc40SHeiko Schocher if (err == UBI_IO_FF_BITFLIPS) 5250195a7bbSHeiko Schocher add_aeb(ai, free, pnum, ec, 1); 526ff94bc40SHeiko Schocher else 5270195a7bbSHeiko Schocher add_aeb(ai, free, pnum, ec, 0); 528ff94bc40SHeiko Schocher continue; 529ff94bc40SHeiko Schocher } else if (err == 0 || err == UBI_IO_BITFLIPS) { 530ff94bc40SHeiko Schocher dbg_bld("Found non empty PEB:%i in pool", pnum); 531ff94bc40SHeiko Schocher 532ff94bc40SHeiko Schocher if (err == UBI_IO_BITFLIPS) 533ff94bc40SHeiko Schocher scrub = 1; 534ff94bc40SHeiko Schocher 535ff94bc40SHeiko Schocher new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, 536ff94bc40SHeiko Schocher GFP_KERNEL); 537ff94bc40SHeiko Schocher if (!new_aeb) { 538ff94bc40SHeiko Schocher ret = -ENOMEM; 539ff94bc40SHeiko Schocher goto out; 540ff94bc40SHeiko Schocher } 541ff94bc40SHeiko Schocher 542ff94bc40SHeiko Schocher new_aeb->ec = be64_to_cpu(ech->ec); 543ff94bc40SHeiko Schocher new_aeb->pnum = pnum; 544ff94bc40SHeiko Schocher new_aeb->lnum = be32_to_cpu(vh->lnum); 545ff94bc40SHeiko Schocher new_aeb->sqnum = be64_to_cpu(vh->sqnum); 546ff94bc40SHeiko Schocher new_aeb->copy_flag = vh->copy_flag; 547ff94bc40SHeiko Schocher new_aeb->scrub = scrub; 548ff94bc40SHeiko Schocher 549ff94bc40SHeiko Schocher if (*max_sqnum < new_aeb->sqnum) 550ff94bc40SHeiko Schocher *max_sqnum = new_aeb->sqnum; 551ff94bc40SHeiko Schocher 552ff94bc40SHeiko Schocher err = process_pool_aeb(ubi, ai, vh, new_aeb); 553ff94bc40SHeiko Schocher if (err) { 554ff94bc40SHeiko Schocher ret = err > 0 ? UBI_BAD_FASTMAP : err; 555ff94bc40SHeiko Schocher goto out; 556ff94bc40SHeiko Schocher } 557ff94bc40SHeiko Schocher } else { 558ff94bc40SHeiko Schocher /* We are paranoid and fall back to scanning mode */ 5590195a7bbSHeiko Schocher ubi_err(ubi, "fastmap pool PEBs contains damaged PEBs!"); 560ff94bc40SHeiko Schocher ret = err > 0 ? UBI_BAD_FASTMAP : err; 561ff94bc40SHeiko Schocher goto out; 562ff94bc40SHeiko Schocher } 563ff94bc40SHeiko Schocher 564ff94bc40SHeiko Schocher } 565ff94bc40SHeiko Schocher 566ff94bc40SHeiko Schocher out: 567ff94bc40SHeiko Schocher ubi_free_vid_hdr(ubi, vh); 568ff94bc40SHeiko Schocher kfree(ech); 569ff94bc40SHeiko Schocher return ret; 570ff94bc40SHeiko Schocher } 571ff94bc40SHeiko Schocher 572ff94bc40SHeiko Schocher /** 573ff94bc40SHeiko Schocher * count_fastmap_pebs - Counts the PEBs found by fastmap. 574ff94bc40SHeiko Schocher * @ai: The UBI attach info object 575ff94bc40SHeiko Schocher */ 576ff94bc40SHeiko Schocher static int count_fastmap_pebs(struct ubi_attach_info *ai) 577ff94bc40SHeiko Schocher { 578ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb; 579ff94bc40SHeiko Schocher struct ubi_ainf_volume *av; 580ff94bc40SHeiko Schocher struct rb_node *rb1, *rb2; 581ff94bc40SHeiko Schocher int n = 0; 582ff94bc40SHeiko Schocher 583ff94bc40SHeiko Schocher list_for_each_entry(aeb, &ai->erase, u.list) 584ff94bc40SHeiko Schocher n++; 585ff94bc40SHeiko Schocher 586ff94bc40SHeiko Schocher list_for_each_entry(aeb, &ai->free, u.list) 587ff94bc40SHeiko Schocher n++; 588ff94bc40SHeiko Schocher 589ff94bc40SHeiko Schocher ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) 590ff94bc40SHeiko Schocher ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) 591ff94bc40SHeiko Schocher n++; 592ff94bc40SHeiko Schocher 593ff94bc40SHeiko Schocher return n; 594ff94bc40SHeiko Schocher } 595ff94bc40SHeiko Schocher 596ff94bc40SHeiko Schocher /** 597ff94bc40SHeiko Schocher * ubi_attach_fastmap - creates ubi_attach_info from a fastmap. 598ff94bc40SHeiko Schocher * @ubi: UBI device object 599ff94bc40SHeiko Schocher * @ai: UBI attach info object 600ff94bc40SHeiko Schocher * @fm: the fastmap to be attached 601ff94bc40SHeiko Schocher * 602ff94bc40SHeiko Schocher * Returns 0 on success, UBI_BAD_FASTMAP if the found fastmap was unusable. 603ff94bc40SHeiko Schocher * < 0 indicates an internal error. 604ff94bc40SHeiko Schocher */ 605ff94bc40SHeiko Schocher static int ubi_attach_fastmap(struct ubi_device *ubi, 606ff94bc40SHeiko Schocher struct ubi_attach_info *ai, 607ff94bc40SHeiko Schocher struct ubi_fastmap_layout *fm) 608ff94bc40SHeiko Schocher { 6090195a7bbSHeiko Schocher struct list_head used, free; 610ff94bc40SHeiko Schocher struct ubi_ainf_volume *av; 611ff94bc40SHeiko Schocher struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb; 612ff94bc40SHeiko Schocher struct ubi_fm_sb *fmsb; 613ff94bc40SHeiko Schocher struct ubi_fm_hdr *fmhdr; 6140195a7bbSHeiko Schocher struct ubi_fm_scan_pool *fmpl, *fmpl_wl; 615ff94bc40SHeiko Schocher struct ubi_fm_ec *fmec; 616ff94bc40SHeiko Schocher struct ubi_fm_volhdr *fmvhdr; 617ff94bc40SHeiko Schocher struct ubi_fm_eba *fm_eba; 618ff94bc40SHeiko Schocher int ret, i, j, pool_size, wl_pool_size; 619ff94bc40SHeiko Schocher size_t fm_pos = 0, fm_size = ubi->fm_size; 620ff94bc40SHeiko Schocher unsigned long long max_sqnum = 0; 621ff94bc40SHeiko Schocher void *fm_raw = ubi->fm_buf; 622ff94bc40SHeiko Schocher 623ff94bc40SHeiko Schocher INIT_LIST_HEAD(&used); 6240195a7bbSHeiko Schocher INIT_LIST_HEAD(&free); 625ff94bc40SHeiko Schocher ai->min_ec = UBI_MAX_ERASECOUNTER; 626ff94bc40SHeiko Schocher 627ff94bc40SHeiko Schocher fmsb = (struct ubi_fm_sb *)(fm_raw); 628ff94bc40SHeiko Schocher ai->max_sqnum = fmsb->sqnum; 629ff94bc40SHeiko Schocher fm_pos += sizeof(struct ubi_fm_sb); 630ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 631ff94bc40SHeiko Schocher goto fail_bad; 632ff94bc40SHeiko Schocher 633ff94bc40SHeiko Schocher fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos); 634ff94bc40SHeiko Schocher fm_pos += sizeof(*fmhdr); 635ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 636ff94bc40SHeiko Schocher goto fail_bad; 637ff94bc40SHeiko Schocher 638ff94bc40SHeiko Schocher if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) { 6390195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap header magic: 0x%x, expected: 0x%x", 640ff94bc40SHeiko Schocher be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC); 641ff94bc40SHeiko Schocher goto fail_bad; 642ff94bc40SHeiko Schocher } 643ff94bc40SHeiko Schocher 6440195a7bbSHeiko Schocher fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); 6450195a7bbSHeiko Schocher fm_pos += sizeof(*fmpl); 646ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 647ff94bc40SHeiko Schocher goto fail_bad; 6480195a7bbSHeiko Schocher if (be32_to_cpu(fmpl->magic) != UBI_FM_POOL_MAGIC) { 6490195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", 6500195a7bbSHeiko Schocher be32_to_cpu(fmpl->magic), UBI_FM_POOL_MAGIC); 651ff94bc40SHeiko Schocher goto fail_bad; 652ff94bc40SHeiko Schocher } 653ff94bc40SHeiko Schocher 6540195a7bbSHeiko Schocher fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); 6550195a7bbSHeiko Schocher fm_pos += sizeof(*fmpl_wl); 656ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 657ff94bc40SHeiko Schocher goto fail_bad; 6580195a7bbSHeiko Schocher if (be32_to_cpu(fmpl_wl->magic) != UBI_FM_POOL_MAGIC) { 6590195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap WL pool magic: 0x%x, expected: 0x%x", 6600195a7bbSHeiko Schocher be32_to_cpu(fmpl_wl->magic), UBI_FM_POOL_MAGIC); 661ff94bc40SHeiko Schocher goto fail_bad; 662ff94bc40SHeiko Schocher } 663ff94bc40SHeiko Schocher 6640195a7bbSHeiko Schocher pool_size = be16_to_cpu(fmpl->size); 6650195a7bbSHeiko Schocher wl_pool_size = be16_to_cpu(fmpl_wl->size); 6660195a7bbSHeiko Schocher fm->max_pool_size = be16_to_cpu(fmpl->max_size); 6670195a7bbSHeiko Schocher fm->max_wl_pool_size = be16_to_cpu(fmpl_wl->max_size); 668ff94bc40SHeiko Schocher 669ff94bc40SHeiko Schocher if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) { 6700195a7bbSHeiko Schocher ubi_err(ubi, "bad pool size: %i", pool_size); 671ff94bc40SHeiko Schocher goto fail_bad; 672ff94bc40SHeiko Schocher } 673ff94bc40SHeiko Schocher 674ff94bc40SHeiko Schocher if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) { 6750195a7bbSHeiko Schocher ubi_err(ubi, "bad WL pool size: %i", wl_pool_size); 676ff94bc40SHeiko Schocher goto fail_bad; 677ff94bc40SHeiko Schocher } 678ff94bc40SHeiko Schocher 679ff94bc40SHeiko Schocher 680ff94bc40SHeiko Schocher if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE || 681ff94bc40SHeiko Schocher fm->max_pool_size < 0) { 6820195a7bbSHeiko Schocher ubi_err(ubi, "bad maximal pool size: %i", fm->max_pool_size); 683ff94bc40SHeiko Schocher goto fail_bad; 684ff94bc40SHeiko Schocher } 685ff94bc40SHeiko Schocher 686ff94bc40SHeiko Schocher if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE || 687ff94bc40SHeiko Schocher fm->max_wl_pool_size < 0) { 6880195a7bbSHeiko Schocher ubi_err(ubi, "bad maximal WL pool size: %i", 6890195a7bbSHeiko Schocher fm->max_wl_pool_size); 690ff94bc40SHeiko Schocher goto fail_bad; 691ff94bc40SHeiko Schocher } 692ff94bc40SHeiko Schocher 693ff94bc40SHeiko Schocher /* read EC values from free list */ 694ff94bc40SHeiko Schocher for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) { 695ff94bc40SHeiko Schocher fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 696ff94bc40SHeiko Schocher fm_pos += sizeof(*fmec); 697ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 698ff94bc40SHeiko Schocher goto fail_bad; 699ff94bc40SHeiko Schocher 700ff94bc40SHeiko Schocher add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum), 701ff94bc40SHeiko Schocher be32_to_cpu(fmec->ec), 0); 702ff94bc40SHeiko Schocher } 703ff94bc40SHeiko Schocher 704ff94bc40SHeiko Schocher /* read EC values from used list */ 705ff94bc40SHeiko Schocher for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) { 706ff94bc40SHeiko Schocher fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 707ff94bc40SHeiko Schocher fm_pos += sizeof(*fmec); 708ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 709ff94bc40SHeiko Schocher goto fail_bad; 710ff94bc40SHeiko Schocher 711ff94bc40SHeiko Schocher add_aeb(ai, &used, be32_to_cpu(fmec->pnum), 712ff94bc40SHeiko Schocher be32_to_cpu(fmec->ec), 0); 713ff94bc40SHeiko Schocher } 714ff94bc40SHeiko Schocher 715ff94bc40SHeiko Schocher /* read EC values from scrub list */ 716ff94bc40SHeiko Schocher for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) { 717ff94bc40SHeiko Schocher fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 718ff94bc40SHeiko Schocher fm_pos += sizeof(*fmec); 719ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 720ff94bc40SHeiko Schocher goto fail_bad; 721ff94bc40SHeiko Schocher 722ff94bc40SHeiko Schocher add_aeb(ai, &used, be32_to_cpu(fmec->pnum), 723ff94bc40SHeiko Schocher be32_to_cpu(fmec->ec), 1); 724ff94bc40SHeiko Schocher } 725ff94bc40SHeiko Schocher 726ff94bc40SHeiko Schocher /* read EC values from erase list */ 727ff94bc40SHeiko Schocher for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) { 728ff94bc40SHeiko Schocher fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 729ff94bc40SHeiko Schocher fm_pos += sizeof(*fmec); 730ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 731ff94bc40SHeiko Schocher goto fail_bad; 732ff94bc40SHeiko Schocher 733ff94bc40SHeiko Schocher add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum), 734ff94bc40SHeiko Schocher be32_to_cpu(fmec->ec), 1); 735ff94bc40SHeiko Schocher } 736ff94bc40SHeiko Schocher 737ff94bc40SHeiko Schocher ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); 738ff94bc40SHeiko Schocher ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count); 739ff94bc40SHeiko Schocher 740ff94bc40SHeiko Schocher /* Iterate over all volumes and read their EBA table */ 741ff94bc40SHeiko Schocher for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) { 742ff94bc40SHeiko Schocher fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos); 743ff94bc40SHeiko Schocher fm_pos += sizeof(*fmvhdr); 744ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 745ff94bc40SHeiko Schocher goto fail_bad; 746ff94bc40SHeiko Schocher 747ff94bc40SHeiko Schocher if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) { 7480195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap vol header magic: 0x%x, expected: 0x%x", 749ff94bc40SHeiko Schocher be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC); 750ff94bc40SHeiko Schocher goto fail_bad; 751ff94bc40SHeiko Schocher } 752ff94bc40SHeiko Schocher 753ff94bc40SHeiko Schocher av = add_vol(ai, be32_to_cpu(fmvhdr->vol_id), 754ff94bc40SHeiko Schocher be32_to_cpu(fmvhdr->used_ebs), 755ff94bc40SHeiko Schocher be32_to_cpu(fmvhdr->data_pad), 756ff94bc40SHeiko Schocher fmvhdr->vol_type, 757ff94bc40SHeiko Schocher be32_to_cpu(fmvhdr->last_eb_bytes)); 758ff94bc40SHeiko Schocher 759ff94bc40SHeiko Schocher if (!av) 760ff94bc40SHeiko Schocher goto fail_bad; 7610195a7bbSHeiko Schocher if (PTR_ERR(av) == -EINVAL) { 7620195a7bbSHeiko Schocher ubi_err(ubi, "volume (ID %i) already exists", 7630195a7bbSHeiko Schocher fmvhdr->vol_id); 7640195a7bbSHeiko Schocher goto fail_bad; 7650195a7bbSHeiko Schocher } 766ff94bc40SHeiko Schocher 767ff94bc40SHeiko Schocher ai->vols_found++; 768ff94bc40SHeiko Schocher if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id)) 769ff94bc40SHeiko Schocher ai->highest_vol_id = be32_to_cpu(fmvhdr->vol_id); 770ff94bc40SHeiko Schocher 771ff94bc40SHeiko Schocher fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos); 772ff94bc40SHeiko Schocher fm_pos += sizeof(*fm_eba); 773ff94bc40SHeiko Schocher fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs)); 774ff94bc40SHeiko Schocher if (fm_pos >= fm_size) 775ff94bc40SHeiko Schocher goto fail_bad; 776ff94bc40SHeiko Schocher 777ff94bc40SHeiko Schocher if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) { 7780195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap EBA header magic: 0x%x, expected: 0x%x", 779ff94bc40SHeiko Schocher be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC); 780ff94bc40SHeiko Schocher goto fail_bad; 781ff94bc40SHeiko Schocher } 782ff94bc40SHeiko Schocher 783ff94bc40SHeiko Schocher for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) { 784ff94bc40SHeiko Schocher int pnum = be32_to_cpu(fm_eba->pnum[j]); 785ff94bc40SHeiko Schocher 786ff94bc40SHeiko Schocher if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0) 787ff94bc40SHeiko Schocher continue; 788ff94bc40SHeiko Schocher 789ff94bc40SHeiko Schocher aeb = NULL; 790ff94bc40SHeiko Schocher list_for_each_entry(tmp_aeb, &used, u.list) { 791ff94bc40SHeiko Schocher if (tmp_aeb->pnum == pnum) { 792ff94bc40SHeiko Schocher aeb = tmp_aeb; 793ff94bc40SHeiko Schocher break; 794ff94bc40SHeiko Schocher } 795ff94bc40SHeiko Schocher } 796ff94bc40SHeiko Schocher 797ff94bc40SHeiko Schocher if (!aeb) { 7980195a7bbSHeiko Schocher ubi_err(ubi, "PEB %i is in EBA but not in used list", pnum); 7990195a7bbSHeiko Schocher goto fail_bad; 800ff94bc40SHeiko Schocher } 801ff94bc40SHeiko Schocher 802ff94bc40SHeiko Schocher aeb->lnum = j; 803ff94bc40SHeiko Schocher 804ff94bc40SHeiko Schocher if (av->highest_lnum <= aeb->lnum) 805ff94bc40SHeiko Schocher av->highest_lnum = aeb->lnum; 806ff94bc40SHeiko Schocher 807ff94bc40SHeiko Schocher assign_aeb_to_av(ai, aeb, av); 808ff94bc40SHeiko Schocher 809ff94bc40SHeiko Schocher dbg_bld("inserting PEB:%i (LEB %i) to vol %i", 810ff94bc40SHeiko Schocher aeb->pnum, aeb->lnum, av->vol_id); 811ff94bc40SHeiko Schocher } 812ff94bc40SHeiko Schocher } 813ff94bc40SHeiko Schocher 8140195a7bbSHeiko Schocher ret = scan_pool(ubi, ai, fmpl->pebs, pool_size, &max_sqnum, &free); 815ff94bc40SHeiko Schocher if (ret) 816ff94bc40SHeiko Schocher goto fail; 817ff94bc40SHeiko Schocher 8180195a7bbSHeiko Schocher ret = scan_pool(ubi, ai, fmpl_wl->pebs, wl_pool_size, &max_sqnum, &free); 819ff94bc40SHeiko Schocher if (ret) 820ff94bc40SHeiko Schocher goto fail; 821ff94bc40SHeiko Schocher 822ff94bc40SHeiko Schocher if (max_sqnum > ai->max_sqnum) 823ff94bc40SHeiko Schocher ai->max_sqnum = max_sqnum; 824ff94bc40SHeiko Schocher 8250195a7bbSHeiko Schocher list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) 826ff94bc40SHeiko Schocher list_move_tail(&tmp_aeb->u.list, &ai->free); 827ff94bc40SHeiko Schocher 8280195a7bbSHeiko Schocher list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) 8290195a7bbSHeiko Schocher list_move_tail(&tmp_aeb->u.list, &ai->erase); 8300195a7bbSHeiko Schocher 8310195a7bbSHeiko Schocher ubi_assert(list_empty(&free)); 832ff94bc40SHeiko Schocher 833ff94bc40SHeiko Schocher /* 834ff94bc40SHeiko Schocher * If fastmap is leaking PEBs (must not happen), raise a 835ff94bc40SHeiko Schocher * fat warning and fall back to scanning mode. 836ff94bc40SHeiko Schocher * We do this here because in ubi_wl_init() it's too late 837ff94bc40SHeiko Schocher * and we cannot fall back to scanning. 838ff94bc40SHeiko Schocher */ 839ff94bc40SHeiko Schocher #ifndef __UBOOT__ 840ff94bc40SHeiko Schocher if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count - 841ff94bc40SHeiko Schocher ai->bad_peb_count - fm->used_blocks)) 842ff94bc40SHeiko Schocher goto fail_bad; 843ff94bc40SHeiko Schocher #else 844ff94bc40SHeiko Schocher if (count_fastmap_pebs(ai) != ubi->peb_count - 845ff94bc40SHeiko Schocher ai->bad_peb_count - fm->used_blocks) { 846ff94bc40SHeiko Schocher WARN_ON(1); 847ff94bc40SHeiko Schocher goto fail_bad; 848ff94bc40SHeiko Schocher } 849ff94bc40SHeiko Schocher #endif 850ff94bc40SHeiko Schocher 851ff94bc40SHeiko Schocher return 0; 852ff94bc40SHeiko Schocher 853ff94bc40SHeiko Schocher fail_bad: 854ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 855ff94bc40SHeiko Schocher fail: 856ff94bc40SHeiko Schocher list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { 857ff94bc40SHeiko Schocher list_del(&tmp_aeb->u.list); 858ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); 859ff94bc40SHeiko Schocher } 8600195a7bbSHeiko Schocher list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { 861ff94bc40SHeiko Schocher list_del(&tmp_aeb->u.list); 862ff94bc40SHeiko Schocher kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); 863ff94bc40SHeiko Schocher } 864ff94bc40SHeiko Schocher 865ff94bc40SHeiko Schocher return ret; 866ff94bc40SHeiko Schocher } 867ff94bc40SHeiko Schocher 868ff94bc40SHeiko Schocher /** 869ff94bc40SHeiko Schocher * ubi_scan_fastmap - scan the fastmap. 870ff94bc40SHeiko Schocher * @ubi: UBI device object 871ff94bc40SHeiko Schocher * @ai: UBI attach info to be filled 872ff94bc40SHeiko Schocher * @fm_anchor: The fastmap starts at this PEB 873ff94bc40SHeiko Schocher * 874ff94bc40SHeiko Schocher * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found, 875ff94bc40SHeiko Schocher * UBI_BAD_FASTMAP if one was found but is not usable. 876ff94bc40SHeiko Schocher * < 0 indicates an internal error. 877ff94bc40SHeiko Schocher */ 878ff94bc40SHeiko Schocher int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, 879ff94bc40SHeiko Schocher int fm_anchor) 880ff94bc40SHeiko Schocher { 881ff94bc40SHeiko Schocher struct ubi_fm_sb *fmsb, *fmsb2; 882ff94bc40SHeiko Schocher struct ubi_vid_hdr *vh; 883ff94bc40SHeiko Schocher struct ubi_ec_hdr *ech; 884ff94bc40SHeiko Schocher struct ubi_fastmap_layout *fm; 885ff94bc40SHeiko Schocher int i, used_blocks, pnum, ret = 0; 886ff94bc40SHeiko Schocher size_t fm_size; 887ff94bc40SHeiko Schocher __be32 crc, tmp_crc; 888ff94bc40SHeiko Schocher unsigned long long sqnum = 0; 889ff94bc40SHeiko Schocher 8900195a7bbSHeiko Schocher down_write(&ubi->fm_protect); 891ff94bc40SHeiko Schocher memset(ubi->fm_buf, 0, ubi->fm_size); 892ff94bc40SHeiko Schocher 893ff94bc40SHeiko Schocher fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); 894ff94bc40SHeiko Schocher if (!fmsb) { 895ff94bc40SHeiko Schocher ret = -ENOMEM; 896ff94bc40SHeiko Schocher goto out; 897ff94bc40SHeiko Schocher } 898ff94bc40SHeiko Schocher 899ff94bc40SHeiko Schocher fm = kzalloc(sizeof(*fm), GFP_KERNEL); 900ff94bc40SHeiko Schocher if (!fm) { 901ff94bc40SHeiko Schocher ret = -ENOMEM; 902ff94bc40SHeiko Schocher kfree(fmsb); 903ff94bc40SHeiko Schocher goto out; 904ff94bc40SHeiko Schocher } 905ff94bc40SHeiko Schocher 906ff94bc40SHeiko Schocher ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb)); 907ff94bc40SHeiko Schocher if (ret && ret != UBI_IO_BITFLIPS) 908ff94bc40SHeiko Schocher goto free_fm_sb; 909ff94bc40SHeiko Schocher else if (ret == UBI_IO_BITFLIPS) 910ff94bc40SHeiko Schocher fm->to_be_tortured[0] = 1; 911ff94bc40SHeiko Schocher 912ff94bc40SHeiko Schocher if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { 9130195a7bbSHeiko Schocher ubi_err(ubi, "bad super block magic: 0x%x, expected: 0x%x", 914ff94bc40SHeiko Schocher be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); 915ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 916ff94bc40SHeiko Schocher goto free_fm_sb; 917ff94bc40SHeiko Schocher } 918ff94bc40SHeiko Schocher 919ff94bc40SHeiko Schocher if (fmsb->version != UBI_FM_FMT_VERSION) { 9200195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap version: %i, expected: %i", 921ff94bc40SHeiko Schocher fmsb->version, UBI_FM_FMT_VERSION); 922ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 923ff94bc40SHeiko Schocher goto free_fm_sb; 924ff94bc40SHeiko Schocher } 925ff94bc40SHeiko Schocher 926ff94bc40SHeiko Schocher used_blocks = be32_to_cpu(fmsb->used_blocks); 927ff94bc40SHeiko Schocher if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { 9280195a7bbSHeiko Schocher ubi_err(ubi, "number of fastmap blocks is invalid: %i", 9290195a7bbSHeiko Schocher used_blocks); 930ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 931ff94bc40SHeiko Schocher goto free_fm_sb; 932ff94bc40SHeiko Schocher } 933ff94bc40SHeiko Schocher 934ff94bc40SHeiko Schocher fm_size = ubi->leb_size * used_blocks; 935ff94bc40SHeiko Schocher if (fm_size != ubi->fm_size) { 9360195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap size: %zi, expected: %zi", 9370195a7bbSHeiko Schocher fm_size, ubi->fm_size); 938ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 939ff94bc40SHeiko Schocher goto free_fm_sb; 940ff94bc40SHeiko Schocher } 941ff94bc40SHeiko Schocher 942ff94bc40SHeiko Schocher ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 943ff94bc40SHeiko Schocher if (!ech) { 944ff94bc40SHeiko Schocher ret = -ENOMEM; 945ff94bc40SHeiko Schocher goto free_fm_sb; 946ff94bc40SHeiko Schocher } 947ff94bc40SHeiko Schocher 948ff94bc40SHeiko Schocher vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 949ff94bc40SHeiko Schocher if (!vh) { 950ff94bc40SHeiko Schocher ret = -ENOMEM; 951ff94bc40SHeiko Schocher goto free_hdr; 952ff94bc40SHeiko Schocher } 953ff94bc40SHeiko Schocher 954ff94bc40SHeiko Schocher for (i = 0; i < used_blocks; i++) { 955ff94bc40SHeiko Schocher int image_seq; 956ff94bc40SHeiko Schocher 957ff94bc40SHeiko Schocher pnum = be32_to_cpu(fmsb->block_loc[i]); 958ff94bc40SHeiko Schocher 959ff94bc40SHeiko Schocher if (ubi_io_is_bad(ubi, pnum)) { 960ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 961ff94bc40SHeiko Schocher goto free_hdr; 962ff94bc40SHeiko Schocher } 963ff94bc40SHeiko Schocher 964ff94bc40SHeiko Schocher ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); 965ff94bc40SHeiko Schocher if (ret && ret != UBI_IO_BITFLIPS) { 9660195a7bbSHeiko Schocher ubi_err(ubi, "unable to read fastmap block# %i EC (PEB: %i)", 967ff94bc40SHeiko Schocher i, pnum); 968ff94bc40SHeiko Schocher if (ret > 0) 969ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 970ff94bc40SHeiko Schocher goto free_hdr; 971ff94bc40SHeiko Schocher } else if (ret == UBI_IO_BITFLIPS) 972ff94bc40SHeiko Schocher fm->to_be_tortured[i] = 1; 973ff94bc40SHeiko Schocher 974ff94bc40SHeiko Schocher image_seq = be32_to_cpu(ech->image_seq); 975ff94bc40SHeiko Schocher if (!ubi->image_seq) 976ff94bc40SHeiko Schocher ubi->image_seq = image_seq; 977ff94bc40SHeiko Schocher 978ff94bc40SHeiko Schocher /* 979ff94bc40SHeiko Schocher * Older UBI implementations have image_seq set to zero, so 980ff94bc40SHeiko Schocher * we shouldn't fail if image_seq == 0. 981ff94bc40SHeiko Schocher */ 982ff94bc40SHeiko Schocher if (image_seq && (image_seq != ubi->image_seq)) { 9830195a7bbSHeiko Schocher ubi_err(ubi, "wrong image seq:%d instead of %d", 984ff94bc40SHeiko Schocher be32_to_cpu(ech->image_seq), ubi->image_seq); 985ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 986ff94bc40SHeiko Schocher goto free_hdr; 987ff94bc40SHeiko Schocher } 988ff94bc40SHeiko Schocher 989ff94bc40SHeiko Schocher ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); 990ff94bc40SHeiko Schocher if (ret && ret != UBI_IO_BITFLIPS) { 9910195a7bbSHeiko Schocher ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i)", 992ff94bc40SHeiko Schocher i, pnum); 993ff94bc40SHeiko Schocher goto free_hdr; 994ff94bc40SHeiko Schocher } 995ff94bc40SHeiko Schocher 996ff94bc40SHeiko Schocher if (i == 0) { 997ff94bc40SHeiko Schocher if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { 9980195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap anchor vol_id: 0x%x, expected: 0x%x", 999ff94bc40SHeiko Schocher be32_to_cpu(vh->vol_id), 1000ff94bc40SHeiko Schocher UBI_FM_SB_VOLUME_ID); 1001ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 1002ff94bc40SHeiko Schocher goto free_hdr; 1003ff94bc40SHeiko Schocher } 1004ff94bc40SHeiko Schocher } else { 1005ff94bc40SHeiko Schocher if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { 10060195a7bbSHeiko Schocher ubi_err(ubi, "bad fastmap data vol_id: 0x%x, expected: 0x%x", 1007ff94bc40SHeiko Schocher be32_to_cpu(vh->vol_id), 1008ff94bc40SHeiko Schocher UBI_FM_DATA_VOLUME_ID); 1009ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 1010ff94bc40SHeiko Schocher goto free_hdr; 1011ff94bc40SHeiko Schocher } 1012ff94bc40SHeiko Schocher } 1013ff94bc40SHeiko Schocher 1014ff94bc40SHeiko Schocher if (sqnum < be64_to_cpu(vh->sqnum)) 1015ff94bc40SHeiko Schocher sqnum = be64_to_cpu(vh->sqnum); 1016ff94bc40SHeiko Schocher 1017ff94bc40SHeiko Schocher ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, 1018ff94bc40SHeiko Schocher ubi->leb_start, ubi->leb_size); 1019ff94bc40SHeiko Schocher if (ret && ret != UBI_IO_BITFLIPS) { 10200195a7bbSHeiko Schocher ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i, " 1021ff94bc40SHeiko Schocher "err: %i)", i, pnum, ret); 1022ff94bc40SHeiko Schocher goto free_hdr; 1023ff94bc40SHeiko Schocher } 1024ff94bc40SHeiko Schocher } 1025ff94bc40SHeiko Schocher 1026ff94bc40SHeiko Schocher kfree(fmsb); 1027ff94bc40SHeiko Schocher fmsb = NULL; 1028ff94bc40SHeiko Schocher 1029ff94bc40SHeiko Schocher fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf); 1030ff94bc40SHeiko Schocher tmp_crc = be32_to_cpu(fmsb2->data_crc); 1031ff94bc40SHeiko Schocher fmsb2->data_crc = 0; 1032ff94bc40SHeiko Schocher crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); 1033ff94bc40SHeiko Schocher if (crc != tmp_crc) { 10340195a7bbSHeiko Schocher ubi_err(ubi, "fastmap data CRC is invalid"); 10350195a7bbSHeiko Schocher ubi_err(ubi, "CRC should be: 0x%x, calc: 0x%x", 10360195a7bbSHeiko Schocher tmp_crc, crc); 1037ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 1038ff94bc40SHeiko Schocher goto free_hdr; 1039ff94bc40SHeiko Schocher } 1040ff94bc40SHeiko Schocher 1041ff94bc40SHeiko Schocher fmsb2->sqnum = sqnum; 1042ff94bc40SHeiko Schocher 1043ff94bc40SHeiko Schocher fm->used_blocks = used_blocks; 1044ff94bc40SHeiko Schocher 1045ff94bc40SHeiko Schocher ret = ubi_attach_fastmap(ubi, ai, fm); 1046ff94bc40SHeiko Schocher if (ret) { 1047ff94bc40SHeiko Schocher if (ret > 0) 1048ff94bc40SHeiko Schocher ret = UBI_BAD_FASTMAP; 1049ff94bc40SHeiko Schocher goto free_hdr; 1050ff94bc40SHeiko Schocher } 1051ff94bc40SHeiko Schocher 1052ff94bc40SHeiko Schocher for (i = 0; i < used_blocks; i++) { 1053ff94bc40SHeiko Schocher struct ubi_wl_entry *e; 1054ff94bc40SHeiko Schocher 1055ff94bc40SHeiko Schocher e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); 1056ff94bc40SHeiko Schocher if (!e) { 1057ff94bc40SHeiko Schocher while (i--) 1058ff94bc40SHeiko Schocher kfree(fm->e[i]); 1059ff94bc40SHeiko Schocher 1060ff94bc40SHeiko Schocher ret = -ENOMEM; 1061ff94bc40SHeiko Schocher goto free_hdr; 1062ff94bc40SHeiko Schocher } 1063ff94bc40SHeiko Schocher 1064ff94bc40SHeiko Schocher e->pnum = be32_to_cpu(fmsb2->block_loc[i]); 1065ff94bc40SHeiko Schocher e->ec = be32_to_cpu(fmsb2->block_ec[i]); 1066ff94bc40SHeiko Schocher fm->e[i] = e; 1067ff94bc40SHeiko Schocher } 1068ff94bc40SHeiko Schocher 1069ff94bc40SHeiko Schocher ubi->fm = fm; 1070ff94bc40SHeiko Schocher ubi->fm_pool.max_size = ubi->fm->max_pool_size; 1071ff94bc40SHeiko Schocher ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; 10720195a7bbSHeiko Schocher ubi_msg(ubi, "attached by fastmap"); 10730195a7bbSHeiko Schocher ubi_msg(ubi, "fastmap pool size: %d", ubi->fm_pool.max_size); 10740195a7bbSHeiko Schocher ubi_msg(ubi, "fastmap WL pool size: %d", 10750195a7bbSHeiko Schocher ubi->fm_wl_pool.max_size); 1076ff94bc40SHeiko Schocher ubi->fm_disabled = 0; 1077ff94bc40SHeiko Schocher 1078ff94bc40SHeiko Schocher ubi_free_vid_hdr(ubi, vh); 1079ff94bc40SHeiko Schocher kfree(ech); 1080ff94bc40SHeiko Schocher out: 10810195a7bbSHeiko Schocher up_write(&ubi->fm_protect); 1082ff94bc40SHeiko Schocher if (ret == UBI_BAD_FASTMAP) 10830195a7bbSHeiko Schocher ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); 1084ff94bc40SHeiko Schocher return ret; 1085ff94bc40SHeiko Schocher 1086ff94bc40SHeiko Schocher free_hdr: 1087ff94bc40SHeiko Schocher ubi_free_vid_hdr(ubi, vh); 1088ff94bc40SHeiko Schocher kfree(ech); 1089ff94bc40SHeiko Schocher free_fm_sb: 1090ff94bc40SHeiko Schocher kfree(fmsb); 1091ff94bc40SHeiko Schocher kfree(fm); 1092ff94bc40SHeiko Schocher goto out; 1093ff94bc40SHeiko Schocher } 1094ff94bc40SHeiko Schocher 1095ff94bc40SHeiko Schocher /** 1096ff94bc40SHeiko Schocher * ubi_write_fastmap - writes a fastmap. 1097ff94bc40SHeiko Schocher * @ubi: UBI device object 1098ff94bc40SHeiko Schocher * @new_fm: the to be written fastmap 1099ff94bc40SHeiko Schocher * 1100ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 1101ff94bc40SHeiko Schocher */ 1102ff94bc40SHeiko Schocher static int ubi_write_fastmap(struct ubi_device *ubi, 1103ff94bc40SHeiko Schocher struct ubi_fastmap_layout *new_fm) 1104ff94bc40SHeiko Schocher { 1105ff94bc40SHeiko Schocher size_t fm_pos = 0; 1106ff94bc40SHeiko Schocher void *fm_raw; 1107ff94bc40SHeiko Schocher struct ubi_fm_sb *fmsb; 1108ff94bc40SHeiko Schocher struct ubi_fm_hdr *fmh; 11090195a7bbSHeiko Schocher struct ubi_fm_scan_pool *fmpl, *fmpl_wl; 1110ff94bc40SHeiko Schocher struct ubi_fm_ec *fec; 1111ff94bc40SHeiko Schocher struct ubi_fm_volhdr *fvh; 1112ff94bc40SHeiko Schocher struct ubi_fm_eba *feba; 1113ff94bc40SHeiko Schocher struct ubi_wl_entry *wl_e; 1114ff94bc40SHeiko Schocher struct ubi_volume *vol; 1115ff94bc40SHeiko Schocher struct ubi_vid_hdr *avhdr, *dvhdr; 1116ff94bc40SHeiko Schocher struct ubi_work *ubi_wrk; 11170195a7bbSHeiko Schocher struct rb_node *tmp_rb; 1118ff94bc40SHeiko Schocher int ret, i, j, free_peb_count, used_peb_count, vol_count; 1119ff94bc40SHeiko Schocher int scrub_peb_count, erase_peb_count; 11200195a7bbSHeiko Schocher int *seen_pebs = NULL; 1121ff94bc40SHeiko Schocher 1122ff94bc40SHeiko Schocher fm_raw = ubi->fm_buf; 1123ff94bc40SHeiko Schocher memset(ubi->fm_buf, 0, ubi->fm_size); 1124ff94bc40SHeiko Schocher 1125ff94bc40SHeiko Schocher avhdr = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID); 1126ff94bc40SHeiko Schocher if (!avhdr) { 1127ff94bc40SHeiko Schocher ret = -ENOMEM; 1128ff94bc40SHeiko Schocher goto out; 1129ff94bc40SHeiko Schocher } 1130ff94bc40SHeiko Schocher 1131ff94bc40SHeiko Schocher dvhdr = new_fm_vhdr(ubi, UBI_FM_DATA_VOLUME_ID); 1132ff94bc40SHeiko Schocher if (!dvhdr) { 1133ff94bc40SHeiko Schocher ret = -ENOMEM; 1134ff94bc40SHeiko Schocher goto out_kfree; 1135ff94bc40SHeiko Schocher } 1136ff94bc40SHeiko Schocher 11370195a7bbSHeiko Schocher seen_pebs = init_seen(ubi); 11380195a7bbSHeiko Schocher if (IS_ERR(seen_pebs)) { 11390195a7bbSHeiko Schocher ret = PTR_ERR(seen_pebs); 11400195a7bbSHeiko Schocher goto out_kfree; 11410195a7bbSHeiko Schocher } 11420195a7bbSHeiko Schocher 1143ff94bc40SHeiko Schocher spin_lock(&ubi->volumes_lock); 1144ff94bc40SHeiko Schocher spin_lock(&ubi->wl_lock); 1145ff94bc40SHeiko Schocher 1146ff94bc40SHeiko Schocher fmsb = (struct ubi_fm_sb *)fm_raw; 1147ff94bc40SHeiko Schocher fm_pos += sizeof(*fmsb); 1148ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1149ff94bc40SHeiko Schocher 1150ff94bc40SHeiko Schocher fmh = (struct ubi_fm_hdr *)(fm_raw + fm_pos); 1151ff94bc40SHeiko Schocher fm_pos += sizeof(*fmh); 1152ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1153ff94bc40SHeiko Schocher 1154ff94bc40SHeiko Schocher fmsb->magic = cpu_to_be32(UBI_FM_SB_MAGIC); 1155ff94bc40SHeiko Schocher fmsb->version = UBI_FM_FMT_VERSION; 1156ff94bc40SHeiko Schocher fmsb->used_blocks = cpu_to_be32(new_fm->used_blocks); 1157ff94bc40SHeiko Schocher /* the max sqnum will be filled in while *reading* the fastmap */ 1158ff94bc40SHeiko Schocher fmsb->sqnum = 0; 1159ff94bc40SHeiko Schocher 1160ff94bc40SHeiko Schocher fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC); 1161ff94bc40SHeiko Schocher free_peb_count = 0; 1162ff94bc40SHeiko Schocher used_peb_count = 0; 1163ff94bc40SHeiko Schocher scrub_peb_count = 0; 1164ff94bc40SHeiko Schocher erase_peb_count = 0; 1165ff94bc40SHeiko Schocher vol_count = 0; 1166ff94bc40SHeiko Schocher 11670195a7bbSHeiko Schocher fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); 11680195a7bbSHeiko Schocher fm_pos += sizeof(*fmpl); 11690195a7bbSHeiko Schocher fmpl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); 11700195a7bbSHeiko Schocher fmpl->size = cpu_to_be16(ubi->fm_pool.size); 11710195a7bbSHeiko Schocher fmpl->max_size = cpu_to_be16(ubi->fm_pool.max_size); 1172ff94bc40SHeiko Schocher 11730195a7bbSHeiko Schocher for (i = 0; i < ubi->fm_pool.size; i++) { 11740195a7bbSHeiko Schocher fmpl->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]); 11750195a7bbSHeiko Schocher set_seen(ubi, ubi->fm_pool.pebs[i], seen_pebs); 11760195a7bbSHeiko Schocher } 1177ff94bc40SHeiko Schocher 11780195a7bbSHeiko Schocher fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); 11790195a7bbSHeiko Schocher fm_pos += sizeof(*fmpl_wl); 11800195a7bbSHeiko Schocher fmpl_wl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); 11810195a7bbSHeiko Schocher fmpl_wl->size = cpu_to_be16(ubi->fm_wl_pool.size); 11820195a7bbSHeiko Schocher fmpl_wl->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size); 1183ff94bc40SHeiko Schocher 11840195a7bbSHeiko Schocher for (i = 0; i < ubi->fm_wl_pool.size; i++) { 11850195a7bbSHeiko Schocher fmpl_wl->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]); 11860195a7bbSHeiko Schocher set_seen(ubi, ubi->fm_wl_pool.pebs[i], seen_pebs); 11870195a7bbSHeiko Schocher } 1188ff94bc40SHeiko Schocher 11890195a7bbSHeiko Schocher ubi_for_each_free_peb(ubi, wl_e, tmp_rb) { 1190ff94bc40SHeiko Schocher fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 1191ff94bc40SHeiko Schocher 1192ff94bc40SHeiko Schocher fec->pnum = cpu_to_be32(wl_e->pnum); 11930195a7bbSHeiko Schocher set_seen(ubi, wl_e->pnum, seen_pebs); 1194ff94bc40SHeiko Schocher fec->ec = cpu_to_be32(wl_e->ec); 1195ff94bc40SHeiko Schocher 1196ff94bc40SHeiko Schocher free_peb_count++; 1197ff94bc40SHeiko Schocher fm_pos += sizeof(*fec); 1198ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1199ff94bc40SHeiko Schocher } 1200ff94bc40SHeiko Schocher fmh->free_peb_count = cpu_to_be32(free_peb_count); 1201ff94bc40SHeiko Schocher 12020195a7bbSHeiko Schocher ubi_for_each_used_peb(ubi, wl_e, tmp_rb) { 1203ff94bc40SHeiko Schocher fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 1204ff94bc40SHeiko Schocher 1205ff94bc40SHeiko Schocher fec->pnum = cpu_to_be32(wl_e->pnum); 12060195a7bbSHeiko Schocher set_seen(ubi, wl_e->pnum, seen_pebs); 12070195a7bbSHeiko Schocher fec->ec = cpu_to_be32(wl_e->ec); 12080195a7bbSHeiko Schocher 12090195a7bbSHeiko Schocher used_peb_count++; 12100195a7bbSHeiko Schocher fm_pos += sizeof(*fec); 12110195a7bbSHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 12120195a7bbSHeiko Schocher } 12130195a7bbSHeiko Schocher 12140195a7bbSHeiko Schocher ubi_for_each_protected_peb(ubi, i, wl_e) { 12150195a7bbSHeiko Schocher fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 12160195a7bbSHeiko Schocher 12170195a7bbSHeiko Schocher fec->pnum = cpu_to_be32(wl_e->pnum); 12180195a7bbSHeiko Schocher set_seen(ubi, wl_e->pnum, seen_pebs); 1219ff94bc40SHeiko Schocher fec->ec = cpu_to_be32(wl_e->ec); 1220ff94bc40SHeiko Schocher 1221ff94bc40SHeiko Schocher used_peb_count++; 1222ff94bc40SHeiko Schocher fm_pos += sizeof(*fec); 1223ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1224ff94bc40SHeiko Schocher } 1225ff94bc40SHeiko Schocher fmh->used_peb_count = cpu_to_be32(used_peb_count); 1226ff94bc40SHeiko Schocher 12270195a7bbSHeiko Schocher ubi_for_each_scrub_peb(ubi, wl_e, tmp_rb) { 1228ff94bc40SHeiko Schocher fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 1229ff94bc40SHeiko Schocher 1230ff94bc40SHeiko Schocher fec->pnum = cpu_to_be32(wl_e->pnum); 12310195a7bbSHeiko Schocher set_seen(ubi, wl_e->pnum, seen_pebs); 1232ff94bc40SHeiko Schocher fec->ec = cpu_to_be32(wl_e->ec); 1233ff94bc40SHeiko Schocher 1234ff94bc40SHeiko Schocher scrub_peb_count++; 1235ff94bc40SHeiko Schocher fm_pos += sizeof(*fec); 1236ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1237ff94bc40SHeiko Schocher } 1238ff94bc40SHeiko Schocher fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count); 1239ff94bc40SHeiko Schocher 1240ff94bc40SHeiko Schocher 1241ff94bc40SHeiko Schocher list_for_each_entry(ubi_wrk, &ubi->works, list) { 1242ff94bc40SHeiko Schocher if (ubi_is_erase_work(ubi_wrk)) { 1243ff94bc40SHeiko Schocher wl_e = ubi_wrk->e; 1244ff94bc40SHeiko Schocher ubi_assert(wl_e); 1245ff94bc40SHeiko Schocher 1246ff94bc40SHeiko Schocher fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); 1247ff94bc40SHeiko Schocher 1248ff94bc40SHeiko Schocher fec->pnum = cpu_to_be32(wl_e->pnum); 12490195a7bbSHeiko Schocher set_seen(ubi, wl_e->pnum, seen_pebs); 1250ff94bc40SHeiko Schocher fec->ec = cpu_to_be32(wl_e->ec); 1251ff94bc40SHeiko Schocher 1252ff94bc40SHeiko Schocher erase_peb_count++; 1253ff94bc40SHeiko Schocher fm_pos += sizeof(*fec); 1254ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1255ff94bc40SHeiko Schocher } 1256ff94bc40SHeiko Schocher } 1257ff94bc40SHeiko Schocher fmh->erase_peb_count = cpu_to_be32(erase_peb_count); 1258ff94bc40SHeiko Schocher 1259ff94bc40SHeiko Schocher for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) { 1260ff94bc40SHeiko Schocher vol = ubi->volumes[i]; 1261ff94bc40SHeiko Schocher 1262ff94bc40SHeiko Schocher if (!vol) 1263ff94bc40SHeiko Schocher continue; 1264ff94bc40SHeiko Schocher 1265ff94bc40SHeiko Schocher vol_count++; 1266ff94bc40SHeiko Schocher 1267ff94bc40SHeiko Schocher fvh = (struct ubi_fm_volhdr *)(fm_raw + fm_pos); 1268ff94bc40SHeiko Schocher fm_pos += sizeof(*fvh); 1269ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1270ff94bc40SHeiko Schocher 1271ff94bc40SHeiko Schocher fvh->magic = cpu_to_be32(UBI_FM_VHDR_MAGIC); 1272ff94bc40SHeiko Schocher fvh->vol_id = cpu_to_be32(vol->vol_id); 1273ff94bc40SHeiko Schocher fvh->vol_type = vol->vol_type; 1274ff94bc40SHeiko Schocher fvh->used_ebs = cpu_to_be32(vol->used_ebs); 1275ff94bc40SHeiko Schocher fvh->data_pad = cpu_to_be32(vol->data_pad); 1276ff94bc40SHeiko Schocher fvh->last_eb_bytes = cpu_to_be32(vol->last_eb_bytes); 1277ff94bc40SHeiko Schocher 1278ff94bc40SHeiko Schocher ubi_assert(vol->vol_type == UBI_DYNAMIC_VOLUME || 1279ff94bc40SHeiko Schocher vol->vol_type == UBI_STATIC_VOLUME); 1280ff94bc40SHeiko Schocher 1281ff94bc40SHeiko Schocher feba = (struct ubi_fm_eba *)(fm_raw + fm_pos); 1282ff94bc40SHeiko Schocher fm_pos += sizeof(*feba) + (sizeof(__be32) * vol->reserved_pebs); 1283ff94bc40SHeiko Schocher ubi_assert(fm_pos <= ubi->fm_size); 1284ff94bc40SHeiko Schocher 1285ff94bc40SHeiko Schocher for (j = 0; j < vol->reserved_pebs; j++) 1286ff94bc40SHeiko Schocher feba->pnum[j] = cpu_to_be32(vol->eba_tbl[j]); 1287ff94bc40SHeiko Schocher 1288ff94bc40SHeiko Schocher feba->reserved_pebs = cpu_to_be32(j); 1289ff94bc40SHeiko Schocher feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC); 1290ff94bc40SHeiko Schocher } 1291ff94bc40SHeiko Schocher fmh->vol_count = cpu_to_be32(vol_count); 1292ff94bc40SHeiko Schocher fmh->bad_peb_count = cpu_to_be32(ubi->bad_peb_count); 1293ff94bc40SHeiko Schocher 1294ff94bc40SHeiko Schocher avhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 1295ff94bc40SHeiko Schocher avhdr->lnum = 0; 1296ff94bc40SHeiko Schocher 1297ff94bc40SHeiko Schocher spin_unlock(&ubi->wl_lock); 1298ff94bc40SHeiko Schocher spin_unlock(&ubi->volumes_lock); 1299ff94bc40SHeiko Schocher 1300ff94bc40SHeiko Schocher dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum); 1301ff94bc40SHeiko Schocher ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr); 1302ff94bc40SHeiko Schocher if (ret) { 13030195a7bbSHeiko Schocher ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); 1304ff94bc40SHeiko Schocher goto out_kfree; 1305ff94bc40SHeiko Schocher } 1306ff94bc40SHeiko Schocher 1307ff94bc40SHeiko Schocher for (i = 0; i < new_fm->used_blocks; i++) { 1308ff94bc40SHeiko Schocher fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum); 13090195a7bbSHeiko Schocher set_seen(ubi, new_fm->e[i]->pnum, seen_pebs); 1310ff94bc40SHeiko Schocher fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec); 1311ff94bc40SHeiko Schocher } 1312ff94bc40SHeiko Schocher 1313ff94bc40SHeiko Schocher fmsb->data_crc = 0; 1314ff94bc40SHeiko Schocher fmsb->data_crc = cpu_to_be32(crc32(UBI_CRC32_INIT, fm_raw, 1315ff94bc40SHeiko Schocher ubi->fm_size)); 1316ff94bc40SHeiko Schocher 1317ff94bc40SHeiko Schocher for (i = 1; i < new_fm->used_blocks; i++) { 1318ff94bc40SHeiko Schocher dvhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 1319ff94bc40SHeiko Schocher dvhdr->lnum = cpu_to_be32(i); 1320ff94bc40SHeiko Schocher dbg_bld("writing fastmap data to PEB %i sqnum %llu", 1321ff94bc40SHeiko Schocher new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum)); 1322ff94bc40SHeiko Schocher ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr); 1323ff94bc40SHeiko Schocher if (ret) { 13240195a7bbSHeiko Schocher ubi_err(ubi, "unable to write vid_hdr to PEB %i!", 1325ff94bc40SHeiko Schocher new_fm->e[i]->pnum); 1326ff94bc40SHeiko Schocher goto out_kfree; 1327ff94bc40SHeiko Schocher } 1328ff94bc40SHeiko Schocher } 1329ff94bc40SHeiko Schocher 1330ff94bc40SHeiko Schocher for (i = 0; i < new_fm->used_blocks; i++) { 1331ff94bc40SHeiko Schocher ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size), 1332ff94bc40SHeiko Schocher new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size); 1333ff94bc40SHeiko Schocher if (ret) { 13340195a7bbSHeiko Schocher ubi_err(ubi, "unable to write fastmap to PEB %i!", 1335ff94bc40SHeiko Schocher new_fm->e[i]->pnum); 1336ff94bc40SHeiko Schocher goto out_kfree; 1337ff94bc40SHeiko Schocher } 1338ff94bc40SHeiko Schocher } 1339ff94bc40SHeiko Schocher 1340ff94bc40SHeiko Schocher ubi_assert(new_fm); 1341ff94bc40SHeiko Schocher ubi->fm = new_fm; 1342ff94bc40SHeiko Schocher 13430195a7bbSHeiko Schocher ret = self_check_seen(ubi, seen_pebs); 1344ff94bc40SHeiko Schocher dbg_bld("fastmap written!"); 1345ff94bc40SHeiko Schocher 1346ff94bc40SHeiko Schocher out_kfree: 1347ff94bc40SHeiko Schocher ubi_free_vid_hdr(ubi, avhdr); 1348ff94bc40SHeiko Schocher ubi_free_vid_hdr(ubi, dvhdr); 13490195a7bbSHeiko Schocher free_seen(seen_pebs); 1350ff94bc40SHeiko Schocher out: 1351ff94bc40SHeiko Schocher return ret; 1352ff94bc40SHeiko Schocher } 1353ff94bc40SHeiko Schocher 1354ff94bc40SHeiko Schocher /** 1355ff94bc40SHeiko Schocher * erase_block - Manually erase a PEB. 1356ff94bc40SHeiko Schocher * @ubi: UBI device object 1357ff94bc40SHeiko Schocher * @pnum: PEB to be erased 1358ff94bc40SHeiko Schocher * 1359ff94bc40SHeiko Schocher * Returns the new EC value on success, < 0 indicates an internal error. 1360ff94bc40SHeiko Schocher */ 1361ff94bc40SHeiko Schocher static int erase_block(struct ubi_device *ubi, int pnum) 1362ff94bc40SHeiko Schocher { 1363ff94bc40SHeiko Schocher int ret; 1364ff94bc40SHeiko Schocher struct ubi_ec_hdr *ec_hdr; 1365ff94bc40SHeiko Schocher long long ec; 1366ff94bc40SHeiko Schocher 1367ff94bc40SHeiko Schocher ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 1368ff94bc40SHeiko Schocher if (!ec_hdr) 1369ff94bc40SHeiko Schocher return -ENOMEM; 1370ff94bc40SHeiko Schocher 1371ff94bc40SHeiko Schocher ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0); 1372ff94bc40SHeiko Schocher if (ret < 0) 1373ff94bc40SHeiko Schocher goto out; 1374ff94bc40SHeiko Schocher else if (ret && ret != UBI_IO_BITFLIPS) { 1375ff94bc40SHeiko Schocher ret = -EINVAL; 1376ff94bc40SHeiko Schocher goto out; 1377ff94bc40SHeiko Schocher } 1378ff94bc40SHeiko Schocher 1379ff94bc40SHeiko Schocher ret = ubi_io_sync_erase(ubi, pnum, 0); 1380ff94bc40SHeiko Schocher if (ret < 0) 1381ff94bc40SHeiko Schocher goto out; 1382ff94bc40SHeiko Schocher 1383ff94bc40SHeiko Schocher ec = be64_to_cpu(ec_hdr->ec); 1384ff94bc40SHeiko Schocher ec += ret; 1385ff94bc40SHeiko Schocher if (ec > UBI_MAX_ERASECOUNTER) { 1386ff94bc40SHeiko Schocher ret = -EINVAL; 1387ff94bc40SHeiko Schocher goto out; 1388ff94bc40SHeiko Schocher } 1389ff94bc40SHeiko Schocher 1390ff94bc40SHeiko Schocher ec_hdr->ec = cpu_to_be64(ec); 1391ff94bc40SHeiko Schocher ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); 1392ff94bc40SHeiko Schocher if (ret < 0) 1393ff94bc40SHeiko Schocher goto out; 1394ff94bc40SHeiko Schocher 1395ff94bc40SHeiko Schocher ret = ec; 1396ff94bc40SHeiko Schocher out: 1397ff94bc40SHeiko Schocher kfree(ec_hdr); 1398ff94bc40SHeiko Schocher return ret; 1399ff94bc40SHeiko Schocher } 1400ff94bc40SHeiko Schocher 1401ff94bc40SHeiko Schocher /** 1402ff94bc40SHeiko Schocher * invalidate_fastmap - destroys a fastmap. 1403ff94bc40SHeiko Schocher * @ubi: UBI device object 1404ff94bc40SHeiko Schocher * 14050195a7bbSHeiko Schocher * This function ensures that upon next UBI attach a full scan 14060195a7bbSHeiko Schocher * is issued. We need this if UBI is about to write a new fastmap 14070195a7bbSHeiko Schocher * but is unable to do so. In this case we have two options: 14080195a7bbSHeiko Schocher * a) Make sure that the current fastmap will not be usued upon 14090195a7bbSHeiko Schocher * attach time and contine or b) fall back to RO mode to have the 14100195a7bbSHeiko Schocher * current fastmap in a valid state. 1411ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 1412ff94bc40SHeiko Schocher */ 14130195a7bbSHeiko Schocher static int invalidate_fastmap(struct ubi_device *ubi) 1414ff94bc40SHeiko Schocher { 1415ff94bc40SHeiko Schocher int ret; 14160195a7bbSHeiko Schocher struct ubi_fastmap_layout *fm; 14170195a7bbSHeiko Schocher struct ubi_wl_entry *e; 14180195a7bbSHeiko Schocher struct ubi_vid_hdr *vh = NULL; 1419ff94bc40SHeiko Schocher 14200195a7bbSHeiko Schocher if (!ubi->fm) 14210195a7bbSHeiko Schocher return 0; 14220195a7bbSHeiko Schocher 14230195a7bbSHeiko Schocher ubi->fm = NULL; 14240195a7bbSHeiko Schocher 14250195a7bbSHeiko Schocher ret = -ENOMEM; 14260195a7bbSHeiko Schocher fm = kzalloc(sizeof(*fm), GFP_KERNEL); 14270195a7bbSHeiko Schocher if (!fm) 14280195a7bbSHeiko Schocher goto out; 1429ff94bc40SHeiko Schocher 1430ff94bc40SHeiko Schocher vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID); 1431ff94bc40SHeiko Schocher if (!vh) 14320195a7bbSHeiko Schocher goto out_free_fm; 1433ff94bc40SHeiko Schocher 14340195a7bbSHeiko Schocher ret = -ENOSPC; 14350195a7bbSHeiko Schocher e = ubi_wl_get_fm_peb(ubi, 1); 14360195a7bbSHeiko Schocher if (!e) 14370195a7bbSHeiko Schocher goto out_free_fm; 14380195a7bbSHeiko Schocher 14390195a7bbSHeiko Schocher /* 14400195a7bbSHeiko Schocher * Create fake fastmap such that UBI will fall back 14410195a7bbSHeiko Schocher * to scanning mode. 14420195a7bbSHeiko Schocher */ 1443ff94bc40SHeiko Schocher vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 14440195a7bbSHeiko Schocher ret = ubi_io_write_vid_hdr(ubi, e->pnum, vh); 14450195a7bbSHeiko Schocher if (ret < 0) { 14460195a7bbSHeiko Schocher ubi_wl_put_fm_peb(ubi, e, 0, 0); 14470195a7bbSHeiko Schocher goto out_free_fm; 14480195a7bbSHeiko Schocher } 1449ff94bc40SHeiko Schocher 14500195a7bbSHeiko Schocher fm->used_blocks = 1; 14510195a7bbSHeiko Schocher fm->e[0] = e; 14520195a7bbSHeiko Schocher 14530195a7bbSHeiko Schocher ubi->fm = fm; 14540195a7bbSHeiko Schocher 14550195a7bbSHeiko Schocher out: 14560195a7bbSHeiko Schocher ubi_free_vid_hdr(ubi, vh); 1457ff94bc40SHeiko Schocher return ret; 14580195a7bbSHeiko Schocher 14590195a7bbSHeiko Schocher out_free_fm: 14600195a7bbSHeiko Schocher kfree(fm); 14610195a7bbSHeiko Schocher goto out; 14620195a7bbSHeiko Schocher } 14630195a7bbSHeiko Schocher 14640195a7bbSHeiko Schocher /** 14650195a7bbSHeiko Schocher * return_fm_pebs - returns all PEBs used by a fastmap back to the 14660195a7bbSHeiko Schocher * WL sub-system. 14670195a7bbSHeiko Schocher * @ubi: UBI device object 14680195a7bbSHeiko Schocher * @fm: fastmap layout object 14690195a7bbSHeiko Schocher */ 14700195a7bbSHeiko Schocher static void return_fm_pebs(struct ubi_device *ubi, 14710195a7bbSHeiko Schocher struct ubi_fastmap_layout *fm) 14720195a7bbSHeiko Schocher { 14730195a7bbSHeiko Schocher int i; 14740195a7bbSHeiko Schocher 14750195a7bbSHeiko Schocher if (!fm) 14760195a7bbSHeiko Schocher return; 14770195a7bbSHeiko Schocher 14780195a7bbSHeiko Schocher for (i = 0; i < fm->used_blocks; i++) { 14790195a7bbSHeiko Schocher if (fm->e[i]) { 14800195a7bbSHeiko Schocher ubi_wl_put_fm_peb(ubi, fm->e[i], i, 14810195a7bbSHeiko Schocher fm->to_be_tortured[i]); 14820195a7bbSHeiko Schocher fm->e[i] = NULL; 14830195a7bbSHeiko Schocher } 14840195a7bbSHeiko Schocher } 1485ff94bc40SHeiko Schocher } 1486ff94bc40SHeiko Schocher 1487ff94bc40SHeiko Schocher /** 1488ff94bc40SHeiko Schocher * ubi_update_fastmap - will be called by UBI if a volume changes or 1489ff94bc40SHeiko Schocher * a fastmap pool becomes full. 1490ff94bc40SHeiko Schocher * @ubi: UBI device object 1491ff94bc40SHeiko Schocher * 1492ff94bc40SHeiko Schocher * Returns 0 on success, < 0 indicates an internal error. 1493ff94bc40SHeiko Schocher */ 1494ff94bc40SHeiko Schocher int ubi_update_fastmap(struct ubi_device *ubi) 1495ff94bc40SHeiko Schocher { 14960195a7bbSHeiko Schocher int ret, i, j; 1497ff94bc40SHeiko Schocher struct ubi_fastmap_layout *new_fm, *old_fm; 1498ff94bc40SHeiko Schocher struct ubi_wl_entry *tmp_e; 1499ff94bc40SHeiko Schocher 15000195a7bbSHeiko Schocher down_write(&ubi->fm_protect); 1501ff94bc40SHeiko Schocher 1502ff94bc40SHeiko Schocher ubi_refill_pools(ubi); 1503ff94bc40SHeiko Schocher 1504ff94bc40SHeiko Schocher if (ubi->ro_mode || ubi->fm_disabled) { 15050195a7bbSHeiko Schocher up_write(&ubi->fm_protect); 1506ff94bc40SHeiko Schocher return 0; 1507ff94bc40SHeiko Schocher } 1508ff94bc40SHeiko Schocher 1509ff94bc40SHeiko Schocher ret = ubi_ensure_anchor_pebs(ubi); 1510ff94bc40SHeiko Schocher if (ret) { 15110195a7bbSHeiko Schocher up_write(&ubi->fm_protect); 1512ff94bc40SHeiko Schocher return ret; 1513ff94bc40SHeiko Schocher } 1514ff94bc40SHeiko Schocher 1515ff94bc40SHeiko Schocher new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); 1516ff94bc40SHeiko Schocher if (!new_fm) { 15170195a7bbSHeiko Schocher up_write(&ubi->fm_protect); 1518ff94bc40SHeiko Schocher return -ENOMEM; 1519ff94bc40SHeiko Schocher } 1520ff94bc40SHeiko Schocher 1521ff94bc40SHeiko Schocher new_fm->used_blocks = ubi->fm_size / ubi->leb_size; 1522ff94bc40SHeiko Schocher old_fm = ubi->fm; 1523ff94bc40SHeiko Schocher ubi->fm = NULL; 1524ff94bc40SHeiko Schocher 1525ff94bc40SHeiko Schocher if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) { 15260195a7bbSHeiko Schocher ubi_err(ubi, "fastmap too large"); 1527ff94bc40SHeiko Schocher ret = -ENOSPC; 1528ff94bc40SHeiko Schocher goto err; 1529ff94bc40SHeiko Schocher } 1530ff94bc40SHeiko Schocher 1531ff94bc40SHeiko Schocher for (i = 1; i < new_fm->used_blocks; i++) { 1532ff94bc40SHeiko Schocher spin_lock(&ubi->wl_lock); 1533ff94bc40SHeiko Schocher tmp_e = ubi_wl_get_fm_peb(ubi, 0); 1534ff94bc40SHeiko Schocher spin_unlock(&ubi->wl_lock); 1535ff94bc40SHeiko Schocher 15360195a7bbSHeiko Schocher if (!tmp_e) { 15370195a7bbSHeiko Schocher if (old_fm && old_fm->e[i]) { 15380195a7bbSHeiko Schocher ret = erase_block(ubi, old_fm->e[i]->pnum); 15390195a7bbSHeiko Schocher if (ret < 0) { 15400195a7bbSHeiko Schocher ubi_err(ubi, "could not erase old fastmap PEB"); 1541ff94bc40SHeiko Schocher 15420195a7bbSHeiko Schocher for (j = 1; j < i; j++) { 15430195a7bbSHeiko Schocher ubi_wl_put_fm_peb(ubi, new_fm->e[j], 15440195a7bbSHeiko Schocher j, 0); 15450195a7bbSHeiko Schocher new_fm->e[j] = NULL; 15460195a7bbSHeiko Schocher } 15470195a7bbSHeiko Schocher goto err; 15480195a7bbSHeiko Schocher } 15490195a7bbSHeiko Schocher new_fm->e[i] = old_fm->e[i]; 15500195a7bbSHeiko Schocher old_fm->e[i] = NULL; 15510195a7bbSHeiko Schocher } else { 15520195a7bbSHeiko Schocher ubi_err(ubi, "could not get any free erase block"); 15530195a7bbSHeiko Schocher 15540195a7bbSHeiko Schocher for (j = 1; j < i; j++) { 1555ff94bc40SHeiko Schocher ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); 15560195a7bbSHeiko Schocher new_fm->e[j] = NULL; 15570195a7bbSHeiko Schocher } 1558ff94bc40SHeiko Schocher 1559ff94bc40SHeiko Schocher ret = -ENOSPC; 1560ff94bc40SHeiko Schocher goto err; 1561ff94bc40SHeiko Schocher } 1562ff94bc40SHeiko Schocher } else { 15630195a7bbSHeiko Schocher new_fm->e[i] = tmp_e; 1564ff94bc40SHeiko Schocher 15650195a7bbSHeiko Schocher if (old_fm && old_fm->e[i]) { 1566ff94bc40SHeiko Schocher ubi_wl_put_fm_peb(ubi, old_fm->e[i], i, 1567ff94bc40SHeiko Schocher old_fm->to_be_tortured[i]); 15680195a7bbSHeiko Schocher old_fm->e[i] = NULL; 15690195a7bbSHeiko Schocher } 15700195a7bbSHeiko Schocher } 15710195a7bbSHeiko Schocher } 15720195a7bbSHeiko Schocher 15730195a7bbSHeiko Schocher /* Old fastmap is larger than the new one */ 15740195a7bbSHeiko Schocher if (old_fm && new_fm->used_blocks < old_fm->used_blocks) { 15750195a7bbSHeiko Schocher for (i = new_fm->used_blocks; i < old_fm->used_blocks; i++) { 15760195a7bbSHeiko Schocher ubi_wl_put_fm_peb(ubi, old_fm->e[i], i, 15770195a7bbSHeiko Schocher old_fm->to_be_tortured[i]); 15780195a7bbSHeiko Schocher old_fm->e[i] = NULL; 1579ff94bc40SHeiko Schocher } 1580ff94bc40SHeiko Schocher } 1581ff94bc40SHeiko Schocher 1582ff94bc40SHeiko Schocher spin_lock(&ubi->wl_lock); 1583ff94bc40SHeiko Schocher tmp_e = ubi_wl_get_fm_peb(ubi, 1); 1584ff94bc40SHeiko Schocher spin_unlock(&ubi->wl_lock); 1585ff94bc40SHeiko Schocher 1586ff94bc40SHeiko Schocher if (old_fm) { 1587ff94bc40SHeiko Schocher /* no fresh anchor PEB was found, reuse the old one */ 1588ff94bc40SHeiko Schocher if (!tmp_e) { 1589ff94bc40SHeiko Schocher ret = erase_block(ubi, old_fm->e[0]->pnum); 1590ff94bc40SHeiko Schocher if (ret < 0) { 15910195a7bbSHeiko Schocher ubi_err(ubi, "could not erase old anchor PEB"); 1592ff94bc40SHeiko Schocher 15930195a7bbSHeiko Schocher for (i = 1; i < new_fm->used_blocks; i++) { 1594ff94bc40SHeiko Schocher ubi_wl_put_fm_peb(ubi, new_fm->e[i], 1595ff94bc40SHeiko Schocher i, 0); 15960195a7bbSHeiko Schocher new_fm->e[i] = NULL; 15970195a7bbSHeiko Schocher } 1598ff94bc40SHeiko Schocher goto err; 1599ff94bc40SHeiko Schocher } 16000195a7bbSHeiko Schocher new_fm->e[0] = old_fm->e[0]; 1601ff94bc40SHeiko Schocher new_fm->e[0]->ec = ret; 16020195a7bbSHeiko Schocher old_fm->e[0] = NULL; 1603ff94bc40SHeiko Schocher } else { 1604ff94bc40SHeiko Schocher /* we've got a new anchor PEB, return the old one */ 1605ff94bc40SHeiko Schocher ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0, 1606ff94bc40SHeiko Schocher old_fm->to_be_tortured[0]); 16070195a7bbSHeiko Schocher new_fm->e[0] = tmp_e; 16080195a7bbSHeiko Schocher old_fm->e[0] = NULL; 1609ff94bc40SHeiko Schocher } 1610ff94bc40SHeiko Schocher } else { 1611ff94bc40SHeiko Schocher if (!tmp_e) { 16120195a7bbSHeiko Schocher ubi_err(ubi, "could not find any anchor PEB"); 1613ff94bc40SHeiko Schocher 16140195a7bbSHeiko Schocher for (i = 1; i < new_fm->used_blocks; i++) { 1615ff94bc40SHeiko Schocher ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); 16160195a7bbSHeiko Schocher new_fm->e[i] = NULL; 16170195a7bbSHeiko Schocher } 1618ff94bc40SHeiko Schocher 1619ff94bc40SHeiko Schocher ret = -ENOSPC; 1620ff94bc40SHeiko Schocher goto err; 1621ff94bc40SHeiko Schocher } 16220195a7bbSHeiko Schocher new_fm->e[0] = tmp_e; 1623ff94bc40SHeiko Schocher } 1624ff94bc40SHeiko Schocher 1625ff94bc40SHeiko Schocher down_write(&ubi->work_sem); 16260195a7bbSHeiko Schocher down_write(&ubi->fm_eba_sem); 1627ff94bc40SHeiko Schocher ret = ubi_write_fastmap(ubi, new_fm); 16280195a7bbSHeiko Schocher up_write(&ubi->fm_eba_sem); 1629ff94bc40SHeiko Schocher up_write(&ubi->work_sem); 1630ff94bc40SHeiko Schocher 1631ff94bc40SHeiko Schocher if (ret) 1632ff94bc40SHeiko Schocher goto err; 1633ff94bc40SHeiko Schocher 1634ff94bc40SHeiko Schocher out_unlock: 16350195a7bbSHeiko Schocher up_write(&ubi->fm_protect); 1636ff94bc40SHeiko Schocher kfree(old_fm); 1637ff94bc40SHeiko Schocher return ret; 1638ff94bc40SHeiko Schocher 1639ff94bc40SHeiko Schocher err: 16400195a7bbSHeiko Schocher ubi_warn(ubi, "Unable to write new fastmap, err=%i", ret); 1641ff94bc40SHeiko Schocher 16420195a7bbSHeiko Schocher ret = invalidate_fastmap(ubi); 16430195a7bbSHeiko Schocher if (ret < 0) { 16440195a7bbSHeiko Schocher ubi_err(ubi, "Unable to invalidiate current fastmap!"); 16450195a7bbSHeiko Schocher ubi_ro_mode(ubi); 16460195a7bbSHeiko Schocher } else { 16470195a7bbSHeiko Schocher return_fm_pebs(ubi, old_fm); 16480195a7bbSHeiko Schocher return_fm_pebs(ubi, new_fm); 1649ff94bc40SHeiko Schocher ret = 0; 1650ff94bc40SHeiko Schocher } 16510195a7bbSHeiko Schocher 16520195a7bbSHeiko Schocher kfree(new_fm); 1653ff94bc40SHeiko Schocher goto out_unlock; 1654ff94bc40SHeiko Schocher } 1655