11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2801c135cSArtem B. Bityutskiy /*
3801c135cSArtem B. Bityutskiy * Copyright (c) International Business Machines Corp., 2006
4801c135cSArtem B. Bityutskiy *
5801c135cSArtem B. Bityutskiy * Author: Artem Bityutskiy (Битюцкий Артём)
6801c135cSArtem B. Bityutskiy */
7801c135cSArtem B. Bityutskiy
8801c135cSArtem B. Bityutskiy /* Here we keep miscellaneous functions which are used all over the UBI code */
9801c135cSArtem B. Bityutskiy
10801c135cSArtem B. Bityutskiy #include "ubi.h"
11801c135cSArtem B. Bityutskiy
12801c135cSArtem B. Bityutskiy /**
13*0b3bc49cSRandy Dunlap * ubi_calc_data_len - calculate how much real data is stored in a buffer.
14801c135cSArtem B. Bityutskiy * @ubi: UBI device description object
15801c135cSArtem B. Bityutskiy * @buf: a buffer with the contents of the physical eraseblock
16801c135cSArtem B. Bityutskiy * @length: the buffer length
17801c135cSArtem B. Bityutskiy *
18801c135cSArtem B. Bityutskiy * This function calculates how much "real data" is stored in @buf and returnes
19801c135cSArtem B. Bityutskiy * the length. Continuous 0xFF bytes at the end of the buffer are not
20801c135cSArtem B. Bityutskiy * considered as "real data".
21801c135cSArtem B. Bityutskiy */
ubi_calc_data_len(const struct ubi_device * ubi,const void * buf,int length)22801c135cSArtem B. Bityutskiy int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
23801c135cSArtem B. Bityutskiy int length)
24801c135cSArtem B. Bityutskiy {
25801c135cSArtem B. Bityutskiy int i;
26801c135cSArtem B. Bityutskiy
27cadb40ccSKyungmin Park ubi_assert(!(length & (ubi->min_io_size - 1)));
28801c135cSArtem B. Bityutskiy
29801c135cSArtem B. Bityutskiy for (i = length - 1; i >= 0; i--)
30801c135cSArtem B. Bityutskiy if (((const uint8_t *)buf)[i] != 0xFF)
31801c135cSArtem B. Bityutskiy break;
32801c135cSArtem B. Bityutskiy
33801c135cSArtem B. Bityutskiy /* The resulting length must be aligned to the minimum flash I/O size */
34801c135cSArtem B. Bityutskiy length = ALIGN(i + 1, ubi->min_io_size);
35801c135cSArtem B. Bityutskiy return length;
36801c135cSArtem B. Bityutskiy }
37801c135cSArtem B. Bityutskiy
38801c135cSArtem B. Bityutskiy /**
39801c135cSArtem B. Bityutskiy * ubi_check_volume - check the contents of a static volume.
40801c135cSArtem B. Bityutskiy * @ubi: UBI device description object
41801c135cSArtem B. Bityutskiy * @vol_id: ID of the volume to check
42801c135cSArtem B. Bityutskiy *
43801c135cSArtem B. Bityutskiy * This function checks if static volume @vol_id is corrupted by fully reading
44801c135cSArtem B. Bityutskiy * it and checking data CRC. This function returns %0 if the volume is not
45801c135cSArtem B. Bityutskiy * corrupted, %1 if it is corrupted and a negative error code in case of
46801c135cSArtem B. Bityutskiy * failure. Dynamic volumes are not checked and zero is returned immediately.
47801c135cSArtem B. Bityutskiy */
ubi_check_volume(struct ubi_device * ubi,int vol_id)48801c135cSArtem B. Bityutskiy int ubi_check_volume(struct ubi_device *ubi, int vol_id)
49801c135cSArtem B. Bityutskiy {
50801c135cSArtem B. Bityutskiy void *buf;
51801c135cSArtem B. Bityutskiy int err = 0, i;
52801c135cSArtem B. Bityutskiy struct ubi_volume *vol = ubi->volumes[vol_id];
53801c135cSArtem B. Bityutskiy
54801c135cSArtem B. Bityutskiy if (vol->vol_type != UBI_STATIC_VOLUME)
55801c135cSArtem B. Bityutskiy return 0;
56801c135cSArtem B. Bityutskiy
5792ad8f37SArtem Bityutskiy buf = vmalloc(vol->usable_leb_size);
58801c135cSArtem B. Bityutskiy if (!buf)
59801c135cSArtem B. Bityutskiy return -ENOMEM;
60801c135cSArtem B. Bityutskiy
61801c135cSArtem B. Bityutskiy for (i = 0; i < vol->used_ebs; i++) {
62801c135cSArtem B. Bityutskiy int size;
63801c135cSArtem B. Bityutskiy
649aa272b4Shujianyang cond_resched();
659aa272b4Shujianyang
66801c135cSArtem B. Bityutskiy if (i == vol->used_ebs - 1)
67801c135cSArtem B. Bityutskiy size = vol->last_eb_bytes;
68801c135cSArtem B. Bityutskiy else
69801c135cSArtem B. Bityutskiy size = vol->usable_leb_size;
70801c135cSArtem B. Bityutskiy
7189b96b69SArtem Bityutskiy err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
72801c135cSArtem B. Bityutskiy if (err) {
73d57f4054SBrian Norris if (mtd_is_eccerr(err))
74801c135cSArtem B. Bityutskiy err = 1;
75801c135cSArtem B. Bityutskiy break;
76801c135cSArtem B. Bityutskiy }
77801c135cSArtem B. Bityutskiy }
78801c135cSArtem B. Bityutskiy
7992ad8f37SArtem Bityutskiy vfree(buf);
80801c135cSArtem B. Bityutskiy return err;
81801c135cSArtem B. Bityutskiy }
82801c135cSArtem B. Bityutskiy
83801c135cSArtem B. Bityutskiy /**
8487e773c9SShmulik Ladkani * ubi_update_reserved - update bad eraseblock handling accounting data.
8587e773c9SShmulik Ladkani * @ubi: UBI device description object
8687e773c9SShmulik Ladkani *
8787e773c9SShmulik Ladkani * This function calculates the gap between current number of PEBs reserved for
8887e773c9SShmulik Ladkani * bad eraseblock handling and the required level of PEBs that must be
8987e773c9SShmulik Ladkani * reserved, and if necessary, reserves more PEBs to fill that gap, according
9087e773c9SShmulik Ladkani * to availability. Should be called with ubi->volumes_lock held.
9187e773c9SShmulik Ladkani */
ubi_update_reserved(struct ubi_device * ubi)9287e773c9SShmulik Ladkani void ubi_update_reserved(struct ubi_device *ubi)
9387e773c9SShmulik Ladkani {
9487e773c9SShmulik Ladkani int need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs;
9587e773c9SShmulik Ladkani
9687e773c9SShmulik Ladkani if (need <= 0 || ubi->avail_pebs == 0)
9787e773c9SShmulik Ladkani return;
9887e773c9SShmulik Ladkani
9987e773c9SShmulik Ladkani need = min_t(int, need, ubi->avail_pebs);
10087e773c9SShmulik Ladkani ubi->avail_pebs -= need;
10187e773c9SShmulik Ladkani ubi->rsvd_pebs += need;
10287e773c9SShmulik Ladkani ubi->beb_rsvd_pebs += need;
10332608703STanya Brokhman ubi_msg(ubi, "reserved more %d PEBs for bad PEB handling", need);
10487e773c9SShmulik Ladkani }
10587e773c9SShmulik Ladkani
10687e773c9SShmulik Ladkani /**
1075c669a5bSShmulik Ladkani * ubi_calculate_reserved - calculate how many PEBs must be reserved for bad
108801c135cSArtem B. Bityutskiy * eraseblock handling.
109801c135cSArtem B. Bityutskiy * @ubi: UBI device description object
110801c135cSArtem B. Bityutskiy */
ubi_calculate_reserved(struct ubi_device * ubi)111801c135cSArtem B. Bityutskiy void ubi_calculate_reserved(struct ubi_device *ubi)
112801c135cSArtem B. Bityutskiy {
11337f758a0SShmulik Ladkani /*
11437f758a0SShmulik Ladkani * Calculate the actual number of PEBs currently needed to be reserved
11537f758a0SShmulik Ladkani * for future bad eraseblock handling.
11637f758a0SShmulik Ladkani */
11737f758a0SShmulik Ladkani ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count;
11837f758a0SShmulik Ladkani if (ubi->beb_rsvd_level < 0) {
11937f758a0SShmulik Ladkani ubi->beb_rsvd_level = 0;
12032608703STanya Brokhman ubi_warn(ubi, "number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)",
12137f758a0SShmulik Ladkani ubi->bad_peb_count, ubi->bad_peb_limit);
12237f758a0SShmulik Ladkani }
123801c135cSArtem B. Bityutskiy }
124bb00e180SArtem Bityutskiy
125bb00e180SArtem Bityutskiy /**
126bb00e180SArtem Bityutskiy * ubi_check_pattern - check if buffer contains only a certain byte pattern.
127bb00e180SArtem Bityutskiy * @buf: buffer to check
128bb00e180SArtem Bityutskiy * @patt: the pattern to check
129bb00e180SArtem Bityutskiy * @size: buffer size in bytes
130bb00e180SArtem Bityutskiy *
131bb00e180SArtem Bityutskiy * This function returns %1 in there are only @patt bytes in @buf, and %0 if
132bb00e180SArtem Bityutskiy * something else was also found.
133bb00e180SArtem Bityutskiy */
ubi_check_pattern(const void * buf,uint8_t patt,int size)134bb00e180SArtem Bityutskiy int ubi_check_pattern(const void *buf, uint8_t patt, int size)
135bb00e180SArtem Bityutskiy {
136bb00e180SArtem Bityutskiy int i;
137bb00e180SArtem Bityutskiy
138bb00e180SArtem Bityutskiy for (i = 0; i < size; i++)
139bb00e180SArtem Bityutskiy if (((const uint8_t *)buf)[i] != patt)
140bb00e180SArtem Bityutskiy return 0;
141bb00e180SArtem Bityutskiy return 1;
142bb00e180SArtem Bityutskiy }
14358d303deSJoe Perches
14458d303deSJoe Perches /* Normal UBI messages */
ubi_msg(const struct ubi_device * ubi,const char * fmt,...)14558d303deSJoe Perches void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...)
14658d303deSJoe Perches {
14758d303deSJoe Perches struct va_format vaf;
14858d303deSJoe Perches va_list args;
14958d303deSJoe Perches
15058d303deSJoe Perches va_start(args, fmt);
15158d303deSJoe Perches
15258d303deSJoe Perches vaf.fmt = fmt;
15358d303deSJoe Perches vaf.va = &args;
15458d303deSJoe Perches
15558d303deSJoe Perches pr_notice(UBI_NAME_STR "%d: %pV\n", ubi->ubi_num, &vaf);
15658d303deSJoe Perches
15758d303deSJoe Perches va_end(args);
15858d303deSJoe Perches }
15958d303deSJoe Perches
16058d303deSJoe Perches /* UBI warning messages */
ubi_warn(const struct ubi_device * ubi,const char * fmt,...)16158d303deSJoe Perches void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...)
16258d303deSJoe Perches {
16358d303deSJoe Perches struct va_format vaf;
16458d303deSJoe Perches va_list args;
16558d303deSJoe Perches
16658d303deSJoe Perches va_start(args, fmt);
16758d303deSJoe Perches
16858d303deSJoe Perches vaf.fmt = fmt;
16958d303deSJoe Perches vaf.va = &args;
17058d303deSJoe Perches
17158d303deSJoe Perches pr_warn(UBI_NAME_STR "%d warning: %ps: %pV\n",
17258d303deSJoe Perches ubi->ubi_num, __builtin_return_address(0), &vaf);
17358d303deSJoe Perches
17458d303deSJoe Perches va_end(args);
17558d303deSJoe Perches }
17658d303deSJoe Perches
17758d303deSJoe Perches /* UBI error messages */
ubi_err(const struct ubi_device * ubi,const char * fmt,...)17858d303deSJoe Perches void ubi_err(const struct ubi_device *ubi, const char *fmt, ...)
17958d303deSJoe Perches {
18058d303deSJoe Perches struct va_format vaf;
18158d303deSJoe Perches va_list args;
18258d303deSJoe Perches
18358d303deSJoe Perches va_start(args, fmt);
18458d303deSJoe Perches
18558d303deSJoe Perches vaf.fmt = fmt;
18658d303deSJoe Perches vaf.va = &args;
18758d303deSJoe Perches
18858d303deSJoe Perches pr_err(UBI_NAME_STR "%d error: %ps: %pV\n",
18958d303deSJoe Perches ubi->ubi_num, __builtin_return_address(0), &vaf);
19058d303deSJoe Perches va_end(args);
19158d303deSJoe Perches }
192