18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2006 48c2ecf20Sopenharmony_ci * Copyright (c) Nokia Corporation, 2006, 2007 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Author: Artem Bityutskiy (Битюцкий Артём) 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* 108c2ecf20Sopenharmony_ci * UBI input/output sub-system. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This sub-system provides a uniform way to work with all kinds of the 138c2ecf20Sopenharmony_ci * underlying MTD devices. It also implements handy functions for reading and 148c2ecf20Sopenharmony_ci * writing UBI headers. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * We are trying to have a paranoid mindset and not to trust to what we read 178c2ecf20Sopenharmony_ci * from the flash media in order to be more secure and robust. So this 188c2ecf20Sopenharmony_ci * sub-system validates every single header it reads from the flash media. 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Some words about how the eraseblock headers are stored. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * The erase counter header is always stored at offset zero. By default, the 238c2ecf20Sopenharmony_ci * VID header is stored after the EC header at the closest aligned offset 248c2ecf20Sopenharmony_ci * (i.e. aligned to the minimum I/O unit size). Data starts next to the VID 258c2ecf20Sopenharmony_ci * header at the closest aligned offset. But this default layout may be 268c2ecf20Sopenharmony_ci * changed. For example, for different reasons (e.g., optimization) UBI may be 278c2ecf20Sopenharmony_ci * asked to put the VID header at further offset, and even at an unaligned 288c2ecf20Sopenharmony_ci * offset. Of course, if the offset of the VID header is unaligned, UBI adds 298c2ecf20Sopenharmony_ci * proper padding in front of it. Data offset may also be changed but it has to 308c2ecf20Sopenharmony_ci * be aligned. 318c2ecf20Sopenharmony_ci * 328c2ecf20Sopenharmony_ci * About minimal I/O units. In general, UBI assumes flash device model where 338c2ecf20Sopenharmony_ci * there is only one minimal I/O unit size. E.g., in case of NOR flash it is 1, 348c2ecf20Sopenharmony_ci * in case of NAND flash it is a NAND page, etc. This is reported by MTD in the 358c2ecf20Sopenharmony_ci * @ubi->mtd->writesize field. But as an exception, UBI admits use of another 368c2ecf20Sopenharmony_ci * (smaller) minimal I/O unit size for EC and VID headers to make it possible 378c2ecf20Sopenharmony_ci * to do different optimizations. 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * This is extremely useful in case of NAND flashes which admit of several 408c2ecf20Sopenharmony_ci * write operations to one NAND page. In this case UBI can fit EC and VID 418c2ecf20Sopenharmony_ci * headers at one NAND page. Thus, UBI may use "sub-page" size as the minimal 428c2ecf20Sopenharmony_ci * I/O unit for the headers (the @ubi->hdrs_min_io_size field). But it still 438c2ecf20Sopenharmony_ci * reports NAND page size (@ubi->min_io_size) as a minimal I/O unit for the UBI 448c2ecf20Sopenharmony_ci * users. 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * Example: some Samsung NANDs with 2KiB pages allow 4x 512-byte writes, so 478c2ecf20Sopenharmony_ci * although the minimal I/O unit is 2K, UBI uses 512 bytes for EC and VID 488c2ecf20Sopenharmony_ci * headers. 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * Q: why not just to treat sub-page as a minimal I/O unit of this flash 518c2ecf20Sopenharmony_ci * device, e.g., make @ubi->min_io_size = 512 in the example above? 528c2ecf20Sopenharmony_ci * 538c2ecf20Sopenharmony_ci * A: because when writing a sub-page, MTD still writes a full 2K page but the 548c2ecf20Sopenharmony_ci * bytes which are not relevant to the sub-page are 0xFF. So, basically, 558c2ecf20Sopenharmony_ci * writing 4x512 sub-pages is 4 times slower than writing one 2KiB NAND page. 568c2ecf20Sopenharmony_ci * Thus, we prefer to use sub-pages only for EC and VID headers. 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * As it was noted above, the VID header may start at a non-aligned offset. 598c2ecf20Sopenharmony_ci * For example, in case of a 2KiB page NAND flash with a 512 bytes sub-page, 608c2ecf20Sopenharmony_ci * the VID header may reside at offset 1984 which is the last 64 bytes of the 618c2ecf20Sopenharmony_ci * last sub-page (EC header is always at offset zero). This causes some 628c2ecf20Sopenharmony_ci * difficulties when reading and writing VID headers. 638c2ecf20Sopenharmony_ci * 648c2ecf20Sopenharmony_ci * Suppose we have a 64-byte buffer and we read a VID header at it. We change 658c2ecf20Sopenharmony_ci * the data and want to write this VID header out. As we can only write in 668c2ecf20Sopenharmony_ci * 512-byte chunks, we have to allocate one more buffer and copy our VID header 678c2ecf20Sopenharmony_ci * to offset 448 of this buffer. 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * The I/O sub-system does the following trick in order to avoid this extra 708c2ecf20Sopenharmony_ci * copy. It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID 718c2ecf20Sopenharmony_ci * header and returns a pointer to offset @ubi->vid_hdr_shift of this buffer. 728c2ecf20Sopenharmony_ci * When the VID header is being written out, it shifts the VID header pointer 738c2ecf20Sopenharmony_ci * back and writes the whole sub-page. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci#include <linux/crc32.h> 778c2ecf20Sopenharmony_ci#include <linux/err.h> 788c2ecf20Sopenharmony_ci#include <linux/slab.h> 798c2ecf20Sopenharmony_ci#include "ubi.h" 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic int self_check_not_bad(const struct ubi_device *ubi, int pnum); 828c2ecf20Sopenharmony_cistatic int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); 838c2ecf20Sopenharmony_cistatic int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, 848c2ecf20Sopenharmony_ci const struct ubi_ec_hdr *ec_hdr); 858c2ecf20Sopenharmony_cistatic int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); 868c2ecf20Sopenharmony_cistatic int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, 878c2ecf20Sopenharmony_ci const struct ubi_vid_hdr *vid_hdr); 888c2ecf20Sopenharmony_cistatic int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, 898c2ecf20Sopenharmony_ci int offset, int len); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/** 928c2ecf20Sopenharmony_ci * ubi_io_read - read data from a physical eraseblock. 938c2ecf20Sopenharmony_ci * @ubi: UBI device description object 948c2ecf20Sopenharmony_ci * @buf: buffer where to store the read data 958c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to read from 968c2ecf20Sopenharmony_ci * @offset: offset within the physical eraseblock from where to read 978c2ecf20Sopenharmony_ci * @len: how many bytes to read 988c2ecf20Sopenharmony_ci * 998c2ecf20Sopenharmony_ci * This function reads data from offset @offset of physical eraseblock @pnum 1008c2ecf20Sopenharmony_ci * and stores the read data in the @buf buffer. The following return codes are 1018c2ecf20Sopenharmony_ci * possible: 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * o %0 if all the requested data were successfully read; 1048c2ecf20Sopenharmony_ci * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but 1058c2ecf20Sopenharmony_ci * correctable bit-flips were detected; this is harmless but may indicate 1068c2ecf20Sopenharmony_ci * that this eraseblock may become bad soon (but do not have to); 1078c2ecf20Sopenharmony_ci * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for 1088c2ecf20Sopenharmony_ci * example it can be an ECC error in case of NAND; this most probably means 1098c2ecf20Sopenharmony_ci * that the data is corrupted; 1108c2ecf20Sopenharmony_ci * o %-EIO if some I/O error occurred; 1118c2ecf20Sopenharmony_ci * o other negative error codes in case of other errors. 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_ciint ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, 1148c2ecf20Sopenharmony_ci int len) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci int err, retries = 0; 1178c2ecf20Sopenharmony_ci size_t read; 1188c2ecf20Sopenharmony_ci loff_t addr; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 1238c2ecf20Sopenharmony_ci ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); 1248c2ecf20Sopenharmony_ci ubi_assert(len > 0); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci err = self_check_not_bad(ubi, pnum); 1278c2ecf20Sopenharmony_ci if (err) 1288c2ecf20Sopenharmony_ci return err; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* 1318c2ecf20Sopenharmony_ci * Deliberately corrupt the buffer to improve robustness. Indeed, if we 1328c2ecf20Sopenharmony_ci * do not do this, the following may happen: 1338c2ecf20Sopenharmony_ci * 1. The buffer contains data from previous operation, e.g., read from 1348c2ecf20Sopenharmony_ci * another PEB previously. The data looks like expected, e.g., if we 1358c2ecf20Sopenharmony_ci * just do not read anything and return - the caller would not 1368c2ecf20Sopenharmony_ci * notice this. E.g., if we are reading a VID header, the buffer may 1378c2ecf20Sopenharmony_ci * contain a valid VID header from another PEB. 1388c2ecf20Sopenharmony_ci * 2. The driver is buggy and returns us success or -EBADMSG or 1398c2ecf20Sopenharmony_ci * -EUCLEAN, but it does not actually put any data to the buffer. 1408c2ecf20Sopenharmony_ci * 1418c2ecf20Sopenharmony_ci * This may confuse UBI or upper layers - they may think the buffer 1428c2ecf20Sopenharmony_ci * contains valid data while in fact it is just old data. This is 1438c2ecf20Sopenharmony_ci * especially possible because UBI (and UBIFS) relies on CRC, and 1448c2ecf20Sopenharmony_ci * treats data as correct even in case of ECC errors if the CRC is 1458c2ecf20Sopenharmony_ci * correct. 1468c2ecf20Sopenharmony_ci * 1478c2ecf20Sopenharmony_ci * Try to prevent this situation by changing the first byte of the 1488c2ecf20Sopenharmony_ci * buffer. 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_ci *((uint8_t *)buf) ^= 0xFF; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci addr = (loff_t)pnum * ubi->peb_size + offset; 1538c2ecf20Sopenharmony_ciretry: 1548c2ecf20Sopenharmony_ci err = mtd_read(ubi->mtd, addr, len, &read, buf); 1558c2ecf20Sopenharmony_ci if (err) { 1568c2ecf20Sopenharmony_ci const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : ""; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci if (mtd_is_bitflip(err)) { 1598c2ecf20Sopenharmony_ci /* 1608c2ecf20Sopenharmony_ci * -EUCLEAN is reported if there was a bit-flip which 1618c2ecf20Sopenharmony_ci * was corrected, so this is harmless. 1628c2ecf20Sopenharmony_ci * 1638c2ecf20Sopenharmony_ci * We do not report about it here unless debugging is 1648c2ecf20Sopenharmony_ci * enabled. A corresponding message will be printed 1658c2ecf20Sopenharmony_ci * later, when it is has been scrubbed. 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_ci ubi_msg(ubi, "fixable bit-flip detected at PEB %d", 1688c2ecf20Sopenharmony_ci pnum); 1698c2ecf20Sopenharmony_ci ubi_assert(len == read); 1708c2ecf20Sopenharmony_ci return UBI_IO_BITFLIPS; 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci if (retries++ < UBI_IO_RETRIES) { 1748c2ecf20Sopenharmony_ci ubi_warn(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", 1758c2ecf20Sopenharmony_ci err, errstr, len, pnum, offset, read); 1768c2ecf20Sopenharmony_ci yield(); 1778c2ecf20Sopenharmony_ci goto retry; 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci ubi_err(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", 1818c2ecf20Sopenharmony_ci err, errstr, len, pnum, offset, read); 1828c2ecf20Sopenharmony_ci dump_stack(); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci /* 1858c2ecf20Sopenharmony_ci * The driver should never return -EBADMSG if it failed to read 1868c2ecf20Sopenharmony_ci * all the requested data. But some buggy drivers might do 1878c2ecf20Sopenharmony_ci * this, so we change it to -EIO. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci if (read != len && mtd_is_eccerr(err)) { 1908c2ecf20Sopenharmony_ci ubi_assert(0); 1918c2ecf20Sopenharmony_ci err = -EIO; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci } else { 1948c2ecf20Sopenharmony_ci ubi_assert(len == read); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci if (ubi_dbg_is_bitflip(ubi)) { 1978c2ecf20Sopenharmony_ci dbg_gen("bit-flip (emulated)"); 1988c2ecf20Sopenharmony_ci err = UBI_IO_BITFLIPS; 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci return err; 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci/** 2068c2ecf20Sopenharmony_ci * ubi_io_write - write data to a physical eraseblock. 2078c2ecf20Sopenharmony_ci * @ubi: UBI device description object 2088c2ecf20Sopenharmony_ci * @buf: buffer with the data to write 2098c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to write to 2108c2ecf20Sopenharmony_ci * @offset: offset within the physical eraseblock where to write 2118c2ecf20Sopenharmony_ci * @len: how many bytes to write 2128c2ecf20Sopenharmony_ci * 2138c2ecf20Sopenharmony_ci * This function writes @len bytes of data from buffer @buf to offset @offset 2148c2ecf20Sopenharmony_ci * of physical eraseblock @pnum. If all the data were successfully written, 2158c2ecf20Sopenharmony_ci * zero is returned. If an error occurred, this function returns a negative 2168c2ecf20Sopenharmony_ci * error code. If %-EIO is returned, the physical eraseblock most probably went 2178c2ecf20Sopenharmony_ci * bad. 2188c2ecf20Sopenharmony_ci * 2198c2ecf20Sopenharmony_ci * Note, in case of an error, it is possible that something was still written 2208c2ecf20Sopenharmony_ci * to the flash media, but may be some garbage. 2218c2ecf20Sopenharmony_ci */ 2228c2ecf20Sopenharmony_ciint ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, 2238c2ecf20Sopenharmony_ci int len) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci int err; 2268c2ecf20Sopenharmony_ci size_t written; 2278c2ecf20Sopenharmony_ci loff_t addr; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci dbg_io("write %d bytes to PEB %d:%d", len, pnum, offset); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 2328c2ecf20Sopenharmony_ci ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); 2338c2ecf20Sopenharmony_ci ubi_assert(offset % ubi->hdrs_min_io_size == 0); 2348c2ecf20Sopenharmony_ci ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci if (ubi->ro_mode) { 2378c2ecf20Sopenharmony_ci ubi_err(ubi, "read-only mode"); 2388c2ecf20Sopenharmony_ci return -EROFS; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci err = self_check_not_bad(ubi, pnum); 2428c2ecf20Sopenharmony_ci if (err) 2438c2ecf20Sopenharmony_ci return err; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci /* The area we are writing to has to contain all 0xFF bytes */ 2468c2ecf20Sopenharmony_ci err = ubi_self_check_all_ff(ubi, pnum, offset, len); 2478c2ecf20Sopenharmony_ci if (err) 2488c2ecf20Sopenharmony_ci return err; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (offset >= ubi->leb_start) { 2518c2ecf20Sopenharmony_ci /* 2528c2ecf20Sopenharmony_ci * We write to the data area of the physical eraseblock. Make 2538c2ecf20Sopenharmony_ci * sure it has valid EC and VID headers. 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_ci err = self_check_peb_ec_hdr(ubi, pnum); 2568c2ecf20Sopenharmony_ci if (err) 2578c2ecf20Sopenharmony_ci return err; 2588c2ecf20Sopenharmony_ci err = self_check_peb_vid_hdr(ubi, pnum); 2598c2ecf20Sopenharmony_ci if (err) 2608c2ecf20Sopenharmony_ci return err; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci if (ubi_dbg_is_write_failure(ubi)) { 2648c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot write %d bytes to PEB %d:%d (emulated)", 2658c2ecf20Sopenharmony_ci len, pnum, offset); 2668c2ecf20Sopenharmony_ci dump_stack(); 2678c2ecf20Sopenharmony_ci return -EIO; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci addr = (loff_t)pnum * ubi->peb_size + offset; 2718c2ecf20Sopenharmony_ci err = mtd_write(ubi->mtd, addr, len, &written, buf); 2728c2ecf20Sopenharmony_ci if (err) { 2738c2ecf20Sopenharmony_ci ubi_err(ubi, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes", 2748c2ecf20Sopenharmony_ci err, len, pnum, offset, written); 2758c2ecf20Sopenharmony_ci dump_stack(); 2768c2ecf20Sopenharmony_ci ubi_dump_flash(ubi, pnum, offset, len); 2778c2ecf20Sopenharmony_ci } else 2788c2ecf20Sopenharmony_ci ubi_assert(written == len); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (!err) { 2818c2ecf20Sopenharmony_ci err = self_check_write(ubi, buf, pnum, offset, len); 2828c2ecf20Sopenharmony_ci if (err) 2838c2ecf20Sopenharmony_ci return err; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci /* 2868c2ecf20Sopenharmony_ci * Since we always write sequentially, the rest of the PEB has 2878c2ecf20Sopenharmony_ci * to contain only 0xFF bytes. 2888c2ecf20Sopenharmony_ci */ 2898c2ecf20Sopenharmony_ci offset += len; 2908c2ecf20Sopenharmony_ci len = ubi->peb_size - offset; 2918c2ecf20Sopenharmony_ci if (len) 2928c2ecf20Sopenharmony_ci err = ubi_self_check_all_ff(ubi, pnum, offset, len); 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci return err; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci/** 2998c2ecf20Sopenharmony_ci * do_sync_erase - synchronously erase a physical eraseblock. 3008c2ecf20Sopenharmony_ci * @ubi: UBI device description object 3018c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to erase 3028c2ecf20Sopenharmony_ci * 3038c2ecf20Sopenharmony_ci * This function synchronously erases physical eraseblock @pnum and returns 3048c2ecf20Sopenharmony_ci * zero in case of success and a negative error code in case of failure. If 3058c2ecf20Sopenharmony_ci * %-EIO is returned, the physical eraseblock most probably went bad. 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_cistatic int do_sync_erase(struct ubi_device *ubi, int pnum) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci int err, retries = 0; 3108c2ecf20Sopenharmony_ci struct erase_info ei; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci dbg_io("erase PEB %d", pnum); 3138c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci if (ubi->ro_mode) { 3168c2ecf20Sopenharmony_ci ubi_err(ubi, "read-only mode"); 3178c2ecf20Sopenharmony_ci return -EROFS; 3188c2ecf20Sopenharmony_ci } 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ciretry: 3218c2ecf20Sopenharmony_ci memset(&ei, 0, sizeof(struct erase_info)); 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci ei.addr = (loff_t)pnum * ubi->peb_size; 3248c2ecf20Sopenharmony_ci ei.len = ubi->peb_size; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci err = mtd_erase(ubi->mtd, &ei); 3278c2ecf20Sopenharmony_ci if (err) { 3288c2ecf20Sopenharmony_ci if (retries++ < UBI_IO_RETRIES) { 3298c2ecf20Sopenharmony_ci ubi_warn(ubi, "error %d while erasing PEB %d, retry", 3308c2ecf20Sopenharmony_ci err, pnum); 3318c2ecf20Sopenharmony_ci yield(); 3328c2ecf20Sopenharmony_ci goto retry; 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot erase PEB %d, error %d", pnum, err); 3358c2ecf20Sopenharmony_ci dump_stack(); 3368c2ecf20Sopenharmony_ci return err; 3378c2ecf20Sopenharmony_ci } 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci err = ubi_self_check_all_ff(ubi, pnum, 0, ubi->peb_size); 3408c2ecf20Sopenharmony_ci if (err) 3418c2ecf20Sopenharmony_ci return err; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci if (ubi_dbg_is_erase_failure(ubi)) { 3448c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot erase PEB %d (emulated)", pnum); 3458c2ecf20Sopenharmony_ci return -EIO; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci return 0; 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci/* Patterns to write to a physical eraseblock when torturing it */ 3528c2ecf20Sopenharmony_cistatic uint8_t patterns[] = {0xa5, 0x5a, 0x0}; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci/** 3558c2ecf20Sopenharmony_ci * torture_peb - test a supposedly bad physical eraseblock. 3568c2ecf20Sopenharmony_ci * @ubi: UBI device description object 3578c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to test 3588c2ecf20Sopenharmony_ci * 3598c2ecf20Sopenharmony_ci * This function returns %-EIO if the physical eraseblock did not pass the 3608c2ecf20Sopenharmony_ci * test, a positive number of erase operations done if the test was 3618c2ecf20Sopenharmony_ci * successfully passed, and other negative error codes in case of other errors. 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_cistatic int torture_peb(struct ubi_device *ubi, int pnum) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci int err, i, patt_count; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci ubi_msg(ubi, "run torture test for PEB %d", pnum); 3688c2ecf20Sopenharmony_ci patt_count = ARRAY_SIZE(patterns); 3698c2ecf20Sopenharmony_ci ubi_assert(patt_count > 0); 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci mutex_lock(&ubi->buf_mutex); 3728c2ecf20Sopenharmony_ci for (i = 0; i < patt_count; i++) { 3738c2ecf20Sopenharmony_ci err = do_sync_erase(ubi, pnum); 3748c2ecf20Sopenharmony_ci if (err) 3758c2ecf20Sopenharmony_ci goto out; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci /* Make sure the PEB contains only 0xFF bytes */ 3788c2ecf20Sopenharmony_ci err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); 3798c2ecf20Sopenharmony_ci if (err) 3808c2ecf20Sopenharmony_ci goto out; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); 3838c2ecf20Sopenharmony_ci if (err == 0) { 3848c2ecf20Sopenharmony_ci ubi_err(ubi, "erased PEB %d, but a non-0xFF byte found", 3858c2ecf20Sopenharmony_ci pnum); 3868c2ecf20Sopenharmony_ci err = -EIO; 3878c2ecf20Sopenharmony_ci goto out; 3888c2ecf20Sopenharmony_ci } 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci /* Write a pattern and check it */ 3918c2ecf20Sopenharmony_ci memset(ubi->peb_buf, patterns[i], ubi->peb_size); 3928c2ecf20Sopenharmony_ci err = ubi_io_write(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); 3938c2ecf20Sopenharmony_ci if (err) 3948c2ecf20Sopenharmony_ci goto out; 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci memset(ubi->peb_buf, ~patterns[i], ubi->peb_size); 3978c2ecf20Sopenharmony_ci err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); 3988c2ecf20Sopenharmony_ci if (err) 3998c2ecf20Sopenharmony_ci goto out; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci err = ubi_check_pattern(ubi->peb_buf, patterns[i], 4028c2ecf20Sopenharmony_ci ubi->peb_size); 4038c2ecf20Sopenharmony_ci if (err == 0) { 4048c2ecf20Sopenharmony_ci ubi_err(ubi, "pattern %x checking failed for PEB %d", 4058c2ecf20Sopenharmony_ci patterns[i], pnum); 4068c2ecf20Sopenharmony_ci err = -EIO; 4078c2ecf20Sopenharmony_ci goto out; 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci err = patt_count; 4128c2ecf20Sopenharmony_ci ubi_msg(ubi, "PEB %d passed torture test, do not mark it as bad", pnum); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ciout: 4158c2ecf20Sopenharmony_ci mutex_unlock(&ubi->buf_mutex); 4168c2ecf20Sopenharmony_ci if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { 4178c2ecf20Sopenharmony_ci /* 4188c2ecf20Sopenharmony_ci * If a bit-flip or data integrity error was detected, the test 4198c2ecf20Sopenharmony_ci * has not passed because it happened on a freshly erased 4208c2ecf20Sopenharmony_ci * physical eraseblock which means something is wrong with it. 4218c2ecf20Sopenharmony_ci */ 4228c2ecf20Sopenharmony_ci ubi_err(ubi, "read problems on freshly erased PEB %d, must be bad", 4238c2ecf20Sopenharmony_ci pnum); 4248c2ecf20Sopenharmony_ci err = -EIO; 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci return err; 4278c2ecf20Sopenharmony_ci} 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci/** 4308c2ecf20Sopenharmony_ci * nor_erase_prepare - prepare a NOR flash PEB for erasure. 4318c2ecf20Sopenharmony_ci * @ubi: UBI device description object 4328c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to prepare 4338c2ecf20Sopenharmony_ci * 4348c2ecf20Sopenharmony_ci * NOR flash, or at least some of them, have peculiar embedded PEB erasure 4358c2ecf20Sopenharmony_ci * algorithm: the PEB is first filled with zeroes, then it is erased. And 4368c2ecf20Sopenharmony_ci * filling with zeroes starts from the end of the PEB. This was observed with 4378c2ecf20Sopenharmony_ci * Spansion S29GL512N NOR flash. 4388c2ecf20Sopenharmony_ci * 4398c2ecf20Sopenharmony_ci * This means that in case of a power cut we may end up with intact data at the 4408c2ecf20Sopenharmony_ci * beginning of the PEB, and all zeroes at the end of PEB. In other words, the 4418c2ecf20Sopenharmony_ci * EC and VID headers are OK, but a large chunk of data at the end of PEB is 4428c2ecf20Sopenharmony_ci * zeroed. This makes UBI mistakenly treat this PEB as used and associate it 4438c2ecf20Sopenharmony_ci * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). 4448c2ecf20Sopenharmony_ci * 4458c2ecf20Sopenharmony_ci * This function is called before erasing NOR PEBs and it zeroes out EC and VID 4468c2ecf20Sopenharmony_ci * magic numbers in order to invalidate them and prevent the failures. Returns 4478c2ecf20Sopenharmony_ci * zero in case of success and a negative error code in case of failure. 4488c2ecf20Sopenharmony_ci */ 4498c2ecf20Sopenharmony_cistatic int nor_erase_prepare(struct ubi_device *ubi, int pnum) 4508c2ecf20Sopenharmony_ci{ 4518c2ecf20Sopenharmony_ci int err; 4528c2ecf20Sopenharmony_ci size_t written; 4538c2ecf20Sopenharmony_ci loff_t addr; 4548c2ecf20Sopenharmony_ci uint32_t data = 0; 4558c2ecf20Sopenharmony_ci struct ubi_ec_hdr ec_hdr; 4568c2ecf20Sopenharmony_ci struct ubi_vid_io_buf vidb; 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci /* 4598c2ecf20Sopenharmony_ci * Note, we cannot generally define VID header buffers on stack, 4608c2ecf20Sopenharmony_ci * because of the way we deal with these buffers (see the header 4618c2ecf20Sopenharmony_ci * comment in this file). But we know this is a NOR-specific piece of 4628c2ecf20Sopenharmony_ci * code, so we can do this. But yes, this is error-prone and we should 4638c2ecf20Sopenharmony_ci * (pre-)allocate VID header buffer instead. 4648c2ecf20Sopenharmony_ci */ 4658c2ecf20Sopenharmony_ci struct ubi_vid_hdr vid_hdr; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci /* 4688c2ecf20Sopenharmony_ci * If VID or EC is valid, we have to corrupt them before erasing. 4698c2ecf20Sopenharmony_ci * It is important to first invalidate the EC header, and then the VID 4708c2ecf20Sopenharmony_ci * header. Otherwise a power cut may lead to valid EC header and 4718c2ecf20Sopenharmony_ci * invalid VID header, in which case UBI will treat this PEB as 4728c2ecf20Sopenharmony_ci * corrupted and will try to preserve it, and print scary warnings. 4738c2ecf20Sopenharmony_ci */ 4748c2ecf20Sopenharmony_ci addr = (loff_t)pnum * ubi->peb_size; 4758c2ecf20Sopenharmony_ci err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); 4768c2ecf20Sopenharmony_ci if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && 4778c2ecf20Sopenharmony_ci err != UBI_IO_FF){ 4788c2ecf20Sopenharmony_ci err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); 4798c2ecf20Sopenharmony_ci if(err) 4808c2ecf20Sopenharmony_ci goto error; 4818c2ecf20Sopenharmony_ci } 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci ubi_init_vid_buf(ubi, &vidb, &vid_hdr); 4848c2ecf20Sopenharmony_ci ubi_assert(&vid_hdr == ubi_get_vid_hdr(&vidb)); 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci err = ubi_io_read_vid_hdr(ubi, pnum, &vidb, 0); 4878c2ecf20Sopenharmony_ci if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && 4888c2ecf20Sopenharmony_ci err != UBI_IO_FF){ 4898c2ecf20Sopenharmony_ci addr += ubi->vid_hdr_aloffset; 4908c2ecf20Sopenharmony_ci err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); 4918c2ecf20Sopenharmony_ci if (err) 4928c2ecf20Sopenharmony_ci goto error; 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci return 0; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cierror: 4978c2ecf20Sopenharmony_ci /* 4988c2ecf20Sopenharmony_ci * The PEB contains a valid VID or EC header, but we cannot invalidate 4998c2ecf20Sopenharmony_ci * it. Supposedly the flash media or the driver is screwed up, so 5008c2ecf20Sopenharmony_ci * return an error. 5018c2ecf20Sopenharmony_ci */ 5028c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot invalidate PEB %d, write returned %d", pnum, err); 5038c2ecf20Sopenharmony_ci ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); 5048c2ecf20Sopenharmony_ci return -EIO; 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci/** 5088c2ecf20Sopenharmony_ci * ubi_io_sync_erase - synchronously erase a physical eraseblock. 5098c2ecf20Sopenharmony_ci * @ubi: UBI device description object 5108c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to erase 5118c2ecf20Sopenharmony_ci * @torture: if this physical eraseblock has to be tortured 5128c2ecf20Sopenharmony_ci * 5138c2ecf20Sopenharmony_ci * This function synchronously erases physical eraseblock @pnum. If @torture 5148c2ecf20Sopenharmony_ci * flag is not zero, the physical eraseblock is checked by means of writing 5158c2ecf20Sopenharmony_ci * different patterns to it and reading them back. If the torturing is enabled, 5168c2ecf20Sopenharmony_ci * the physical eraseblock is erased more than once. 5178c2ecf20Sopenharmony_ci * 5188c2ecf20Sopenharmony_ci * This function returns the number of erasures made in case of success, %-EIO 5198c2ecf20Sopenharmony_ci * if the erasure failed or the torturing test failed, and other negative error 5208c2ecf20Sopenharmony_ci * codes in case of other errors. Note, %-EIO means that the physical 5218c2ecf20Sopenharmony_ci * eraseblock is bad. 5228c2ecf20Sopenharmony_ci */ 5238c2ecf20Sopenharmony_ciint ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) 5248c2ecf20Sopenharmony_ci{ 5258c2ecf20Sopenharmony_ci int err, ret = 0; 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci err = self_check_not_bad(ubi, pnum); 5308c2ecf20Sopenharmony_ci if (err != 0) 5318c2ecf20Sopenharmony_ci return err; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci if (ubi->ro_mode) { 5348c2ecf20Sopenharmony_ci ubi_err(ubi, "read-only mode"); 5358c2ecf20Sopenharmony_ci return -EROFS; 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci if (ubi->nor_flash) { 5398c2ecf20Sopenharmony_ci err = nor_erase_prepare(ubi, pnum); 5408c2ecf20Sopenharmony_ci if (err) 5418c2ecf20Sopenharmony_ci return err; 5428c2ecf20Sopenharmony_ci } 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci if (torture) { 5458c2ecf20Sopenharmony_ci ret = torture_peb(ubi, pnum); 5468c2ecf20Sopenharmony_ci if (ret < 0) 5478c2ecf20Sopenharmony_ci return ret; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci err = do_sync_erase(ubi, pnum); 5518c2ecf20Sopenharmony_ci if (err) 5528c2ecf20Sopenharmony_ci return err; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci return ret + 1; 5558c2ecf20Sopenharmony_ci} 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci/** 5588c2ecf20Sopenharmony_ci * ubi_io_is_bad - check if a physical eraseblock is bad. 5598c2ecf20Sopenharmony_ci * @ubi: UBI device description object 5608c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to check 5618c2ecf20Sopenharmony_ci * 5628c2ecf20Sopenharmony_ci * This function returns a positive number if the physical eraseblock is bad, 5638c2ecf20Sopenharmony_ci * zero if not, and a negative error code if an error occurred. 5648c2ecf20Sopenharmony_ci */ 5658c2ecf20Sopenharmony_ciint ubi_io_is_bad(const struct ubi_device *ubi, int pnum) 5668c2ecf20Sopenharmony_ci{ 5678c2ecf20Sopenharmony_ci struct mtd_info *mtd = ubi->mtd; 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci if (ubi->bad_allowed) { 5728c2ecf20Sopenharmony_ci int ret; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size); 5758c2ecf20Sopenharmony_ci if (ret < 0) 5768c2ecf20Sopenharmony_ci ubi_err(ubi, "error %d while checking if PEB %d is bad", 5778c2ecf20Sopenharmony_ci ret, pnum); 5788c2ecf20Sopenharmony_ci else if (ret) 5798c2ecf20Sopenharmony_ci dbg_io("PEB %d is bad", pnum); 5808c2ecf20Sopenharmony_ci return ret; 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci return 0; 5848c2ecf20Sopenharmony_ci} 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci/** 5878c2ecf20Sopenharmony_ci * ubi_io_mark_bad - mark a physical eraseblock as bad. 5888c2ecf20Sopenharmony_ci * @ubi: UBI device description object 5898c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to mark 5908c2ecf20Sopenharmony_ci * 5918c2ecf20Sopenharmony_ci * This function returns zero in case of success and a negative error code in 5928c2ecf20Sopenharmony_ci * case of failure. 5938c2ecf20Sopenharmony_ci */ 5948c2ecf20Sopenharmony_ciint ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) 5958c2ecf20Sopenharmony_ci{ 5968c2ecf20Sopenharmony_ci int err; 5978c2ecf20Sopenharmony_ci struct mtd_info *mtd = ubi->mtd; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci if (ubi->ro_mode) { 6028c2ecf20Sopenharmony_ci ubi_err(ubi, "read-only mode"); 6038c2ecf20Sopenharmony_ci return -EROFS; 6048c2ecf20Sopenharmony_ci } 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci if (!ubi->bad_allowed) 6078c2ecf20Sopenharmony_ci return 0; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size); 6108c2ecf20Sopenharmony_ci if (err) 6118c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot mark PEB %d bad, error %d", pnum, err); 6128c2ecf20Sopenharmony_ci return err; 6138c2ecf20Sopenharmony_ci} 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci/** 6168c2ecf20Sopenharmony_ci * validate_ec_hdr - validate an erase counter header. 6178c2ecf20Sopenharmony_ci * @ubi: UBI device description object 6188c2ecf20Sopenharmony_ci * @ec_hdr: the erase counter header to check 6198c2ecf20Sopenharmony_ci * 6208c2ecf20Sopenharmony_ci * This function returns zero if the erase counter header is OK, and %1 if 6218c2ecf20Sopenharmony_ci * not. 6228c2ecf20Sopenharmony_ci */ 6238c2ecf20Sopenharmony_cistatic int validate_ec_hdr(const struct ubi_device *ubi, 6248c2ecf20Sopenharmony_ci const struct ubi_ec_hdr *ec_hdr) 6258c2ecf20Sopenharmony_ci{ 6268c2ecf20Sopenharmony_ci long long ec; 6278c2ecf20Sopenharmony_ci int vid_hdr_offset, leb_start; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci ec = be64_to_cpu(ec_hdr->ec); 6308c2ecf20Sopenharmony_ci vid_hdr_offset = be32_to_cpu(ec_hdr->vid_hdr_offset); 6318c2ecf20Sopenharmony_ci leb_start = be32_to_cpu(ec_hdr->data_offset); 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci if (ec_hdr->version != UBI_VERSION) { 6348c2ecf20Sopenharmony_ci ubi_err(ubi, "node with incompatible UBI version found: this UBI version is %d, image version is %d", 6358c2ecf20Sopenharmony_ci UBI_VERSION, (int)ec_hdr->version); 6368c2ecf20Sopenharmony_ci goto bad; 6378c2ecf20Sopenharmony_ci } 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci if (vid_hdr_offset != ubi->vid_hdr_offset) { 6408c2ecf20Sopenharmony_ci ubi_err(ubi, "bad VID header offset %d, expected %d", 6418c2ecf20Sopenharmony_ci vid_hdr_offset, ubi->vid_hdr_offset); 6428c2ecf20Sopenharmony_ci goto bad; 6438c2ecf20Sopenharmony_ci } 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci if (leb_start != ubi->leb_start) { 6468c2ecf20Sopenharmony_ci ubi_err(ubi, "bad data offset %d, expected %d", 6478c2ecf20Sopenharmony_ci leb_start, ubi->leb_start); 6488c2ecf20Sopenharmony_ci goto bad; 6498c2ecf20Sopenharmony_ci } 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci if (ec < 0 || ec > UBI_MAX_ERASECOUNTER) { 6528c2ecf20Sopenharmony_ci ubi_err(ubi, "bad erase counter %lld", ec); 6538c2ecf20Sopenharmony_ci goto bad; 6548c2ecf20Sopenharmony_ci } 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci return 0; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_cibad: 6598c2ecf20Sopenharmony_ci ubi_err(ubi, "bad EC header"); 6608c2ecf20Sopenharmony_ci ubi_dump_ec_hdr(ec_hdr); 6618c2ecf20Sopenharmony_ci dump_stack(); 6628c2ecf20Sopenharmony_ci return 1; 6638c2ecf20Sopenharmony_ci} 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci/** 6668c2ecf20Sopenharmony_ci * ubi_io_read_ec_hdr - read and check an erase counter header. 6678c2ecf20Sopenharmony_ci * @ubi: UBI device description object 6688c2ecf20Sopenharmony_ci * @pnum: physical eraseblock to read from 6698c2ecf20Sopenharmony_ci * @ec_hdr: a &struct ubi_ec_hdr object where to store the read erase counter 6708c2ecf20Sopenharmony_ci * header 6718c2ecf20Sopenharmony_ci * @verbose: be verbose if the header is corrupted or was not found 6728c2ecf20Sopenharmony_ci * 6738c2ecf20Sopenharmony_ci * This function reads erase counter header from physical eraseblock @pnum and 6748c2ecf20Sopenharmony_ci * stores it in @ec_hdr. This function also checks CRC checksum of the read 6758c2ecf20Sopenharmony_ci * erase counter header. The following codes may be returned: 6768c2ecf20Sopenharmony_ci * 6778c2ecf20Sopenharmony_ci * o %0 if the CRC checksum is correct and the header was successfully read; 6788c2ecf20Sopenharmony_ci * o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected 6798c2ecf20Sopenharmony_ci * and corrected by the flash driver; this is harmless but may indicate that 6808c2ecf20Sopenharmony_ci * this eraseblock may become bad soon (but may be not); 6818c2ecf20Sopenharmony_ci * o %UBI_IO_BAD_HDR if the erase counter header is corrupted (a CRC error); 6828c2ecf20Sopenharmony_ci * o %UBI_IO_BAD_HDR_EBADMSG is the same as %UBI_IO_BAD_HDR, but there also was 6838c2ecf20Sopenharmony_ci * a data integrity error (uncorrectable ECC error in case of NAND); 6848c2ecf20Sopenharmony_ci * o %UBI_IO_FF if only 0xFF bytes were read (the PEB is supposedly empty) 6858c2ecf20Sopenharmony_ci * o a negative error code in case of failure. 6868c2ecf20Sopenharmony_ci */ 6878c2ecf20Sopenharmony_ciint ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, 6888c2ecf20Sopenharmony_ci struct ubi_ec_hdr *ec_hdr, int verbose) 6898c2ecf20Sopenharmony_ci{ 6908c2ecf20Sopenharmony_ci int err, read_err; 6918c2ecf20Sopenharmony_ci uint32_t crc, magic, hdr_crc; 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci dbg_io("read EC header from PEB %d", pnum); 6948c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); 6978c2ecf20Sopenharmony_ci if (read_err) { 6988c2ecf20Sopenharmony_ci if (read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) 6998c2ecf20Sopenharmony_ci return read_err; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci /* 7028c2ecf20Sopenharmony_ci * We read all the data, but either a correctable bit-flip 7038c2ecf20Sopenharmony_ci * occurred, or MTD reported a data integrity error 7048c2ecf20Sopenharmony_ci * (uncorrectable ECC error in case of NAND). The former is 7058c2ecf20Sopenharmony_ci * harmless, the later may mean that the read data is 7068c2ecf20Sopenharmony_ci * corrupted. But we have a CRC check-sum and we will detect 7078c2ecf20Sopenharmony_ci * this. If the EC header is still OK, we just report this as 7088c2ecf20Sopenharmony_ci * there was a bit-flip, to force scrubbing. 7098c2ecf20Sopenharmony_ci */ 7108c2ecf20Sopenharmony_ci } 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci magic = be32_to_cpu(ec_hdr->magic); 7138c2ecf20Sopenharmony_ci if (magic != UBI_EC_HDR_MAGIC) { 7148c2ecf20Sopenharmony_ci if (mtd_is_eccerr(read_err)) 7158c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR_EBADMSG; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci /* 7188c2ecf20Sopenharmony_ci * The magic field is wrong. Let's check if we have read all 7198c2ecf20Sopenharmony_ci * 0xFF. If yes, this physical eraseblock is assumed to be 7208c2ecf20Sopenharmony_ci * empty. 7218c2ecf20Sopenharmony_ci */ 7228c2ecf20Sopenharmony_ci if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { 7238c2ecf20Sopenharmony_ci /* The physical eraseblock is supposedly empty */ 7248c2ecf20Sopenharmony_ci if (verbose) 7258c2ecf20Sopenharmony_ci ubi_warn(ubi, "no EC header found at PEB %d, only 0xFF bytes", 7268c2ecf20Sopenharmony_ci pnum); 7278c2ecf20Sopenharmony_ci dbg_bld("no EC header found at PEB %d, only 0xFF bytes", 7288c2ecf20Sopenharmony_ci pnum); 7298c2ecf20Sopenharmony_ci if (!read_err) 7308c2ecf20Sopenharmony_ci return UBI_IO_FF; 7318c2ecf20Sopenharmony_ci else 7328c2ecf20Sopenharmony_ci return UBI_IO_FF_BITFLIPS; 7338c2ecf20Sopenharmony_ci } 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci /* 7368c2ecf20Sopenharmony_ci * This is not a valid erase counter header, and these are not 7378c2ecf20Sopenharmony_ci * 0xFF bytes. Report that the header is corrupted. 7388c2ecf20Sopenharmony_ci */ 7398c2ecf20Sopenharmony_ci if (verbose) { 7408c2ecf20Sopenharmony_ci ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", 7418c2ecf20Sopenharmony_ci pnum, magic, UBI_EC_HDR_MAGIC); 7428c2ecf20Sopenharmony_ci ubi_dump_ec_hdr(ec_hdr); 7438c2ecf20Sopenharmony_ci } 7448c2ecf20Sopenharmony_ci dbg_bld("bad magic number at PEB %d: %08x instead of %08x", 7458c2ecf20Sopenharmony_ci pnum, magic, UBI_EC_HDR_MAGIC); 7468c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR; 7478c2ecf20Sopenharmony_ci } 7488c2ecf20Sopenharmony_ci 7498c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 7508c2ecf20Sopenharmony_ci hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci if (hdr_crc != crc) { 7538c2ecf20Sopenharmony_ci if (verbose) { 7548c2ecf20Sopenharmony_ci ubi_warn(ubi, "bad EC header CRC at PEB %d, calculated %#08x, read %#08x", 7558c2ecf20Sopenharmony_ci pnum, crc, hdr_crc); 7568c2ecf20Sopenharmony_ci ubi_dump_ec_hdr(ec_hdr); 7578c2ecf20Sopenharmony_ci } 7588c2ecf20Sopenharmony_ci dbg_bld("bad EC header CRC at PEB %d, calculated %#08x, read %#08x", 7598c2ecf20Sopenharmony_ci pnum, crc, hdr_crc); 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci if (!read_err) 7628c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR; 7638c2ecf20Sopenharmony_ci else 7648c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR_EBADMSG; 7658c2ecf20Sopenharmony_ci } 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci /* And of course validate what has just been read from the media */ 7688c2ecf20Sopenharmony_ci err = validate_ec_hdr(ubi, ec_hdr); 7698c2ecf20Sopenharmony_ci if (err) { 7708c2ecf20Sopenharmony_ci ubi_err(ubi, "validation failed for PEB %d", pnum); 7718c2ecf20Sopenharmony_ci return -EINVAL; 7728c2ecf20Sopenharmony_ci } 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_ci /* 7758c2ecf20Sopenharmony_ci * If there was %-EBADMSG, but the header CRC is still OK, report about 7768c2ecf20Sopenharmony_ci * a bit-flip to force scrubbing on this PEB. 7778c2ecf20Sopenharmony_ci */ 7788c2ecf20Sopenharmony_ci return read_err ? UBI_IO_BITFLIPS : 0; 7798c2ecf20Sopenharmony_ci} 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci/** 7828c2ecf20Sopenharmony_ci * ubi_io_write_ec_hdr - write an erase counter header. 7838c2ecf20Sopenharmony_ci * @ubi: UBI device description object 7848c2ecf20Sopenharmony_ci * @pnum: physical eraseblock to write to 7858c2ecf20Sopenharmony_ci * @ec_hdr: the erase counter header to write 7868c2ecf20Sopenharmony_ci * 7878c2ecf20Sopenharmony_ci * This function writes erase counter header described by @ec_hdr to physical 7888c2ecf20Sopenharmony_ci * eraseblock @pnum. It also fills most fields of @ec_hdr before writing, so 7898c2ecf20Sopenharmony_ci * the caller do not have to fill them. Callers must only fill the @ec_hdr->ec 7908c2ecf20Sopenharmony_ci * field. 7918c2ecf20Sopenharmony_ci * 7928c2ecf20Sopenharmony_ci * This function returns zero in case of success and a negative error code in 7938c2ecf20Sopenharmony_ci * case of failure. If %-EIO is returned, the physical eraseblock most probably 7948c2ecf20Sopenharmony_ci * went bad. 7958c2ecf20Sopenharmony_ci */ 7968c2ecf20Sopenharmony_ciint ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, 7978c2ecf20Sopenharmony_ci struct ubi_ec_hdr *ec_hdr) 7988c2ecf20Sopenharmony_ci{ 7998c2ecf20Sopenharmony_ci int err; 8008c2ecf20Sopenharmony_ci uint32_t crc; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci dbg_io("write EC header to PEB %d", pnum); 8038c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci ec_hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); 8068c2ecf20Sopenharmony_ci ec_hdr->version = UBI_VERSION; 8078c2ecf20Sopenharmony_ci ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); 8088c2ecf20Sopenharmony_ci ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); 8098c2ecf20Sopenharmony_ci ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); 8108c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 8118c2ecf20Sopenharmony_ci ec_hdr->hdr_crc = cpu_to_be32(crc); 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci err = self_check_ec_hdr(ubi, pnum, ec_hdr); 8148c2ecf20Sopenharmony_ci if (err) 8158c2ecf20Sopenharmony_ci return err; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci if (ubi_dbg_power_cut(ubi, POWER_CUT_EC_WRITE)) 8188c2ecf20Sopenharmony_ci return -EROFS; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); 8218c2ecf20Sopenharmony_ci return err; 8228c2ecf20Sopenharmony_ci} 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci/** 8258c2ecf20Sopenharmony_ci * validate_vid_hdr - validate a volume identifier header. 8268c2ecf20Sopenharmony_ci * @ubi: UBI device description object 8278c2ecf20Sopenharmony_ci * @vid_hdr: the volume identifier header to check 8288c2ecf20Sopenharmony_ci * 8298c2ecf20Sopenharmony_ci * This function checks that data stored in the volume identifier header 8308c2ecf20Sopenharmony_ci * @vid_hdr. Returns zero if the VID header is OK and %1 if not. 8318c2ecf20Sopenharmony_ci */ 8328c2ecf20Sopenharmony_cistatic int validate_vid_hdr(const struct ubi_device *ubi, 8338c2ecf20Sopenharmony_ci const struct ubi_vid_hdr *vid_hdr) 8348c2ecf20Sopenharmony_ci{ 8358c2ecf20Sopenharmony_ci int vol_type = vid_hdr->vol_type; 8368c2ecf20Sopenharmony_ci int copy_flag = vid_hdr->copy_flag; 8378c2ecf20Sopenharmony_ci int vol_id = be32_to_cpu(vid_hdr->vol_id); 8388c2ecf20Sopenharmony_ci int lnum = be32_to_cpu(vid_hdr->lnum); 8398c2ecf20Sopenharmony_ci int compat = vid_hdr->compat; 8408c2ecf20Sopenharmony_ci int data_size = be32_to_cpu(vid_hdr->data_size); 8418c2ecf20Sopenharmony_ci int used_ebs = be32_to_cpu(vid_hdr->used_ebs); 8428c2ecf20Sopenharmony_ci int data_pad = be32_to_cpu(vid_hdr->data_pad); 8438c2ecf20Sopenharmony_ci int data_crc = be32_to_cpu(vid_hdr->data_crc); 8448c2ecf20Sopenharmony_ci int usable_leb_size = ubi->leb_size - data_pad; 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci if (copy_flag != 0 && copy_flag != 1) { 8478c2ecf20Sopenharmony_ci ubi_err(ubi, "bad copy_flag"); 8488c2ecf20Sopenharmony_ci goto bad; 8498c2ecf20Sopenharmony_ci } 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || 8528c2ecf20Sopenharmony_ci data_pad < 0) { 8538c2ecf20Sopenharmony_ci ubi_err(ubi, "negative values"); 8548c2ecf20Sopenharmony_ci goto bad; 8558c2ecf20Sopenharmony_ci } 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { 8588c2ecf20Sopenharmony_ci ubi_err(ubi, "bad vol_id"); 8598c2ecf20Sopenharmony_ci goto bad; 8608c2ecf20Sopenharmony_ci } 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { 8638c2ecf20Sopenharmony_ci ubi_err(ubi, "bad compat"); 8648c2ecf20Sopenharmony_ci goto bad; 8658c2ecf20Sopenharmony_ci } 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && 8688c2ecf20Sopenharmony_ci compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && 8698c2ecf20Sopenharmony_ci compat != UBI_COMPAT_REJECT) { 8708c2ecf20Sopenharmony_ci ubi_err(ubi, "bad compat"); 8718c2ecf20Sopenharmony_ci goto bad; 8728c2ecf20Sopenharmony_ci } 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { 8758c2ecf20Sopenharmony_ci ubi_err(ubi, "bad vol_type"); 8768c2ecf20Sopenharmony_ci goto bad; 8778c2ecf20Sopenharmony_ci } 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci if (data_pad >= ubi->leb_size / 2) { 8808c2ecf20Sopenharmony_ci ubi_err(ubi, "bad data_pad"); 8818c2ecf20Sopenharmony_ci goto bad; 8828c2ecf20Sopenharmony_ci } 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci if (data_size > ubi->leb_size) { 8858c2ecf20Sopenharmony_ci ubi_err(ubi, "bad data_size"); 8868c2ecf20Sopenharmony_ci goto bad; 8878c2ecf20Sopenharmony_ci } 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci if (vol_type == UBI_VID_STATIC) { 8908c2ecf20Sopenharmony_ci /* 8918c2ecf20Sopenharmony_ci * Although from high-level point of view static volumes may 8928c2ecf20Sopenharmony_ci * contain zero bytes of data, but no VID headers can contain 8938c2ecf20Sopenharmony_ci * zero at these fields, because they empty volumes do not have 8948c2ecf20Sopenharmony_ci * mapped logical eraseblocks. 8958c2ecf20Sopenharmony_ci */ 8968c2ecf20Sopenharmony_ci if (used_ebs == 0) { 8978c2ecf20Sopenharmony_ci ubi_err(ubi, "zero used_ebs"); 8988c2ecf20Sopenharmony_ci goto bad; 8998c2ecf20Sopenharmony_ci } 9008c2ecf20Sopenharmony_ci if (data_size == 0) { 9018c2ecf20Sopenharmony_ci ubi_err(ubi, "zero data_size"); 9028c2ecf20Sopenharmony_ci goto bad; 9038c2ecf20Sopenharmony_ci } 9048c2ecf20Sopenharmony_ci if (lnum < used_ebs - 1) { 9058c2ecf20Sopenharmony_ci if (data_size != usable_leb_size) { 9068c2ecf20Sopenharmony_ci ubi_err(ubi, "bad data_size"); 9078c2ecf20Sopenharmony_ci goto bad; 9088c2ecf20Sopenharmony_ci } 9098c2ecf20Sopenharmony_ci } else if (lnum == used_ebs - 1) { 9108c2ecf20Sopenharmony_ci if (data_size == 0) { 9118c2ecf20Sopenharmony_ci ubi_err(ubi, "bad data_size at last LEB"); 9128c2ecf20Sopenharmony_ci goto bad; 9138c2ecf20Sopenharmony_ci } 9148c2ecf20Sopenharmony_ci } else { 9158c2ecf20Sopenharmony_ci ubi_err(ubi, "too high lnum"); 9168c2ecf20Sopenharmony_ci goto bad; 9178c2ecf20Sopenharmony_ci } 9188c2ecf20Sopenharmony_ci } else { 9198c2ecf20Sopenharmony_ci if (copy_flag == 0) { 9208c2ecf20Sopenharmony_ci if (data_crc != 0) { 9218c2ecf20Sopenharmony_ci ubi_err(ubi, "non-zero data CRC"); 9228c2ecf20Sopenharmony_ci goto bad; 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ci if (data_size != 0) { 9258c2ecf20Sopenharmony_ci ubi_err(ubi, "non-zero data_size"); 9268c2ecf20Sopenharmony_ci goto bad; 9278c2ecf20Sopenharmony_ci } 9288c2ecf20Sopenharmony_ci } else { 9298c2ecf20Sopenharmony_ci if (data_size == 0) { 9308c2ecf20Sopenharmony_ci ubi_err(ubi, "zero data_size of copy"); 9318c2ecf20Sopenharmony_ci goto bad; 9328c2ecf20Sopenharmony_ci } 9338c2ecf20Sopenharmony_ci } 9348c2ecf20Sopenharmony_ci if (used_ebs != 0) { 9358c2ecf20Sopenharmony_ci ubi_err(ubi, "bad used_ebs"); 9368c2ecf20Sopenharmony_ci goto bad; 9378c2ecf20Sopenharmony_ci } 9388c2ecf20Sopenharmony_ci } 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci return 0; 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_cibad: 9438c2ecf20Sopenharmony_ci ubi_err(ubi, "bad VID header"); 9448c2ecf20Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 9458c2ecf20Sopenharmony_ci dump_stack(); 9468c2ecf20Sopenharmony_ci return 1; 9478c2ecf20Sopenharmony_ci} 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_ci/** 9508c2ecf20Sopenharmony_ci * ubi_io_read_vid_hdr - read and check a volume identifier header. 9518c2ecf20Sopenharmony_ci * @ubi: UBI device description object 9528c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to read from 9538c2ecf20Sopenharmony_ci * @vidb: the volume identifier buffer to store data in 9548c2ecf20Sopenharmony_ci * @verbose: be verbose if the header is corrupted or wasn't found 9558c2ecf20Sopenharmony_ci * 9568c2ecf20Sopenharmony_ci * This function reads the volume identifier header from physical eraseblock 9578c2ecf20Sopenharmony_ci * @pnum and stores it in @vidb. It also checks CRC checksum of the read 9588c2ecf20Sopenharmony_ci * volume identifier header. The error codes are the same as in 9598c2ecf20Sopenharmony_ci * 'ubi_io_read_ec_hdr()'. 9608c2ecf20Sopenharmony_ci * 9618c2ecf20Sopenharmony_ci * Note, the implementation of this function is also very similar to 9628c2ecf20Sopenharmony_ci * 'ubi_io_read_ec_hdr()', so refer commentaries in 'ubi_io_read_ec_hdr()'. 9638c2ecf20Sopenharmony_ci */ 9648c2ecf20Sopenharmony_ciint ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, 9658c2ecf20Sopenharmony_ci struct ubi_vid_io_buf *vidb, int verbose) 9668c2ecf20Sopenharmony_ci{ 9678c2ecf20Sopenharmony_ci int err, read_err; 9688c2ecf20Sopenharmony_ci uint32_t crc, magic, hdr_crc; 9698c2ecf20Sopenharmony_ci struct ubi_vid_hdr *vid_hdr = ubi_get_vid_hdr(vidb); 9708c2ecf20Sopenharmony_ci void *p = vidb->buffer; 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci dbg_io("read VID header from PEB %d", pnum); 9738c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, 9768c2ecf20Sopenharmony_ci ubi->vid_hdr_shift + UBI_VID_HDR_SIZE); 9778c2ecf20Sopenharmony_ci if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) 9788c2ecf20Sopenharmony_ci return read_err; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci magic = be32_to_cpu(vid_hdr->magic); 9818c2ecf20Sopenharmony_ci if (magic != UBI_VID_HDR_MAGIC) { 9828c2ecf20Sopenharmony_ci if (mtd_is_eccerr(read_err)) 9838c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR_EBADMSG; 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_ci if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { 9868c2ecf20Sopenharmony_ci if (verbose) 9878c2ecf20Sopenharmony_ci ubi_warn(ubi, "no VID header found at PEB %d, only 0xFF bytes", 9888c2ecf20Sopenharmony_ci pnum); 9898c2ecf20Sopenharmony_ci dbg_bld("no VID header found at PEB %d, only 0xFF bytes", 9908c2ecf20Sopenharmony_ci pnum); 9918c2ecf20Sopenharmony_ci if (!read_err) 9928c2ecf20Sopenharmony_ci return UBI_IO_FF; 9938c2ecf20Sopenharmony_ci else 9948c2ecf20Sopenharmony_ci return UBI_IO_FF_BITFLIPS; 9958c2ecf20Sopenharmony_ci } 9968c2ecf20Sopenharmony_ci 9978c2ecf20Sopenharmony_ci if (verbose) { 9988c2ecf20Sopenharmony_ci ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", 9998c2ecf20Sopenharmony_ci pnum, magic, UBI_VID_HDR_MAGIC); 10008c2ecf20Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 10018c2ecf20Sopenharmony_ci } 10028c2ecf20Sopenharmony_ci dbg_bld("bad magic number at PEB %d: %08x instead of %08x", 10038c2ecf20Sopenharmony_ci pnum, magic, UBI_VID_HDR_MAGIC); 10048c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR; 10058c2ecf20Sopenharmony_ci } 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); 10088c2ecf20Sopenharmony_ci hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci if (hdr_crc != crc) { 10118c2ecf20Sopenharmony_ci if (verbose) { 10128c2ecf20Sopenharmony_ci ubi_warn(ubi, "bad CRC at PEB %d, calculated %#08x, read %#08x", 10138c2ecf20Sopenharmony_ci pnum, crc, hdr_crc); 10148c2ecf20Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 10158c2ecf20Sopenharmony_ci } 10168c2ecf20Sopenharmony_ci dbg_bld("bad CRC at PEB %d, calculated %#08x, read %#08x", 10178c2ecf20Sopenharmony_ci pnum, crc, hdr_crc); 10188c2ecf20Sopenharmony_ci if (!read_err) 10198c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR; 10208c2ecf20Sopenharmony_ci else 10218c2ecf20Sopenharmony_ci return UBI_IO_BAD_HDR_EBADMSG; 10228c2ecf20Sopenharmony_ci } 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ci err = validate_vid_hdr(ubi, vid_hdr); 10258c2ecf20Sopenharmony_ci if (err) { 10268c2ecf20Sopenharmony_ci ubi_err(ubi, "validation failed for PEB %d", pnum); 10278c2ecf20Sopenharmony_ci return -EINVAL; 10288c2ecf20Sopenharmony_ci } 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci return read_err ? UBI_IO_BITFLIPS : 0; 10318c2ecf20Sopenharmony_ci} 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci/** 10348c2ecf20Sopenharmony_ci * ubi_io_write_vid_hdr - write a volume identifier header. 10358c2ecf20Sopenharmony_ci * @ubi: UBI device description object 10368c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to write to 10378c2ecf20Sopenharmony_ci * @vidb: the volume identifier buffer to write 10388c2ecf20Sopenharmony_ci * 10398c2ecf20Sopenharmony_ci * This function writes the volume identifier header described by @vid_hdr to 10408c2ecf20Sopenharmony_ci * physical eraseblock @pnum. This function automatically fills the 10418c2ecf20Sopenharmony_ci * @vidb->hdr->magic and the @vidb->hdr->version fields, as well as calculates 10428c2ecf20Sopenharmony_ci * header CRC checksum and stores it at vidb->hdr->hdr_crc. 10438c2ecf20Sopenharmony_ci * 10448c2ecf20Sopenharmony_ci * This function returns zero in case of success and a negative error code in 10458c2ecf20Sopenharmony_ci * case of failure. If %-EIO is returned, the physical eraseblock probably went 10468c2ecf20Sopenharmony_ci * bad. 10478c2ecf20Sopenharmony_ci */ 10488c2ecf20Sopenharmony_ciint ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, 10498c2ecf20Sopenharmony_ci struct ubi_vid_io_buf *vidb) 10508c2ecf20Sopenharmony_ci{ 10518c2ecf20Sopenharmony_ci struct ubi_vid_hdr *vid_hdr = ubi_get_vid_hdr(vidb); 10528c2ecf20Sopenharmony_ci int err; 10538c2ecf20Sopenharmony_ci uint32_t crc; 10548c2ecf20Sopenharmony_ci void *p = vidb->buffer; 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci dbg_io("write VID header to PEB %d", pnum); 10578c2ecf20Sopenharmony_ci ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci err = self_check_peb_ec_hdr(ubi, pnum); 10608c2ecf20Sopenharmony_ci if (err) 10618c2ecf20Sopenharmony_ci return err; 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); 10648c2ecf20Sopenharmony_ci vid_hdr->version = UBI_VERSION; 10658c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); 10668c2ecf20Sopenharmony_ci vid_hdr->hdr_crc = cpu_to_be32(crc); 10678c2ecf20Sopenharmony_ci 10688c2ecf20Sopenharmony_ci err = self_check_vid_hdr(ubi, pnum, vid_hdr); 10698c2ecf20Sopenharmony_ci if (err) 10708c2ecf20Sopenharmony_ci return err; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci if (ubi_dbg_power_cut(ubi, POWER_CUT_VID_WRITE)) 10738c2ecf20Sopenharmony_ci return -EROFS; 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_ci err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, 10768c2ecf20Sopenharmony_ci ubi->vid_hdr_alsize); 10778c2ecf20Sopenharmony_ci return err; 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci/** 10818c2ecf20Sopenharmony_ci * self_check_not_bad - ensure that a physical eraseblock is not bad. 10828c2ecf20Sopenharmony_ci * @ubi: UBI device description object 10838c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number to check 10848c2ecf20Sopenharmony_ci * 10858c2ecf20Sopenharmony_ci * This function returns zero if the physical eraseblock is good, %-EINVAL if 10868c2ecf20Sopenharmony_ci * it is bad and a negative error code if an error occurred. 10878c2ecf20Sopenharmony_ci */ 10888c2ecf20Sopenharmony_cistatic int self_check_not_bad(const struct ubi_device *ubi, int pnum) 10898c2ecf20Sopenharmony_ci{ 10908c2ecf20Sopenharmony_ci int err; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 10938c2ecf20Sopenharmony_ci return 0; 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci err = ubi_io_is_bad(ubi, pnum); 10968c2ecf20Sopenharmony_ci if (!err) 10978c2ecf20Sopenharmony_ci return err; 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 11008c2ecf20Sopenharmony_ci dump_stack(); 11018c2ecf20Sopenharmony_ci return err > 0 ? -EINVAL : err; 11028c2ecf20Sopenharmony_ci} 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci/** 11058c2ecf20Sopenharmony_ci * self_check_ec_hdr - check if an erase counter header is all right. 11068c2ecf20Sopenharmony_ci * @ubi: UBI device description object 11078c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number the erase counter header belongs to 11088c2ecf20Sopenharmony_ci * @ec_hdr: the erase counter header to check 11098c2ecf20Sopenharmony_ci * 11108c2ecf20Sopenharmony_ci * This function returns zero if the erase counter header contains valid 11118c2ecf20Sopenharmony_ci * values, and %-EINVAL if not. 11128c2ecf20Sopenharmony_ci */ 11138c2ecf20Sopenharmony_cistatic int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, 11148c2ecf20Sopenharmony_ci const struct ubi_ec_hdr *ec_hdr) 11158c2ecf20Sopenharmony_ci{ 11168c2ecf20Sopenharmony_ci int err; 11178c2ecf20Sopenharmony_ci uint32_t magic; 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 11208c2ecf20Sopenharmony_ci return 0; 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci magic = be32_to_cpu(ec_hdr->magic); 11238c2ecf20Sopenharmony_ci if (magic != UBI_EC_HDR_MAGIC) { 11248c2ecf20Sopenharmony_ci ubi_err(ubi, "bad magic %#08x, must be %#08x", 11258c2ecf20Sopenharmony_ci magic, UBI_EC_HDR_MAGIC); 11268c2ecf20Sopenharmony_ci goto fail; 11278c2ecf20Sopenharmony_ci } 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci err = validate_ec_hdr(ubi, ec_hdr); 11308c2ecf20Sopenharmony_ci if (err) { 11318c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 11328c2ecf20Sopenharmony_ci goto fail; 11338c2ecf20Sopenharmony_ci } 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci return 0; 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_cifail: 11388c2ecf20Sopenharmony_ci ubi_dump_ec_hdr(ec_hdr); 11398c2ecf20Sopenharmony_ci dump_stack(); 11408c2ecf20Sopenharmony_ci return -EINVAL; 11418c2ecf20Sopenharmony_ci} 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ci/** 11448c2ecf20Sopenharmony_ci * self_check_peb_ec_hdr - check erase counter header. 11458c2ecf20Sopenharmony_ci * @ubi: UBI device description object 11468c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to check 11478c2ecf20Sopenharmony_ci * 11488c2ecf20Sopenharmony_ci * This function returns zero if the erase counter header is all right and and 11498c2ecf20Sopenharmony_ci * a negative error code if not or if an error occurred. 11508c2ecf20Sopenharmony_ci */ 11518c2ecf20Sopenharmony_cistatic int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) 11528c2ecf20Sopenharmony_ci{ 11538c2ecf20Sopenharmony_ci int err; 11548c2ecf20Sopenharmony_ci uint32_t crc, hdr_crc; 11558c2ecf20Sopenharmony_ci struct ubi_ec_hdr *ec_hdr; 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 11588c2ecf20Sopenharmony_ci return 0; 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_ci ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 11618c2ecf20Sopenharmony_ci if (!ec_hdr) 11628c2ecf20Sopenharmony_ci return -ENOMEM; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); 11658c2ecf20Sopenharmony_ci if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 11668c2ecf20Sopenharmony_ci goto exit; 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 11698c2ecf20Sopenharmony_ci hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); 11708c2ecf20Sopenharmony_ci if (hdr_crc != crc) { 11718c2ecf20Sopenharmony_ci ubi_err(ubi, "bad CRC, calculated %#08x, read %#08x", 11728c2ecf20Sopenharmony_ci crc, hdr_crc); 11738c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 11748c2ecf20Sopenharmony_ci ubi_dump_ec_hdr(ec_hdr); 11758c2ecf20Sopenharmony_ci dump_stack(); 11768c2ecf20Sopenharmony_ci err = -EINVAL; 11778c2ecf20Sopenharmony_ci goto exit; 11788c2ecf20Sopenharmony_ci } 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci err = self_check_ec_hdr(ubi, pnum, ec_hdr); 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ciexit: 11838c2ecf20Sopenharmony_ci kfree(ec_hdr); 11848c2ecf20Sopenharmony_ci return err; 11858c2ecf20Sopenharmony_ci} 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci/** 11888c2ecf20Sopenharmony_ci * self_check_vid_hdr - check that a volume identifier header is all right. 11898c2ecf20Sopenharmony_ci * @ubi: UBI device description object 11908c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number the volume identifier header belongs to 11918c2ecf20Sopenharmony_ci * @vid_hdr: the volume identifier header to check 11928c2ecf20Sopenharmony_ci * 11938c2ecf20Sopenharmony_ci * This function returns zero if the volume identifier header is all right, and 11948c2ecf20Sopenharmony_ci * %-EINVAL if not. 11958c2ecf20Sopenharmony_ci */ 11968c2ecf20Sopenharmony_cistatic int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, 11978c2ecf20Sopenharmony_ci const struct ubi_vid_hdr *vid_hdr) 11988c2ecf20Sopenharmony_ci{ 11998c2ecf20Sopenharmony_ci int err; 12008c2ecf20Sopenharmony_ci uint32_t magic; 12018c2ecf20Sopenharmony_ci 12028c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 12038c2ecf20Sopenharmony_ci return 0; 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci magic = be32_to_cpu(vid_hdr->magic); 12068c2ecf20Sopenharmony_ci if (magic != UBI_VID_HDR_MAGIC) { 12078c2ecf20Sopenharmony_ci ubi_err(ubi, "bad VID header magic %#08x at PEB %d, must be %#08x", 12088c2ecf20Sopenharmony_ci magic, pnum, UBI_VID_HDR_MAGIC); 12098c2ecf20Sopenharmony_ci goto fail; 12108c2ecf20Sopenharmony_ci } 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci err = validate_vid_hdr(ubi, vid_hdr); 12138c2ecf20Sopenharmony_ci if (err) { 12148c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 12158c2ecf20Sopenharmony_ci goto fail; 12168c2ecf20Sopenharmony_ci } 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci return err; 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_cifail: 12218c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 12228c2ecf20Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 12238c2ecf20Sopenharmony_ci dump_stack(); 12248c2ecf20Sopenharmony_ci return -EINVAL; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci} 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci/** 12298c2ecf20Sopenharmony_ci * self_check_peb_vid_hdr - check volume identifier header. 12308c2ecf20Sopenharmony_ci * @ubi: UBI device description object 12318c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to check 12328c2ecf20Sopenharmony_ci * 12338c2ecf20Sopenharmony_ci * This function returns zero if the volume identifier header is all right, 12348c2ecf20Sopenharmony_ci * and a negative error code if not or if an error occurred. 12358c2ecf20Sopenharmony_ci */ 12368c2ecf20Sopenharmony_cistatic int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) 12378c2ecf20Sopenharmony_ci{ 12388c2ecf20Sopenharmony_ci int err; 12398c2ecf20Sopenharmony_ci uint32_t crc, hdr_crc; 12408c2ecf20Sopenharmony_ci struct ubi_vid_io_buf *vidb; 12418c2ecf20Sopenharmony_ci struct ubi_vid_hdr *vid_hdr; 12428c2ecf20Sopenharmony_ci void *p; 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 12458c2ecf20Sopenharmony_ci return 0; 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS); 12488c2ecf20Sopenharmony_ci if (!vidb) 12498c2ecf20Sopenharmony_ci return -ENOMEM; 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci vid_hdr = ubi_get_vid_hdr(vidb); 12528c2ecf20Sopenharmony_ci p = vidb->buffer; 12538c2ecf20Sopenharmony_ci err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, 12548c2ecf20Sopenharmony_ci ubi->vid_hdr_alsize); 12558c2ecf20Sopenharmony_ci if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 12568c2ecf20Sopenharmony_ci goto exit; 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); 12598c2ecf20Sopenharmony_ci hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); 12608c2ecf20Sopenharmony_ci if (hdr_crc != crc) { 12618c2ecf20Sopenharmony_ci ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x", 12628c2ecf20Sopenharmony_ci pnum, crc, hdr_crc); 12638c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 12648c2ecf20Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 12658c2ecf20Sopenharmony_ci dump_stack(); 12668c2ecf20Sopenharmony_ci err = -EINVAL; 12678c2ecf20Sopenharmony_ci goto exit; 12688c2ecf20Sopenharmony_ci } 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci err = self_check_vid_hdr(ubi, pnum, vid_hdr); 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ciexit: 12738c2ecf20Sopenharmony_ci ubi_free_vid_buf(vidb); 12748c2ecf20Sopenharmony_ci return err; 12758c2ecf20Sopenharmony_ci} 12768c2ecf20Sopenharmony_ci 12778c2ecf20Sopenharmony_ci/** 12788c2ecf20Sopenharmony_ci * self_check_write - make sure write succeeded. 12798c2ecf20Sopenharmony_ci * @ubi: UBI device description object 12808c2ecf20Sopenharmony_ci * @buf: buffer with data which were written 12818c2ecf20Sopenharmony_ci * @pnum: physical eraseblock number the data were written to 12828c2ecf20Sopenharmony_ci * @offset: offset within the physical eraseblock the data were written to 12838c2ecf20Sopenharmony_ci * @len: how many bytes were written 12848c2ecf20Sopenharmony_ci * 12858c2ecf20Sopenharmony_ci * This functions reads data which were recently written and compares it with 12868c2ecf20Sopenharmony_ci * the original data buffer - the data have to match. Returns zero if the data 12878c2ecf20Sopenharmony_ci * match and a negative error code if not or in case of failure. 12888c2ecf20Sopenharmony_ci */ 12898c2ecf20Sopenharmony_cistatic int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, 12908c2ecf20Sopenharmony_ci int offset, int len) 12918c2ecf20Sopenharmony_ci{ 12928c2ecf20Sopenharmony_ci int err, i; 12938c2ecf20Sopenharmony_ci size_t read; 12948c2ecf20Sopenharmony_ci void *buf1; 12958c2ecf20Sopenharmony_ci loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 12988c2ecf20Sopenharmony_ci return 0; 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci buf1 = __vmalloc(len, GFP_NOFS); 13018c2ecf20Sopenharmony_ci if (!buf1) { 13028c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot allocate memory to check writes"); 13038c2ecf20Sopenharmony_ci return 0; 13048c2ecf20Sopenharmony_ci } 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci err = mtd_read(ubi->mtd, addr, len, &read, buf1); 13078c2ecf20Sopenharmony_ci if (err && !mtd_is_bitflip(err)) 13088c2ecf20Sopenharmony_ci goto out_free; 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) { 13118c2ecf20Sopenharmony_ci uint8_t c = ((uint8_t *)buf)[i]; 13128c2ecf20Sopenharmony_ci uint8_t c1 = ((uint8_t *)buf1)[i]; 13138c2ecf20Sopenharmony_ci int dump_len; 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci if (c == c1) 13168c2ecf20Sopenharmony_ci continue; 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d:%d, len %d", 13198c2ecf20Sopenharmony_ci pnum, offset, len); 13208c2ecf20Sopenharmony_ci ubi_msg(ubi, "data differ at position %d", i); 13218c2ecf20Sopenharmony_ci dump_len = max_t(int, 128, len - i); 13228c2ecf20Sopenharmony_ci ubi_msg(ubi, "hex dump of the original buffer from %d to %d", 13238c2ecf20Sopenharmony_ci i, i + dump_len); 13248c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 13258c2ecf20Sopenharmony_ci buf + i, dump_len, 1); 13268c2ecf20Sopenharmony_ci ubi_msg(ubi, "hex dump of the read buffer from %d to %d", 13278c2ecf20Sopenharmony_ci i, i + dump_len); 13288c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 13298c2ecf20Sopenharmony_ci buf1 + i, dump_len, 1); 13308c2ecf20Sopenharmony_ci dump_stack(); 13318c2ecf20Sopenharmony_ci err = -EINVAL; 13328c2ecf20Sopenharmony_ci goto out_free; 13338c2ecf20Sopenharmony_ci } 13348c2ecf20Sopenharmony_ci 13358c2ecf20Sopenharmony_ci vfree(buf1); 13368c2ecf20Sopenharmony_ci return 0; 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_ciout_free: 13398c2ecf20Sopenharmony_ci vfree(buf1); 13408c2ecf20Sopenharmony_ci return err; 13418c2ecf20Sopenharmony_ci} 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci/** 13448c2ecf20Sopenharmony_ci * ubi_self_check_all_ff - check that a region of flash is empty. 13458c2ecf20Sopenharmony_ci * @ubi: UBI device description object 13468c2ecf20Sopenharmony_ci * @pnum: the physical eraseblock number to check 13478c2ecf20Sopenharmony_ci * @offset: the starting offset within the physical eraseblock to check 13488c2ecf20Sopenharmony_ci * @len: the length of the region to check 13498c2ecf20Sopenharmony_ci * 13508c2ecf20Sopenharmony_ci * This function returns zero if only 0xFF bytes are present at offset 13518c2ecf20Sopenharmony_ci * @offset of the physical eraseblock @pnum, and a negative error code if not 13528c2ecf20Sopenharmony_ci * or if an error occurred. 13538c2ecf20Sopenharmony_ci */ 13548c2ecf20Sopenharmony_ciint ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) 13558c2ecf20Sopenharmony_ci{ 13568c2ecf20Sopenharmony_ci size_t read; 13578c2ecf20Sopenharmony_ci int err; 13588c2ecf20Sopenharmony_ci void *buf; 13598c2ecf20Sopenharmony_ci loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci if (!ubi_dbg_chk_io(ubi)) 13628c2ecf20Sopenharmony_ci return 0; 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_ci buf = __vmalloc(len, GFP_NOFS); 13658c2ecf20Sopenharmony_ci if (!buf) { 13668c2ecf20Sopenharmony_ci ubi_err(ubi, "cannot allocate memory to check for 0xFFs"); 13678c2ecf20Sopenharmony_ci return 0; 13688c2ecf20Sopenharmony_ci } 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci err = mtd_read(ubi->mtd, addr, len, &read, buf); 13718c2ecf20Sopenharmony_ci if (err && !mtd_is_bitflip(err)) { 13728c2ecf20Sopenharmony_ci ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", 13738c2ecf20Sopenharmony_ci err, len, pnum, offset, read); 13748c2ecf20Sopenharmony_ci goto error; 13758c2ecf20Sopenharmony_ci } 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci err = ubi_check_pattern(buf, 0xFF, len); 13788c2ecf20Sopenharmony_ci if (err == 0) { 13798c2ecf20Sopenharmony_ci ubi_err(ubi, "flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", 13808c2ecf20Sopenharmony_ci pnum, offset, len); 13818c2ecf20Sopenharmony_ci goto fail; 13828c2ecf20Sopenharmony_ci } 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci vfree(buf); 13858c2ecf20Sopenharmony_ci return 0; 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_cifail: 13888c2ecf20Sopenharmony_ci ubi_err(ubi, "self-check failed for PEB %d", pnum); 13898c2ecf20Sopenharmony_ci ubi_msg(ubi, "hex dump of the %d-%d region", offset, offset + len); 13908c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); 13918c2ecf20Sopenharmony_ci err = -EINVAL; 13928c2ecf20Sopenharmony_cierror: 13938c2ecf20Sopenharmony_ci dump_stack(); 13948c2ecf20Sopenharmony_ci vfree(buf); 13958c2ecf20Sopenharmony_ci return err; 13968c2ecf20Sopenharmony_ci} 1397