xref: /kernel/linux/linux-5.10/drivers/mtd/ubi/attach.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2006
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Author: Artem Bityutskiy (Битюцкий Артём)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * UBI attaching sub-system.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * This sub-system is responsible for attaching MTD devices and it also
128c2ecf20Sopenharmony_ci * implements flash media scanning.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * The attaching information is represented by a &struct ubi_attach_info'
158c2ecf20Sopenharmony_ci * object. Information about volumes is represented by &struct ubi_ainf_volume
168c2ecf20Sopenharmony_ci * objects which are kept in volume RB-tree with root at the @volumes field.
178c2ecf20Sopenharmony_ci * The RB-tree is indexed by the volume ID.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These
208c2ecf20Sopenharmony_ci * objects are kept in per-volume RB-trees with the root at the corresponding
218c2ecf20Sopenharmony_ci * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of
228c2ecf20Sopenharmony_ci * per-volume objects and each of these objects is the root of RB-tree of
238c2ecf20Sopenharmony_ci * per-LEB objects.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * Corrupted physical eraseblocks are put to the @corr list, free physical
268c2ecf20Sopenharmony_ci * eraseblocks are put to the @free list and the physical eraseblock to be
278c2ecf20Sopenharmony_ci * erased are put to the @erase list.
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci * About corruptions
308c2ecf20Sopenharmony_ci * ~~~~~~~~~~~~~~~~~
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * UBI protects EC and VID headers with CRC-32 checksums, so it can detect
338c2ecf20Sopenharmony_ci * whether the headers are corrupted or not. Sometimes UBI also protects the
348c2ecf20Sopenharmony_ci * data with CRC-32, e.g., when it executes the atomic LEB change operation, or
358c2ecf20Sopenharmony_ci * when it moves the contents of a PEB for wear-leveling purposes.
368c2ecf20Sopenharmony_ci *
378c2ecf20Sopenharmony_ci * UBI tries to distinguish between 2 types of corruptions.
388c2ecf20Sopenharmony_ci *
398c2ecf20Sopenharmony_ci * 1. Corruptions caused by power cuts. These are expected corruptions and UBI
408c2ecf20Sopenharmony_ci * tries to handle them gracefully, without printing too many warnings and
418c2ecf20Sopenharmony_ci * error messages. The idea is that we do not lose important data in these
428c2ecf20Sopenharmony_ci * cases - we may lose only the data which were being written to the media just
438c2ecf20Sopenharmony_ci * before the power cut happened, and the upper layers (e.g., UBIFS) are
448c2ecf20Sopenharmony_ci * supposed to handle such data losses (e.g., by using the FS journal).
458c2ecf20Sopenharmony_ci *
468c2ecf20Sopenharmony_ci * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like
478c2ecf20Sopenharmony_ci * the reason is a power cut, UBI puts this PEB to the @erase list, and all
488c2ecf20Sopenharmony_ci * PEBs in the @erase list are scheduled for erasure later.
498c2ecf20Sopenharmony_ci *
508c2ecf20Sopenharmony_ci * 2. Unexpected corruptions which are not caused by power cuts. During
518c2ecf20Sopenharmony_ci * attaching, such PEBs are put to the @corr list and UBI preserves them.
528c2ecf20Sopenharmony_ci * Obviously, this lessens the amount of available PEBs, and if at some  point
538c2ecf20Sopenharmony_ci * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs
548c2ecf20Sopenharmony_ci * about such PEBs every time the MTD device is attached.
558c2ecf20Sopenharmony_ci *
568c2ecf20Sopenharmony_ci * However, it is difficult to reliably distinguish between these types of
578c2ecf20Sopenharmony_ci * corruptions and UBI's strategy is as follows (in case of attaching by
588c2ecf20Sopenharmony_ci * scanning). UBI assumes corruption type 2 if the VID header is corrupted and
598c2ecf20Sopenharmony_ci * the data area does not contain all 0xFFs, and there were no bit-flips or
608c2ecf20Sopenharmony_ci * integrity errors (e.g., ECC errors in case of NAND) while reading the data
618c2ecf20Sopenharmony_ci * area.  Otherwise UBI assumes corruption type 1. So the decision criteria
628c2ecf20Sopenharmony_ci * are as follows.
638c2ecf20Sopenharmony_ci *   o If the data area contains only 0xFFs, there are no data, and it is safe
648c2ecf20Sopenharmony_ci *     to just erase this PEB - this is corruption type 1.
658c2ecf20Sopenharmony_ci *   o If the data area has bit-flips or data integrity errors (ECC errors on
668c2ecf20Sopenharmony_ci *     NAND), it is probably a PEB which was being erased when power cut
678c2ecf20Sopenharmony_ci *     happened, so this is corruption type 1. However, this is just a guess,
688c2ecf20Sopenharmony_ci *     which might be wrong.
698c2ecf20Sopenharmony_ci *   o Otherwise this is corruption type 2.
708c2ecf20Sopenharmony_ci */
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#include <linux/err.h>
738c2ecf20Sopenharmony_ci#include <linux/slab.h>
748c2ecf20Sopenharmony_ci#include <linux/crc32.h>
758c2ecf20Sopenharmony_ci#include <linux/math64.h>
768c2ecf20Sopenharmony_ci#include <linux/random.h>
778c2ecf20Sopenharmony_ci#include "ubi.h"
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#define AV_FIND		BIT(0)
828c2ecf20Sopenharmony_ci#define AV_ADD		BIT(1)
838c2ecf20Sopenharmony_ci#define AV_FIND_OR_ADD	(AV_FIND | AV_ADD)
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci/**
868c2ecf20Sopenharmony_ci * find_or_add_av - internal function to find a volume, add a volume or do
878c2ecf20Sopenharmony_ci *		    both (find and add if missing).
888c2ecf20Sopenharmony_ci * @ai: attaching information
898c2ecf20Sopenharmony_ci * @vol_id: the requested volume ID
908c2ecf20Sopenharmony_ci * @flags: a combination of the %AV_FIND and %AV_ADD flags describing the
918c2ecf20Sopenharmony_ci *	   expected operation. If only %AV_ADD is set, -EEXIST is returned
928c2ecf20Sopenharmony_ci *	   if the volume already exists. If only %AV_FIND is set, NULL is
938c2ecf20Sopenharmony_ci *	   returned if the volume does not exist. And if both flags are
948c2ecf20Sopenharmony_ci *	   set, the helper first tries to find an existing volume, and if
958c2ecf20Sopenharmony_ci *	   it does not exist it creates a new one.
968c2ecf20Sopenharmony_ci * @created: in value used to inform the caller whether it"s a newly created
978c2ecf20Sopenharmony_ci *	     volume or not.
988c2ecf20Sopenharmony_ci *
998c2ecf20Sopenharmony_ci * This function returns a pointer to a volume description or an ERR_PTR if
1008c2ecf20Sopenharmony_ci * the operation failed. It can also return NULL if only %AV_FIND is set and
1018c2ecf20Sopenharmony_ci * the volume does not exist.
1028c2ecf20Sopenharmony_ci */
1038c2ecf20Sopenharmony_cistatic struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai,
1048c2ecf20Sopenharmony_ci					      int vol_id, unsigned int flags,
1058c2ecf20Sopenharmony_ci					      bool *created)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
1088c2ecf20Sopenharmony_ci	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* Walk the volume RB-tree to look if this volume is already present */
1118c2ecf20Sopenharmony_ci	while (*p) {
1128c2ecf20Sopenharmony_ci		parent = *p;
1138c2ecf20Sopenharmony_ci		av = rb_entry(parent, struct ubi_ainf_volume, rb);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci		if (vol_id == av->vol_id) {
1168c2ecf20Sopenharmony_ci			*created = false;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci			if (!(flags & AV_FIND))
1198c2ecf20Sopenharmony_ci				return ERR_PTR(-EEXIST);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci			return av;
1228c2ecf20Sopenharmony_ci		}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci		if (vol_id > av->vol_id)
1258c2ecf20Sopenharmony_ci			p = &(*p)->rb_left;
1268c2ecf20Sopenharmony_ci		else
1278c2ecf20Sopenharmony_ci			p = &(*p)->rb_right;
1288c2ecf20Sopenharmony_ci	}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	if (!(flags & AV_ADD))
1318c2ecf20Sopenharmony_ci		return NULL;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	/* The volume is absent - add it */
1348c2ecf20Sopenharmony_ci	av = kzalloc(sizeof(*av), GFP_KERNEL);
1358c2ecf20Sopenharmony_ci	if (!av)
1368c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	av->vol_id = vol_id;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	if (vol_id > ai->highest_vol_id)
1418c2ecf20Sopenharmony_ci		ai->highest_vol_id = vol_id;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	rb_link_node(&av->rb, parent, p);
1448c2ecf20Sopenharmony_ci	rb_insert_color(&av->rb, &ai->volumes);
1458c2ecf20Sopenharmony_ci	ai->vols_found += 1;
1468c2ecf20Sopenharmony_ci	*created = true;
1478c2ecf20Sopenharmony_ci	dbg_bld("added volume %d", vol_id);
1488c2ecf20Sopenharmony_ci	return av;
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci/**
1528c2ecf20Sopenharmony_ci * ubi_find_or_add_av - search for a volume in the attaching information and
1538c2ecf20Sopenharmony_ci *			add one if it does not exist.
1548c2ecf20Sopenharmony_ci * @ai: attaching information
1558c2ecf20Sopenharmony_ci * @vol_id: the requested volume ID
1568c2ecf20Sopenharmony_ci * @created: whether the volume has been created or not
1578c2ecf20Sopenharmony_ci *
1588c2ecf20Sopenharmony_ci * This function returns a pointer to the new volume description or an
1598c2ecf20Sopenharmony_ci * ERR_PTR if the operation failed.
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_cistatic struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai,
1628c2ecf20Sopenharmony_ci						  int vol_id, bool *created)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci/**
1688c2ecf20Sopenharmony_ci * ubi_alloc_aeb - allocate an aeb element
1698c2ecf20Sopenharmony_ci * @ai: attaching information
1708c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number
1718c2ecf20Sopenharmony_ci * @ec: erase counter of the physical eraseblock
1728c2ecf20Sopenharmony_ci *
1738c2ecf20Sopenharmony_ci * Allocate an aeb object and initialize the pnum and ec information.
1748c2ecf20Sopenharmony_ci * vol_id and lnum are set to UBI_UNKNOWN, and the other fields are
1758c2ecf20Sopenharmony_ci * initialized to zero.
1768c2ecf20Sopenharmony_ci * Note that the element is not added in any list or RB tree.
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_cistruct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
1798c2ecf20Sopenharmony_ci				   int ec)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL);
1848c2ecf20Sopenharmony_ci	if (!aeb)
1858c2ecf20Sopenharmony_ci		return NULL;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	aeb->pnum = pnum;
1888c2ecf20Sopenharmony_ci	aeb->ec = ec;
1898c2ecf20Sopenharmony_ci	aeb->vol_id = UBI_UNKNOWN;
1908c2ecf20Sopenharmony_ci	aeb->lnum = UBI_UNKNOWN;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	return aeb;
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci/**
1968c2ecf20Sopenharmony_ci * ubi_free_aeb - free an aeb element
1978c2ecf20Sopenharmony_ci * @ai: attaching information
1988c2ecf20Sopenharmony_ci * @aeb: the element to free
1998c2ecf20Sopenharmony_ci *
2008c2ecf20Sopenharmony_ci * Free an aeb object. The caller must have removed the element from any list
2018c2ecf20Sopenharmony_ci * or RB tree.
2028c2ecf20Sopenharmony_ci */
2038c2ecf20Sopenharmony_civoid ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	kmem_cache_free(ai->aeb_slab_cache, aeb);
2068c2ecf20Sopenharmony_ci}
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci/**
2098c2ecf20Sopenharmony_ci * add_to_list - add physical eraseblock to a list.
2108c2ecf20Sopenharmony_ci * @ai: attaching information
2118c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to add
2128c2ecf20Sopenharmony_ci * @vol_id: the last used volume id for the PEB
2138c2ecf20Sopenharmony_ci * @lnum: the last used LEB number for the PEB
2148c2ecf20Sopenharmony_ci * @ec: erase counter of the physical eraseblock
2158c2ecf20Sopenharmony_ci * @to_head: if not zero, add to the head of the list
2168c2ecf20Sopenharmony_ci * @list: the list to add to
2178c2ecf20Sopenharmony_ci *
2188c2ecf20Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for physical
2198c2ecf20Sopenharmony_ci * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists.
2208c2ecf20Sopenharmony_ci * It stores the @lnum and @vol_id alongside, which can both be
2218c2ecf20Sopenharmony_ci * %UBI_UNKNOWN if they are not available, not readable, or not assigned.
2228c2ecf20Sopenharmony_ci * If @to_head is not zero, PEB will be added to the head of the list, which
2238c2ecf20Sopenharmony_ci * basically means it will be processed first later. E.g., we add corrupted
2248c2ecf20Sopenharmony_ci * PEBs (corrupted due to power cuts) to the head of the erase list to make
2258c2ecf20Sopenharmony_ci * sure we erase them first and get rid of corruptions ASAP. This function
2268c2ecf20Sopenharmony_ci * returns zero in case of success and a negative error code in case of
2278c2ecf20Sopenharmony_ci * failure.
2288c2ecf20Sopenharmony_ci */
2298c2ecf20Sopenharmony_cistatic int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
2308c2ecf20Sopenharmony_ci		       int lnum, int ec, int to_head, struct list_head *list)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	if (list == &ai->free) {
2358c2ecf20Sopenharmony_ci		dbg_bld("add to free: PEB %d, EC %d", pnum, ec);
2368c2ecf20Sopenharmony_ci	} else if (list == &ai->erase) {
2378c2ecf20Sopenharmony_ci		dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);
2388c2ecf20Sopenharmony_ci	} else if (list == &ai->alien) {
2398c2ecf20Sopenharmony_ci		dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);
2408c2ecf20Sopenharmony_ci		ai->alien_peb_count += 1;
2418c2ecf20Sopenharmony_ci	} else
2428c2ecf20Sopenharmony_ci		BUG();
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	aeb = ubi_alloc_aeb(ai, pnum, ec);
2458c2ecf20Sopenharmony_ci	if (!aeb)
2468c2ecf20Sopenharmony_ci		return -ENOMEM;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	aeb->vol_id = vol_id;
2498c2ecf20Sopenharmony_ci	aeb->lnum = lnum;
2508c2ecf20Sopenharmony_ci	if (to_head)
2518c2ecf20Sopenharmony_ci		list_add(&aeb->u.list, list);
2528c2ecf20Sopenharmony_ci	else
2538c2ecf20Sopenharmony_ci		list_add_tail(&aeb->u.list, list);
2548c2ecf20Sopenharmony_ci	return 0;
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci/**
2588c2ecf20Sopenharmony_ci * add_corrupted - add a corrupted physical eraseblock.
2598c2ecf20Sopenharmony_ci * @ai: attaching information
2608c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to add
2618c2ecf20Sopenharmony_ci * @ec: erase counter of the physical eraseblock
2628c2ecf20Sopenharmony_ci *
2638c2ecf20Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for a corrupted
2648c2ecf20Sopenharmony_ci * physical eraseblock @pnum and adds it to the 'corr' list.  The corruption
2658c2ecf20Sopenharmony_ci * was presumably not caused by a power cut. Returns zero in case of success
2668c2ecf20Sopenharmony_ci * and a negative error code in case of failure.
2678c2ecf20Sopenharmony_ci */
2688c2ecf20Sopenharmony_cistatic int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	aeb = ubi_alloc_aeb(ai, pnum, ec);
2758c2ecf20Sopenharmony_ci	if (!aeb)
2768c2ecf20Sopenharmony_ci		return -ENOMEM;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	ai->corr_peb_count += 1;
2798c2ecf20Sopenharmony_ci	list_add(&aeb->u.list, &ai->corr);
2808c2ecf20Sopenharmony_ci	return 0;
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/**
2848c2ecf20Sopenharmony_ci * add_fastmap - add a Fastmap related physical eraseblock.
2858c2ecf20Sopenharmony_ci * @ai: attaching information
2868c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number the VID header came from
2878c2ecf20Sopenharmony_ci * @vid_hdr: the volume identifier header
2888c2ecf20Sopenharmony_ci * @ec: erase counter of the physical eraseblock
2898c2ecf20Sopenharmony_ci *
2908c2ecf20Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for a Fastamp
2918c2ecf20Sopenharmony_ci * physical eraseblock @pnum and adds it to the 'fastmap' list.
2928c2ecf20Sopenharmony_ci * Such blocks can be Fastmap super and data blocks from both the most
2938c2ecf20Sopenharmony_ci * recent Fastmap we're attaching from or from old Fastmaps which will
2948c2ecf20Sopenharmony_ci * be erased.
2958c2ecf20Sopenharmony_ci */
2968c2ecf20Sopenharmony_cistatic int add_fastmap(struct ubi_attach_info *ai, int pnum,
2978c2ecf20Sopenharmony_ci		       struct ubi_vid_hdr *vid_hdr, int ec)
2988c2ecf20Sopenharmony_ci{
2998c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	aeb = ubi_alloc_aeb(ai, pnum, ec);
3028c2ecf20Sopenharmony_ci	if (!aeb)
3038c2ecf20Sopenharmony_ci		return -ENOMEM;
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	aeb->vol_id = be32_to_cpu(vid_hdr->vol_id);
3068c2ecf20Sopenharmony_ci	aeb->sqnum = be64_to_cpu(vid_hdr->sqnum);
3078c2ecf20Sopenharmony_ci	list_add(&aeb->u.list, &ai->fastmap);
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum,
3108c2ecf20Sopenharmony_ci		aeb->vol_id, aeb->sqnum);
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	return 0;
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci/**
3168c2ecf20Sopenharmony_ci * validate_vid_hdr - check volume identifier header.
3178c2ecf20Sopenharmony_ci * @ubi: UBI device description object
3188c2ecf20Sopenharmony_ci * @vid_hdr: the volume identifier header to check
3198c2ecf20Sopenharmony_ci * @av: information about the volume this logical eraseblock belongs to
3208c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number the VID header came from
3218c2ecf20Sopenharmony_ci *
3228c2ecf20Sopenharmony_ci * This function checks that data stored in @vid_hdr is consistent. Returns
3238c2ecf20Sopenharmony_ci * non-zero if an inconsistency was found and zero if not.
3248c2ecf20Sopenharmony_ci *
3258c2ecf20Sopenharmony_ci * Note, UBI does sanity check of everything it reads from the flash media.
3268c2ecf20Sopenharmony_ci * Most of the checks are done in the I/O sub-system. Here we check that the
3278c2ecf20Sopenharmony_ci * information in the VID header is consistent to the information in other VID
3288c2ecf20Sopenharmony_ci * headers of the same volume.
3298c2ecf20Sopenharmony_ci */
3308c2ecf20Sopenharmony_cistatic int validate_vid_hdr(const struct ubi_device *ubi,
3318c2ecf20Sopenharmony_ci			    const struct ubi_vid_hdr *vid_hdr,
3328c2ecf20Sopenharmony_ci			    const struct ubi_ainf_volume *av, int pnum)
3338c2ecf20Sopenharmony_ci{
3348c2ecf20Sopenharmony_ci	int vol_type = vid_hdr->vol_type;
3358c2ecf20Sopenharmony_ci	int vol_id = be32_to_cpu(vid_hdr->vol_id);
3368c2ecf20Sopenharmony_ci	int used_ebs = be32_to_cpu(vid_hdr->used_ebs);
3378c2ecf20Sopenharmony_ci	int data_pad = be32_to_cpu(vid_hdr->data_pad);
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci	if (av->leb_count != 0) {
3408c2ecf20Sopenharmony_ci		int av_vol_type;
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci		/*
3438c2ecf20Sopenharmony_ci		 * This is not the first logical eraseblock belonging to this
3448c2ecf20Sopenharmony_ci		 * volume. Ensure that the data in its VID header is consistent
3458c2ecf20Sopenharmony_ci		 * to the data in previous logical eraseblock headers.
3468c2ecf20Sopenharmony_ci		 */
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci		if (vol_id != av->vol_id) {
3498c2ecf20Sopenharmony_ci			ubi_err(ubi, "inconsistent vol_id");
3508c2ecf20Sopenharmony_ci			goto bad;
3518c2ecf20Sopenharmony_ci		}
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci		if (av->vol_type == UBI_STATIC_VOLUME)
3548c2ecf20Sopenharmony_ci			av_vol_type = UBI_VID_STATIC;
3558c2ecf20Sopenharmony_ci		else
3568c2ecf20Sopenharmony_ci			av_vol_type = UBI_VID_DYNAMIC;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci		if (vol_type != av_vol_type) {
3598c2ecf20Sopenharmony_ci			ubi_err(ubi, "inconsistent vol_type");
3608c2ecf20Sopenharmony_ci			goto bad;
3618c2ecf20Sopenharmony_ci		}
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci		if (used_ebs != av->used_ebs) {
3648c2ecf20Sopenharmony_ci			ubi_err(ubi, "inconsistent used_ebs");
3658c2ecf20Sopenharmony_ci			goto bad;
3668c2ecf20Sopenharmony_ci		}
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci		if (data_pad != av->data_pad) {
3698c2ecf20Sopenharmony_ci			ubi_err(ubi, "inconsistent data_pad");
3708c2ecf20Sopenharmony_ci			goto bad;
3718c2ecf20Sopenharmony_ci		}
3728c2ecf20Sopenharmony_ci	}
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	return 0;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_cibad:
3778c2ecf20Sopenharmony_ci	ubi_err(ubi, "inconsistent VID header at PEB %d", pnum);
3788c2ecf20Sopenharmony_ci	ubi_dump_vid_hdr(vid_hdr);
3798c2ecf20Sopenharmony_ci	ubi_dump_av(av);
3808c2ecf20Sopenharmony_ci	return -EINVAL;
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci/**
3848c2ecf20Sopenharmony_ci * add_volume - add volume to the attaching information.
3858c2ecf20Sopenharmony_ci * @ai: attaching information
3868c2ecf20Sopenharmony_ci * @vol_id: ID of the volume to add
3878c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number
3888c2ecf20Sopenharmony_ci * @vid_hdr: volume identifier header
3898c2ecf20Sopenharmony_ci *
3908c2ecf20Sopenharmony_ci * If the volume corresponding to the @vid_hdr logical eraseblock is already
3918c2ecf20Sopenharmony_ci * present in the attaching information, this function does nothing. Otherwise
3928c2ecf20Sopenharmony_ci * it adds corresponding volume to the attaching information. Returns a pointer
3938c2ecf20Sopenharmony_ci * to the allocated "av" object in case of success and a negative error code in
3948c2ecf20Sopenharmony_ci * case of failure.
3958c2ecf20Sopenharmony_ci */
3968c2ecf20Sopenharmony_cistatic struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
3978c2ecf20Sopenharmony_ci					  int vol_id, int pnum,
3988c2ecf20Sopenharmony_ci					  const struct ubi_vid_hdr *vid_hdr)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
4018c2ecf20Sopenharmony_ci	bool created;
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci	ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id));
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	av = ubi_find_or_add_av(ai, vol_id, &created);
4068c2ecf20Sopenharmony_ci	if (IS_ERR(av) || !created)
4078c2ecf20Sopenharmony_ci		return av;
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	av->used_ebs = be32_to_cpu(vid_hdr->used_ebs);
4108c2ecf20Sopenharmony_ci	av->data_pad = be32_to_cpu(vid_hdr->data_pad);
4118c2ecf20Sopenharmony_ci	av->compat = vid_hdr->compat;
4128c2ecf20Sopenharmony_ci	av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME
4138c2ecf20Sopenharmony_ci							    : UBI_STATIC_VOLUME;
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	return av;
4168c2ecf20Sopenharmony_ci}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci/**
4198c2ecf20Sopenharmony_ci * ubi_compare_lebs - find out which logical eraseblock is newer.
4208c2ecf20Sopenharmony_ci * @ubi: UBI device description object
4218c2ecf20Sopenharmony_ci * @aeb: first logical eraseblock to compare
4228c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number of the second logical eraseblock to
4238c2ecf20Sopenharmony_ci * compare
4248c2ecf20Sopenharmony_ci * @vid_hdr: volume identifier header of the second logical eraseblock
4258c2ecf20Sopenharmony_ci *
4268c2ecf20Sopenharmony_ci * This function compares 2 copies of a LEB and informs which one is newer. In
4278c2ecf20Sopenharmony_ci * case of success this function returns a positive value, in case of failure, a
4288c2ecf20Sopenharmony_ci * negative error code is returned. The success return codes use the following
4298c2ecf20Sopenharmony_ci * bits:
4308c2ecf20Sopenharmony_ci *     o bit 0 is cleared: the first PEB (described by @aeb) is newer than the
4318c2ecf20Sopenharmony_ci *       second PEB (described by @pnum and @vid_hdr);
4328c2ecf20Sopenharmony_ci *     o bit 0 is set: the second PEB is newer;
4338c2ecf20Sopenharmony_ci *     o bit 1 is cleared: no bit-flips were detected in the newer LEB;
4348c2ecf20Sopenharmony_ci *     o bit 1 is set: bit-flips were detected in the newer LEB;
4358c2ecf20Sopenharmony_ci *     o bit 2 is cleared: the older LEB is not corrupted;
4368c2ecf20Sopenharmony_ci *     o bit 2 is set: the older LEB is corrupted.
4378c2ecf20Sopenharmony_ci */
4388c2ecf20Sopenharmony_ciint ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
4398c2ecf20Sopenharmony_ci			int pnum, const struct ubi_vid_hdr *vid_hdr)
4408c2ecf20Sopenharmony_ci{
4418c2ecf20Sopenharmony_ci	int len, err, second_is_newer, bitflips = 0, corrupted = 0;
4428c2ecf20Sopenharmony_ci	uint32_t data_crc, crc;
4438c2ecf20Sopenharmony_ci	struct ubi_vid_io_buf *vidb = NULL;
4448c2ecf20Sopenharmony_ci	unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum);
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	if (sqnum2 == aeb->sqnum) {
4478c2ecf20Sopenharmony_ci		/*
4488c2ecf20Sopenharmony_ci		 * This must be a really ancient UBI image which has been
4498c2ecf20Sopenharmony_ci		 * created before sequence numbers support has been added. At
4508c2ecf20Sopenharmony_ci		 * that times we used 32-bit LEB versions stored in logical
4518c2ecf20Sopenharmony_ci		 * eraseblocks. That was before UBI got into mainline. We do not
4528c2ecf20Sopenharmony_ci		 * support these images anymore. Well, those images still work,
4538c2ecf20Sopenharmony_ci		 * but only if no unclean reboots happened.
4548c2ecf20Sopenharmony_ci		 */
4558c2ecf20Sopenharmony_ci		ubi_err(ubi, "unsupported on-flash UBI format");
4568c2ecf20Sopenharmony_ci		return -EINVAL;
4578c2ecf20Sopenharmony_ci	}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	/* Obviously the LEB with lower sequence counter is older */
4608c2ecf20Sopenharmony_ci	second_is_newer = (sqnum2 > aeb->sqnum);
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	/*
4638c2ecf20Sopenharmony_ci	 * Now we know which copy is newer. If the copy flag of the PEB with
4648c2ecf20Sopenharmony_ci	 * newer version is not set, then we just return, otherwise we have to
4658c2ecf20Sopenharmony_ci	 * check data CRC. For the second PEB we already have the VID header,
4668c2ecf20Sopenharmony_ci	 * for the first one - we'll need to re-read it from flash.
4678c2ecf20Sopenharmony_ci	 *
4688c2ecf20Sopenharmony_ci	 * Note: this may be optimized so that we wouldn't read twice.
4698c2ecf20Sopenharmony_ci	 */
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	if (second_is_newer) {
4728c2ecf20Sopenharmony_ci		if (!vid_hdr->copy_flag) {
4738c2ecf20Sopenharmony_ci			/* It is not a copy, so it is newer */
4748c2ecf20Sopenharmony_ci			dbg_bld("second PEB %d is newer, copy_flag is unset",
4758c2ecf20Sopenharmony_ci				pnum);
4768c2ecf20Sopenharmony_ci			return 1;
4778c2ecf20Sopenharmony_ci		}
4788c2ecf20Sopenharmony_ci	} else {
4798c2ecf20Sopenharmony_ci		if (!aeb->copy_flag) {
4808c2ecf20Sopenharmony_ci			/* It is not a copy, so it is newer */
4818c2ecf20Sopenharmony_ci			dbg_bld("first PEB %d is newer, copy_flag is unset",
4828c2ecf20Sopenharmony_ci				pnum);
4838c2ecf20Sopenharmony_ci			return bitflips << 1;
4848c2ecf20Sopenharmony_ci		}
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci		vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL);
4878c2ecf20Sopenharmony_ci		if (!vidb)
4888c2ecf20Sopenharmony_ci			return -ENOMEM;
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci		pnum = aeb->pnum;
4918c2ecf20Sopenharmony_ci		err = ubi_io_read_vid_hdr(ubi, pnum, vidb, 0);
4928c2ecf20Sopenharmony_ci		if (err) {
4938c2ecf20Sopenharmony_ci			if (err == UBI_IO_BITFLIPS)
4948c2ecf20Sopenharmony_ci				bitflips = 1;
4958c2ecf20Sopenharmony_ci			else {
4968c2ecf20Sopenharmony_ci				ubi_err(ubi, "VID of PEB %d header is bad, but it was OK earlier, err %d",
4978c2ecf20Sopenharmony_ci					pnum, err);
4988c2ecf20Sopenharmony_ci				if (err > 0)
4998c2ecf20Sopenharmony_ci					err = -EIO;
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci				goto out_free_vidh;
5028c2ecf20Sopenharmony_ci			}
5038c2ecf20Sopenharmony_ci		}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci		vid_hdr = ubi_get_vid_hdr(vidb);
5068c2ecf20Sopenharmony_ci	}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	/* Read the data of the copy and check the CRC */
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	len = be32_to_cpu(vid_hdr->data_size);
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_ci	mutex_lock(&ubi->buf_mutex);
5138c2ecf20Sopenharmony_ci	err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len);
5148c2ecf20Sopenharmony_ci	if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
5158c2ecf20Sopenharmony_ci		goto out_unlock;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	data_crc = be32_to_cpu(vid_hdr->data_crc);
5188c2ecf20Sopenharmony_ci	crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len);
5198c2ecf20Sopenharmony_ci	if (crc != data_crc) {
5208c2ecf20Sopenharmony_ci		dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x",
5218c2ecf20Sopenharmony_ci			pnum, crc, data_crc);
5228c2ecf20Sopenharmony_ci		corrupted = 1;
5238c2ecf20Sopenharmony_ci		bitflips = 0;
5248c2ecf20Sopenharmony_ci		second_is_newer = !second_is_newer;
5258c2ecf20Sopenharmony_ci	} else {
5268c2ecf20Sopenharmony_ci		dbg_bld("PEB %d CRC is OK", pnum);
5278c2ecf20Sopenharmony_ci		bitflips |= !!err;
5288c2ecf20Sopenharmony_ci	}
5298c2ecf20Sopenharmony_ci	mutex_unlock(&ubi->buf_mutex);
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	ubi_free_vid_buf(vidb);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	if (second_is_newer)
5348c2ecf20Sopenharmony_ci		dbg_bld("second PEB %d is newer, copy_flag is set", pnum);
5358c2ecf20Sopenharmony_ci	else
5368c2ecf20Sopenharmony_ci		dbg_bld("first PEB %d is newer, copy_flag is set", pnum);
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	return second_is_newer | (bitflips << 1) | (corrupted << 2);
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_ciout_unlock:
5418c2ecf20Sopenharmony_ci	mutex_unlock(&ubi->buf_mutex);
5428c2ecf20Sopenharmony_ciout_free_vidh:
5438c2ecf20Sopenharmony_ci	ubi_free_vid_buf(vidb);
5448c2ecf20Sopenharmony_ci	return err;
5458c2ecf20Sopenharmony_ci}
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci/**
5488c2ecf20Sopenharmony_ci * ubi_add_to_av - add used physical eraseblock to the attaching information.
5498c2ecf20Sopenharmony_ci * @ubi: UBI device description object
5508c2ecf20Sopenharmony_ci * @ai: attaching information
5518c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number
5528c2ecf20Sopenharmony_ci * @ec: erase counter
5538c2ecf20Sopenharmony_ci * @vid_hdr: the volume identifier header
5548c2ecf20Sopenharmony_ci * @bitflips: if bit-flips were detected when this physical eraseblock was read
5558c2ecf20Sopenharmony_ci *
5568c2ecf20Sopenharmony_ci * This function adds information about a used physical eraseblock to the
5578c2ecf20Sopenharmony_ci * 'used' tree of the corresponding volume. The function is rather complex
5588c2ecf20Sopenharmony_ci * because it has to handle cases when this is not the first physical
5598c2ecf20Sopenharmony_ci * eraseblock belonging to the same logical eraseblock, and the newer one has
5608c2ecf20Sopenharmony_ci * to be picked, while the older one has to be dropped. This function returns
5618c2ecf20Sopenharmony_ci * zero in case of success and a negative error code in case of failure.
5628c2ecf20Sopenharmony_ci */
5638c2ecf20Sopenharmony_ciint ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
5648c2ecf20Sopenharmony_ci		  int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips)
5658c2ecf20Sopenharmony_ci{
5668c2ecf20Sopenharmony_ci	int err, vol_id, lnum;
5678c2ecf20Sopenharmony_ci	unsigned long long sqnum;
5688c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
5698c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
5708c2ecf20Sopenharmony_ci	struct rb_node **p, *parent = NULL;
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	vol_id = be32_to_cpu(vid_hdr->vol_id);
5738c2ecf20Sopenharmony_ci	lnum = be32_to_cpu(vid_hdr->lnum);
5748c2ecf20Sopenharmony_ci	sqnum = be64_to_cpu(vid_hdr->sqnum);
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d",
5778c2ecf20Sopenharmony_ci		pnum, vol_id, lnum, ec, sqnum, bitflips);
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_ci	av = add_volume(ai, vol_id, pnum, vid_hdr);
5808c2ecf20Sopenharmony_ci	if (IS_ERR(av))
5818c2ecf20Sopenharmony_ci		return PTR_ERR(av);
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	if (ai->max_sqnum < sqnum)
5848c2ecf20Sopenharmony_ci		ai->max_sqnum = sqnum;
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci	/*
5878c2ecf20Sopenharmony_ci	 * Walk the RB-tree of logical eraseblocks of volume @vol_id to look
5888c2ecf20Sopenharmony_ci	 * if this is the first instance of this logical eraseblock or not.
5898c2ecf20Sopenharmony_ci	 */
5908c2ecf20Sopenharmony_ci	p = &av->root.rb_node;
5918c2ecf20Sopenharmony_ci	while (*p) {
5928c2ecf20Sopenharmony_ci		int cmp_res;
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci		parent = *p;
5958c2ecf20Sopenharmony_ci		aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
5968c2ecf20Sopenharmony_ci		if (lnum != aeb->lnum) {
5978c2ecf20Sopenharmony_ci			if (lnum < aeb->lnum)
5988c2ecf20Sopenharmony_ci				p = &(*p)->rb_left;
5998c2ecf20Sopenharmony_ci			else
6008c2ecf20Sopenharmony_ci				p = &(*p)->rb_right;
6018c2ecf20Sopenharmony_ci			continue;
6028c2ecf20Sopenharmony_ci		}
6038c2ecf20Sopenharmony_ci
6048c2ecf20Sopenharmony_ci		/*
6058c2ecf20Sopenharmony_ci		 * There is already a physical eraseblock describing the same
6068c2ecf20Sopenharmony_ci		 * logical eraseblock present.
6078c2ecf20Sopenharmony_ci		 */
6088c2ecf20Sopenharmony_ci
6098c2ecf20Sopenharmony_ci		dbg_bld("this LEB already exists: PEB %d, sqnum %llu, EC %d",
6108c2ecf20Sopenharmony_ci			aeb->pnum, aeb->sqnum, aeb->ec);
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci		/*
6138c2ecf20Sopenharmony_ci		 * Make sure that the logical eraseblocks have different
6148c2ecf20Sopenharmony_ci		 * sequence numbers. Otherwise the image is bad.
6158c2ecf20Sopenharmony_ci		 *
6168c2ecf20Sopenharmony_ci		 * However, if the sequence number is zero, we assume it must
6178c2ecf20Sopenharmony_ci		 * be an ancient UBI image from the era when UBI did not have
6188c2ecf20Sopenharmony_ci		 * sequence numbers. We still can attach these images, unless
6198c2ecf20Sopenharmony_ci		 * there is a need to distinguish between old and new
6208c2ecf20Sopenharmony_ci		 * eraseblocks, in which case we'll refuse the image in
6218c2ecf20Sopenharmony_ci		 * 'ubi_compare_lebs()'. In other words, we attach old clean
6228c2ecf20Sopenharmony_ci		 * images, but refuse attaching old images with duplicated
6238c2ecf20Sopenharmony_ci		 * logical eraseblocks because there was an unclean reboot.
6248c2ecf20Sopenharmony_ci		 */
6258c2ecf20Sopenharmony_ci		if (aeb->sqnum == sqnum && sqnum != 0) {
6268c2ecf20Sopenharmony_ci			ubi_err(ubi, "two LEBs with same sequence number %llu",
6278c2ecf20Sopenharmony_ci				sqnum);
6288c2ecf20Sopenharmony_ci			ubi_dump_aeb(aeb, 0);
6298c2ecf20Sopenharmony_ci			ubi_dump_vid_hdr(vid_hdr);
6308c2ecf20Sopenharmony_ci			return -EINVAL;
6318c2ecf20Sopenharmony_ci		}
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci		/*
6348c2ecf20Sopenharmony_ci		 * Now we have to drop the older one and preserve the newer
6358c2ecf20Sopenharmony_ci		 * one.
6368c2ecf20Sopenharmony_ci		 */
6378c2ecf20Sopenharmony_ci		cmp_res = ubi_compare_lebs(ubi, aeb, pnum, vid_hdr);
6388c2ecf20Sopenharmony_ci		if (cmp_res < 0)
6398c2ecf20Sopenharmony_ci			return cmp_res;
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci		if (cmp_res & 1) {
6428c2ecf20Sopenharmony_ci			/*
6438c2ecf20Sopenharmony_ci			 * This logical eraseblock is newer than the one
6448c2ecf20Sopenharmony_ci			 * found earlier.
6458c2ecf20Sopenharmony_ci			 */
6468c2ecf20Sopenharmony_ci			err = validate_vid_hdr(ubi, vid_hdr, av, pnum);
6478c2ecf20Sopenharmony_ci			if (err)
6488c2ecf20Sopenharmony_ci				return err;
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci			err = add_to_list(ai, aeb->pnum, aeb->vol_id,
6518c2ecf20Sopenharmony_ci					  aeb->lnum, aeb->ec, cmp_res & 4,
6528c2ecf20Sopenharmony_ci					  &ai->erase);
6538c2ecf20Sopenharmony_ci			if (err)
6548c2ecf20Sopenharmony_ci				return err;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci			aeb->ec = ec;
6578c2ecf20Sopenharmony_ci			aeb->pnum = pnum;
6588c2ecf20Sopenharmony_ci			aeb->vol_id = vol_id;
6598c2ecf20Sopenharmony_ci			aeb->lnum = lnum;
6608c2ecf20Sopenharmony_ci			aeb->scrub = ((cmp_res & 2) || bitflips);
6618c2ecf20Sopenharmony_ci			aeb->copy_flag = vid_hdr->copy_flag;
6628c2ecf20Sopenharmony_ci			aeb->sqnum = sqnum;
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci			if (av->highest_lnum == lnum)
6658c2ecf20Sopenharmony_ci				av->last_data_size =
6668c2ecf20Sopenharmony_ci					be32_to_cpu(vid_hdr->data_size);
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci			return 0;
6698c2ecf20Sopenharmony_ci		} else {
6708c2ecf20Sopenharmony_ci			/*
6718c2ecf20Sopenharmony_ci			 * This logical eraseblock is older than the one found
6728c2ecf20Sopenharmony_ci			 * previously.
6738c2ecf20Sopenharmony_ci			 */
6748c2ecf20Sopenharmony_ci			return add_to_list(ai, pnum, vol_id, lnum, ec,
6758c2ecf20Sopenharmony_ci					   cmp_res & 4, &ai->erase);
6768c2ecf20Sopenharmony_ci		}
6778c2ecf20Sopenharmony_ci	}
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci	/*
6808c2ecf20Sopenharmony_ci	 * We've met this logical eraseblock for the first time, add it to the
6818c2ecf20Sopenharmony_ci	 * attaching information.
6828c2ecf20Sopenharmony_ci	 */
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci	err = validate_vid_hdr(ubi, vid_hdr, av, pnum);
6858c2ecf20Sopenharmony_ci	if (err)
6868c2ecf20Sopenharmony_ci		return err;
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci	aeb = ubi_alloc_aeb(ai, pnum, ec);
6898c2ecf20Sopenharmony_ci	if (!aeb)
6908c2ecf20Sopenharmony_ci		return -ENOMEM;
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci	aeb->vol_id = vol_id;
6938c2ecf20Sopenharmony_ci	aeb->lnum = lnum;
6948c2ecf20Sopenharmony_ci	aeb->scrub = bitflips;
6958c2ecf20Sopenharmony_ci	aeb->copy_flag = vid_hdr->copy_flag;
6968c2ecf20Sopenharmony_ci	aeb->sqnum = sqnum;
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	if (av->highest_lnum <= lnum) {
6998c2ecf20Sopenharmony_ci		av->highest_lnum = lnum;
7008c2ecf20Sopenharmony_ci		av->last_data_size = be32_to_cpu(vid_hdr->data_size);
7018c2ecf20Sopenharmony_ci	}
7028c2ecf20Sopenharmony_ci
7038c2ecf20Sopenharmony_ci	av->leb_count += 1;
7048c2ecf20Sopenharmony_ci	rb_link_node(&aeb->u.rb, parent, p);
7058c2ecf20Sopenharmony_ci	rb_insert_color(&aeb->u.rb, &av->root);
7068c2ecf20Sopenharmony_ci	return 0;
7078c2ecf20Sopenharmony_ci}
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci/**
7108c2ecf20Sopenharmony_ci * ubi_add_av - add volume to the attaching information.
7118c2ecf20Sopenharmony_ci * @ai: attaching information
7128c2ecf20Sopenharmony_ci * @vol_id: the requested volume ID
7138c2ecf20Sopenharmony_ci *
7148c2ecf20Sopenharmony_ci * This function returns a pointer to the new volume description or an
7158c2ecf20Sopenharmony_ci * ERR_PTR if the operation failed.
7168c2ecf20Sopenharmony_ci */
7178c2ecf20Sopenharmony_cistruct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id)
7188c2ecf20Sopenharmony_ci{
7198c2ecf20Sopenharmony_ci	bool created;
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci	return find_or_add_av(ai, vol_id, AV_ADD, &created);
7228c2ecf20Sopenharmony_ci}
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ci/**
7258c2ecf20Sopenharmony_ci * ubi_find_av - find volume in the attaching information.
7268c2ecf20Sopenharmony_ci * @ai: attaching information
7278c2ecf20Sopenharmony_ci * @vol_id: the requested volume ID
7288c2ecf20Sopenharmony_ci *
7298c2ecf20Sopenharmony_ci * This function returns a pointer to the volume description or %NULL if there
7308c2ecf20Sopenharmony_ci * are no data about this volume in the attaching information.
7318c2ecf20Sopenharmony_ci */
7328c2ecf20Sopenharmony_cistruct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
7338c2ecf20Sopenharmony_ci				    int vol_id)
7348c2ecf20Sopenharmony_ci{
7358c2ecf20Sopenharmony_ci	bool created;
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	return find_or_add_av((struct ubi_attach_info *)ai, vol_id, AV_FIND,
7388c2ecf20Sopenharmony_ci			      &created);
7398c2ecf20Sopenharmony_ci}
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_cistatic void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av,
7428c2ecf20Sopenharmony_ci		       struct list_head *list);
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_ci/**
7458c2ecf20Sopenharmony_ci * ubi_remove_av - delete attaching information about a volume.
7468c2ecf20Sopenharmony_ci * @ai: attaching information
7478c2ecf20Sopenharmony_ci * @av: the volume attaching information to delete
7488c2ecf20Sopenharmony_ci */
7498c2ecf20Sopenharmony_civoid ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av)
7508c2ecf20Sopenharmony_ci{
7518c2ecf20Sopenharmony_ci	dbg_bld("remove attaching information about volume %d", av->vol_id);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci	rb_erase(&av->rb, &ai->volumes);
7548c2ecf20Sopenharmony_ci	destroy_av(ai, av, &ai->erase);
7558c2ecf20Sopenharmony_ci	ai->vols_found -= 1;
7568c2ecf20Sopenharmony_ci}
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci/**
7598c2ecf20Sopenharmony_ci * early_erase_peb - erase a physical eraseblock.
7608c2ecf20Sopenharmony_ci * @ubi: UBI device description object
7618c2ecf20Sopenharmony_ci * @ai: attaching information
7628c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to erase;
7638c2ecf20Sopenharmony_ci * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown)
7648c2ecf20Sopenharmony_ci *
7658c2ecf20Sopenharmony_ci * This function erases physical eraseblock 'pnum', and writes the erase
7668c2ecf20Sopenharmony_ci * counter header to it. This function should only be used on UBI device
7678c2ecf20Sopenharmony_ci * initialization stages, when the EBA sub-system had not been yet initialized.
7688c2ecf20Sopenharmony_ci * This function returns zero in case of success and a negative error code in
7698c2ecf20Sopenharmony_ci * case of failure.
7708c2ecf20Sopenharmony_ci */
7718c2ecf20Sopenharmony_cistatic int early_erase_peb(struct ubi_device *ubi,
7728c2ecf20Sopenharmony_ci			   const struct ubi_attach_info *ai, int pnum, int ec)
7738c2ecf20Sopenharmony_ci{
7748c2ecf20Sopenharmony_ci	int err;
7758c2ecf20Sopenharmony_ci	struct ubi_ec_hdr *ec_hdr;
7768c2ecf20Sopenharmony_ci
7778c2ecf20Sopenharmony_ci	if ((long long)ec >= UBI_MAX_ERASECOUNTER) {
7788c2ecf20Sopenharmony_ci		/*
7798c2ecf20Sopenharmony_ci		 * Erase counter overflow. Upgrade UBI and use 64-bit
7808c2ecf20Sopenharmony_ci		 * erase counters internally.
7818c2ecf20Sopenharmony_ci		 */
7828c2ecf20Sopenharmony_ci		ubi_err(ubi, "erase counter overflow at PEB %d, EC %d",
7838c2ecf20Sopenharmony_ci			pnum, ec);
7848c2ecf20Sopenharmony_ci		return -EINVAL;
7858c2ecf20Sopenharmony_ci	}
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
7888c2ecf20Sopenharmony_ci	if (!ec_hdr)
7898c2ecf20Sopenharmony_ci		return -ENOMEM;
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_ci	ec_hdr->ec = cpu_to_be64(ec);
7928c2ecf20Sopenharmony_ci
7938c2ecf20Sopenharmony_ci	err = ubi_io_sync_erase(ubi, pnum, 0);
7948c2ecf20Sopenharmony_ci	if (err < 0)
7958c2ecf20Sopenharmony_ci		goto out_free;
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci	err = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ciout_free:
8008c2ecf20Sopenharmony_ci	kfree(ec_hdr);
8018c2ecf20Sopenharmony_ci	return err;
8028c2ecf20Sopenharmony_ci}
8038c2ecf20Sopenharmony_ci
8048c2ecf20Sopenharmony_ci/**
8058c2ecf20Sopenharmony_ci * ubi_early_get_peb - get a free physical eraseblock.
8068c2ecf20Sopenharmony_ci * @ubi: UBI device description object
8078c2ecf20Sopenharmony_ci * @ai: attaching information
8088c2ecf20Sopenharmony_ci *
8098c2ecf20Sopenharmony_ci * This function returns a free physical eraseblock. It is supposed to be
8108c2ecf20Sopenharmony_ci * called on the UBI initialization stages when the wear-leveling sub-system is
8118c2ecf20Sopenharmony_ci * not initialized yet. This function picks a physical eraseblocks from one of
8128c2ecf20Sopenharmony_ci * the lists, writes the EC header if it is needed, and removes it from the
8138c2ecf20Sopenharmony_ci * list.
8148c2ecf20Sopenharmony_ci *
8158c2ecf20Sopenharmony_ci * This function returns a pointer to the "aeb" of the found free PEB in case
8168c2ecf20Sopenharmony_ci * of success and an error code in case of failure.
8178c2ecf20Sopenharmony_ci */
8188c2ecf20Sopenharmony_cistruct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
8198c2ecf20Sopenharmony_ci				       struct ubi_attach_info *ai)
8208c2ecf20Sopenharmony_ci{
8218c2ecf20Sopenharmony_ci	int err = 0;
8228c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb, *tmp_aeb;
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci	if (!list_empty(&ai->free)) {
8258c2ecf20Sopenharmony_ci		aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list);
8268c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
8278c2ecf20Sopenharmony_ci		dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec);
8288c2ecf20Sopenharmony_ci		return aeb;
8298c2ecf20Sopenharmony_ci	}
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci	/*
8328c2ecf20Sopenharmony_ci	 * We try to erase the first physical eraseblock from the erase list
8338c2ecf20Sopenharmony_ci	 * and pick it if we succeed, or try to erase the next one if not. And
8348c2ecf20Sopenharmony_ci	 * so forth. We don't want to take care about bad eraseblocks here -
8358c2ecf20Sopenharmony_ci	 * they'll be handled later.
8368c2ecf20Sopenharmony_ci	 */
8378c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) {
8388c2ecf20Sopenharmony_ci		if (aeb->ec == UBI_UNKNOWN)
8398c2ecf20Sopenharmony_ci			aeb->ec = ai->mean_ec;
8408c2ecf20Sopenharmony_ci
8418c2ecf20Sopenharmony_ci		err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1);
8428c2ecf20Sopenharmony_ci		if (err)
8438c2ecf20Sopenharmony_ci			continue;
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci		aeb->ec += 1;
8468c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
8478c2ecf20Sopenharmony_ci		dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec);
8488c2ecf20Sopenharmony_ci		return aeb;
8498c2ecf20Sopenharmony_ci	}
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_ci	ubi_err(ubi, "no free eraseblocks");
8528c2ecf20Sopenharmony_ci	return ERR_PTR(-ENOSPC);
8538c2ecf20Sopenharmony_ci}
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci/**
8568c2ecf20Sopenharmony_ci * check_corruption - check the data area of PEB.
8578c2ecf20Sopenharmony_ci * @ubi: UBI device description object
8588c2ecf20Sopenharmony_ci * @vid_hdr: the (corrupted) VID header of this PEB
8598c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to check
8608c2ecf20Sopenharmony_ci *
8618c2ecf20Sopenharmony_ci * This is a helper function which is used to distinguish between VID header
8628c2ecf20Sopenharmony_ci * corruptions caused by power cuts and other reasons. If the PEB contains only
8638c2ecf20Sopenharmony_ci * 0xFF bytes in the data area, the VID header is most probably corrupted
8648c2ecf20Sopenharmony_ci * because of a power cut (%0 is returned in this case). Otherwise, it was
8658c2ecf20Sopenharmony_ci * probably corrupted for some other reasons (%1 is returned in this case). A
8668c2ecf20Sopenharmony_ci * negative error code is returned if a read error occurred.
8678c2ecf20Sopenharmony_ci *
8688c2ecf20Sopenharmony_ci * If the corruption reason was a power cut, UBI can safely erase this PEB.
8698c2ecf20Sopenharmony_ci * Otherwise, it should preserve it to avoid possibly destroying important
8708c2ecf20Sopenharmony_ci * information.
8718c2ecf20Sopenharmony_ci */
8728c2ecf20Sopenharmony_cistatic int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
8738c2ecf20Sopenharmony_ci			    int pnum)
8748c2ecf20Sopenharmony_ci{
8758c2ecf20Sopenharmony_ci	int err;
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci	mutex_lock(&ubi->buf_mutex);
8788c2ecf20Sopenharmony_ci	memset(ubi->peb_buf, 0x00, ubi->leb_size);
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci	err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start,
8818c2ecf20Sopenharmony_ci			  ubi->leb_size);
8828c2ecf20Sopenharmony_ci	if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) {
8838c2ecf20Sopenharmony_ci		/*
8848c2ecf20Sopenharmony_ci		 * Bit-flips or integrity errors while reading the data area.
8858c2ecf20Sopenharmony_ci		 * It is difficult to say for sure what type of corruption is
8868c2ecf20Sopenharmony_ci		 * this, but presumably a power cut happened while this PEB was
8878c2ecf20Sopenharmony_ci		 * erased, so it became unstable and corrupted, and should be
8888c2ecf20Sopenharmony_ci		 * erased.
8898c2ecf20Sopenharmony_ci		 */
8908c2ecf20Sopenharmony_ci		err = 0;
8918c2ecf20Sopenharmony_ci		goto out_unlock;
8928c2ecf20Sopenharmony_ci	}
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci	if (err)
8958c2ecf20Sopenharmony_ci		goto out_unlock;
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size))
8988c2ecf20Sopenharmony_ci		goto out_unlock;
8998c2ecf20Sopenharmony_ci
9008c2ecf20Sopenharmony_ci	ubi_err(ubi, "PEB %d contains corrupted VID header, and the data does not contain all 0xFF",
9018c2ecf20Sopenharmony_ci		pnum);
9028c2ecf20Sopenharmony_ci	ubi_err(ubi, "this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection");
9038c2ecf20Sopenharmony_ci	ubi_dump_vid_hdr(vid_hdr);
9048c2ecf20Sopenharmony_ci	pr_err("hexdump of PEB %d offset %d, length %d",
9058c2ecf20Sopenharmony_ci	       pnum, ubi->leb_start, ubi->leb_size);
9068c2ecf20Sopenharmony_ci	ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
9078c2ecf20Sopenharmony_ci			       ubi->peb_buf, ubi->leb_size, 1);
9088c2ecf20Sopenharmony_ci	err = 1;
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ciout_unlock:
9118c2ecf20Sopenharmony_ci	mutex_unlock(&ubi->buf_mutex);
9128c2ecf20Sopenharmony_ci	return err;
9138c2ecf20Sopenharmony_ci}
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_cistatic bool vol_ignored(int vol_id)
9168c2ecf20Sopenharmony_ci{
9178c2ecf20Sopenharmony_ci	switch (vol_id) {
9188c2ecf20Sopenharmony_ci		case UBI_LAYOUT_VOLUME_ID:
9198c2ecf20Sopenharmony_ci		return true;
9208c2ecf20Sopenharmony_ci	}
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP
9238c2ecf20Sopenharmony_ci	return ubi_is_fm_vol(vol_id);
9248c2ecf20Sopenharmony_ci#else
9258c2ecf20Sopenharmony_ci	return false;
9268c2ecf20Sopenharmony_ci#endif
9278c2ecf20Sopenharmony_ci}
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_ci/**
9308c2ecf20Sopenharmony_ci * scan_peb - scan and process UBI headers of a PEB.
9318c2ecf20Sopenharmony_ci * @ubi: UBI device description object
9328c2ecf20Sopenharmony_ci * @ai: attaching information
9338c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number
9348c2ecf20Sopenharmony_ci * @fast: true if we're scanning for a Fastmap
9358c2ecf20Sopenharmony_ci *
9368c2ecf20Sopenharmony_ci * This function reads UBI headers of PEB @pnum, checks them, and adds
9378c2ecf20Sopenharmony_ci * information about this PEB to the corresponding list or RB-tree in the
9388c2ecf20Sopenharmony_ci * "attaching info" structure. Returns zero if the physical eraseblock was
9398c2ecf20Sopenharmony_ci * successfully handled and a negative error code in case of failure.
9408c2ecf20Sopenharmony_ci */
9418c2ecf20Sopenharmony_cistatic int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
9428c2ecf20Sopenharmony_ci		    int pnum, bool fast)
9438c2ecf20Sopenharmony_ci{
9448c2ecf20Sopenharmony_ci	struct ubi_ec_hdr *ech = ai->ech;
9458c2ecf20Sopenharmony_ci	struct ubi_vid_io_buf *vidb = ai->vidb;
9468c2ecf20Sopenharmony_ci	struct ubi_vid_hdr *vidh = ubi_get_vid_hdr(vidb);
9478c2ecf20Sopenharmony_ci	long long ec;
9488c2ecf20Sopenharmony_ci	int err, bitflips = 0, vol_id = -1, ec_err = 0;
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	dbg_bld("scan PEB %d", pnum);
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_ci	/* Skip bad physical eraseblocks */
9538c2ecf20Sopenharmony_ci	err = ubi_io_is_bad(ubi, pnum);
9548c2ecf20Sopenharmony_ci	if (err < 0)
9558c2ecf20Sopenharmony_ci		return err;
9568c2ecf20Sopenharmony_ci	else if (err) {
9578c2ecf20Sopenharmony_ci		ai->bad_peb_count += 1;
9588c2ecf20Sopenharmony_ci		return 0;
9598c2ecf20Sopenharmony_ci	}
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci	err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
9628c2ecf20Sopenharmony_ci	if (err < 0)
9638c2ecf20Sopenharmony_ci		return err;
9648c2ecf20Sopenharmony_ci	switch (err) {
9658c2ecf20Sopenharmony_ci	case 0:
9668c2ecf20Sopenharmony_ci		break;
9678c2ecf20Sopenharmony_ci	case UBI_IO_BITFLIPS:
9688c2ecf20Sopenharmony_ci		bitflips = 1;
9698c2ecf20Sopenharmony_ci		break;
9708c2ecf20Sopenharmony_ci	case UBI_IO_FF:
9718c2ecf20Sopenharmony_ci		ai->empty_peb_count += 1;
9728c2ecf20Sopenharmony_ci		return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
9738c2ecf20Sopenharmony_ci				   UBI_UNKNOWN, 0, &ai->erase);
9748c2ecf20Sopenharmony_ci	case UBI_IO_FF_BITFLIPS:
9758c2ecf20Sopenharmony_ci		ai->empty_peb_count += 1;
9768c2ecf20Sopenharmony_ci		return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
9778c2ecf20Sopenharmony_ci				   UBI_UNKNOWN, 1, &ai->erase);
9788c2ecf20Sopenharmony_ci	case UBI_IO_BAD_HDR_EBADMSG:
9798c2ecf20Sopenharmony_ci	case UBI_IO_BAD_HDR:
9808c2ecf20Sopenharmony_ci		/*
9818c2ecf20Sopenharmony_ci		 * We have to also look at the VID header, possibly it is not
9828c2ecf20Sopenharmony_ci		 * corrupted. Set %bitflips flag in order to make this PEB be
9838c2ecf20Sopenharmony_ci		 * moved and EC be re-created.
9848c2ecf20Sopenharmony_ci		 */
9858c2ecf20Sopenharmony_ci		ec_err = err;
9868c2ecf20Sopenharmony_ci		ec = UBI_UNKNOWN;
9878c2ecf20Sopenharmony_ci		bitflips = 1;
9888c2ecf20Sopenharmony_ci		break;
9898c2ecf20Sopenharmony_ci	default:
9908c2ecf20Sopenharmony_ci		ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code %d",
9918c2ecf20Sopenharmony_ci			err);
9928c2ecf20Sopenharmony_ci		return -EINVAL;
9938c2ecf20Sopenharmony_ci	}
9948c2ecf20Sopenharmony_ci
9958c2ecf20Sopenharmony_ci	if (!ec_err) {
9968c2ecf20Sopenharmony_ci		int image_seq;
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci		/* Make sure UBI version is OK */
9998c2ecf20Sopenharmony_ci		if (ech->version != UBI_VERSION) {
10008c2ecf20Sopenharmony_ci			ubi_err(ubi, "this UBI version is %d, image version is %d",
10018c2ecf20Sopenharmony_ci				UBI_VERSION, (int)ech->version);
10028c2ecf20Sopenharmony_ci			return -EINVAL;
10038c2ecf20Sopenharmony_ci		}
10048c2ecf20Sopenharmony_ci
10058c2ecf20Sopenharmony_ci		ec = be64_to_cpu(ech->ec);
10068c2ecf20Sopenharmony_ci		if (ec > UBI_MAX_ERASECOUNTER) {
10078c2ecf20Sopenharmony_ci			/*
10088c2ecf20Sopenharmony_ci			 * Erase counter overflow. The EC headers have 64 bits
10098c2ecf20Sopenharmony_ci			 * reserved, but we anyway make use of only 31 bit
10108c2ecf20Sopenharmony_ci			 * values, as this seems to be enough for any existing
10118c2ecf20Sopenharmony_ci			 * flash. Upgrade UBI and use 64-bit erase counters
10128c2ecf20Sopenharmony_ci			 * internally.
10138c2ecf20Sopenharmony_ci			 */
10148c2ecf20Sopenharmony_ci			ubi_err(ubi, "erase counter overflow, max is %d",
10158c2ecf20Sopenharmony_ci				UBI_MAX_ERASECOUNTER);
10168c2ecf20Sopenharmony_ci			ubi_dump_ec_hdr(ech);
10178c2ecf20Sopenharmony_ci			return -EINVAL;
10188c2ecf20Sopenharmony_ci		}
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_ci		/*
10218c2ecf20Sopenharmony_ci		 * Make sure that all PEBs have the same image sequence number.
10228c2ecf20Sopenharmony_ci		 * This allows us to detect situations when users flash UBI
10238c2ecf20Sopenharmony_ci		 * images incorrectly, so that the flash has the new UBI image
10248c2ecf20Sopenharmony_ci		 * and leftovers from the old one. This feature was added
10258c2ecf20Sopenharmony_ci		 * relatively recently, and the sequence number was always
10268c2ecf20Sopenharmony_ci		 * zero, because old UBI implementations always set it to zero.
10278c2ecf20Sopenharmony_ci		 * For this reasons, we do not panic if some PEBs have zero
10288c2ecf20Sopenharmony_ci		 * sequence number, while other PEBs have non-zero sequence
10298c2ecf20Sopenharmony_ci		 * number.
10308c2ecf20Sopenharmony_ci		 */
10318c2ecf20Sopenharmony_ci		image_seq = be32_to_cpu(ech->image_seq);
10328c2ecf20Sopenharmony_ci		if (!ubi->image_seq)
10338c2ecf20Sopenharmony_ci			ubi->image_seq = image_seq;
10348c2ecf20Sopenharmony_ci		if (image_seq && ubi->image_seq != image_seq) {
10358c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad image sequence number %d in PEB %d, expected %d",
10368c2ecf20Sopenharmony_ci				image_seq, pnum, ubi->image_seq);
10378c2ecf20Sopenharmony_ci			ubi_dump_ec_hdr(ech);
10388c2ecf20Sopenharmony_ci			return -EINVAL;
10398c2ecf20Sopenharmony_ci		}
10408c2ecf20Sopenharmony_ci	}
10418c2ecf20Sopenharmony_ci
10428c2ecf20Sopenharmony_ci	/* OK, we've done with the EC header, let's look at the VID header */
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci	err = ubi_io_read_vid_hdr(ubi, pnum, vidb, 0);
10458c2ecf20Sopenharmony_ci	if (err < 0)
10468c2ecf20Sopenharmony_ci		return err;
10478c2ecf20Sopenharmony_ci	switch (err) {
10488c2ecf20Sopenharmony_ci	case 0:
10498c2ecf20Sopenharmony_ci		break;
10508c2ecf20Sopenharmony_ci	case UBI_IO_BITFLIPS:
10518c2ecf20Sopenharmony_ci		bitflips = 1;
10528c2ecf20Sopenharmony_ci		break;
10538c2ecf20Sopenharmony_ci	case UBI_IO_BAD_HDR_EBADMSG:
10548c2ecf20Sopenharmony_ci		if (ec_err == UBI_IO_BAD_HDR_EBADMSG)
10558c2ecf20Sopenharmony_ci			/*
10568c2ecf20Sopenharmony_ci			 * Both EC and VID headers are corrupted and were read
10578c2ecf20Sopenharmony_ci			 * with data integrity error, probably this is a bad
10588c2ecf20Sopenharmony_ci			 * PEB, bit it is not marked as bad yet. This may also
10598c2ecf20Sopenharmony_ci			 * be a result of power cut during erasure.
10608c2ecf20Sopenharmony_ci			 */
10618c2ecf20Sopenharmony_ci			ai->maybe_bad_peb_count += 1;
10628c2ecf20Sopenharmony_ci		fallthrough;
10638c2ecf20Sopenharmony_ci	case UBI_IO_BAD_HDR:
10648c2ecf20Sopenharmony_ci			/*
10658c2ecf20Sopenharmony_ci			 * If we're facing a bad VID header we have to drop *all*
10668c2ecf20Sopenharmony_ci			 * Fastmap data structures we find. The most recent Fastmap
10678c2ecf20Sopenharmony_ci			 * could be bad and therefore there is a chance that we attach
10688c2ecf20Sopenharmony_ci			 * from an old one. On a fine MTD stack a PEB must not render
10698c2ecf20Sopenharmony_ci			 * bad all of a sudden, but the reality is different.
10708c2ecf20Sopenharmony_ci			 * So, let's be paranoid and help finding the root cause by
10718c2ecf20Sopenharmony_ci			 * falling back to scanning mode instead of attaching with a
10728c2ecf20Sopenharmony_ci			 * bad EBA table and cause data corruption which is hard to
10738c2ecf20Sopenharmony_ci			 * analyze.
10748c2ecf20Sopenharmony_ci			 */
10758c2ecf20Sopenharmony_ci			if (fast)
10768c2ecf20Sopenharmony_ci				ai->force_full_scan = 1;
10778c2ecf20Sopenharmony_ci
10788c2ecf20Sopenharmony_ci		if (ec_err)
10798c2ecf20Sopenharmony_ci			/*
10808c2ecf20Sopenharmony_ci			 * Both headers are corrupted. There is a possibility
10818c2ecf20Sopenharmony_ci			 * that this a valid UBI PEB which has corresponding
10828c2ecf20Sopenharmony_ci			 * LEB, but the headers are corrupted. However, it is
10838c2ecf20Sopenharmony_ci			 * impossible to distinguish it from a PEB which just
10848c2ecf20Sopenharmony_ci			 * contains garbage because of a power cut during erase
10858c2ecf20Sopenharmony_ci			 * operation. So we just schedule this PEB for erasure.
10868c2ecf20Sopenharmony_ci			 *
10878c2ecf20Sopenharmony_ci			 * Besides, in case of NOR flash, we deliberately
10888c2ecf20Sopenharmony_ci			 * corrupt both headers because NOR flash erasure is
10898c2ecf20Sopenharmony_ci			 * slow and can start from the end.
10908c2ecf20Sopenharmony_ci			 */
10918c2ecf20Sopenharmony_ci			err = 0;
10928c2ecf20Sopenharmony_ci		else
10938c2ecf20Sopenharmony_ci			/*
10948c2ecf20Sopenharmony_ci			 * The EC was OK, but the VID header is corrupted. We
10958c2ecf20Sopenharmony_ci			 * have to check what is in the data area.
10968c2ecf20Sopenharmony_ci			 */
10978c2ecf20Sopenharmony_ci			err = check_corruption(ubi, vidh, pnum);
10988c2ecf20Sopenharmony_ci
10998c2ecf20Sopenharmony_ci		if (err < 0)
11008c2ecf20Sopenharmony_ci			return err;
11018c2ecf20Sopenharmony_ci		else if (!err)
11028c2ecf20Sopenharmony_ci			/* This corruption is caused by a power cut */
11038c2ecf20Sopenharmony_ci			err = add_to_list(ai, pnum, UBI_UNKNOWN,
11048c2ecf20Sopenharmony_ci					  UBI_UNKNOWN, ec, 1, &ai->erase);
11058c2ecf20Sopenharmony_ci		else
11068c2ecf20Sopenharmony_ci			/* This is an unexpected corruption */
11078c2ecf20Sopenharmony_ci			err = add_corrupted(ai, pnum, ec);
11088c2ecf20Sopenharmony_ci		if (err)
11098c2ecf20Sopenharmony_ci			return err;
11108c2ecf20Sopenharmony_ci		goto adjust_mean_ec;
11118c2ecf20Sopenharmony_ci	case UBI_IO_FF_BITFLIPS:
11128c2ecf20Sopenharmony_ci		err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
11138c2ecf20Sopenharmony_ci				  ec, 1, &ai->erase);
11148c2ecf20Sopenharmony_ci		if (err)
11158c2ecf20Sopenharmony_ci			return err;
11168c2ecf20Sopenharmony_ci		goto adjust_mean_ec;
11178c2ecf20Sopenharmony_ci	case UBI_IO_FF:
11188c2ecf20Sopenharmony_ci		if (ec_err || bitflips)
11198c2ecf20Sopenharmony_ci			err = add_to_list(ai, pnum, UBI_UNKNOWN,
11208c2ecf20Sopenharmony_ci					  UBI_UNKNOWN, ec, 1, &ai->erase);
11218c2ecf20Sopenharmony_ci		else
11228c2ecf20Sopenharmony_ci			err = add_to_list(ai, pnum, UBI_UNKNOWN,
11238c2ecf20Sopenharmony_ci					  UBI_UNKNOWN, ec, 0, &ai->free);
11248c2ecf20Sopenharmony_ci		if (err)
11258c2ecf20Sopenharmony_ci			return err;
11268c2ecf20Sopenharmony_ci		goto adjust_mean_ec;
11278c2ecf20Sopenharmony_ci	default:
11288c2ecf20Sopenharmony_ci		ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code %d",
11298c2ecf20Sopenharmony_ci			err);
11308c2ecf20Sopenharmony_ci		return -EINVAL;
11318c2ecf20Sopenharmony_ci	}
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_ci	vol_id = be32_to_cpu(vidh->vol_id);
11348c2ecf20Sopenharmony_ci	if (vol_id > UBI_MAX_VOLUMES && !vol_ignored(vol_id)) {
11358c2ecf20Sopenharmony_ci		int lnum = be32_to_cpu(vidh->lnum);
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_ci		/* Unsupported internal volume */
11388c2ecf20Sopenharmony_ci		switch (vidh->compat) {
11398c2ecf20Sopenharmony_ci		case UBI_COMPAT_DELETE:
11408c2ecf20Sopenharmony_ci			ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it",
11418c2ecf20Sopenharmony_ci				vol_id, lnum);
11428c2ecf20Sopenharmony_ci
11438c2ecf20Sopenharmony_ci			err = add_to_list(ai, pnum, vol_id, lnum,
11448c2ecf20Sopenharmony_ci					  ec, 1, &ai->erase);
11458c2ecf20Sopenharmony_ci			if (err)
11468c2ecf20Sopenharmony_ci				return err;
11478c2ecf20Sopenharmony_ci			return 0;
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_ci		case UBI_COMPAT_RO:
11508c2ecf20Sopenharmony_ci			ubi_msg(ubi, "read-only compatible internal volume %d:%d found, switch to read-only mode",
11518c2ecf20Sopenharmony_ci				vol_id, lnum);
11528c2ecf20Sopenharmony_ci			ubi->ro_mode = 1;
11538c2ecf20Sopenharmony_ci			break;
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ci		case UBI_COMPAT_PRESERVE:
11568c2ecf20Sopenharmony_ci			ubi_msg(ubi, "\"preserve\" compatible internal volume %d:%d found",
11578c2ecf20Sopenharmony_ci				vol_id, lnum);
11588c2ecf20Sopenharmony_ci			err = add_to_list(ai, pnum, vol_id, lnum,
11598c2ecf20Sopenharmony_ci					  ec, 0, &ai->alien);
11608c2ecf20Sopenharmony_ci			if (err)
11618c2ecf20Sopenharmony_ci				return err;
11628c2ecf20Sopenharmony_ci			return 0;
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci		case UBI_COMPAT_REJECT:
11658c2ecf20Sopenharmony_ci			ubi_err(ubi, "incompatible internal volume %d:%d found",
11668c2ecf20Sopenharmony_ci				vol_id, lnum);
11678c2ecf20Sopenharmony_ci			return -EINVAL;
11688c2ecf20Sopenharmony_ci		}
11698c2ecf20Sopenharmony_ci	}
11708c2ecf20Sopenharmony_ci
11718c2ecf20Sopenharmony_ci	if (ec_err)
11728c2ecf20Sopenharmony_ci		ubi_warn(ubi, "valid VID header but corrupted EC header at PEB %d",
11738c2ecf20Sopenharmony_ci			 pnum);
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_ci	if (ubi_is_fm_vol(vol_id))
11768c2ecf20Sopenharmony_ci		err = add_fastmap(ai, pnum, vidh, ec);
11778c2ecf20Sopenharmony_ci	else
11788c2ecf20Sopenharmony_ci		err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips);
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_ci	if (err)
11818c2ecf20Sopenharmony_ci		return err;
11828c2ecf20Sopenharmony_ci
11838c2ecf20Sopenharmony_ciadjust_mean_ec:
11848c2ecf20Sopenharmony_ci	if (!ec_err) {
11858c2ecf20Sopenharmony_ci		ai->ec_sum += ec;
11868c2ecf20Sopenharmony_ci		ai->ec_count += 1;
11878c2ecf20Sopenharmony_ci		if (ec > ai->max_ec)
11888c2ecf20Sopenharmony_ci			ai->max_ec = ec;
11898c2ecf20Sopenharmony_ci		if (ec < ai->min_ec)
11908c2ecf20Sopenharmony_ci			ai->min_ec = ec;
11918c2ecf20Sopenharmony_ci	}
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_ci	return 0;
11948c2ecf20Sopenharmony_ci}
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci/**
11978c2ecf20Sopenharmony_ci * late_analysis - analyze the overall situation with PEB.
11988c2ecf20Sopenharmony_ci * @ubi: UBI device description object
11998c2ecf20Sopenharmony_ci * @ai: attaching information
12008c2ecf20Sopenharmony_ci *
12018c2ecf20Sopenharmony_ci * This is a helper function which takes a look what PEBs we have after we
12028c2ecf20Sopenharmony_ci * gather information about all of them ("ai" is compete). It decides whether
12038c2ecf20Sopenharmony_ci * the flash is empty and should be formatted of whether there are too many
12048c2ecf20Sopenharmony_ci * corrupted PEBs and we should not attach this MTD device. Returns zero if we
12058c2ecf20Sopenharmony_ci * should proceed with attaching the MTD device, and %-EINVAL if we should not.
12068c2ecf20Sopenharmony_ci */
12078c2ecf20Sopenharmony_cistatic int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai)
12088c2ecf20Sopenharmony_ci{
12098c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
12108c2ecf20Sopenharmony_ci	int max_corr, peb_count;
12118c2ecf20Sopenharmony_ci
12128c2ecf20Sopenharmony_ci	peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count;
12138c2ecf20Sopenharmony_ci	max_corr = peb_count / 20 ?: 8;
12148c2ecf20Sopenharmony_ci
12158c2ecf20Sopenharmony_ci	/*
12168c2ecf20Sopenharmony_ci	 * Few corrupted PEBs is not a problem and may be just a result of
12178c2ecf20Sopenharmony_ci	 * unclean reboots. However, many of them may indicate some problems
12188c2ecf20Sopenharmony_ci	 * with the flash HW or driver.
12198c2ecf20Sopenharmony_ci	 */
12208c2ecf20Sopenharmony_ci	if (ai->corr_peb_count) {
12218c2ecf20Sopenharmony_ci		ubi_err(ubi, "%d PEBs are corrupted and preserved",
12228c2ecf20Sopenharmony_ci			ai->corr_peb_count);
12238c2ecf20Sopenharmony_ci		pr_err("Corrupted PEBs are:");
12248c2ecf20Sopenharmony_ci		list_for_each_entry(aeb, &ai->corr, u.list)
12258c2ecf20Sopenharmony_ci			pr_cont(" %d", aeb->pnum);
12268c2ecf20Sopenharmony_ci		pr_cont("\n");
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci		/*
12298c2ecf20Sopenharmony_ci		 * If too many PEBs are corrupted, we refuse attaching,
12308c2ecf20Sopenharmony_ci		 * otherwise, only print a warning.
12318c2ecf20Sopenharmony_ci		 */
12328c2ecf20Sopenharmony_ci		if (ai->corr_peb_count >= max_corr) {
12338c2ecf20Sopenharmony_ci			ubi_err(ubi, "too many corrupted PEBs, refusing");
12348c2ecf20Sopenharmony_ci			return -EINVAL;
12358c2ecf20Sopenharmony_ci		}
12368c2ecf20Sopenharmony_ci	}
12378c2ecf20Sopenharmony_ci
12388c2ecf20Sopenharmony_ci	if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) {
12398c2ecf20Sopenharmony_ci		/*
12408c2ecf20Sopenharmony_ci		 * All PEBs are empty, or almost all - a couple PEBs look like
12418c2ecf20Sopenharmony_ci		 * they may be bad PEBs which were not marked as bad yet.
12428c2ecf20Sopenharmony_ci		 *
12438c2ecf20Sopenharmony_ci		 * This piece of code basically tries to distinguish between
12448c2ecf20Sopenharmony_ci		 * the following situations:
12458c2ecf20Sopenharmony_ci		 *
12468c2ecf20Sopenharmony_ci		 * 1. Flash is empty, but there are few bad PEBs, which are not
12478c2ecf20Sopenharmony_ci		 *    marked as bad so far, and which were read with error. We
12488c2ecf20Sopenharmony_ci		 *    want to go ahead and format this flash. While formatting,
12498c2ecf20Sopenharmony_ci		 *    the faulty PEBs will probably be marked as bad.
12508c2ecf20Sopenharmony_ci		 *
12518c2ecf20Sopenharmony_ci		 * 2. Flash contains non-UBI data and we do not want to format
12528c2ecf20Sopenharmony_ci		 *    it and destroy possibly important information.
12538c2ecf20Sopenharmony_ci		 */
12548c2ecf20Sopenharmony_ci		if (ai->maybe_bad_peb_count <= 2) {
12558c2ecf20Sopenharmony_ci			ai->is_empty = 1;
12568c2ecf20Sopenharmony_ci			ubi_msg(ubi, "empty MTD device detected");
12578c2ecf20Sopenharmony_ci			get_random_bytes(&ubi->image_seq,
12588c2ecf20Sopenharmony_ci					 sizeof(ubi->image_seq));
12598c2ecf20Sopenharmony_ci		} else {
12608c2ecf20Sopenharmony_ci			ubi_err(ubi, "MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it");
12618c2ecf20Sopenharmony_ci			return -EINVAL;
12628c2ecf20Sopenharmony_ci		}
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	}
12658c2ecf20Sopenharmony_ci
12668c2ecf20Sopenharmony_ci	return 0;
12678c2ecf20Sopenharmony_ci}
12688c2ecf20Sopenharmony_ci
12698c2ecf20Sopenharmony_ci/**
12708c2ecf20Sopenharmony_ci * destroy_av - free volume attaching information.
12718c2ecf20Sopenharmony_ci * @av: volume attaching information
12728c2ecf20Sopenharmony_ci * @ai: attaching information
12738c2ecf20Sopenharmony_ci * @list: put the aeb elements in there if !NULL, otherwise free them
12748c2ecf20Sopenharmony_ci *
12758c2ecf20Sopenharmony_ci * This function destroys the volume attaching information.
12768c2ecf20Sopenharmony_ci */
12778c2ecf20Sopenharmony_cistatic void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av,
12788c2ecf20Sopenharmony_ci		       struct list_head *list)
12798c2ecf20Sopenharmony_ci{
12808c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
12818c2ecf20Sopenharmony_ci	struct rb_node *this = av->root.rb_node;
12828c2ecf20Sopenharmony_ci
12838c2ecf20Sopenharmony_ci	while (this) {
12848c2ecf20Sopenharmony_ci		if (this->rb_left)
12858c2ecf20Sopenharmony_ci			this = this->rb_left;
12868c2ecf20Sopenharmony_ci		else if (this->rb_right)
12878c2ecf20Sopenharmony_ci			this = this->rb_right;
12888c2ecf20Sopenharmony_ci		else {
12898c2ecf20Sopenharmony_ci			aeb = rb_entry(this, struct ubi_ainf_peb, u.rb);
12908c2ecf20Sopenharmony_ci			this = rb_parent(this);
12918c2ecf20Sopenharmony_ci			if (this) {
12928c2ecf20Sopenharmony_ci				if (this->rb_left == &aeb->u.rb)
12938c2ecf20Sopenharmony_ci					this->rb_left = NULL;
12948c2ecf20Sopenharmony_ci				else
12958c2ecf20Sopenharmony_ci					this->rb_right = NULL;
12968c2ecf20Sopenharmony_ci			}
12978c2ecf20Sopenharmony_ci
12988c2ecf20Sopenharmony_ci			if (list)
12998c2ecf20Sopenharmony_ci				list_add_tail(&aeb->u.list, list);
13008c2ecf20Sopenharmony_ci			else
13018c2ecf20Sopenharmony_ci				ubi_free_aeb(ai, aeb);
13028c2ecf20Sopenharmony_ci		}
13038c2ecf20Sopenharmony_ci	}
13048c2ecf20Sopenharmony_ci	kfree(av);
13058c2ecf20Sopenharmony_ci}
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci/**
13088c2ecf20Sopenharmony_ci * destroy_ai - destroy attaching information.
13098c2ecf20Sopenharmony_ci * @ai: attaching information
13108c2ecf20Sopenharmony_ci */
13118c2ecf20Sopenharmony_cistatic void destroy_ai(struct ubi_attach_info *ai)
13128c2ecf20Sopenharmony_ci{
13138c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb, *aeb_tmp;
13148c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
13158c2ecf20Sopenharmony_ci	struct rb_node *rb;
13168c2ecf20Sopenharmony_ci
13178c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) {
13188c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
13198c2ecf20Sopenharmony_ci		ubi_free_aeb(ai, aeb);
13208c2ecf20Sopenharmony_ci	}
13218c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) {
13228c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
13238c2ecf20Sopenharmony_ci		ubi_free_aeb(ai, aeb);
13248c2ecf20Sopenharmony_ci	}
13258c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) {
13268c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
13278c2ecf20Sopenharmony_ci		ubi_free_aeb(ai, aeb);
13288c2ecf20Sopenharmony_ci	}
13298c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) {
13308c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
13318c2ecf20Sopenharmony_ci		ubi_free_aeb(ai, aeb);
13328c2ecf20Sopenharmony_ci	}
13338c2ecf20Sopenharmony_ci	list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) {
13348c2ecf20Sopenharmony_ci		list_del(&aeb->u.list);
13358c2ecf20Sopenharmony_ci		ubi_free_aeb(ai, aeb);
13368c2ecf20Sopenharmony_ci	}
13378c2ecf20Sopenharmony_ci
13388c2ecf20Sopenharmony_ci	/* Destroy the volume RB-tree */
13398c2ecf20Sopenharmony_ci	rb = ai->volumes.rb_node;
13408c2ecf20Sopenharmony_ci	while (rb) {
13418c2ecf20Sopenharmony_ci		if (rb->rb_left)
13428c2ecf20Sopenharmony_ci			rb = rb->rb_left;
13438c2ecf20Sopenharmony_ci		else if (rb->rb_right)
13448c2ecf20Sopenharmony_ci			rb = rb->rb_right;
13458c2ecf20Sopenharmony_ci		else {
13468c2ecf20Sopenharmony_ci			av = rb_entry(rb, struct ubi_ainf_volume, rb);
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci			rb = rb_parent(rb);
13498c2ecf20Sopenharmony_ci			if (rb) {
13508c2ecf20Sopenharmony_ci				if (rb->rb_left == &av->rb)
13518c2ecf20Sopenharmony_ci					rb->rb_left = NULL;
13528c2ecf20Sopenharmony_ci				else
13538c2ecf20Sopenharmony_ci					rb->rb_right = NULL;
13548c2ecf20Sopenharmony_ci			}
13558c2ecf20Sopenharmony_ci
13568c2ecf20Sopenharmony_ci			destroy_av(ai, av, NULL);
13578c2ecf20Sopenharmony_ci		}
13588c2ecf20Sopenharmony_ci	}
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci	kmem_cache_destroy(ai->aeb_slab_cache);
13618c2ecf20Sopenharmony_ci	kfree(ai);
13628c2ecf20Sopenharmony_ci}
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_ci/**
13658c2ecf20Sopenharmony_ci * scan_all - scan entire MTD device.
13668c2ecf20Sopenharmony_ci * @ubi: UBI device description object
13678c2ecf20Sopenharmony_ci * @ai: attach info object
13688c2ecf20Sopenharmony_ci * @start: start scanning at this PEB
13698c2ecf20Sopenharmony_ci *
13708c2ecf20Sopenharmony_ci * This function does full scanning of an MTD device and returns complete
13718c2ecf20Sopenharmony_ci * information about it in form of a "struct ubi_attach_info" object. In case
13728c2ecf20Sopenharmony_ci * of failure, an error code is returned.
13738c2ecf20Sopenharmony_ci */
13748c2ecf20Sopenharmony_cistatic int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
13758c2ecf20Sopenharmony_ci		    int start)
13768c2ecf20Sopenharmony_ci{
13778c2ecf20Sopenharmony_ci	int err, pnum;
13788c2ecf20Sopenharmony_ci	struct rb_node *rb1, *rb2;
13798c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
13808c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb;
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci	err = -ENOMEM;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	ai->ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
13858c2ecf20Sopenharmony_ci	if (!ai->ech)
13868c2ecf20Sopenharmony_ci		return err;
13878c2ecf20Sopenharmony_ci
13888c2ecf20Sopenharmony_ci	ai->vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL);
13898c2ecf20Sopenharmony_ci	if (!ai->vidb)
13908c2ecf20Sopenharmony_ci		goto out_ech;
13918c2ecf20Sopenharmony_ci
13928c2ecf20Sopenharmony_ci	for (pnum = start; pnum < ubi->peb_count; pnum++) {
13938c2ecf20Sopenharmony_ci		cond_resched();
13948c2ecf20Sopenharmony_ci
13958c2ecf20Sopenharmony_ci		dbg_gen("process PEB %d", pnum);
13968c2ecf20Sopenharmony_ci		err = scan_peb(ubi, ai, pnum, false);
13978c2ecf20Sopenharmony_ci		if (err < 0)
13988c2ecf20Sopenharmony_ci			goto out_vidh;
13998c2ecf20Sopenharmony_ci	}
14008c2ecf20Sopenharmony_ci
14018c2ecf20Sopenharmony_ci	ubi_msg(ubi, "scanning is finished");
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	/* Calculate mean erase counter */
14048c2ecf20Sopenharmony_ci	if (ai->ec_count)
14058c2ecf20Sopenharmony_ci		ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	err = late_analysis(ubi, ai);
14088c2ecf20Sopenharmony_ci	if (err)
14098c2ecf20Sopenharmony_ci		goto out_vidh;
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	/*
14128c2ecf20Sopenharmony_ci	 * In case of unknown erase counter we use the mean erase counter
14138c2ecf20Sopenharmony_ci	 * value.
14148c2ecf20Sopenharmony_ci	 */
14158c2ecf20Sopenharmony_ci	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
14168c2ecf20Sopenharmony_ci		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
14178c2ecf20Sopenharmony_ci			if (aeb->ec == UBI_UNKNOWN)
14188c2ecf20Sopenharmony_ci				aeb->ec = ai->mean_ec;
14198c2ecf20Sopenharmony_ci	}
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->free, u.list) {
14228c2ecf20Sopenharmony_ci		if (aeb->ec == UBI_UNKNOWN)
14238c2ecf20Sopenharmony_ci			aeb->ec = ai->mean_ec;
14248c2ecf20Sopenharmony_ci	}
14258c2ecf20Sopenharmony_ci
14268c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->corr, u.list)
14278c2ecf20Sopenharmony_ci		if (aeb->ec == UBI_UNKNOWN)
14288c2ecf20Sopenharmony_ci			aeb->ec = ai->mean_ec;
14298c2ecf20Sopenharmony_ci
14308c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->erase, u.list)
14318c2ecf20Sopenharmony_ci		if (aeb->ec == UBI_UNKNOWN)
14328c2ecf20Sopenharmony_ci			aeb->ec = ai->mean_ec;
14338c2ecf20Sopenharmony_ci
14348c2ecf20Sopenharmony_ci	err = self_check_ai(ubi, ai);
14358c2ecf20Sopenharmony_ci	if (err)
14368c2ecf20Sopenharmony_ci		goto out_vidh;
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci	ubi_free_vid_buf(ai->vidb);
14398c2ecf20Sopenharmony_ci	kfree(ai->ech);
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci	return 0;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ciout_vidh:
14448c2ecf20Sopenharmony_ci	ubi_free_vid_buf(ai->vidb);
14458c2ecf20Sopenharmony_ciout_ech:
14468c2ecf20Sopenharmony_ci	kfree(ai->ech);
14478c2ecf20Sopenharmony_ci	return err;
14488c2ecf20Sopenharmony_ci}
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_cistatic struct ubi_attach_info *alloc_ai(void)
14518c2ecf20Sopenharmony_ci{
14528c2ecf20Sopenharmony_ci	struct ubi_attach_info *ai;
14538c2ecf20Sopenharmony_ci
14548c2ecf20Sopenharmony_ci	ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
14558c2ecf20Sopenharmony_ci	if (!ai)
14568c2ecf20Sopenharmony_ci		return ai;
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ai->corr);
14598c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ai->free);
14608c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ai->erase);
14618c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ai->alien);
14628c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ai->fastmap);
14638c2ecf20Sopenharmony_ci	ai->volumes = RB_ROOT;
14648c2ecf20Sopenharmony_ci	ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
14658c2ecf20Sopenharmony_ci					       sizeof(struct ubi_ainf_peb),
14668c2ecf20Sopenharmony_ci					       0, 0, NULL);
14678c2ecf20Sopenharmony_ci	if (!ai->aeb_slab_cache) {
14688c2ecf20Sopenharmony_ci		kfree(ai);
14698c2ecf20Sopenharmony_ci		ai = NULL;
14708c2ecf20Sopenharmony_ci	}
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	return ai;
14738c2ecf20Sopenharmony_ci}
14748c2ecf20Sopenharmony_ci
14758c2ecf20Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci/**
14788c2ecf20Sopenharmony_ci * scan_fast - try to find a fastmap and attach from it.
14798c2ecf20Sopenharmony_ci * @ubi: UBI device description object
14808c2ecf20Sopenharmony_ci * @ai: attach info object
14818c2ecf20Sopenharmony_ci *
14828c2ecf20Sopenharmony_ci * Returns 0 on success, negative return values indicate an internal
14838c2ecf20Sopenharmony_ci * error.
14848c2ecf20Sopenharmony_ci * UBI_NO_FASTMAP denotes that no fastmap was found.
14858c2ecf20Sopenharmony_ci * UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
14868c2ecf20Sopenharmony_ci */
14878c2ecf20Sopenharmony_cistatic int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
14888c2ecf20Sopenharmony_ci{
14898c2ecf20Sopenharmony_ci	int err, pnum;
14908c2ecf20Sopenharmony_ci	struct ubi_attach_info *scan_ai;
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	err = -ENOMEM;
14938c2ecf20Sopenharmony_ci
14948c2ecf20Sopenharmony_ci	scan_ai = alloc_ai();
14958c2ecf20Sopenharmony_ci	if (!scan_ai)
14968c2ecf20Sopenharmony_ci		goto out;
14978c2ecf20Sopenharmony_ci
14988c2ecf20Sopenharmony_ci	scan_ai->ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
14998c2ecf20Sopenharmony_ci	if (!scan_ai->ech)
15008c2ecf20Sopenharmony_ci		goto out_ai;
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	scan_ai->vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL);
15038c2ecf20Sopenharmony_ci	if (!scan_ai->vidb)
15048c2ecf20Sopenharmony_ci		goto out_ech;
15058c2ecf20Sopenharmony_ci
15068c2ecf20Sopenharmony_ci	for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
15078c2ecf20Sopenharmony_ci		cond_resched();
15088c2ecf20Sopenharmony_ci
15098c2ecf20Sopenharmony_ci		dbg_gen("process PEB %d", pnum);
15108c2ecf20Sopenharmony_ci		err = scan_peb(ubi, scan_ai, pnum, true);
15118c2ecf20Sopenharmony_ci		if (err < 0)
15128c2ecf20Sopenharmony_ci			goto out_vidh;
15138c2ecf20Sopenharmony_ci	}
15148c2ecf20Sopenharmony_ci
15158c2ecf20Sopenharmony_ci	ubi_free_vid_buf(scan_ai->vidb);
15168c2ecf20Sopenharmony_ci	kfree(scan_ai->ech);
15178c2ecf20Sopenharmony_ci
15188c2ecf20Sopenharmony_ci	if (scan_ai->force_full_scan)
15198c2ecf20Sopenharmony_ci		err = UBI_NO_FASTMAP;
15208c2ecf20Sopenharmony_ci	else
15218c2ecf20Sopenharmony_ci		err = ubi_scan_fastmap(ubi, *ai, scan_ai);
15228c2ecf20Sopenharmony_ci
15238c2ecf20Sopenharmony_ci	if (err) {
15248c2ecf20Sopenharmony_ci		/*
15258c2ecf20Sopenharmony_ci		 * Didn't attach via fastmap, do a full scan but reuse what
15268c2ecf20Sopenharmony_ci		 * we've aready scanned.
15278c2ecf20Sopenharmony_ci		 */
15288c2ecf20Sopenharmony_ci		destroy_ai(*ai);
15298c2ecf20Sopenharmony_ci		*ai = scan_ai;
15308c2ecf20Sopenharmony_ci	} else
15318c2ecf20Sopenharmony_ci		destroy_ai(scan_ai);
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	return err;
15348c2ecf20Sopenharmony_ci
15358c2ecf20Sopenharmony_ciout_vidh:
15368c2ecf20Sopenharmony_ci	ubi_free_vid_buf(scan_ai->vidb);
15378c2ecf20Sopenharmony_ciout_ech:
15388c2ecf20Sopenharmony_ci	kfree(scan_ai->ech);
15398c2ecf20Sopenharmony_ciout_ai:
15408c2ecf20Sopenharmony_ci	destroy_ai(scan_ai);
15418c2ecf20Sopenharmony_ciout:
15428c2ecf20Sopenharmony_ci	return err;
15438c2ecf20Sopenharmony_ci}
15448c2ecf20Sopenharmony_ci
15458c2ecf20Sopenharmony_ci#endif
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci/**
15488c2ecf20Sopenharmony_ci * ubi_attach - attach an MTD device.
15498c2ecf20Sopenharmony_ci * @ubi: UBI device descriptor
15508c2ecf20Sopenharmony_ci * @force_scan: if set to non-zero attach by scanning
15518c2ecf20Sopenharmony_ci *
15528c2ecf20Sopenharmony_ci * This function returns zero in case of success and a negative error code in
15538c2ecf20Sopenharmony_ci * case of failure.
15548c2ecf20Sopenharmony_ci */
15558c2ecf20Sopenharmony_ciint ubi_attach(struct ubi_device *ubi, int force_scan)
15568c2ecf20Sopenharmony_ci{
15578c2ecf20Sopenharmony_ci	int err;
15588c2ecf20Sopenharmony_ci	struct ubi_attach_info *ai;
15598c2ecf20Sopenharmony_ci
15608c2ecf20Sopenharmony_ci	ai = alloc_ai();
15618c2ecf20Sopenharmony_ci	if (!ai)
15628c2ecf20Sopenharmony_ci		return -ENOMEM;
15638c2ecf20Sopenharmony_ci
15648c2ecf20Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP
15658c2ecf20Sopenharmony_ci	/* On small flash devices we disable fastmap in any case. */
15668c2ecf20Sopenharmony_ci	if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
15678c2ecf20Sopenharmony_ci		ubi->fm_disabled = 1;
15688c2ecf20Sopenharmony_ci		force_scan = 1;
15698c2ecf20Sopenharmony_ci	}
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci	if (force_scan)
15728c2ecf20Sopenharmony_ci		err = scan_all(ubi, ai, 0);
15738c2ecf20Sopenharmony_ci	else {
15748c2ecf20Sopenharmony_ci		err = scan_fast(ubi, &ai);
15758c2ecf20Sopenharmony_ci		if (err > 0 || mtd_is_eccerr(err)) {
15768c2ecf20Sopenharmony_ci			if (err != UBI_NO_FASTMAP) {
15778c2ecf20Sopenharmony_ci				destroy_ai(ai);
15788c2ecf20Sopenharmony_ci				ai = alloc_ai();
15798c2ecf20Sopenharmony_ci				if (!ai)
15808c2ecf20Sopenharmony_ci					return -ENOMEM;
15818c2ecf20Sopenharmony_ci
15828c2ecf20Sopenharmony_ci				err = scan_all(ubi, ai, 0);
15838c2ecf20Sopenharmony_ci			} else {
15848c2ecf20Sopenharmony_ci				err = scan_all(ubi, ai, UBI_FM_MAX_START);
15858c2ecf20Sopenharmony_ci			}
15868c2ecf20Sopenharmony_ci		}
15878c2ecf20Sopenharmony_ci	}
15888c2ecf20Sopenharmony_ci#else
15898c2ecf20Sopenharmony_ci	err = scan_all(ubi, ai, 0);
15908c2ecf20Sopenharmony_ci#endif
15918c2ecf20Sopenharmony_ci	if (err)
15928c2ecf20Sopenharmony_ci		goto out_ai;
15938c2ecf20Sopenharmony_ci
15948c2ecf20Sopenharmony_ci	ubi->bad_peb_count = ai->bad_peb_count;
15958c2ecf20Sopenharmony_ci	ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
15968c2ecf20Sopenharmony_ci	ubi->corr_peb_count = ai->corr_peb_count;
15978c2ecf20Sopenharmony_ci	ubi->max_ec = ai->max_ec;
15988c2ecf20Sopenharmony_ci	ubi->mean_ec = ai->mean_ec;
15998c2ecf20Sopenharmony_ci	dbg_gen("max. sequence number:       %llu", ai->max_sqnum);
16008c2ecf20Sopenharmony_ci
16018c2ecf20Sopenharmony_ci	err = ubi_read_volume_table(ubi, ai);
16028c2ecf20Sopenharmony_ci	if (err)
16038c2ecf20Sopenharmony_ci		goto out_ai;
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_ci	err = ubi_wl_init(ubi, ai);
16068c2ecf20Sopenharmony_ci	if (err)
16078c2ecf20Sopenharmony_ci		goto out_vtbl;
16088c2ecf20Sopenharmony_ci
16098c2ecf20Sopenharmony_ci	err = ubi_eba_init(ubi, ai);
16108c2ecf20Sopenharmony_ci	if (err)
16118c2ecf20Sopenharmony_ci		goto out_wl;
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP
16148c2ecf20Sopenharmony_ci	if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) {
16158c2ecf20Sopenharmony_ci		struct ubi_attach_info *scan_ai;
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_ci		scan_ai = alloc_ai();
16188c2ecf20Sopenharmony_ci		if (!scan_ai) {
16198c2ecf20Sopenharmony_ci			err = -ENOMEM;
16208c2ecf20Sopenharmony_ci			goto out_wl;
16218c2ecf20Sopenharmony_ci		}
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci		err = scan_all(ubi, scan_ai, 0);
16248c2ecf20Sopenharmony_ci		if (err) {
16258c2ecf20Sopenharmony_ci			destroy_ai(scan_ai);
16268c2ecf20Sopenharmony_ci			goto out_wl;
16278c2ecf20Sopenharmony_ci		}
16288c2ecf20Sopenharmony_ci
16298c2ecf20Sopenharmony_ci		err = self_check_eba(ubi, ai, scan_ai);
16308c2ecf20Sopenharmony_ci		destroy_ai(scan_ai);
16318c2ecf20Sopenharmony_ci
16328c2ecf20Sopenharmony_ci		if (err)
16338c2ecf20Sopenharmony_ci			goto out_wl;
16348c2ecf20Sopenharmony_ci	}
16358c2ecf20Sopenharmony_ci#endif
16368c2ecf20Sopenharmony_ci
16378c2ecf20Sopenharmony_ci	destroy_ai(ai);
16388c2ecf20Sopenharmony_ci	return 0;
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_ciout_wl:
16418c2ecf20Sopenharmony_ci	ubi_wl_close(ubi);
16428c2ecf20Sopenharmony_ciout_vtbl:
16438c2ecf20Sopenharmony_ci	ubi_free_all_volumes(ubi);
16448c2ecf20Sopenharmony_ci	vfree(ubi->vtbl);
16458c2ecf20Sopenharmony_ciout_ai:
16468c2ecf20Sopenharmony_ci	destroy_ai(ai);
16478c2ecf20Sopenharmony_ci	return err;
16488c2ecf20Sopenharmony_ci}
16498c2ecf20Sopenharmony_ci
16508c2ecf20Sopenharmony_ci/**
16518c2ecf20Sopenharmony_ci * self_check_ai - check the attaching information.
16528c2ecf20Sopenharmony_ci * @ubi: UBI device description object
16538c2ecf20Sopenharmony_ci * @ai: attaching information
16548c2ecf20Sopenharmony_ci *
16558c2ecf20Sopenharmony_ci * This function returns zero if the attaching information is all right, and a
16568c2ecf20Sopenharmony_ci * negative error code if not or if an error occurred.
16578c2ecf20Sopenharmony_ci */
16588c2ecf20Sopenharmony_cistatic int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai)
16598c2ecf20Sopenharmony_ci{
16608c2ecf20Sopenharmony_ci	struct ubi_vid_io_buf *vidb = ai->vidb;
16618c2ecf20Sopenharmony_ci	struct ubi_vid_hdr *vidh = ubi_get_vid_hdr(vidb);
16628c2ecf20Sopenharmony_ci	int pnum, err, vols_found = 0;
16638c2ecf20Sopenharmony_ci	struct rb_node *rb1, *rb2;
16648c2ecf20Sopenharmony_ci	struct ubi_ainf_volume *av;
16658c2ecf20Sopenharmony_ci	struct ubi_ainf_peb *aeb, *last_aeb;
16668c2ecf20Sopenharmony_ci	uint8_t *buf;
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci	if (!ubi_dbg_chk_gen(ubi))
16698c2ecf20Sopenharmony_ci		return 0;
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_ci	/*
16728c2ecf20Sopenharmony_ci	 * At first, check that attaching information is OK.
16738c2ecf20Sopenharmony_ci	 */
16748c2ecf20Sopenharmony_ci	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
16758c2ecf20Sopenharmony_ci		int leb_count = 0;
16768c2ecf20Sopenharmony_ci
16778c2ecf20Sopenharmony_ci		cond_resched();
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci		vols_found += 1;
16808c2ecf20Sopenharmony_ci
16818c2ecf20Sopenharmony_ci		if (ai->is_empty) {
16828c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad is_empty flag");
16838c2ecf20Sopenharmony_ci			goto bad_av;
16848c2ecf20Sopenharmony_ci		}
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci		if (av->vol_id < 0 || av->highest_lnum < 0 ||
16878c2ecf20Sopenharmony_ci		    av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 ||
16888c2ecf20Sopenharmony_ci		    av->data_pad < 0 || av->last_data_size < 0) {
16898c2ecf20Sopenharmony_ci			ubi_err(ubi, "negative values");
16908c2ecf20Sopenharmony_ci			goto bad_av;
16918c2ecf20Sopenharmony_ci		}
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_ci		if (av->vol_id >= UBI_MAX_VOLUMES &&
16948c2ecf20Sopenharmony_ci		    av->vol_id < UBI_INTERNAL_VOL_START) {
16958c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad vol_id");
16968c2ecf20Sopenharmony_ci			goto bad_av;
16978c2ecf20Sopenharmony_ci		}
16988c2ecf20Sopenharmony_ci
16998c2ecf20Sopenharmony_ci		if (av->vol_id > ai->highest_vol_id) {
17008c2ecf20Sopenharmony_ci			ubi_err(ubi, "highest_vol_id is %d, but vol_id %d is there",
17018c2ecf20Sopenharmony_ci				ai->highest_vol_id, av->vol_id);
17028c2ecf20Sopenharmony_ci			goto out;
17038c2ecf20Sopenharmony_ci		}
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci		if (av->vol_type != UBI_DYNAMIC_VOLUME &&
17068c2ecf20Sopenharmony_ci		    av->vol_type != UBI_STATIC_VOLUME) {
17078c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad vol_type");
17088c2ecf20Sopenharmony_ci			goto bad_av;
17098c2ecf20Sopenharmony_ci		}
17108c2ecf20Sopenharmony_ci
17118c2ecf20Sopenharmony_ci		if (av->data_pad > ubi->leb_size / 2) {
17128c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad data_pad");
17138c2ecf20Sopenharmony_ci			goto bad_av;
17148c2ecf20Sopenharmony_ci		}
17158c2ecf20Sopenharmony_ci
17168c2ecf20Sopenharmony_ci		last_aeb = NULL;
17178c2ecf20Sopenharmony_ci		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) {
17188c2ecf20Sopenharmony_ci			cond_resched();
17198c2ecf20Sopenharmony_ci
17208c2ecf20Sopenharmony_ci			last_aeb = aeb;
17218c2ecf20Sopenharmony_ci			leb_count += 1;
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci			if (aeb->pnum < 0 || aeb->ec < 0) {
17248c2ecf20Sopenharmony_ci				ubi_err(ubi, "negative values");
17258c2ecf20Sopenharmony_ci				goto bad_aeb;
17268c2ecf20Sopenharmony_ci			}
17278c2ecf20Sopenharmony_ci
17288c2ecf20Sopenharmony_ci			if (aeb->ec < ai->min_ec) {
17298c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad ai->min_ec (%d), %d found",
17308c2ecf20Sopenharmony_ci					ai->min_ec, aeb->ec);
17318c2ecf20Sopenharmony_ci				goto bad_aeb;
17328c2ecf20Sopenharmony_ci			}
17338c2ecf20Sopenharmony_ci
17348c2ecf20Sopenharmony_ci			if (aeb->ec > ai->max_ec) {
17358c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad ai->max_ec (%d), %d found",
17368c2ecf20Sopenharmony_ci					ai->max_ec, aeb->ec);
17378c2ecf20Sopenharmony_ci				goto bad_aeb;
17388c2ecf20Sopenharmony_ci			}
17398c2ecf20Sopenharmony_ci
17408c2ecf20Sopenharmony_ci			if (aeb->pnum >= ubi->peb_count) {
17418c2ecf20Sopenharmony_ci				ubi_err(ubi, "too high PEB number %d, total PEBs %d",
17428c2ecf20Sopenharmony_ci					aeb->pnum, ubi->peb_count);
17438c2ecf20Sopenharmony_ci				goto bad_aeb;
17448c2ecf20Sopenharmony_ci			}
17458c2ecf20Sopenharmony_ci
17468c2ecf20Sopenharmony_ci			if (av->vol_type == UBI_STATIC_VOLUME) {
17478c2ecf20Sopenharmony_ci				if (aeb->lnum >= av->used_ebs) {
17488c2ecf20Sopenharmony_ci					ubi_err(ubi, "bad lnum or used_ebs");
17498c2ecf20Sopenharmony_ci					goto bad_aeb;
17508c2ecf20Sopenharmony_ci				}
17518c2ecf20Sopenharmony_ci			} else {
17528c2ecf20Sopenharmony_ci				if (av->used_ebs != 0) {
17538c2ecf20Sopenharmony_ci					ubi_err(ubi, "non-zero used_ebs");
17548c2ecf20Sopenharmony_ci					goto bad_aeb;
17558c2ecf20Sopenharmony_ci				}
17568c2ecf20Sopenharmony_ci			}
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_ci			if (aeb->lnum > av->highest_lnum) {
17598c2ecf20Sopenharmony_ci				ubi_err(ubi, "incorrect highest_lnum or lnum");
17608c2ecf20Sopenharmony_ci				goto bad_aeb;
17618c2ecf20Sopenharmony_ci			}
17628c2ecf20Sopenharmony_ci		}
17638c2ecf20Sopenharmony_ci
17648c2ecf20Sopenharmony_ci		if (av->leb_count != leb_count) {
17658c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad leb_count, %d objects in the tree",
17668c2ecf20Sopenharmony_ci				leb_count);
17678c2ecf20Sopenharmony_ci			goto bad_av;
17688c2ecf20Sopenharmony_ci		}
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_ci		if (!last_aeb)
17718c2ecf20Sopenharmony_ci			continue;
17728c2ecf20Sopenharmony_ci
17738c2ecf20Sopenharmony_ci		aeb = last_aeb;
17748c2ecf20Sopenharmony_ci
17758c2ecf20Sopenharmony_ci		if (aeb->lnum != av->highest_lnum) {
17768c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad highest_lnum");
17778c2ecf20Sopenharmony_ci			goto bad_aeb;
17788c2ecf20Sopenharmony_ci		}
17798c2ecf20Sopenharmony_ci	}
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci	if (vols_found != ai->vols_found) {
17828c2ecf20Sopenharmony_ci		ubi_err(ubi, "bad ai->vols_found %d, should be %d",
17838c2ecf20Sopenharmony_ci			ai->vols_found, vols_found);
17848c2ecf20Sopenharmony_ci		goto out;
17858c2ecf20Sopenharmony_ci	}
17868c2ecf20Sopenharmony_ci
17878c2ecf20Sopenharmony_ci	/* Check that attaching information is correct */
17888c2ecf20Sopenharmony_ci	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
17898c2ecf20Sopenharmony_ci		last_aeb = NULL;
17908c2ecf20Sopenharmony_ci		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) {
17918c2ecf20Sopenharmony_ci			int vol_type;
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_ci			cond_resched();
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_ci			last_aeb = aeb;
17968c2ecf20Sopenharmony_ci
17978c2ecf20Sopenharmony_ci			err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidb, 1);
17988c2ecf20Sopenharmony_ci			if (err && err != UBI_IO_BITFLIPS) {
17998c2ecf20Sopenharmony_ci				ubi_err(ubi, "VID header is not OK (%d)",
18008c2ecf20Sopenharmony_ci					err);
18018c2ecf20Sopenharmony_ci				if (err > 0)
18028c2ecf20Sopenharmony_ci					err = -EIO;
18038c2ecf20Sopenharmony_ci				return err;
18048c2ecf20Sopenharmony_ci			}
18058c2ecf20Sopenharmony_ci
18068c2ecf20Sopenharmony_ci			vol_type = vidh->vol_type == UBI_VID_DYNAMIC ?
18078c2ecf20Sopenharmony_ci				   UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
18088c2ecf20Sopenharmony_ci			if (av->vol_type != vol_type) {
18098c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad vol_type");
18108c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18118c2ecf20Sopenharmony_ci			}
18128c2ecf20Sopenharmony_ci
18138c2ecf20Sopenharmony_ci			if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) {
18148c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad sqnum %llu", aeb->sqnum);
18158c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18168c2ecf20Sopenharmony_ci			}
18178c2ecf20Sopenharmony_ci
18188c2ecf20Sopenharmony_ci			if (av->vol_id != be32_to_cpu(vidh->vol_id)) {
18198c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad vol_id %d", av->vol_id);
18208c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18218c2ecf20Sopenharmony_ci			}
18228c2ecf20Sopenharmony_ci
18238c2ecf20Sopenharmony_ci			if (av->compat != vidh->compat) {
18248c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad compat %d", vidh->compat);
18258c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18268c2ecf20Sopenharmony_ci			}
18278c2ecf20Sopenharmony_ci
18288c2ecf20Sopenharmony_ci			if (aeb->lnum != be32_to_cpu(vidh->lnum)) {
18298c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad lnum %d", aeb->lnum);
18308c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18318c2ecf20Sopenharmony_ci			}
18328c2ecf20Sopenharmony_ci
18338c2ecf20Sopenharmony_ci			if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) {
18348c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad used_ebs %d", av->used_ebs);
18358c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18368c2ecf20Sopenharmony_ci			}
18378c2ecf20Sopenharmony_ci
18388c2ecf20Sopenharmony_ci			if (av->data_pad != be32_to_cpu(vidh->data_pad)) {
18398c2ecf20Sopenharmony_ci				ubi_err(ubi, "bad data_pad %d", av->data_pad);
18408c2ecf20Sopenharmony_ci				goto bad_vid_hdr;
18418c2ecf20Sopenharmony_ci			}
18428c2ecf20Sopenharmony_ci		}
18438c2ecf20Sopenharmony_ci
18448c2ecf20Sopenharmony_ci		if (!last_aeb)
18458c2ecf20Sopenharmony_ci			continue;
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci		if (av->highest_lnum != be32_to_cpu(vidh->lnum)) {
18488c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad highest_lnum %d", av->highest_lnum);
18498c2ecf20Sopenharmony_ci			goto bad_vid_hdr;
18508c2ecf20Sopenharmony_ci		}
18518c2ecf20Sopenharmony_ci
18528c2ecf20Sopenharmony_ci		if (av->last_data_size != be32_to_cpu(vidh->data_size)) {
18538c2ecf20Sopenharmony_ci			ubi_err(ubi, "bad last_data_size %d",
18548c2ecf20Sopenharmony_ci				av->last_data_size);
18558c2ecf20Sopenharmony_ci			goto bad_vid_hdr;
18568c2ecf20Sopenharmony_ci		}
18578c2ecf20Sopenharmony_ci	}
18588c2ecf20Sopenharmony_ci
18598c2ecf20Sopenharmony_ci	/*
18608c2ecf20Sopenharmony_ci	 * Make sure that all the physical eraseblocks are in one of the lists
18618c2ecf20Sopenharmony_ci	 * or trees.
18628c2ecf20Sopenharmony_ci	 */
18638c2ecf20Sopenharmony_ci	buf = kzalloc(ubi->peb_count, GFP_KERNEL);
18648c2ecf20Sopenharmony_ci	if (!buf)
18658c2ecf20Sopenharmony_ci		return -ENOMEM;
18668c2ecf20Sopenharmony_ci
18678c2ecf20Sopenharmony_ci	for (pnum = 0; pnum < ubi->peb_count; pnum++) {
18688c2ecf20Sopenharmony_ci		err = ubi_io_is_bad(ubi, pnum);
18698c2ecf20Sopenharmony_ci		if (err < 0) {
18708c2ecf20Sopenharmony_ci			kfree(buf);
18718c2ecf20Sopenharmony_ci			return err;
18728c2ecf20Sopenharmony_ci		} else if (err)
18738c2ecf20Sopenharmony_ci			buf[pnum] = 1;
18748c2ecf20Sopenharmony_ci	}
18758c2ecf20Sopenharmony_ci
18768c2ecf20Sopenharmony_ci	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb)
18778c2ecf20Sopenharmony_ci		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
18788c2ecf20Sopenharmony_ci			buf[aeb->pnum] = 1;
18798c2ecf20Sopenharmony_ci
18808c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->free, u.list)
18818c2ecf20Sopenharmony_ci		buf[aeb->pnum] = 1;
18828c2ecf20Sopenharmony_ci
18838c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->corr, u.list)
18848c2ecf20Sopenharmony_ci		buf[aeb->pnum] = 1;
18858c2ecf20Sopenharmony_ci
18868c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->erase, u.list)
18878c2ecf20Sopenharmony_ci		buf[aeb->pnum] = 1;
18888c2ecf20Sopenharmony_ci
18898c2ecf20Sopenharmony_ci	list_for_each_entry(aeb, &ai->alien, u.list)
18908c2ecf20Sopenharmony_ci		buf[aeb->pnum] = 1;
18918c2ecf20Sopenharmony_ci
18928c2ecf20Sopenharmony_ci	err = 0;
18938c2ecf20Sopenharmony_ci	for (pnum = 0; pnum < ubi->peb_count; pnum++)
18948c2ecf20Sopenharmony_ci		if (!buf[pnum]) {
18958c2ecf20Sopenharmony_ci			ubi_err(ubi, "PEB %d is not referred", pnum);
18968c2ecf20Sopenharmony_ci			err = 1;
18978c2ecf20Sopenharmony_ci		}
18988c2ecf20Sopenharmony_ci
18998c2ecf20Sopenharmony_ci	kfree(buf);
19008c2ecf20Sopenharmony_ci	if (err)
19018c2ecf20Sopenharmony_ci		goto out;
19028c2ecf20Sopenharmony_ci	return 0;
19038c2ecf20Sopenharmony_ci
19048c2ecf20Sopenharmony_cibad_aeb:
19058c2ecf20Sopenharmony_ci	ubi_err(ubi, "bad attaching information about LEB %d", aeb->lnum);
19068c2ecf20Sopenharmony_ci	ubi_dump_aeb(aeb, 0);
19078c2ecf20Sopenharmony_ci	ubi_dump_av(av);
19088c2ecf20Sopenharmony_ci	goto out;
19098c2ecf20Sopenharmony_ci
19108c2ecf20Sopenharmony_cibad_av:
19118c2ecf20Sopenharmony_ci	ubi_err(ubi, "bad attaching information about volume %d", av->vol_id);
19128c2ecf20Sopenharmony_ci	ubi_dump_av(av);
19138c2ecf20Sopenharmony_ci	goto out;
19148c2ecf20Sopenharmony_ci
19158c2ecf20Sopenharmony_cibad_vid_hdr:
19168c2ecf20Sopenharmony_ci	ubi_err(ubi, "bad attaching information about volume %d", av->vol_id);
19178c2ecf20Sopenharmony_ci	ubi_dump_av(av);
19188c2ecf20Sopenharmony_ci	ubi_dump_vid_hdr(vidh);
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ciout:
19218c2ecf20Sopenharmony_ci	dump_stack();
19228c2ecf20Sopenharmony_ci	return -EINVAL;
19238c2ecf20Sopenharmony_ci}
1924