1801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* 2801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Copyright (c) International Business Machines Corp., 2006 3801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Copyright (c) Nokia Corporation, 2006, 2007 4801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 5801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This program is free software; you can redistribute it and/or modify 6801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * it under the terms of the GNU General Public License as published by 7801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the Free Software Foundation; either version 2 of the License, or 8801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * (at your option) any later version. 9801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 10801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This program is distributed in the hope that it will be useful, 11801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * but WITHOUT ANY WARRANTY; without even the implied warranty of 12801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the GNU General Public License for more details. 14801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 15801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * You should have received a copy of the GNU General Public License 16801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * along with this program; if not, write to the Free Software 17801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 19801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Author: Artem Bityutskiy (Битюцкий Артём) 20801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 21801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 22801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* 2385c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * UBI input/output sub-system. 24801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 2585c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * This sub-system provides a uniform way to work with all kinds of the 2685c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * underlying MTD devices. It also implements handy functions for reading and 2785c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * writing UBI headers. 28801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 29801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * We are trying to have a paranoid mindset and not to trust to what we read 3085c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * from the flash media in order to be more secure and robust. So this 3185c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * sub-system validates every single header it reads from the flash media. 32801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 33801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Some words about how the eraseblock headers are stored. 34801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 35801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The erase counter header is always stored at offset zero. By default, the 36801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * VID header is stored after the EC header at the closest aligned offset 37801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * (i.e. aligned to the minimum I/O unit size). Data starts next to the VID 38801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * header at the closest aligned offset. But this default layout may be 39801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * changed. For example, for different reasons (e.g., optimization) UBI may be 40801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * asked to put the VID header at further offset, and even at an unaligned 41801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * offset. Of course, if the offset of the VID header is unaligned, UBI adds 42801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * proper padding in front of it. Data offset may also be changed but it has to 43801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * be aligned. 44801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 45801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * About minimal I/O units. In general, UBI assumes flash device model where 46801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * there is only one minimal I/O unit size. E.g., in case of NOR flash it is 1, 47801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * in case of NAND flash it is a NAND page, etc. This is reported by MTD in the 48801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi->mtd->writesize field. But as an exception, UBI admits of using another 49801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * (smaller) minimal I/O unit size for EC and VID headers to make it possible 50801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to do different optimizations. 51801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 52801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This is extremely useful in case of NAND flashes which admit of several 53801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * write operations to one NAND page. In this case UBI can fit EC and VID 54801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * headers at one NAND page. Thus, UBI may use "sub-page" size as the minimal 55801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * I/O unit for the headers (the @ubi->hdrs_min_io_size field). But it still 56801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * reports NAND page size (@ubi->min_io_size) as a minimal I/O unit for the UBI 57801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * users. 58801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 59801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Example: some Samsung NANDs with 2KiB pages allow 4x 512-byte writes, so 60801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * although the minimal I/O unit is 2K, UBI uses 512 bytes for EC and VID 61801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * headers. 62801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 63801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Q: why not just to treat sub-page as a minimal I/O unit of this flash 64801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * device, e.g., make @ubi->min_io_size = 512 in the example above? 65801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 66801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * A: because when writing a sub-page, MTD still writes a full 2K page but the 67be436f6238a17b8432b9de0212bcfc838afb1f85Shinya Kuribayashi * bytes which are not relevant to the sub-page are 0xFF. So, basically, 68be436f6238a17b8432b9de0212bcfc838afb1f85Shinya Kuribayashi * writing 4x512 sub-pages is 4 times slower than writing one 2KiB NAND page. 69be436f6238a17b8432b9de0212bcfc838afb1f85Shinya Kuribayashi * Thus, we prefer to use sub-pages only for EC and VID headers. 70801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 71801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * As it was noted above, the VID header may start at a non-aligned offset. 72801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * For example, in case of a 2KiB page NAND flash with a 512 bytes sub-page, 73801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the VID header may reside at offset 1984 which is the last 64 bytes of the 74801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * last sub-page (EC header is always at offset zero). This causes some 75801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * difficulties when reading and writing VID headers. 76801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 77801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Suppose we have a 64-byte buffer and we read a VID header at it. We change 78801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the data and want to write this VID header out. As we can only write in 79801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 512-byte chunks, we have to allocate one more buffer and copy our VID header 80801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to offset 448 of this buffer. 81801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 8285c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * The I/O sub-system does the following trick in order to avoid this extra 8385c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * copy. It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID 8485c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * header and returns a pointer to offset @ubi->vid_hdr_shift of this buffer. 8585c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * When the VID header is being written out, it shifts the VID header pointer 8685c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * back and writes the whole sub-page. 87801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 88801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 89801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include <linux/crc32.h> 90801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include <linux/err.h> 915a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 92801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include "ubi.h" 93801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 9492d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy#ifdef CONFIG_MTD_UBI_DEBUG 95801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); 96801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); 97801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, 98801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_ec_hdr *ec_hdr); 99801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); 100801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, 101801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_vid_hdr *vid_hdr); 102801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#else 103801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#define paranoid_check_not_bad(ubi, pnum) 0 104801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#define paranoid_check_peb_ec_hdr(ubi, pnum) 0 105801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 106801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#define paranoid_check_peb_vid_hdr(ubi, pnum) 0 107801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 108801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#endif 109801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 110801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 111801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_read - read data from a physical eraseblock. 112801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 113801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: buffer where to store the read data 114801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number to read from 115801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: offset within the physical eraseblock from where to read 116801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to read 117801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 118801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function reads data from offset @offset of physical eraseblock @pnum 119801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * and stores the read data in the @buf buffer. The following return codes are 120801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * possible: 121801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 122801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o %0 if all the requested data were successfully read; 123801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but 124801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * correctable bit-flips were detected; this is harmless but may indicate 125801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * that this eraseblock may become bad soon (but do not have to); 12663b6c1ed56f69fdd35122dc591164587e3407ba0Artem Bityutskiy * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for 12763b6c1ed56f69fdd35122dc591164587e3407ba0Artem Bityutskiy * example it can be an ECC error in case of NAND; this most probably means 12863b6c1ed56f69fdd35122dc591164587e3407ba0Artem Bityutskiy * that the data is corrupted; 129801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o %-EIO if some I/O error occurred; 130801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o other negative error codes in case of other errors. 131801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 132801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyint ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, 133801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int len) 134801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 135801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err, retries = 0; 136801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy size_t read; 137801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy loff_t addr; 138801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 139801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); 140801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 141801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 142801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); 143801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(len > 0); 144801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 145801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_not_bad(ubi, pnum); 146801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 147adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 148801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 149276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy /* 150276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * Deliberately corrupt the buffer to improve robustness. Indeed, if we 151276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * do not do this, the following may happen: 152276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * 1. The buffer contains data from previous operation, e.g., read from 153276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * another PEB previously. The data looks like expected, e.g., if we 154276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * just do not read anything and return - the caller would not 155276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * notice this. E.g., if we are reading a VID header, the buffer may 156276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * contain a valid VID header from another PEB. 157276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * 2. The driver is buggy and returns us success or -EBADMSG or 158276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * -EUCLEAN, but it does not actually put any data to the buffer. 159276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * 160276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * This may confuse UBI or upper layers - they may think the buffer 161276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * contains valid data while in fact it is just old data. This is 162276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * especially possible because UBI (and UBIFS) relies on CRC, and 163276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * treats data as correct even in case of ECC errors if the CRC is 164276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * correct. 165276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * 166276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * Try to prevent this situation by changing the first byte of the 167276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy * buffer. 168276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy */ 169276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy *((uint8_t *)buf) ^= 0xFF; 170276832d878d8a892ac7b40fd0ee07fe757e080c7Artem Bityutskiy 171801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy addr = (loff_t)pnum * ubi->peb_size + offset; 172801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 173329ad399a9b3adf52c90637b21ca029fcf7f8795Artem Bityutskiy err = mtd_read(ubi->mtd, addr, len, &read, buf); 174801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 175d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : ""; 1761a49af2ca019dcb4614c32f832bbcb814b61409cArtem Bityutskiy 177d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (mtd_is_bitflip(err)) { 178801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 179801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * -EUCLEAN is reported if there was a bit-flip which 180801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * was corrected, so this is harmless. 1818c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy * 1828c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy * We do not report about it here unless debugging is 1838c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy * enabled. A corresponding message will be printed 1848c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy * later, when it is has been scrubbed. 185801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1868c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy dbg_msg("fixable bit-flip detected at PEB %d", pnum); 187801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(len == read); 188801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return UBI_IO_BITFLIPS; 189801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 190801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 191a87f29cbbcbd5bd1e4990367cd18967e9bbeacffArtem Bityutskiy if (retries++ < UBI_IO_RETRIES) { 192feddbb34ebd75e9b6bf573b852079e327a88c07aArtem Bityutskiy dbg_io("error %d%s while reading %d bytes from PEB " 193feddbb34ebd75e9b6bf573b852079e327a88c07aArtem Bityutskiy "%d:%d, read only %zd bytes, retry", 1941a49af2ca019dcb4614c32f832bbcb814b61409cArtem Bityutskiy err, errstr, len, pnum, offset, read); 195801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy yield(); 196801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 197801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 198801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 199f5d5b1f8c12a7637ee1145f2f00358eb375edb54Artem Bityutskiy ubi_err("error %d%s while reading %d bytes from PEB %d:%d, " 2001a49af2ca019dcb4614c32f832bbcb814b61409cArtem Bityutskiy "read %zd bytes", err, errstr, len, pnum, offset, read); 201801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 2022362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy 2032362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy /* 2042362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy * The driver should never return -EBADMSG if it failed to read 2052362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy * all the requested data. But some buggy drivers might do 2062362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy * this, so we change it to -EIO. 2072362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy */ 208d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (read != len && mtd_is_eccerr(err)) { 2092362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy ubi_assert(0); 2102362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy err = -EIO; 2112362a53ec59f286495307e0e0d8ef2401e8c5c49Artem Bityutskiy } 212801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else { 213801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(len == read); 214801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 21527a0f2a37aa46cb0174decddf8830715e5f1645aArtem Bityutskiy if (ubi_dbg_is_bitflip(ubi)) { 216c8566350a3229ca505b84313c65d1403b4d0cbfcArtem Bityutskiy dbg_gen("bit-flip (emulated)"); 217801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = UBI_IO_BITFLIPS; 218801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 219801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 220801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 221801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 222801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 223801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 224801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 225801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_write - write data to a physical eraseblock. 226801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 227801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: buffer with the data to write 228801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number to write to 229801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: offset within the physical eraseblock where to write 230801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to write 231801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 232801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function writes @len bytes of data from buffer @buf to offset @offset 233801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * of physical eraseblock @pnum. If all the data were successfully written, 234801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * zero is returned. If an error occurred, this function returns a negative 235801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * error code. If %-EIO is returned, the physical eraseblock most probably went 236801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * bad. 237801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 238801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Note, in case of an error, it is possible that something was still written 239801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to the flash media, but may be some garbage. 240801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 241e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, 242e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy int len) 243801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 244801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 245801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy size_t written; 246801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy loff_t addr; 247801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 248801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("write %d bytes to PEB %d:%d", len, pnum, offset); 249801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 250801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 251801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); 252801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(offset % ubi->hdrs_min_io_size == 0); 253801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); 254801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 255801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) { 256801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("read-only mode"); 257801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 258801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 259801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 260801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* The below has to be compiled out if paranoid checks are disabled */ 261801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 262801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_not_bad(ubi, pnum); 263801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 264adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 265801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 266801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* The area we are writing to has to contain all 0xFF bytes */ 26740a71a87fa8e0cb3ec0fca4d152263734b203eb2Artem Bityutskiy err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); 268801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 269adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 270801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 271801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (offset >= ubi->leb_start) { 272801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 273801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * We write to the data area of the physical eraseblock. Make 274801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * sure it has valid EC and VID headers. 275801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 276801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_peb_ec_hdr(ubi, pnum); 277801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 278adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 279801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_peb_vid_hdr(ubi, pnum); 280801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 281adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 282801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 283801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 28427a0f2a37aa46cb0174decddf8830715e5f1645aArtem Bityutskiy if (ubi_dbg_is_write_failure(ubi)) { 285801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("cannot write %d bytes to PEB %d:%d " 286801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "(emulated)", len, pnum, offset); 287801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 288801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EIO; 289801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 290801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 291801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy addr = (loff_t)pnum * ubi->peb_size + offset; 292eda95cbf75193808f62948fb0142ba0901d8bee2Artem Bityutskiy err = mtd_write(ubi->mtd, addr, len, &written, buf); 293801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 294ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy ubi_err("error %d while writing %d bytes to PEB %d:%d, written " 295ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy "%zd bytes", err, len, pnum, offset, written); 296801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 297867996b15c1f0a98d2c405bada907e97499ba8c2Artem Bityutskiy ubi_dbg_dump_flash(ubi, pnum, offset, len); 298801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else 299801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(written == len); 300801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 3016e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy if (!err) { 3026e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy err = ubi_dbg_check_write(ubi, buf, pnum, offset, len); 3036e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy if (err) 3046e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy return err; 3056e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 3066e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy /* 3076e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * Since we always write sequentially, the rest of the PEB has 3086e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * to contain only 0xFF bytes. 3096e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy */ 3106e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy offset += len; 3116e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy len = ubi->peb_size - offset; 3126e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy if (len) 3136e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); 3146e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy } 3156e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 316801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 317801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 318801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 319801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 320801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * erase_callback - MTD erasure call-back. 321801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ei: MTD erase information object. 322801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 323801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Note, even though MTD erase interface is asynchronous, all the current 324801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * implementations are synchronous anyway. 325801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 326801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic void erase_callback(struct erase_info *ei) 327801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 328801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy wake_up_interruptible((wait_queue_head_t *)ei->priv); 329801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 330801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 331801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 332801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * do_sync_erase - synchronously erase a physical eraseblock. 333801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 334801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to erase 335801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 336801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function synchronously erases physical eraseblock @pnum and returns 337801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * zero in case of success and a negative error code in case of failure. If 338801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * %-EIO is returned, the physical eraseblock most probably went bad. 339801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 340e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiystatic int do_sync_erase(struct ubi_device *ubi, int pnum) 341801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 342801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err, retries = 0; 343801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct erase_info ei; 344801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy wait_queue_head_t wq; 345801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 346801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("erase PEB %d", pnum); 3473efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 3483efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy 3493efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy if (ubi->ro_mode) { 3503efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy ubi_err("read-only mode"); 3513efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy return -EROFS; 3523efe509070e3d27e6d5dbc4bf8588e9453e9b949Artem Bityutskiy } 353801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 354801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 355801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy init_waitqueue_head(&wq); 356801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy memset(&ei, 0, sizeof(struct erase_info)); 357801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 358801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ei.mtd = ubi->mtd; 3592f176f79877937082ce052977e552a75e23a73d1Brijesh Singh ei.addr = (loff_t)pnum * ubi->peb_size; 360801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ei.len = ubi->peb_size; 361801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ei.callback = erase_callback; 362801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ei.priv = (unsigned long)&wq; 363801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 3647e1f0dc0551b99acb5e8fa161a7ac401994d57d8Artem Bityutskiy err = mtd_erase(ubi->mtd, &ei); 365801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 366801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (retries++ < UBI_IO_RETRIES) { 367801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("error %d while erasing PEB %d, retry", 368801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err, pnum); 369801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy yield(); 370801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 371801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 372801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("cannot erase PEB %d, error %d", pnum, err); 373801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 374801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 375801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 376801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 377801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE || 378801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ei.state == MTD_ERASE_FAILED); 379801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 380801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("interrupted PEB %d erasure", pnum); 381801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EINTR; 382801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 383801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 384801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ei.state == MTD_ERASE_FAILED) { 385801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (retries++ < UBI_IO_RETRIES) { 386801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("error while erasing PEB %d, retry", pnum); 387801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy yield(); 388801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 389801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 390801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("cannot erase PEB %d", pnum); 391801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 392801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EIO; 393801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 394801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 39540a71a87fa8e0cb3ec0fca4d152263734b203eb2Artem Bityutskiy err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); 396801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 397adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 398801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 39927a0f2a37aa46cb0174decddf8830715e5f1645aArtem Bityutskiy if (ubi_dbg_is_erase_failure(ubi)) { 400801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("cannot erase PEB %d (emulated)", pnum); 401801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EIO; 402801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 403801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 404801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 405801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 406801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 407801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* Patterns to write to a physical eraseblock when torturing it */ 408801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic uint8_t patterns[] = {0xa5, 0x5a, 0x0}; 409801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 410801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 411801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * torture_peb - test a supposedly bad physical eraseblock. 412801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 413801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to test 414801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 415801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns %-EIO if the physical eraseblock did not pass the 416801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * test, a positive number of erase operations done if the test was 417801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * successfully passed, and other negative error codes in case of other errors. 418801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 419e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiystatic int torture_peb(struct ubi_device *ubi, int pnum) 420801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 421801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err, i, patt_count; 422801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 4238c1e6ee10bd87d70faada065a8d1f70732c17382Artem Bityutskiy ubi_msg("run torture test for PEB %d", pnum); 424801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy patt_count = ARRAY_SIZE(patterns); 425801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(patt_count > 0); 426801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 427e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy mutex_lock(&ubi->buf_mutex); 428801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy for (i = 0; i < patt_count; i++) { 429801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = do_sync_erase(ubi, pnum); 430801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 431801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 432801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 433801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* Make sure the PEB contains only 0xFF bytes */ 434e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); 435801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 436801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 437801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 438bb00e180a93a6c8e89c3b2d1f9473781e1e2d2a4Artem Bityutskiy err = ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); 439801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err == 0) { 440801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("erased PEB %d, but a non-0xFF byte found", 441801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum); 442801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EIO; 443801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 444801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 445801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 446801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* Write a pattern and check it */ 447e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy memset(ubi->peb_buf1, patterns[i], ubi->peb_size); 448e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); 449801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 450801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 451801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 452e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); 453e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); 454801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 455801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 456801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 457bb00e180a93a6c8e89c3b2d1f9473781e1e2d2a4Artem Bityutskiy err = ubi_check_pattern(ubi->peb_buf1, patterns[i], 458bb00e180a93a6c8e89c3b2d1f9473781e1e2d2a4Artem Bityutskiy ubi->peb_size); 459801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err == 0) { 460801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("pattern %x checking failed for PEB %d", 461801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy patterns[i], pnum); 462801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EIO; 463801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out; 464801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 465801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 466801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 467801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = patt_count; 4681426414431a8d37a6e631e0b5e2ad6186b81876aArtem Bityutskiy ubi_msg("PEB %d passed torture test, do not mark it as bad", pnum); 469801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 470801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyout: 471e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy mutex_unlock(&ubi->buf_mutex); 472d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { 473801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 474801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * If a bit-flip or data integrity error was detected, the test 475801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * has not passed because it happened on a freshly erased 476801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * physical eraseblock which means something is wrong with it. 477801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 4788d2d4011f1398d984819c65043abb559c451a3c8Artem Bityutskiy ubi_err("read problems on freshly erased PEB %d, must be bad", 4798d2d4011f1398d984819c65043abb559c451a3c8Artem Bityutskiy pnum); 480801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EIO; 4818d2d4011f1398d984819c65043abb559c451a3c8Artem Bityutskiy } 482801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 483801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 484801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 485801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 486ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * nor_erase_prepare - prepare a NOR flash PEB for erasure. 487ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * @ubi: UBI device description object 488ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * @pnum: physical eraseblock number to prepare 489ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * 490ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * NOR flash, or at least some of them, have peculiar embedded PEB erasure 491ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * algorithm: the PEB is first filled with zeroes, then it is erased. And 492ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * filling with zeroes starts from the end of the PEB. This was observed with 493ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * Spansion S29GL512N NOR flash. 494ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * 495ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * This means that in case of a power cut we may end up with intact data at the 496ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * beginning of the PEB, and all zeroes at the end of PEB. In other words, the 497ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * EC and VID headers are OK, but a large chunk of data at the end of PEB is 498ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * zeroed. This makes UBI mistakenly treat this PEB as used and associate it 499ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). 500ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * 501ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * This function is called before erasing NOR PEBs and it zeroes out EC and VID 502ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * magic numbers in order to invalidate them and prevent the failures. Returns 503ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy * zero in case of success and a negative error code in case of failure. 504ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy */ 505ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiystatic int nor_erase_prepare(struct ubi_device *ubi, int pnum) 506ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy{ 507de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy int err, err1; 508ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy size_t written; 509ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy loff_t addr; 510ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy uint32_t data = 0; 5112fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy /* 5122fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy * Note, we cannot generally define VID header buffers on stack, 5132fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy * because of the way we deal with these buffers (see the header 5142fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy * comment in this file). But we know this is a NOR-specific piece of 5152fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy * code, so we can do this. But yes, this is error-prone and we should 5162fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy * (pre-)allocate VID header buffer instead. 5172fff570e7c8f97e411cd852d64b77b92d9ab8da9Artem Bityutskiy */ 518de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy struct ubi_vid_hdr vid_hdr; 519ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy 5207ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy /* 5217ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * It is important to first invalidate the EC header, and then the VID 5227ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * header. Otherwise a power cut may lead to valid EC header and 5237ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * invalid VID header, in which case UBI will treat this PEB as 5247ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * corrupted and will try to preserve it, and print scary warnings (see 5257ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * the header comment in scan.c for more information). 5267ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy */ 5277ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy addr = (loff_t)pnum * ubi->peb_size; 528eda95cbf75193808f62948fb0142ba0901d8bee2Artem Bityutskiy err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); 529de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy if (!err) { 5307ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy addr += ubi->vid_hdr_aloffset; 531eda95cbf75193808f62948fb0142ba0901d8bee2Artem Bityutskiy err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); 532de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy if (!err) 533de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy return 0; 534ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy } 535ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy 536de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy /* 537de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy * We failed to write to the media. This was observed with Spansion 5387ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * S29GL512N NOR flash. Most probably the previously eraseblock erasure 5397ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * was interrupted at a very inappropriate moment, so it became 5407ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * unwritable. In this case we probably anyway have garbage in this 5417ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * PEB. 542de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy */ 543de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); 544d4c6381303163e774a72db8c172cdc5c23f01588Holger Brunck if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || 545d4c6381303163e774a72db8c172cdc5c23f01588Holger Brunck err1 == UBI_IO_FF) { 5467ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy struct ubi_ec_hdr ec_hdr; 5477ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy 5487ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); 549d4c6381303163e774a72db8c172cdc5c23f01588Holger Brunck if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || 550d4c6381303163e774a72db8c172cdc5c23f01588Holger Brunck err1 == UBI_IO_FF) 5517ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy /* 5527ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * Both VID and EC headers are corrupted, so we can 5537ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * safely erase this PEB and not afraid that it will be 5547ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy * treated as a valid PEB in case of an unclean reboot. 5557ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy */ 5567ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy return 0; 5577ac760c2f78ddd8e1bd633767b01becfbbf96720Artem Bityutskiy } 558de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy 559de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy /* 560de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy * The PEB contains a valid VID header, but we cannot invalidate it. 561de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy * Supposedly the flash media or the driver is screwed up, so return an 562de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy * error. 563de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy */ 564de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", 565de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy pnum, err, err1); 566de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size); 567de75c771b4cc4da963164a538a8448128301bc35Artem Bityutskiy return -EIO; 568ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy} 569ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy 570ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy/** 571801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_sync_erase - synchronously erase a physical eraseblock. 572801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 573801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number to erase 574801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @torture: if this physical eraseblock has to be tortured 575801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 576801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function synchronously erases physical eraseblock @pnum. If @torture 577801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * flag is not zero, the physical eraseblock is checked by means of writing 578801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * different patterns to it and reading them back. If the torturing is enabled, 579025dfdafe77f20b3890981a394774baab7b9c827Frederik Schwarzer * the physical eraseblock is erased more than once. 580801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 581801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns the number of erasures made in case of success, %-EIO 582801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * if the erasure failed or the torturing test failed, and other negative error 583801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * codes in case of other errors. Note, %-EIO means that the physical 584801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock is bad. 585801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 586e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) 587801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 588801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err, ret = 0; 589801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 590801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 591801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 592801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_not_bad(ubi, pnum); 593801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err != 0) 594adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 595801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 596801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) { 597801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("read-only mode"); 598801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 599801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 600801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 601ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy if (ubi->nor_flash) { 602ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy err = nor_erase_prepare(ubi, pnum); 603ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy if (err) 604ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy return err; 605ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy } 606ebf53f421308c2f59c9bcbad4c5c297a0d00199aArtem Bityutskiy 607801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (torture) { 608801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ret = torture_peb(ubi, pnum); 609801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ret < 0) 610801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return ret; 611801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 612801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 613801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = do_sync_erase(ubi, pnum); 614801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 615801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 616801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 617801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return ret + 1; 618801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 619801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 620801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 621801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_is_bad - check if a physical eraseblock is bad. 622801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 623801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to check 624801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 625801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns a positive number if the physical eraseblock is bad, 626801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * zero if not, and a negative error code if an error occurred. 627801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 628801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyint ubi_io_is_bad(const struct ubi_device *ubi, int pnum) 629801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 630801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct mtd_info *mtd = ubi->mtd; 631801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 632801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 633801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 634801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->bad_allowed) { 635801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int ret; 636801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 6377086c19d07429d697057587caf1e5e0345442d16Artem Bityutskiy ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size); 638801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ret < 0) 639801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("error %d while checking if PEB %d is bad", 640801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ret, pnum); 641801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else if (ret) 642801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("PEB %d is bad", pnum); 643801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return ret; 644801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 645801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 646801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 647801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 648801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 649801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 650801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_mark_bad - mark a physical eraseblock as bad. 651801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 652801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to mark 653801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 654801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero in case of success and a negative error code in 655801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * case of failure. 656801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 657801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyint ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) 658801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 659801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 660801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct mtd_info *mtd = ubi->mtd; 661801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 662801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 663801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 664801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) { 665801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("read-only mode"); 666801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 667801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 668801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 669801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!ubi->bad_allowed) 670801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 671801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 6725942ddbc500d1c9b75e571b656be97f65b26adfeArtem Bityutskiy err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size); 673801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 674801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("cannot mark PEB %d bad, error %d", pnum, err); 675801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 676801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 677801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 678801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 679801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * validate_ec_hdr - validate an erase counter header. 680801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 681801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ec_hdr: the erase counter header to check 682801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 683801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero if the erase counter header is OK, and %1 if 684801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * not. 685801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 686fe96efc1a3c049f0a1bcd9b65e0faeb751ce5ec6Artem Bityutskiystatic int validate_ec_hdr(const struct ubi_device *ubi, 687801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_ec_hdr *ec_hdr) 688801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 689801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy long long ec; 690fe96efc1a3c049f0a1bcd9b65e0faeb751ce5ec6Artem Bityutskiy int vid_hdr_offset, leb_start; 691801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 6923261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ec = be64_to_cpu(ec_hdr->ec); 6933261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr_offset = be32_to_cpu(ec_hdr->vid_hdr_offset); 6943261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig leb_start = be32_to_cpu(ec_hdr->data_offset); 695801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 696801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ec_hdr->version != UBI_VERSION) { 697801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("node with incompatible UBI version found: " 698801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "this UBI version is %d, image version is %d", 699801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy UBI_VERSION, (int)ec_hdr->version); 700801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 701801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 702801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 703801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vid_hdr_offset != ubi->vid_hdr_offset) { 704801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad VID header offset %d, expected %d", 705801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr_offset, ubi->vid_hdr_offset); 706801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 707801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 708801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 709801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (leb_start != ubi->leb_start) { 710801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad data offset %d, expected %d", 711801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_start, ubi->leb_start); 712801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 713801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 714801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 715801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ec < 0 || ec > UBI_MAX_ERASECOUNTER) { 716801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad erase counter %lld", ec); 717801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 718801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 719801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 720801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 721801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 722801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiybad: 723801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad EC header"); 724801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_ec_hdr(ec_hdr); 725801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 726801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 1; 727801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 728801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 729801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 730801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_read_ec_hdr - read and check an erase counter header. 731801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 732801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock to read from 733801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ec_hdr: a &struct ubi_ec_hdr object where to store the read erase counter 734801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * header 735801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @verbose: be verbose if the header is corrupted or was not found 736801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 737801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function reads erase counter header from physical eraseblock @pnum and 738801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * stores it in @ec_hdr. This function also checks CRC checksum of the read 739801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * erase counter header. The following codes may be returned: 740801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 741801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o %0 if the CRC checksum is correct and the header was successfully read; 742801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected 743801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * and corrected by the flash driver; this is harmless but may indicate that 744801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * this eraseblock may become bad soon (but may be not); 745786d78318586cbdc8aec539fe5a4942490267fefArtem Bityutskiy * o %UBI_IO_BAD_HDR if the erase counter header is corrupted (a CRC error); 746756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * o %UBI_IO_BAD_HDR_EBADMSG is the same as %UBI_IO_BAD_HDR, but there also was 747756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * a data integrity error (uncorrectable ECC error in case of NAND); 74874d82d2660058e32644f0c673656b2a1d01d3688Artem Bityutskiy * o %UBI_IO_FF if only 0xFF bytes were read (the PEB is supposedly empty) 749801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * o a negative error code in case of failure. 750801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 751e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, 752801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_ec_hdr *ec_hdr, int verbose) 753801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 75492e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy int err, read_err; 755801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc, magic, hdr_crc; 756801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 757801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("read EC header from PEB %d", pnum); 758801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 759801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 76092e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); 76192e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy if (read_err) { 762d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) 76392e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return read_err; 764801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 765801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 766801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * We read all the data, but either a correctable bit-flip 767756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * occurred, or MTD reported a data integrity error 768756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * (uncorrectable ECC error in case of NAND). The former is 769756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * harmless, the later may mean that the read data is 770756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * corrupted. But we have a CRC check-sum and we will detect 771756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * this. If the EC header is still OK, we just report this as 772756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy * there was a bit-flip, to force scrubbing. 773801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 774801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 775801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 7763261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig magic = be32_to_cpu(ec_hdr->magic); 777801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (magic != UBI_EC_HDR_MAGIC) { 778d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (mtd_is_eccerr(read_err)) 77992e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR_EBADMSG; 780eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy 781801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 782801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The magic field is wrong. Let's check if we have read all 783801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 0xFF. If yes, this physical eraseblock is assumed to be 784801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * empty. 785801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 786bb00e180a93a6c8e89c3b2d1f9473781e1e2d2a4Artem Bityutskiy if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { 787801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* The physical eraseblock is supposedly empty */ 788801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) 789801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("no EC header found at PEB %d, " 790801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "only 0xFF bytes", pnum); 7916f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("no EC header found at PEB %d, " 7926f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "only 0xFF bytes", pnum); 79392e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy if (!read_err) 79492e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_FF; 79592e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy else 79692e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_FF_BITFLIPS; 797801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 798801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 799801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 800801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This is not a valid erase counter header, and these are not 801801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 0xFF bytes. Report that the header is corrupted. 802801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 803801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) { 804801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("bad magic number at PEB %d: %08x instead of " 805801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "%08x", pnum, magic, UBI_EC_HDR_MAGIC); 806801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_ec_hdr(ec_hdr); 8076f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy } 8086f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("bad magic number at PEB %d: %08x instead of " 8096f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "%08x", pnum, magic, UBI_EC_HDR_MAGIC); 810786d78318586cbdc8aec539fe5a4942490267fefArtem Bityutskiy return UBI_IO_BAD_HDR; 811801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 812801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 813801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 8143261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); 815801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 816801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (hdr_crc != crc) { 817801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) { 8189c9ec147709e63e4e8ac6a037c6bb50688ff8e9cArtem Bityutskiy ubi_warn("bad EC header CRC at PEB %d, calculated " 8199c9ec147709e63e4e8ac6a037c6bb50688ff8e9cArtem Bityutskiy "%#08x, read %#08x", pnum, crc, hdr_crc); 820801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_ec_hdr(ec_hdr); 8216f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy } 8226f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("bad EC header CRC at PEB %d, calculated " 8236f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "%#08x, read %#08x", pnum, crc, hdr_crc); 82492e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy 82592e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy if (!read_err) 82692e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR; 82792e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy else 82892e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR_EBADMSG; 829801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 830801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 831801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* And of course validate what has just been read from the media */ 832801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = validate_ec_hdr(ubi, ec_hdr); 833801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 834801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("validation failed for PEB %d", pnum); 835801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EINVAL; 836801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 837801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 838eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy /* 839eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy * If there was %-EBADMSG, but the header CRC is still OK, report about 840eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy * a bit-flip to force scrubbing on this PEB. 841eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy */ 842801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return read_err ? UBI_IO_BITFLIPS : 0; 843801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 844801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 845801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 846801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_write_ec_hdr - write an erase counter header. 847801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 848801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock to write to 849801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ec_hdr: the erase counter header to write 850801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 851801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function writes erase counter header described by @ec_hdr to physical 852801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock @pnum. It also fills most fields of @ec_hdr before writing, so 853801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the caller do not have to fill them. Callers must only fill the @ec_hdr->ec 854801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * field. 855801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 856801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero in case of success and a negative error code in 857801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * case of failure. If %-EIO is returned, the physical eraseblock most probably 858801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * went bad. 859801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 860e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, 861801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_ec_hdr *ec_hdr) 862801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 863801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 864801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc; 865801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 866801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("write EC header to PEB %d", pnum); 867801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 868801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 8693261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ec_hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); 870801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ec_hdr->version = UBI_VERSION; 8713261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); 8723261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); 8730c6c7fa1313fcb69cae35e34168d2e83b8da854aAdrian Hunter ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); 874801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 8753261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ec_hdr->hdr_crc = cpu_to_be32(crc); 876801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 877801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); 878801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 879adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 880801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 881801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); 882801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 883801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 884801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 885801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 886801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * validate_vid_hdr - validate a volume identifier header. 887801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 888801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr: the volume identifier header to check 889801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 890801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function checks that data stored in the volume identifier header 891801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr. Returns zero if the VID header is OK and %1 if not. 892801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 893801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int validate_vid_hdr(const struct ubi_device *ubi, 894801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_vid_hdr *vid_hdr) 895801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 896801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int vol_type = vid_hdr->vol_type; 897801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int copy_flag = vid_hdr->copy_flag; 8983261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int vol_id = be32_to_cpu(vid_hdr->vol_id); 8993261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int lnum = be32_to_cpu(vid_hdr->lnum); 900801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int compat = vid_hdr->compat; 9013261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int data_size = be32_to_cpu(vid_hdr->data_size); 9023261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int used_ebs = be32_to_cpu(vid_hdr->used_ebs); 9033261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int data_pad = be32_to_cpu(vid_hdr->data_pad); 9043261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig int data_crc = be32_to_cpu(vid_hdr->data_crc); 905801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int usable_leb_size = ubi->leb_size - data_pad; 906801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 907801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (copy_flag != 0 && copy_flag != 1) { 908801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad copy_flag"); 909801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 910801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 911801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 912801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || 913801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy data_pad < 0) { 914801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("negative values"); 915801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 916801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 917801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 918801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { 919801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad vol_id"); 920801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 921801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 922801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 923801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { 924801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad compat"); 925801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 926801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 927801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 928801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && 929801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && 930801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy compat != UBI_COMPAT_REJECT) { 931801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad compat"); 932801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 933801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 934801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 935801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { 936801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad vol_type"); 937801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 938801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 939801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 940801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_pad >= ubi->leb_size / 2) { 941801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad data_pad"); 942801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 943801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 944801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 945801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_type == UBI_VID_STATIC) { 946801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 947801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Although from high-level point of view static volumes may 948801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * contain zero bytes of data, but no VID headers can contain 949801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * zero at these fields, because they empty volumes do not have 950801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * mapped logical eraseblocks. 951801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 952801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (used_ebs == 0) { 953801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("zero used_ebs"); 954801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 955801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 956801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size == 0) { 957801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("zero data_size"); 958801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 959801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 960801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (lnum < used_ebs - 1) { 961801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size != usable_leb_size) { 962801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad data_size"); 963801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 964801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 965801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else if (lnum == used_ebs - 1) { 966801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size == 0) { 967801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad data_size at last LEB"); 968801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 969801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 970801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else { 971801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("too high lnum"); 972801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 973801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 974801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else { 975801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (copy_flag == 0) { 976801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_crc != 0) { 977801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("non-zero data CRC"); 978801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 979801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 980801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size != 0) { 981801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("non-zero data_size"); 982801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 983801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 984801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else { 985801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size == 0) { 986801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("zero data_size of copy"); 987801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 988801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 989801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 990801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (used_ebs != 0) { 991801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_err("bad used_ebs"); 992801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto bad; 993801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 994801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 995801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 996801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 997801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 998801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiybad: 999801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad VID header"); 1000801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_vid_hdr(vid_hdr); 1001801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1002801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 1; 1003801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1004801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1005801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1006801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_read_vid_hdr - read and check a volume identifier header. 1007801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1008801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number to read from 1009801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr: &struct ubi_vid_hdr object where to store the read volume 1010801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * identifier header 1011801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @verbose: be verbose if the header is corrupted or wasn't found 1012801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1013801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function reads the volume identifier header from physical eraseblock 1014801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum and stores it in @vid_hdr. It also checks CRC checksum of the read 101574d82d2660058e32644f0c673656b2a1d01d3688Artem Bityutskiy * volume identifier header. The error codes are the same as in 101674d82d2660058e32644f0c673656b2a1d01d3688Artem Bityutskiy * 'ubi_io_read_ec_hdr()'. 1017801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 101874d82d2660058e32644f0c673656b2a1d01d3688Artem Bityutskiy * Note, the implementation of this function is also very similar to 101974d82d2660058e32644f0c673656b2a1d01d3688Artem Bityutskiy * 'ubi_io_read_ec_hdr()', so refer commentaries in 'ubi_io_read_ec_hdr()'. 1020801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1021e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, 1022801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr, int verbose) 1023801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 102492e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy int err, read_err; 1025801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc, magic, hdr_crc; 1026801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy void *p; 1027801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1028801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("read VID header from PEB %d", pnum); 1029801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 1030801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1031801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = (char *)vid_hdr - ubi->vid_hdr_shift; 103292e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, 1033801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->vid_hdr_alsize); 1034d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) 103592e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return read_err; 1036801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 10373261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig magic = be32_to_cpu(vid_hdr->magic); 1038801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (magic != UBI_VID_HDR_MAGIC) { 1039d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (mtd_is_eccerr(read_err)) 104092e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR_EBADMSG; 1041eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy 1042bb00e180a93a6c8e89c3b2d1f9473781e1e2d2a4Artem Bityutskiy if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { 1043801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) 1044801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("no VID header found at PEB %d, " 1045801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "only 0xFF bytes", pnum); 10466f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("no VID header found at PEB %d, " 10476f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "only 0xFF bytes", pnum); 104892e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy if (!read_err) 104992e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_FF; 105092e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy else 105192e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_FF_BITFLIPS; 1052801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1053801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1054801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) { 1055801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("bad magic number at PEB %d: %08x instead of " 1056801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "%08x", pnum, magic, UBI_VID_HDR_MAGIC); 1057801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_vid_hdr(vid_hdr); 10586f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy } 10596f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("bad magic number at PEB %d: %08x instead of " 10606f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "%08x", pnum, magic, UBI_VID_HDR_MAGIC); 1061786d78318586cbdc8aec539fe5a4942490267fefArtem Bityutskiy return UBI_IO_BAD_HDR; 1062801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1063801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1064801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); 10653261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); 1066801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1067801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (hdr_crc != crc) { 1068801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (verbose) { 1069801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("bad CRC at PEB %d, calculated %#08x, " 1070801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "read %#08x", pnum, crc, hdr_crc); 1071801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_vid_hdr(vid_hdr); 10726f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy } 10736f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy dbg_bld("bad CRC at PEB %d, calculated %#08x, " 10746f9fdf62db64b1e52e5b7a9f785554e8b877b65cArtem Bityutskiy "read %#08x", pnum, crc, hdr_crc); 107592e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy if (!read_err) 107692e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR; 107792e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy else 107892e1a7d9e7e07fb1cf0cbbcdf202938d0819b54dArtem Bityutskiy return UBI_IO_BAD_HDR_EBADMSG; 1079801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1080801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1081801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = validate_vid_hdr(ubi, vid_hdr); 1082801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 1083801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("validation failed for PEB %d", pnum); 1084801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EINVAL; 1085801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1086801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1087801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return read_err ? UBI_IO_BITFLIPS : 0; 1088801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1089801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1090801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1091801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_io_write_vid_hdr - write a volume identifier header. 1092801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1093801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to write to 1094801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr: the volume identifier header to write 1095801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1096801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function writes the volume identifier header described by @vid_hdr to 1097801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * physical eraseblock @pnum. This function automatically fills the 1098801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr->magic and the @vid_hdr->version fields, as well as calculates 1099801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * header CRC checksum and stores it at vid_hdr->hdr_crc. 1100801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1101801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero in case of success and a negative error code in 1102801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * case of failure. If %-EIO is returned, the physical eraseblock probably went 1103801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * bad. 1104801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1105e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiyint ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, 1106801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr) 1107801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1108801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1109801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc; 1110801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy void *p; 1111801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1112801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_io("write VID header to PEB %d", pnum); 1113801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(pnum >= 0 && pnum < ubi->peb_count); 1114801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1115801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_peb_ec_hdr(ubi, pnum); 1116801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 1117adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 1118801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 11193261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); 1120801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->version = UBI_VERSION; 1121801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); 11223261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->hdr_crc = cpu_to_be32(crc); 1123801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1124801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); 1125801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 1126adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err; 1127801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1128801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = (char *)vid_hdr - ubi->vid_hdr_shift; 1129801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, 1130801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->vid_hdr_alsize); 1131801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1132801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1133801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 113492d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy#ifdef CONFIG_MTD_UBI_DEBUG 1135801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1136801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1137801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. 1138801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1139801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number to check 1140801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1141adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * This function returns zero if the physical eraseblock is good, %-EINVAL if 1142adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * it is bad and a negative error code if an error occurred. 1143801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1144801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) 1145801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1146801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1147801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 11482a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 114992d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 115092d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 1151801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_is_bad(ubi, pnum); 1152801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!err) 1153801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1154801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1155801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1156801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1157adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return err > 0 ? -EINVAL : err; 1158801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1159801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1160801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1161801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * paranoid_check_ec_hdr - check if an erase counter header is all right. 1162801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1163801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number the erase counter header belongs to 1164801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ec_hdr: the erase counter header to check 1165801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1166801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero if the erase counter header contains valid 1167adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * values, and %-EINVAL if not. 1168801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1169801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, 1170801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_ec_hdr *ec_hdr) 1171801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1172801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1173801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t magic; 1174801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 11752a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 117692d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 117792d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 11783261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig magic = be32_to_cpu(ec_hdr->magic); 1179801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (magic != UBI_EC_HDR_MAGIC) { 1180801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad magic %#08x, must be %#08x", 1181801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy magic, UBI_EC_HDR_MAGIC); 1182801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto fail; 1183801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1184801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1185801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = validate_ec_hdr(ubi, ec_hdr); 1186801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 1187801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1188801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto fail; 1189801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1190801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1191801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 1192801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1193801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyfail: 1194801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_ec_hdr(ec_hdr); 1195801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1196adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return -EINVAL; 1197801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1198801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1199801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1200ebaaf1af3e9ef05c4fb7c61e4530c15e1ad10e3bArtem Bityutskiy * paranoid_check_peb_ec_hdr - check erase counter header. 1201801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1202801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to check 1203801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1204adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * This function returns zero if the erase counter header is all right and and 1205adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * a negative error code if not or if an error occurred. 1206801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1207801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) 1208801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1209801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1210801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc, hdr_crc; 1211801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_ec_hdr *ec_hdr; 1212801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 12132a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 121492d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 121592d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 121633818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 1217801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!ec_hdr) 1218801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 1219801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1220801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); 1221d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 1222801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto exit; 1223801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1224801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); 12253261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); 1226801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (hdr_crc != crc) { 1227801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); 1228801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1229801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_ec_hdr(ec_hdr); 1230801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1231adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy err = -EINVAL; 1232801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto exit; 1233801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1234801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1235801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); 1236801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1237801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyexit: 1238801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy kfree(ec_hdr); 1239801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1240801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1241801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1242801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1243801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * paranoid_check_vid_hdr - check that a volume identifier header is all right. 1244801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1245801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: physical eraseblock number the volume identifier header belongs to 1246801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr: the volume identifier header to check 1247801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1248801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero if the volume identifier header is all right, and 1249adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * %-EINVAL if not. 1250801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1251801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, 1252801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const struct ubi_vid_hdr *vid_hdr) 1253801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1254801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1255801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t magic; 1256801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 12572a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 125892d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 125992d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 12603261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig magic = be32_to_cpu(vid_hdr->magic); 1261801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (magic != UBI_VID_HDR_MAGIC) { 1262801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", 1263801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy magic, pnum, UBI_VID_HDR_MAGIC); 1264801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto fail; 1265801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1266801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1267801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = validate_vid_hdr(ubi, vid_hdr); 1268801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 1269801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1270801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto fail; 1271801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1272801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1273801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1274801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1275801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyfail: 1276801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1277801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_vid_hdr(vid_hdr); 1278801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1279adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy return -EINVAL; 1280801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1281801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1282801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1283801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 1284ebaaf1af3e9ef05c4fb7c61e4530c15e1ad10e3bArtem Bityutskiy * paranoid_check_peb_vid_hdr - check volume identifier header. 1285801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1286801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to check 1287801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1288801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero if the volume identifier header is all right, 1289adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * and a negative error code if not or if an error occurred. 1290801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1291801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) 1292801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1293801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1294801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc, hdr_crc; 1295801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 1296801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy void *p; 1297801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 12982a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 129992d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 130092d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 130133818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 1302801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vid_hdr) 1303801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 1304801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1305801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = (char *)vid_hdr - ubi->vid_hdr_shift; 1306801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, 1307801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->vid_hdr_alsize); 1308d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 1309801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto exit; 1310801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1311801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); 13123261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); 1313801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (hdr_crc != crc) { 1314801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " 1315801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "read %#08x", pnum, crc, hdr_crc); 1316801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1317801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_vid_hdr(vid_hdr); 1318801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1319adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy err = -EINVAL; 1320801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto exit; 1321801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1322801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1323801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); 1324801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1325801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyexit: 1326801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 1327801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1328801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1329801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1330801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 13316e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * ubi_dbg_check_write - make sure write succeeded. 13326e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * @ubi: UBI device description object 13336e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * @buf: buffer with data which were written 13346e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * @pnum: physical eraseblock number the data were written to 13356e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * @offset: offset within the physical eraseblock the data were written to 13366e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * @len: how many bytes were written 13376e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * 13386e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * This functions reads data which were recently written and compares it with 13396e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * the original data buffer - the data have to match. Returns zero if the data 13406e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy * match and a negative error code if not or in case of failure. 13416e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy */ 13426e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiyint ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, 13436e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy int offset, int len) 13446e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy{ 13456e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy int err, i; 13467950d023c562823345892aac2e7c6a49f8de9ad1Artem Bityutskiy size_t read; 1347a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy void *buf1; 13487950d023c562823345892aac2e7c6a49f8de9ad1Artem Bityutskiy loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 13496e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 13502a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 135192d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 135292d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 13533d46b316bcc1ecb17f8e7874a8ec620c64864898Artem Bityutskiy buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); 1354a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy if (!buf1) { 1355a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy ubi_err("cannot allocate memory to check writes"); 1356a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy return 0; 1357a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy } 1358a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy 1359329ad399a9b3adf52c90637b21ca029fcf7f8795Artem Bityutskiy err = mtd_read(ubi->mtd, addr, len, &read, buf1); 1360d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (err && !mtd_is_bitflip(err)) 1361a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy goto out_free; 13626e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 13636e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy for (i = 0; i < len; i++) { 13646e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy uint8_t c = ((uint8_t *)buf)[i]; 1365a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy uint8_t c1 = ((uint8_t *)buf1)[i]; 13666e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy int dump_len; 13676e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 13686e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy if (c == c1) 13696e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy continue; 13706e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 13716e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy ubi_err("paranoid check failed for PEB %d:%d, len %d", 13726e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy pnum, offset, len); 13736e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy ubi_msg("data differ at position %d", i); 13746e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy dump_len = max_t(int, 128, len - i); 13756e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy ubi_msg("hex dump of the original buffer from %d to %d", 13766e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy i, i + dump_len); 13776e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 13786e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy buf + i, dump_len, 1); 13796e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy ubi_msg("hex dump of the read buffer from %d to %d", 13806e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy i, i + dump_len); 13816e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 1382a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy buf1 + i, dump_len, 1); 13836e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy ubi_dbg_dump_stack(); 13846e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy err = -EINVAL; 1385a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy goto out_free; 13866e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy } 13876e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 1388a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy vfree(buf1); 13896e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy return 0; 13906e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 1391a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiyout_free: 1392a75867432a7eb2cdcaa8613a3b72b1d0594dd930Artem Bityutskiy vfree(buf1); 13936e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy return err; 13946e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy} 13956e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy 13966e9065d756df5dac6dc02b94b82b4f5dbbf38cafArtem Bityutskiy/** 139740a71a87fa8e0cb3ec0fca4d152263734b203eb2Artem Bityutskiy * ubi_dbg_check_all_ff - check that a region of flash is empty. 1398801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1399801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock number to check 1400801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: the starting offset within the physical eraseblock to check 1401801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: the length of the region to check 1402801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1403801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero if only 0xFF bytes are present at offset 1404adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * @offset of the physical eraseblock @pnum, and a negative error code if not 1405adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy * or if an error occurred. 1406801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 140740a71a87fa8e0cb3ec0fca4d152263734b203eb2Artem Bityutskiyint ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) 1408801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1409801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy size_t read; 1410801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err; 1411332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy void *buf; 1412801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1413801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 14142a734bb8d502b645c061fa329e87c5d651498e68Artem Bityutskiy if (!ubi->dbg->chk_io) 141592d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy return 0; 141692d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy 14173d46b316bcc1ecb17f8e7874a8ec620c64864898Artem Bityutskiy buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); 1418332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy if (!buf) { 1419332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy ubi_err("cannot allocate memory to check for 0xFFs"); 1420332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy return 0; 1421332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy } 1422332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy 1423329ad399a9b3adf52c90637b21ca029fcf7f8795Artem Bityutskiy err = mtd_read(ubi->mtd, addr, len, &read, buf); 1424d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris if (err && !mtd_is_bitflip(err)) { 1425801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("error %d while reading %d bytes from PEB %d:%d, " 1426801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "read %zd bytes", err, len, pnum, offset, read); 1427801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto error; 1428801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1429801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1430332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy err = ubi_check_pattern(buf, 0xFF, len); 1431801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err == 0) { 1432801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("flash region at PEB %d:%d, length %d does not " 1433801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy "contain all 0xFF bytes", pnum, offset, len); 1434801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto fail; 1435801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1436801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1437332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy vfree(buf); 1438801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 1439801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1440801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyfail: 1441801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_err("paranoid check failed for PEB %d", pnum); 1442c8566350a3229ca505b84313c65d1403b4d0cbfcArtem Bityutskiy ubi_msg("hex dump of the %d-%d region", offset, offset + len); 1443332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); 1444adbf05e3ec6ea380ba145b6fa89d9125ed76eb98Artem Bityutskiy err = -EINVAL; 1445801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyerror: 1446801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_dbg_dump_stack(); 1447332873d60b943c9bf53957c6e334038ac5e9dc6bArtem Bityutskiy vfree(buf); 1448801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1449801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1450801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 145192d124f5314913a21f7fa98b22ee457dab171eddArtem Bityutskiy#endif /* CONFIG_MTD_UBI_DEBUG */ 1452