/*
* Copyright (c) International Business Machines Corp., 2006
* Copyright (c) Nokia Corporation, 2006, 2007
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Artem Bityutskiy (Битюцкий Артём)
*/
/*
* UBI input/output sub-system.
*
* This sub-system provides a uniform way to work with all kinds of the
* underlying MTD devices. It also implements handy functions for reading and
* writing UBI headers.
*
* We are trying to have a paranoid mindset and not to trust to what we read
* from the flash media in order to be more secure and robust. So this
* sub-system validates every single header it reads from the flash media.
*
* Some words about how the eraseblock headers are stored.
*
* The erase counter header is always stored at offset zero. By default, the
* VID header is stored after the EC header at the closest aligned offset
* (i.e. aligned to the minimum I/O unit size). Data starts next to the VID
* header at the closest aligned offset. But this default layout may be
* changed. For example, for different reasons (e.g., optimization) UBI may be
* asked to put the VID header at further offset, and even at an unaligned
* offset. Of course, if the offset of the VID header is unaligned, UBI adds
* proper padding in front of it. Data offset may also be changed but it has to
* be aligned.
*
* About minimal I/O units. In general, UBI assumes flash device model where
* there is only one minimal I/O unit size. E.g., in case of NOR flash it is 1,
* in case of NAND flash it is a NAND page, etc. This is reported by MTD in the
* @ubi->mtd->writesize field. But as an exception, UBI admits of using another
* (smaller) minimal I/O unit size for EC and VID headers to make it possible
* to do different optimizations.
*
* This is extremely useful in case of NAND flashes which admit of several
* write operations to one NAND page. In this case UBI can fit EC and VID
* headers at one NAND page. Thus, UBI may use "sub-page" size as the minimal
* I/O unit for the headers (the @ubi->hdrs_min_io_size field). But it still
* reports NAND page size (@ubi->min_io_size) as a minimal I/O unit for the UBI
* users.
*
* Example: some Samsung NANDs with 2KiB pages allow 4x 512-byte writes, so
* although the minimal I/O unit is 2K, UBI uses 512 bytes for EC and VID
* headers.
*
* Q: why not just to treat sub-page as a minimal I/O unit of this flash
* device, e.g., make @ubi->min_io_size = 512 in the example above?
*
* A: because when writing a sub-page, MTD still writes a full 2K page but the
* bytes which are no relevant to the sub-page are 0xFF. So, basically, writing
* 4x512 sub-pages is 4 times slower then writing one 2KiB NAND page. Thus, we
* prefer to use sub-pages only for EV and VID headers.
*
* As it was noted above, the VID header may start at a non-aligned offset.
* For example, in case of a 2KiB page NAND flash with a 512 bytes sub-page,
* the VID header may reside at offset 1984 which is the last 64 bytes of the
* last sub-page (EC header is always at offset zero). This causes some
* difficulties when reading and writing VID headers.
*
* Suppose we have a 64-byte buffer and we read a VID header at it. We change
* the data and want to write this VID header out. As we can only write in
* 512-byte chunks, we have to allocate one more buffer and copy our VID header
* to offset 448 of this buffer.
*
* The I/O sub-system does the following trick in order to avoid this extra
* copy. It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID
* header and returns a pointer to offset @ubi->vid_hdr_shift of this buffer.
* When the VID header is being written out, it shifts the VID header pointer
* back and writes the whole sub-page.
*/
#include <linux/crc32.h>
#include <linux/err.h>
#include <linux/slab.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum);
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
static int paranoid_check_ec_hdr(const