9
0
Fork 0

UBI: reimport UBI from Linux v3.10

This is a fresh UBI import from Linux v3.10

This is done mainly to get fastmap support.

This was tested with the i.MX nand driver, the MXS nand driver and
on CFI NOR flash.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2012-11-08 19:02:06 +01:00
parent 10f7528afb
commit 50f75a1a0e
31 changed files with 14535 additions and 107 deletions

View File

@ -401,13 +401,13 @@ config CMD_FLASH
config CMD_UBI
tristate
default y if UBI
depends on UBI
default y if MTD_UBI
depends on MTD_UBI
prompt "ubimkvol, ubirmvol, ubiattach"
config CMD_UBIFORMAT
tristate
depends on UBI
depends on MTD_UBI
select LIBMTD
select LIBSCAN
select LIBUBIGEN

View File

@ -76,7 +76,7 @@ static int do_ubiattach(int argc, char *argv[])
goto err;
}
ret = ubi_attach_mtd_dev(user.mtd, UBI_DEV_NUM_AUTO, 0);
ret = ubi_attach_mtd_dev(user.mtd, UBI_DEV_NUM_AUTO, 0, 20);
if (ret < 0)
printf("failed to attach: %s\n", strerror(-ret));
else

View File

@ -23,6 +23,6 @@ config MTD_RAW_DEVICE
source "drivers/mtd/devices/Kconfig"
source "drivers/mtd/nor/Kconfig"
source "drivers/mtd/nand/Kconfig"
#source "drivers/mtd/ubi/Kconfig"
source "drivers/mtd/ubi/Kconfig"
endif

View File

@ -1,6 +1,6 @@
obj-$(CONFIG_NAND) += nand/
obj-$(CONFIG_DRIVER_CFI) += nor/
obj-$(CONFIG_UBI) += ubi/
obj-$(CONFIG_MTD_UBI) += ubi/
obj-y += devices/
obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o
obj-$(CONFIG_MTD) += core.o

81
drivers/mtd/ubi/Kconfig Normal file
View File

@ -0,0 +1,81 @@
menuconfig MTD_UBI
tristate "Enable UBI - Unsorted block images"
select CRC32
select PARTITION_NEED_MTD
help
UBI is a software layer above MTD layer which admits of LVM-like
logical volumes on top of MTD devices, hides some complexities of
flash chips like wear and bad blocks and provides some other useful
capabilities. Please, consult the MTD web site for more details
(www.linux-mtd.infradead.org).
if MTD_UBI
config MTD_UBI_WL_THRESHOLD
int "UBI wear-leveling threshold"
default 4096
range 2 65536
help
This parameter defines the maximum difference between the highest
erase counter value and the lowest erase counter value of eraseblocks
of UBI devices. When this threshold is exceeded, UBI starts performing
wear leveling by means of moving data from eraseblock with low erase
counter to eraseblocks with high erase counter.
The default value should be OK for SLC NAND flashes, NOR flashes and
other flashes which have eraseblock life-cycle 100000 or more.
However, in case of MLC NAND flashes which typically have eraseblock
life-cycle less than 10000, the threshold should be lessened (e.g.,
to 128 or 256, although it does not have to be power of 2).
config MTD_UBI_BEB_LIMIT
int "Maximum expected bad eraseblock count per 1024 eraseblocks"
default 20
range 0 768
help
This option specifies the maximum bad physical eraseblocks UBI
expects on the MTD device (per 1024 eraseblocks). If the underlying
flash does not admit of bad eraseblocks (e.g. NOR flash), this value
is ignored.
NAND datasheets often specify the minimum and maximum NVM (Number of
Valid Blocks) for the flashes' endurance lifetime. The maximum
expected bad eraseblocks per 1024 eraseblocks then can be calculated
as "1024 * (1 - MinNVB / MaxNVB)", which gives 20 for most NANDs
(MaxNVB is basically the total count of eraseblocks on the chip).
To put it differently, if this value is 20, UBI will try to reserve
about 1.9% of physical eraseblocks for bad blocks handling. And that
will be 1.9% of eraseblocks on the entire NAND chip, not just the MTD
partition UBI attaches. This means that if you have, say, a NAND
flash chip admits maximum 40 bad eraseblocks, and it is split on two
MTD partitions of the same size, UBI will reserve 40 eraseblocks when
attaching a partition.
This option can be overridden by the "mtd=" UBI module parameter or
by the "attach" ioctl.
Leave the default value if unsure.
config MTD_UBI_FASTMAP
bool "UBI Fastmap (Experimental feature)"
default n
help
Important: this feature is experimental so far and the on-flash
format for fastmap may change in the next kernel versions
Fastmap is a mechanism which allows attaching an UBI device
in nearly constant time. Instead of scanning the whole MTD device it
only has to locate a checkpoint (called fastmap) on the device.
The on-flash fastmap contains all information needed to attach
the device. Using fastmap makes only sense on large devices where
attaching by scanning takes long. UBI will not automatically install
a fastmap on old images, but you can set the UBI module parameter
fm_autoconvert to 1 if you want so. Please note that fastmap-enabled
images are still usable with UBI implementations without
fastmap support. On typical flash devices the whole fastmap fits
into one PEB. UBI will reserve PEBs to hold two fastmaps.
If in doubt, say "N".
endif # MTD_UBI

5
drivers/mtd/ubi/Makefile Normal file
View File

@ -0,0 +1,5 @@
obj-$(CONFIG_MTD_UBI) += ubi.o
ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
ubi-y += misc.o debug.o
ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o

1728
drivers/mtd/ubi/attach.c Normal file

File diff suppressed because it is too large Load Diff

686
drivers/mtd/ubi/build.c Normal file
View File

@ -0,0 +1,686 @@
/*
* Copyright (c) International Business Machines Corp., 2006
* Copyright (c) Nokia Corporation, 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 (Битюцкий Артём),
* Frank Haverkamp
*/
/*
* This file includes UBI initialization and building of UBI devices.
*
* When UBI is initialized, it attaches all the MTD devices specified as the
* module load parameters or the kernel boot parameters. If MTD devices were
* specified, UBI does not attach any MTD device, but it is possible to do
* later using the "UBI control device".
*/
#include <linux/err.h>
#include <linux/stringify.h>
#include <linux/stat.h>
#include <linux/log2.h>
#include "ubi.h"
/* Maximum length of the 'mtd=' parameter */
#define MTD_PARAM_LEN_MAX 64
/* Maximum value for the number of bad PEBs per 1024 PEBs */
#define MAX_MTD_UBI_BEB_LIMIT 768
/**
* struct mtd_dev_param - MTD device parameter description data structure.
* @name: MTD character device node path, MTD device name, or MTD device number
* string
* @vid_hdr_offs: VID header offset
* @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs
*/
struct mtd_dev_param {
char name[MTD_PARAM_LEN_MAX];
int vid_hdr_offs;
int max_beb_per1024;
};
/* MTD devices specification parameters */
#ifdef CONFIG_MTD_UBI_FASTMAP
/* UBI module parameter to enable fastmap automatically on non-fastmap images */
static bool fm_autoconvert = 1;
#endif
/* All UBI devices in system */
struct ubi_device *ubi_devices[UBI_MAX_DEVICES];
/**
* ubi_get_device - get UBI device.
* @ubi_num: UBI device number
*
* This function returns UBI device description object for UBI device number
* @ubi_num, or %NULL if the device does not exist. This function increases the
* device reference count to prevent removal of the device. In other words, the
* device cannot be removed if its reference count is not zero.
*/
struct ubi_device *ubi_get_device(int ubi_num)
{
struct ubi_device *ubi;
ubi = ubi_devices[ubi_num];
ubi->ref_count++;
return ubi;
}
/**
* ubi_put_device - drop an UBI device reference.
* @ubi: UBI device description object
*/
void ubi_put_device(struct ubi_device *ubi)
{
ubi->ref_count--;
}
/**
* kill_volumes - destroy all user volumes.
* @ubi: UBI device description object
*/
static void kill_volumes(struct ubi_device *ubi)
{
int i;
for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i])
ubi_free_volume(ubi, ubi->volumes[i]);
}
/**
* uif_init - initialize user interfaces for an UBI device.
* @ubi: UBI device description object
* @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
* taken, otherwise set to %0
*
* This function initializes various user interfaces for an UBI device. If the
* initialization fails at an early stage, this function frees all the
* resources it allocated, returns an error, and @ref is set to %0. However,
* if the initialization fails after the UBI device was registered in the
* driver core subsystem, this function takes a reference to @ubi->dev, because
* otherwise the release function ('dev_release()') would free whole @ubi
* object. The @ref argument is set to %1 in this case. The caller has to put
* this reference.
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static int uif_init(struct ubi_device *ubi, int *ref)
{
int i, err;
*ref = 0;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
err = ubi_cdev_add(ubi);
if (err) {
ubi_err("cannot add character device");
goto out_unreg;
}
for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i]) {
err = ubi_add_volume(ubi, ubi->volumes[i]);
if (err) {
ubi_err("cannot add volume %d", i);
goto out_volumes;
}
}
return 0;
out_volumes:
kill_volumes(ubi);
devfs_remove(&ubi->cdev);
out_unreg:
ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
return err;
}
/**
* uif_close - close user interfaces for an UBI device.
* @ubi: UBI device description object
*
* Note, since this function un-registers UBI volume device objects (@vol->dev),
* the memory allocated voe the volumes is freed as well (in the release
* function).
*/
static void uif_close(struct ubi_device *ubi)
{
kill_volumes(ubi);
ubi_cdev_remove(ubi);
}
/**
* ubi_free_internal_volumes - free internal volumes.
* @ubi: UBI device description object
*/
void ubi_free_internal_volumes(struct ubi_device *ubi)
{
int i;
for (i = ubi->vtbl_slots;
i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
kfree(ubi->volumes[i]->eba_tbl);
kfree(ubi->volumes[i]);
}
}
static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
{
int limit, device_pebs;
uint64_t device_size;
if (!max_beb_per1024)
return 0;
/*
* Here we are using size of the entire flash chip and
* not just the MTD partition size because the maximum
* number of bad eraseblocks is a percentage of the
* whole device and bad eraseblocks are not fairly
* distributed over the flash chip. So the worst case
* is that all the bad eraseblocks of the chip are in
* the MTD partition we are attaching (ubi->mtd).
*/
device_size = ubi->mtd->size;
device_pebs = mtd_div_by_eb(device_size, ubi->mtd);
limit = mult_frac(device_pebs, max_beb_per1024, 1024);
/* Round it up */
if (mult_frac(limit, 1024, max_beb_per1024) < device_pebs)
limit += 1;
return limit;
}
/**
* io_init - initialize I/O sub-system for a given UBI device.
* @ubi: UBI device description object
* @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
*
* If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are
* assumed:
* o EC header is always at offset zero - this cannot be changed;
* o VID header starts just after the EC header at the closest address
* aligned to @io->hdrs_min_io_size;
* o data starts just after the VID header at the closest address aligned to
* @io->min_io_size
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static int io_init(struct ubi_device *ubi, int max_beb_per1024)
{
dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
if (ubi->mtd->numeraseregions != 0) {
/*
* Some flashes have several erase regions. Different regions
* may have different eraseblock size and other
* characteristics. It looks like mostly multi-region flashes
* have one "main" region and one or more small regions to
* store boot loader code or boot parameters or whatever. I
* guess we should just pick the largest region. But this is
* not implemented.
*/
ubi_err("multiple regions, not implemented");
return -EINVAL;
}
if (ubi->vid_hdr_offset < 0)
return -EINVAL;
/*
* Note, in this implementation we support MTD devices with 0x7FFFFFFF
* physical eraseblocks maximum.
*/
ubi->peb_size = ubi->mtd->erasesize;
ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd);
ubi->flash_size = ubi->mtd->size;
if (mtd_can_have_bb(ubi->mtd)) {
ubi->bad_allowed = 1;
ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024);
}
if (ubi->mtd->type == MTD_NORFLASH) {
ubi_assert(ubi->mtd->writesize == 1);
ubi->nor_flash = 1;
}
ubi->min_io_size = ubi->mtd->writesize;
ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
/*
* Make sure minimal I/O unit is power of 2. Note, there is no
* fundamental reason for this assumption. It is just an optimization
* which allows us to avoid costly division operations.
*/
if (!is_power_of_2(ubi->min_io_size)) {
ubi_err("min. I/O unit (%d) is not power of 2",
ubi->min_io_size);
return -EINVAL;
}
ubi_assert(ubi->hdrs_min_io_size > 0);
ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size);
ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0);
ubi->max_write_size = ubi->mtd->writesize; /* FIXME: writebufsize */
/*
* Maximum write size has to be greater or equivalent to min. I/O
* size, and be multiple of min. I/O size.
*/
if (ubi->max_write_size < ubi->min_io_size ||
ubi->max_write_size % ubi->min_io_size ||
!is_power_of_2(ubi->max_write_size)) {
ubi_err("bad write buffer size %d for %d min. I/O unit",
ubi->max_write_size, ubi->min_io_size);
return -EINVAL;
}
/* Calculate default aligned sizes of EC and VID headers */
ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
dbg_gen("min_io_size %d", ubi->min_io_size);
dbg_gen("max_write_size %d", ubi->max_write_size);
dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
dbg_gen("ec_hdr_alsize %d", ubi->ec_hdr_alsize);
dbg_gen("vid_hdr_alsize %d", ubi->vid_hdr_alsize);
if (ubi->vid_hdr_offset == 0)
/* Default offset */
ubi->vid_hdr_offset = ubi->vid_hdr_aloffset =
ubi->ec_hdr_alsize;
else {
ubi->vid_hdr_aloffset = ubi->vid_hdr_offset &
~(ubi->hdrs_min_io_size - 1);
ubi->vid_hdr_shift = ubi->vid_hdr_offset -
ubi->vid_hdr_aloffset;
}
/* Similar for the data offset */
ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
dbg_gen("vid_hdr_offset %d", ubi->vid_hdr_offset);
dbg_gen("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset);
dbg_gen("vid_hdr_shift %d", ubi->vid_hdr_shift);
dbg_gen("leb_start %d", ubi->leb_start);
/* The shift must be aligned to 32-bit boundary */
if (ubi->vid_hdr_shift % 4) {
ubi_err("unaligned VID header shift %d",
ubi->vid_hdr_shift);
return -EINVAL;
}
/* Check sanity */
if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE ||
ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE ||
ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE ||
ubi->leb_start & (ubi->min_io_size - 1)) {
ubi_err("bad VID header (%d) or data offsets (%d)",
ubi->vid_hdr_offset, ubi->leb_start);
return -EINVAL;
}
/*
* Set maximum amount of physical erroneous eraseblocks to be 10%.
* Erroneous PEB are those which have read errors.
*/
ubi->max_erroneous = ubi->peb_count / 10;
if (ubi->max_erroneous < 16)
ubi->max_erroneous = 16;
dbg_gen("max_erroneous %d", ubi->max_erroneous);
/*
* It may happen that EC and VID headers are situated in one minimal
* I/O unit. In this case we can only accept this UBI image in
* read-only mode.
*/
if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) {
ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode");
ubi->ro_mode = 1;
}
ubi->leb_size = ubi->peb_size - ubi->leb_start;
if (!(ubi->mtd->flags & MTD_WRITEABLE)) {
ubi_msg("MTD device %d is write-protected, attach in read-only mode",
ubi->mtd->index);
ubi->ro_mode = 1;
}
/*
* Note, ideally, we have to initialize @ubi->bad_peb_count here. But
* unfortunately, MTD does not provide this information. We should loop
* over all physical eraseblocks and invoke mtd->block_is_bad() for
* each physical eraseblock. So, we leave @ubi->bad_peb_count
* uninitialized so far.
*/
return 0;
}
/**
* autoresize - re-size the volume which has the "auto-resize" flag set.
* @ubi: UBI device description object
* @vol_id: ID of the volume to re-size
*
* This function re-sizes the volume marked by the %UBI_VTBL_AUTORESIZE_FLG in
* the volume table to the largest possible size. See comments in ubi-header.h
* for more description of the flag. Returns zero in case of success and a
* negative error code in case of failure.
*/
static int autoresize(struct ubi_device *ubi, int vol_id)
{
struct ubi_volume_desc desc;
struct ubi_volume *vol = ubi->volumes[vol_id];
int err, old_reserved_pebs = vol->reserved_pebs;
if (ubi->ro_mode) {
ubi_warn("skip auto-resize because of R/O mode");
return 0;
}
/*
* Clear the auto-resize flag in the volume in-memory copy of the
* volume table, and 'ubi_resize_volume()' will propagate this change
* to the flash.
*/
ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG;
if (ubi->avail_pebs == 0) {
struct ubi_vtbl_record vtbl_rec;
/*
* No available PEBs to re-size the volume, clear the flag on
* flash and exit.
*/
vtbl_rec = ubi->vtbl[vol_id];
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
ubi_err("cannot clean auto-resize flag for volume %d",
vol_id);
} else {
desc.vol = vol;
err = ubi_resize_volume(&desc,
old_reserved_pebs + ubi->avail_pebs);
if (err)
ubi_err("cannot auto-resize volume %d", vol_id);
}
if (err)
return err;
ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id,
vol->name, old_reserved_pebs, vol->reserved_pebs);
return 0;
}
/**
* ubi_attach_mtd_dev - attach an MTD device.
* @mtd: MTD device description object
* @ubi_num: number to assign to the new UBI device
* @vid_hdr_offset: VID header offset
* @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
*
* This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number
* to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in
* which case this function finds a vacant device number and assigns it
* automatically. Returns the new UBI device number in case of success and a
* negative error code in case of failure.
*
* Note, the invocations of this function has to be serialized by the
* @ubi_devices_mutex.
*/
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024)
{
struct ubi_device *ubi;
int i, err, ref = 0;
if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT)
return -EINVAL;
if (!max_beb_per1024)
max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
/*
* Check if we already have the same MTD device attached.
*
* Note, this function assumes that UBI devices creations and deletions
* are serialized, so it does not take the &ubi_devices_lock.
*/
for (i = 0; i < UBI_MAX_DEVICES; i++) {
ubi = ubi_devices[i];
if (ubi && mtd == ubi->mtd) {
ubi_err("mtd%d is already attached to ubi%d",
mtd->index, i);
return -EEXIST;
}
}
/*
* Make sure this MTD device is not emulated on top of an UBI volume
* already. Well, generally this recursion works fine, but there are
* different problems like the UBI module takes a reference to itself
* by attaching (and thus, opening) the emulated MTD device. This
* results in inability to unload the module. And in general it makes
* no sense to attach emulated MTD devices, so we prohibit this.
*/
if (mtd->type == MTD_UBIVOLUME) {
ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI",
mtd->index);
return -EINVAL;
}
if (ubi_num == UBI_DEV_NUM_AUTO) {
/* Search for an empty slot in the @ubi_devices array */
for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
if (!ubi_devices[ubi_num])
break;
if (ubi_num == UBI_MAX_DEVICES) {
ubi_err("only %d UBI devices may be created",
UBI_MAX_DEVICES);
return -ENFILE;
}
} else {
if (ubi_num >= UBI_MAX_DEVICES)
return -EINVAL;
/* Make sure ubi_num is not busy */
if (ubi_devices[ubi_num]) {
ubi_err("ubi%d already exists", ubi_num);
return -EEXIST;
}
}
ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL);
if (!ubi)
return -ENOMEM;
ubi->mtd = mtd;
ubi->ubi_num = ubi_num;
ubi->vid_hdr_offset = vid_hdr_offset;
ubi->autoresize_vol_id = -1;
#ifdef CONFIG_MTD_UBI_FASTMAP
ubi->fm_pool.used = ubi->fm_pool.size = 0;
ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0;
/*
* fm_pool.max_size is 5% of the total number of PEBs but it's also
* between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE.
*/
ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size,
ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE);
if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE)
ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE;
ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE;
ubi->fm_disabled = !fm_autoconvert;
if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd)
<= UBI_FM_MAX_START) {
ubi_err("More than %i PEBs are needed for fastmap, sorry.",
UBI_FM_MAX_START);
ubi->fm_disabled = 1;
}
ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size);
ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
#else
ubi->fm_disabled = 1;
#endif
ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
err = io_init(ubi, max_beb_per1024);
if (err)
goto out_free;
err = -ENOMEM;
ubi->peb_buf = vmalloc(ubi->peb_size);
if (!ubi->peb_buf)
goto out_free;
#ifdef CONFIG_MTD_UBI_FASTMAP
ubi->fm_size = ubi_calc_fm_size(ubi);
ubi->fm_buf = kzalloc(ubi->fm_size, GFP_KERNEL);
if (!ubi->fm_buf)
goto out_free;
#endif
err = ubi_attach(ubi, 0);
if (err) {
ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
goto out_free;
}
if (ubi->autoresize_vol_id != -1) {
err = autoresize(ubi, ubi->autoresize_vol_id);
if (err)
goto out_detach;
}
err = uif_init(ubi, &ref);
if (err)
goto out_detach;
ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d",
mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num);
ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes",
ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size);
ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d",
ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size);
ubi_msg("VID header offset: %d (aligned %d), data offset: %d",
ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start);
ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d",
ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count);
ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d",
ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT,
ubi->vtbl_slots);
ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u",
ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD,
ubi->image_seq);
ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d",
ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs);
/*
* The below lock makes sure we do not race with 'ubi_thread()' which
* checks @ubi->thread_enabled. Otherwise we may fail to wake it up.
*/
ubi->thread_enabled = 1;
wake_up_process(ubi->bgt_thread);
ubi_devices[ubi_num] = ubi;
return ubi_num;
out_detach:
ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_free:
vfree(ubi->peb_buf);
vfree(ubi->fm_buf);
kfree(ubi);
return err;
}
/**
* ubi_detach_mtd_dev - detach an MTD device.
* @ubi_num: UBI device number to detach from
* @anyway: detach MTD even if device reference count is not zero
*
* This function destroys an UBI device number @ubi_num and detaches the
* underlying MTD device. Returns zero in case of success and %-EBUSY if the
* UBI device is busy and cannot be destroyed, and %-EINVAL if it does not
* exist.
*
* Note, the invocations of this function has to be serialized by the
* @ubi_devices_mutex.
*/
int ubi_detach_mtd_dev(int ubi_num, int anyway)
{
struct ubi_device *ubi;
if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
return -EINVAL;
ubi = ubi_get_device(ubi_num);
if (!ubi)
return -EINVAL;
ubi->ref_count--;
if (ubi->ref_count)
return -EBUSY;
ubi_devices[ubi_num] = NULL;
ubi_assert(ubi_num == ubi->ubi_num);
ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num);
#ifdef CONFIG_MTD_UBI_FASTMAP
/* If we don't write a new fastmap at detach time we lose all
* EC updates that have been made since the last written fastmap. */
ubi_update_fastmap(ubi);
ubi_free_fastmap(ubi);
#endif
uif_close(ubi);
ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
vfree(ubi->peb_buf);
vfree(ubi->fm_buf);
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
kfree(ubi);
return 0;
}

253
drivers/mtd/ubi/cdev.c Normal file
View File

@ -0,0 +1,253 @@
#include <common.h>
#include <fcntl.h>
#include <fs.h>
#include <ioctl.h>
#include "ubi-barebox.h"
#include "ubi.h"
struct ubi_volume_cdev_priv {
struct ubi_device *ubi;
struct ubi_volume *vol;
int written;
};
static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
loff_t offset, unsigned long flags)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
struct ubi_volume *vol = priv->vol;
struct ubi_device *ubi = priv->ubi;
int err, lnum, off, len;
size_t count_save = size;
unsigned long long tmp;
loff_t offp = offset;
int usable_leb_size = vol->usable_leb_size;
debug("%s: %zd @ 0x%08llx\n", __func__, size, offset);
len = size > usable_leb_size ? usable_leb_size : size;
tmp = offp;
off = do_div(tmp, usable_leb_size);
lnum = tmp;
do {
if (off + len >= usable_leb_size)
len = usable_leb_size - off;
err = ubi_eba_read_leb(ubi, vol, lnum, buf, off, len, 0);
if (err) {
printf("read err %x\n", err);
break;
}
off += len;
if (off == usable_leb_size) {
lnum += 1;
off -= usable_leb_size;
}
size -= len;
offp += len;
buf += len;
len = size > usable_leb_size ? usable_leb_size : size;
} while (size);
return count_save;
}
static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf,
size_t size, loff_t offset, unsigned long flags)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
struct ubi_volume *vol = priv->vol;
struct ubi_device *ubi = priv->ubi;
int err;
if (!priv->written) {
err = ubi_start_update(ubi, vol, vol->used_bytes);
if (err < 0) {
printf("Cannot start volume update\n");
return err;
}
}
err = ubi_more_update_data(ubi, vol, buf, size);
if (err < 0) {
printf("Couldnt or partially wrote data \n");
return err;
}
priv->written += size;
return size;
}
static int ubi_volume_cdev_open(struct cdev *cdev, unsigned long flags)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
priv->written = 0;
return 0;
}
static int ubi_volume_cdev_close(struct cdev *cdev)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
struct ubi_volume *vol = priv->vol;
struct ubi_device *ubi = priv->ubi;
int err;
if (priv->written) {
int remaining = vol->usable_leb_size -
(priv->written % vol->usable_leb_size);
if (remaining) {
void *buf = kmalloc(remaining, GFP_KERNEL);
if (!buf)
return -ENOMEM;
memset(buf, 0xff, remaining);
err = ubi_more_update_data(ubi, vol, buf, remaining);
kfree(buf);
if (err < 0) {
printf("Couldnt or partially wrote data \n");
return err;
}
}
err = ubi_finish_update(ubi, vol);
if (err)
return err;
err = ubi_check_volume(ubi, vol->vol_id);
if (err < 0) {
printf("check failed: %s\n", strerror(err));
return err;
}
if (err) {
ubi_warn("volume %d on UBI device %d is corrupted",
vol->vol_id, ubi->ubi_num);
vol->corrupted = 1;
}
vol->checked = 1;
}
return 0;
}
static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
/* We can only update ubi volumes sequentially */
if (priv->written)
return -EINVAL;
return ofs;
}
static struct file_operations ubi_volume_fops = {
.open = ubi_volume_cdev_open,
.close = ubi_volume_cdev_close,
.read = ubi_volume_cdev_read,
.write = ubi_volume_cdev_write,
.lseek = ubi_volume_cdev_lseek,
};
int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol)
{
struct cdev *cdev = &vol->cdev;
struct ubi_volume_cdev_priv *priv;
int ret;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
priv->vol = vol;
priv->ubi = ubi;
cdev->ops = &ubi_volume_fops;
cdev->name = asprintf("ubi%d.%s", ubi->ubi_num, vol->name);
cdev->priv = priv;
cdev->size = vol->used_bytes;
printf("registering %s as /dev/%s\n", vol->name, cdev->name);
ret = devfs_create(cdev);
if (ret) {
kfree(priv);
free(cdev->name);
}
return 0;
}
void ubi_volume_cdev_remove(struct ubi_volume *vol)
{
struct cdev *cdev = &vol->cdev;
struct ubi_volume_cdev_priv *priv = cdev->priv;
devfs_remove(cdev);
kfree(cdev->name);
kfree(priv);
}
static int ubi_cdev_ioctl(struct cdev *cdev, int cmd, void *buf)
{
struct ubi_volume_desc *desc;
struct ubi_device *ubi = cdev->priv;
struct ubi_mkvol_req *req = buf;
switch (cmd) {
case UBI_IOCRMVOL:
desc = ubi_open_volume_nm(ubi->ubi_num, req->name,
UBI_EXCLUSIVE);
if (IS_ERR(desc))
return PTR_ERR(desc);
ubi_remove_volume(desc, 0);
ubi_close_volume(desc);
break;
case UBI_IOCMKVOL:
if (!req->bytes)
req->bytes = ubi->avail_pebs * ubi->leb_size;
return ubi_create_volume(ubi, req);
};
return 0;
}
static struct file_operations ubi_fops = {
.ioctl = ubi_cdev_ioctl,
};
int ubi_cdev_add(struct ubi_device *ubi)
{
struct cdev *cdev = &ubi->cdev;
int ret;
cdev->ops = &ubi_fops;
cdev->name = asprintf("ubi%d", ubi->ubi_num);
cdev->priv = ubi;
cdev->size = 0;
printf("registering /dev/%s\n", cdev->name);
ret = devfs_create(cdev);
if (ret)
kfree(cdev->name);
return ret;
}
void ubi_cdev_remove(struct ubi_device *ubi)
{
struct cdev *cdev = &ubi->cdev;
printf("removing %s\n", cdev->name);
devfs_remove(cdev);
kfree(cdev->name);
}

214
drivers/mtd/ubi/debug.c Normal file
View File

@ -0,0 +1,214 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
#include "ubi.h"
/**
* ubi_dump_flash - dump a region of flash.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to dump
* @offset: the starting offset within the physical eraseblock to dump
* @len: the length of the region to dump
*/
void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
{
int err;
size_t read;
void *buf;
loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
buf = vmalloc(len);
if (!buf)
return;
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && err != -EUCLEAN) {
ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes",
err, len, pnum, offset, read);
goto out;
}
ubi_msg("dumping %d bytes of data from PEB %d, offset %d",
len, pnum, offset);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
out:
vfree(buf);
return;
}
/**
* ubi_dump_ec_hdr - dump an erase counter header.
* @ec_hdr: the erase counter header to dump
*/
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
pr_err("Erase counter header dump:\n");
pr_err("\tmagic %#08x\n", be32_to_cpu(ec_hdr->magic));
pr_err("\tversion %d\n", (int)ec_hdr->version);
pr_err("\tec %llu\n", (long long)be64_to_cpu(ec_hdr->ec));
pr_err("\tvid_hdr_offset %d\n", be32_to_cpu(ec_hdr->vid_hdr_offset));
pr_err("\tdata_offset %d\n", be32_to_cpu(ec_hdr->data_offset));
pr_err("\timage_seq %d\n", be32_to_cpu(ec_hdr->image_seq));
pr_err("\thdr_crc %#08x\n", be32_to_cpu(ec_hdr->hdr_crc));
pr_err("erase counter header hexdump:\n");
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
ec_hdr, UBI_EC_HDR_SIZE, 1);
}
/**
* ubi_dump_vid_hdr - dump a volume identifier header.
* @vid_hdr: the volume identifier header to dump
*/
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
pr_err("Volume identifier header dump:\n");
pr_err("\tmagic %08x\n", be32_to_cpu(vid_hdr->magic));
pr_err("\tversion %d\n", (int)vid_hdr->version);
pr_err("\tvol_type %d\n", (int)vid_hdr->vol_type);
pr_err("\tcopy_flag %d\n", (int)vid_hdr->copy_flag);
pr_err("\tcompat %d\n", (int)vid_hdr->compat);
pr_err("\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id));
pr_err("\tlnum %d\n", be32_to_cpu(vid_hdr->lnum));
pr_err("\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size));
pr_err("\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs));
pr_err("\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad));
pr_err("\tsqnum %llu\n",
(unsigned long long)be64_to_cpu(vid_hdr->sqnum));
pr_err("\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc));
pr_err("Volume identifier header hexdump:\n");
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
vid_hdr, UBI_VID_HDR_SIZE, 1);
}
/**
* ubi_dump_vol_info - dump volume information.
* @vol: UBI volume description object
*/
void ubi_dump_vol_info(const struct ubi_volume *vol)
{
pr_err("Volume information dump:\n");
pr_err("\tvol_id %d\n", vol->vol_id);
pr_err("\treserved_pebs %d\n", vol->reserved_pebs);
pr_err("\talignment %d\n", vol->alignment);
pr_err("\tdata_pad %d\n", vol->data_pad);
pr_err("\tvol_type %d\n", vol->vol_type);
pr_err("\tname_len %d\n", vol->name_len);
pr_err("\tusable_leb_size %d\n", vol->usable_leb_size);
pr_err("\tused_ebs %d\n", vol->used_ebs);
pr_err("\tused_bytes %lld\n", vol->used_bytes);
pr_err("\tlast_eb_bytes %d\n", vol->last_eb_bytes);
pr_err("\tcorrupted %d\n", vol->corrupted);
pr_err("\tupd_marker %d\n", vol->upd_marker);
if (vol->name_len <= UBI_VOL_NAME_MAX &&
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
pr_err("\tname %s\n", vol->name);
} else {
pr_err("\t1st 5 characters of name: %c%c%c%c%c\n",
vol->name[0], vol->name[1], vol->name[2],
vol->name[3], vol->name[4]);
}
}
/**
* ubi_dump_vtbl_record - dump a &struct ubi_vtbl_record object.
* @r: the object to dump
* @idx: volume table index
*/
void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
int name_len = be16_to_cpu(r->name_len);
pr_err("Volume table record %d dump:\n", idx);
pr_err("\treserved_pebs %d\n", be32_to_cpu(r->reserved_pebs));
pr_err("\talignment %d\n", be32_to_cpu(r->alignment));
pr_err("\tdata_pad %d\n", be32_to_cpu(r->data_pad));
pr_err("\tvol_type %d\n", (int)r->vol_type);
pr_err("\tupd_marker %d\n", (int)r->upd_marker);
pr_err("\tname_len %d\n", name_len);
if (r->name[0] == '\0') {
pr_err("\tname NULL\n");
return;
}
if (name_len <= UBI_VOL_NAME_MAX &&
strnlen(&r->name[0], name_len + 1) == name_len) {
pr_err("\tname %s\n", &r->name[0]);
} else {
pr_err("\t1st 5 characters of name: %c%c%c%c%c\n",
r->name[0], r->name[1], r->name[2], r->name[3],
r->name[4]);
}
pr_err("\tcrc %#08x\n", be32_to_cpu(r->crc));
}
/**
* ubi_dump_av - dump a &struct ubi_ainf_volume object.
* @av: the object to dump
*/
void ubi_dump_av(const struct ubi_ainf_volume *av)
{
pr_err("Volume attaching information dump:\n");
pr_err("\tvol_id %d\n", av->vol_id);
pr_err("\thighest_lnum %d\n", av->highest_lnum);
pr_err("\tleb_count %d\n", av->leb_count);
pr_err("\tcompat %d\n", av->compat);
pr_err("\tvol_type %d\n", av->vol_type);
pr_err("\tused_ebs %d\n", av->used_ebs);
pr_err("\tlast_data_size %d\n", av->last_data_size);
pr_err("\tdata_pad %d\n", av->data_pad);
}
/**
* ubi_dump_aeb - dump a &struct ubi_ainf_peb object.
* @aeb: the object to dump
* @type: object type: 0 - not corrupted, 1 - corrupted
*/
void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type)
{
pr_err("eraseblock attaching information dump:\n");
pr_err("\tec %d\n", aeb->ec);
pr_err("\tpnum %d\n", aeb->pnum);
if (type == 0) {
pr_err("\tlnum %d\n", aeb->lnum);
pr_err("\tscrub %d\n", aeb->scrub);
pr_err("\tsqnum %llu\n", aeb->sqnum);
}
}
/**
* ubi_dump_mkvol_req - dump a &struct ubi_mkvol_req object.
* @req: the object to dump
*/
void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
{
char nm[17];
pr_err("Volume creation request dump:\n");
pr_err("\tvol_id %d\n", req->vol_id);
pr_err("\talignment %d\n", req->alignment);
pr_err("\tbytes %lld\n", (long long)req->bytes);
pr_err("\tvol_type %d\n", req->vol_type);
pr_err("\tname_len %d\n", req->name_len);
memcpy(nm, req->name, 16);
nm[16] = 0;
pr_err("\t1st 16 characters of name: %s\n", nm);
}

129
drivers/mtd/ubi/debug.h Normal file
View File

@ -0,0 +1,129 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
#ifndef __UBI_DEBUG_H__
#define __UBI_DEBUG_H__
#include <stdlib.h>
void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr);
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
#define ubi_assert(expr) do { \
if (unlikely(!(expr))) { \
pr_crit("UBI assert failed in %s at %u\n", \
__func__, __LINE__); \
dump_stack(); \
} \
} while (0)
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
print_hex_dump(l, ps, pt, r, g, b, len, a)
#define ubi_dbg_msg(type, fmt, ...) \
pr_debug("UBI DBG " type ": " fmt "\n", \
##__VA_ARGS__)
/* General debugging messages */
#define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__)
/* Messages from the eraseblock association sub-system */
#define dbg_eba(fmt, ...) ubi_dbg_msg("eba", fmt, ##__VA_ARGS__)
/* Messages from the wear-leveling sub-system */
#define dbg_wl(fmt, ...) ubi_dbg_msg("wl", fmt, ##__VA_ARGS__)
/* Messages from the input/output sub-system */
#define dbg_io(fmt, ...) ubi_dbg_msg("io", fmt, ##__VA_ARGS__)
/* Initialization and build messages */
#define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__)
void ubi_dump_vol_info(const struct ubi_volume *vol);
void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
void ubi_dump_av(const struct ubi_ainf_volume *av);
void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type);
void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req);
int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
int len);
int ubi_debugfs_init(void);
void ubi_debugfs_exit(void);
int ubi_debugfs_init_dev(struct ubi_device *ubi);
/**
* ubi_dbg_is_bgt_disabled - if the background thread is disabled.
* @ubi: UBI device description object
*
* Returns non-zero if the UBI background thread is disabled for testing
* purposes.
*/
static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
{
return ubi->dbg.disable_bgt;
}
/**
* ubi_dbg_is_bitflip - if it is time to emulate a bit-flip.
* @ubi: UBI device description object
*
* Returns non-zero if a bit-flip should be emulated, otherwise returns zero.
*/
static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
{
if (ubi->dbg.emulate_bitflips)
return !(random32() % 200);
return 0;
}
/**
* ubi_dbg_is_write_failure - if it is time to emulate a write failure.
* @ubi: UBI device description object
*
* Returns non-zero if a write failure should be emulated, otherwise returns
* zero.
*/
static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
{
if (ubi->dbg.emulate_io_failures)
return !(random32() % 500);
return 0;
}
/**
* ubi_dbg_is_erase_failure - if its time to emulate an erase failure.
* @ubi: UBI device description object
*
* Returns non-zero if an erase failure should be emulated, otherwise returns
* zero.
*/
static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
{
if (ubi->dbg.emulate_io_failures)
return !(random32() % 400);
return 0;
}
static inline int ubi_dbg_chk_io(const struct ubi_device *ubi)
{
return ubi->dbg.chk_io;
}
static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi)
{
return ubi->dbg.chk_gen;
}
#endif /* !__UBI_DEBUG_H__ */

1352
drivers/mtd/ubi/eba.c Normal file

File diff suppressed because it is too large Load Diff

1514
drivers/mtd/ubi/fastmap.c Normal file

File diff suppressed because it is too large Load Diff

1418
drivers/mtd/ubi/io.c Normal file

File diff suppressed because it is too large Load Diff

574
drivers/mtd/ubi/kapi.c Normal file
View File

@ -0,0 +1,574 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
/* This file mostly implements UBI kernel API functions */
#include <linux/err.h>
#include <asm-generic/div64.h>
#include "ubi.h"
/**
* ubi_open_volume - open UBI volume.
* @ubi_num: UBI device number
* @vol_id: volume ID
* @mode: open mode
*
* The @mode parameter specifies if the volume should be opened in read-only
* mode, read-write mode, or exclusive mode. The exclusive mode guarantees that
* nobody else will be able to open this volume. UBI allows to have many volume
* readers and one writer at a time.
*
* If a static volume is being opened for the first time since boot, it will be
* checked by this function, which means it will be fully read and the CRC
* checksum of each logical eraseblock will be checked.
*
* This function returns volume descriptor in case of success and a negative
* error code in case of failure.
*/
struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
{
int err;
struct ubi_volume_desc *desc;
struct ubi_device *ubi;
struct ubi_volume *vol;
dbg_gen("open device %d, volume %d, mode %d", ubi_num, vol_id, mode);
if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
return ERR_PTR(-EINVAL);
if (mode != UBI_READONLY && mode != UBI_READWRITE &&
mode != UBI_EXCLUSIVE)
return ERR_PTR(-EINVAL);
/*
* First of all, we have to get the UBI device to prevent its removal.
*/
ubi = ubi_get_device(ubi_num);
if (!ubi)
return ERR_PTR(-ENODEV);
if (vol_id < 0 || vol_id >= ubi->vtbl_slots) {
err = -EINVAL;
goto out_put_ubi;
}
desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL);
if (!desc) {
err = -ENOMEM;
goto out_put_ubi;
}
err = -ENODEV;
vol = ubi->volumes[vol_id];
if (!vol)
goto out_unlock;
err = -EBUSY;
switch (mode) {
case UBI_READONLY:
if (vol->exclusive)
goto out_unlock;
vol->readers += 1;
break;
case UBI_READWRITE:
if (vol->exclusive || vol->writers > 0)
goto out_unlock;
vol->writers += 1;
break;
case UBI_EXCLUSIVE:
if (vol->exclusive || vol->writers || vol->readers)
goto out_unlock;
vol->exclusive = 1;
break;
}
vol->ref_count += 1;
desc->vol = vol;
desc->mode = mode;
if (!vol->checked) {
/* This is the first open - check the volume */
err = ubi_check_volume(ubi, vol_id);
if (err < 0) {
ubi_close_volume(desc);
return ERR_PTR(err);
}
if (err == 1) {
ubi_warn("volume %d on UBI device %d is corrupted",
vol_id, ubi->ubi_num);
vol->corrupted = 1;
}
vol->checked = 1;
}
return desc;
out_unlock:
kfree(desc);
out_put_ubi:
ubi_put_device(ubi);
ubi_err("cannot open device %d, volume %d, error %d",
ubi_num, vol_id, err);
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(ubi_open_volume);
/**
* ubi_open_volume_nm - open UBI volume by name.
* @ubi_num: UBI device number
* @name: volume name
* @mode: open mode
*
* This function is similar to 'ubi_open_volume()', but opens a volume by name.
*/
struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
int mode)
{
int i, vol_id = -1, len;
struct ubi_device *ubi;
struct ubi_volume_desc *ret;
dbg_gen("open device %d, volume %s, mode %d", ubi_num, name, mode);
if (!name)
return ERR_PTR(-EINVAL);
len = strnlen(name, UBI_VOL_NAME_MAX + 1);
if (len > UBI_VOL_NAME_MAX)
return ERR_PTR(-EINVAL);
if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
return ERR_PTR(-EINVAL);
ubi = ubi_get_device(ubi_num);
if (!ubi)
return ERR_PTR(-ENODEV);
/* Walk all volumes of this UBI device */
for (i = 0; i < ubi->vtbl_slots; i++) {
struct ubi_volume *vol = ubi->volumes[i];
if (vol && len == vol->name_len && !strcmp(name, vol->name)) {
vol_id = i;
break;
}
}
if (vol_id >= 0)
ret = ubi_open_volume(ubi_num, vol_id, mode);
else
ret = ERR_PTR(-ENODEV);
/*
* We should put the UBI device even in case of success, because
* 'ubi_open_volume()' took a reference as well.
*/
ubi_put_device(ubi);
return ret;
}
EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
/**
* ubi_close_volume - close UBI volume.
* @desc: volume descriptor
*/
void ubi_close_volume(struct ubi_volume_desc *desc)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
dbg_gen("close device %d, volume %d, mode %d",
ubi->ubi_num, vol->vol_id, desc->mode);
switch (desc->mode) {
case UBI_READONLY:
vol->readers -= 1;
break;
case UBI_READWRITE:
vol->writers -= 1;
break;
case UBI_EXCLUSIVE:
vol->exclusive = 0;
}
vol->ref_count -= 1;
kfree(desc);
ubi_put_device(ubi);
}
EXPORT_SYMBOL_GPL(ubi_close_volume);
/**
* ubi_leb_read - read data.
* @desc: volume descriptor
* @lnum: logical eraseblock number to read from
* @buf: buffer where to store the read data
* @offset: offset within the logical eraseblock to read from
* @len: how many bytes to read
* @check: whether UBI has to check the read data's CRC or not.
*
* This function reads data from offset @offset of logical eraseblock @lnum and
* stores the data at @buf. When reading from static volumes, @check specifies
* whether the data has to be checked or not. If yes, the whole logical
* eraseblock will be read and its CRC checksum will be checked (i.e., the CRC
* checksum is per-eraseblock). So checking may substantially slow down the
* read speed. The @check argument is ignored for dynamic volumes.
*
* In case of success, this function returns zero. In case of failure, this
* function returns a negative error code.
*
* %-EBADMSG error code is returned:
* o for both static and dynamic volumes if MTD driver has detected a data
* integrity problem (unrecoverable ECC checksum mismatch in case of NAND);
* o for static volumes in case of data CRC mismatch.
*
* If the volume is damaged because of an interrupted update this function just
* returns immediately with %-EBADF error code.
*/
int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
int len, int check)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int err, vol_id = vol->vol_id;
dbg_gen("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset);
if (vol_id < 0 || vol_id >= ubi->vtbl_slots || lnum < 0 ||
lnum >= vol->used_ebs || offset < 0 || len < 0 ||
offset + len > vol->usable_leb_size)
return -EINVAL;
if (vol->vol_type == UBI_STATIC_VOLUME) {
if (vol->used_ebs == 0)
/* Empty static UBI volume */
return 0;
if (lnum == vol->used_ebs - 1 &&
offset + len > vol->last_eb_bytes)
return -EINVAL;
}
if (vol->upd_marker)
return -EBADF;
if (len == 0)
return 0;
err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check);
if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) {
ubi_warn("mark volume %d as corrupted", vol_id);
vol->corrupted = 1;
}
return err;
}
EXPORT_SYMBOL_GPL(ubi_leb_read);
/**
* ubi_leb_write - write data.
* @desc: volume descriptor
* @lnum: logical eraseblock number to write to
* @buf: data to write
* @offset: offset within the logical eraseblock where to write
* @len: how many bytes to write
*
* This function writes @len bytes of data from @buf to offset @offset of
* logical eraseblock @lnum.
*
* This function takes care of physical eraseblock write failures. If write to
* the physical eraseblock write operation fails, the logical eraseblock is
* re-mapped to another physical eraseblock, the data is recovered, and the
* write finishes. UBI has a pool of reserved physical eraseblocks for this.
*
* If all the data were successfully written, zero is returned. If an error
* occurred and UBI has not been able to recover from it, this function returns
* a negative error code. Note, in case of an error, it is possible that
* something was still written to the flash media, but that may be some
* garbage.
*
* If the volume is damaged because of an interrupted update this function just
* returns immediately with %-EBADF code.
*/
int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
int offset, int len)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int vol_id = vol->vol_id;
dbg_gen("write %d bytes to LEB %d:%d:%d", len, vol_id, lnum, offset);
if (vol_id < 0 || vol_id >= ubi->vtbl_slots)
return -EINVAL;
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs || offset < 0 || len < 0 ||
offset + len > vol->usable_leb_size ||
offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1))
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (len == 0)
return 0;
return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len);
}
EXPORT_SYMBOL_GPL(ubi_leb_write);
/*
* ubi_leb_change - change logical eraseblock atomically.
* @desc: volume descriptor
* @lnum: logical eraseblock number to change
* @buf: data to write
* @len: how many bytes to write
*
* This function changes the contents of a logical eraseblock atomically. @buf
* has to contain new logical eraseblock data, and @len - the length of the
* data, which has to be aligned. The length may be shorter than the logical
* eraseblock size, ant the logical eraseblock may be appended to more times
* later on. This function guarantees that in case of an unclean reboot the old
* contents is preserved. Returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int vol_id = vol->vol_id;
dbg_gen("atomically write %d bytes to LEB %d:%d", len, vol_id, lnum);
if (vol_id < 0 || vol_id >= ubi->vtbl_slots)
return -EINVAL;
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs || len < 0 ||
len > vol->usable_leb_size || len & (ubi->min_io_size - 1))
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (len == 0)
return 0;
return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len);
}
EXPORT_SYMBOL_GPL(ubi_leb_change);
/**
* ubi_leb_erase - erase logical eraseblock.
* @desc: volume descriptor
* @lnum: logical eraseblock number
*
* This function un-maps logical eraseblock @lnum and synchronously erases the
* correspondent physical eraseblock. Returns zero in case of success and a
* negative error code in case of failure.
*
* If the volume is damaged because of an interrupted update this function just
* returns immediately with %-EBADF code.
*/
int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int err;
dbg_gen("erase LEB %d:%d", vol->vol_id, lnum);
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
err = ubi_eba_unmap_leb(ubi, vol, lnum);
if (err)
return err;
return ubi_wl_flush(ubi, vol->vol_id, lnum);
}
EXPORT_SYMBOL_GPL(ubi_leb_erase);
/**
* ubi_leb_unmap - un-map logical eraseblock.
* @desc: volume descriptor
* @lnum: logical eraseblock number
*
* This function un-maps logical eraseblock @lnum and schedules the
* corresponding physical eraseblock for erasure, so that it will eventually be
* physically erased in background. This operation is much faster than the
* erase operation.
*
* Unlike erase, the un-map operation does not guarantee that the logical
* eraseblock will contain all 0xFF bytes when UBI is initialized again. For
* example, if several logical eraseblocks are un-mapped, and an unclean reboot
* happens after this, the logical eraseblocks will not necessarily be
* un-mapped again when this MTD device is attached. They may actually be
* mapped to the same physical eraseblocks again. So, this function has to be
* used with care.
*
* In other words, when un-mapping a logical eraseblock, UBI does not store
* any information about this on the flash media, it just marks the logical
* eraseblock as "un-mapped" in RAM. If UBI is detached before the physical
* eraseblock is physically erased, it will be mapped again to the same logical
* eraseblock when the MTD device is attached again.
*
* The main and obvious use-case of this function is when the contents of a
* logical eraseblock has to be re-written. Then it is much more efficient to
* first un-map it, then write new data, rather than first erase it, then write
* new data. Note, once new data has been written to the logical eraseblock,
* UBI guarantees that the old contents has gone forever. In other words, if an
* unclean reboot happens after the logical eraseblock has been un-mapped and
* then written to, it will contain the last written data.
*
* This function returns zero in case of success and a negative error code in
* case of failure. If the volume is damaged because of an interrupted update
* this function just returns immediately with %-EBADF code.
*/
int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
dbg_gen("unmap LEB %d:%d", vol->vol_id, lnum);
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
return ubi_eba_unmap_leb(ubi, vol, lnum);
}
EXPORT_SYMBOL_GPL(ubi_leb_unmap);
/**
* ubi_leb_map - map logical eraseblock to a physical eraseblock.
* @desc: volume descriptor
* @lnum: logical eraseblock number
*
* This function maps an un-mapped logical eraseblock @lnum to a physical
* eraseblock. This means, that after a successful invocation of this
* function the logical eraseblock @lnum will be empty (contain only %0xFF
* bytes) and be mapped to a physical eraseblock, even if an unclean reboot
* happens.
*
* This function returns zero in case of success, %-EBADF if the volume is
* damaged because of an interrupted update, %-EBADMSG if the logical
* eraseblock is already mapped, and other negative error codes in case of
* other failures.
*/
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
dbg_gen("unmap LEB %d:%d", vol->vol_id, lnum);
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (vol->eba_tbl[lnum] >= 0)
return -EBADMSG;
return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0);
}
EXPORT_SYMBOL_GPL(ubi_leb_map);
/**
* ubi_is_mapped - check if logical eraseblock is mapped.
* @desc: volume descriptor
* @lnum: logical eraseblock number
*
* This function checks if logical eraseblock @lnum is mapped to a physical
* eraseblock. If a logical eraseblock is un-mapped, this does not necessarily
* mean it will still be un-mapped after the UBI device is re-attached. The
* logical eraseblock may become mapped to the physical eraseblock it was last
* mapped to.
*
* This function returns %1 if the LEB is mapped, %0 if not, and a negative
* error code in case of failure. If the volume is damaged because of an
* interrupted update this function just returns immediately with %-EBADF error
* code.
*/
int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum)
{
struct ubi_volume *vol = desc->vol;
dbg_gen("test LEB %d:%d", vol->vol_id, lnum);
if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
return vol->eba_tbl[lnum] >= 0;
}
EXPORT_SYMBOL_GPL(ubi_is_mapped);
/**
* ubi_flush - flush UBI work queue.
* @ubi_num: UBI device to flush work queue
* @vol_id: volume id to flush for
* @lnum: logical eraseblock number to flush for
*
* This function executes all pending works for a particular volume id / logical
* eraseblock number pair. If either value is set to %UBI_ALL, then it acts as
* a wildcard for all of the corresponding volume numbers or logical
* eraseblock numbers. It returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_flush(int ubi_num, int vol_id, int lnum)
{
struct ubi_device *ubi;
int err = 0;
ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
err = ubi_wl_flush(ubi, vol_id, lnum);
ubi_put_device(ubi);
return err;
}
EXPORT_SYMBOL_GPL(ubi_flush);

153
drivers/mtd/ubi/misc.c Normal file
View File

@ -0,0 +1,153 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
/* Here we keep miscellaneous functions which are used all over the UBI code */
#include "ubi.h"
/**
* calc_data_len - calculate how much real data is stored in a buffer.
* @ubi: UBI device description object
* @buf: a buffer with the contents of the physical eraseblock
* @length: the buffer length
*
* This function calculates how much "real data" is stored in @buf and returnes
* the length. Continuous 0xFF bytes at the end of the buffer are not
* considered as "real data".
*/
int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
int length)
{
int i;
ubi_assert(!(length & (ubi->min_io_size - 1)));
for (i = length - 1; i >= 0; i--)
if (((const uint8_t *)buf)[i] != 0xFF)
break;
/* The resulting length must be aligned to the minimum flash I/O size */
length = ALIGN(i + 1, ubi->min_io_size);
return length;
}
/**
* ubi_check_volume - check the contents of a static volume.
* @ubi: UBI device description object
* @vol_id: ID of the volume to check
*
* This function checks if static volume @vol_id is corrupted by fully reading
* it and checking data CRC. This function returns %0 if the volume is not
* corrupted, %1 if it is corrupted and a negative error code in case of
* failure. Dynamic volumes are not checked and zero is returned immediately.
*/
int ubi_check_volume(struct ubi_device *ubi, int vol_id)
{
void *buf;
int err = 0, i;
struct ubi_volume *vol = ubi->volumes[vol_id];
if (vol->vol_type != UBI_STATIC_VOLUME)
return 0;
buf = vmalloc(vol->usable_leb_size);
if (!buf)
return -ENOMEM;
for (i = 0; i < vol->used_ebs; i++) {
int size;
if (i == vol->used_ebs - 1)
size = vol->last_eb_bytes;
else
size = vol->usable_leb_size;
err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
if (err) {
if (mtd_is_eccerr(err))
err = 1;
break;
}
}
vfree(buf);
return err;
}
/**
* ubi_update_reserved - update bad eraseblock handling accounting data.
* @ubi: UBI device description object
*
* This function calculates the gap between current number of PEBs reserved for
* bad eraseblock handling and the required level of PEBs that must be
* reserved, and if necessary, reserves more PEBs to fill that gap, according
* to availability. Should be called with ubi->volumes_lock held.
*/
void ubi_update_reserved(struct ubi_device *ubi)
{
int need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs;
if (need <= 0 || ubi->avail_pebs == 0)
return;
need = min_t(int, need, ubi->avail_pebs);
ubi->avail_pebs -= need;
ubi->rsvd_pebs += need;
ubi->beb_rsvd_pebs += need;
ubi_msg("reserved more %d PEBs for bad PEB handling", need);
}
/**
* ubi_calculate_reserved - calculate how many PEBs must be reserved for bad
* eraseblock handling.
* @ubi: UBI device description object
*/
void ubi_calculate_reserved(struct ubi_device *ubi)
{
/*
* Calculate the actual number of PEBs currently needed to be reserved
* for future bad eraseblock handling.
*/
ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count;
if (ubi->beb_rsvd_level < 0) {
ubi->beb_rsvd_level = 0;
ubi_warn("number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)",
ubi->bad_peb_count, ubi->bad_peb_limit);
}
}
/**
* ubi_check_pattern - check if buffer contains only a certain byte pattern.
* @buf: buffer to check
* @patt: the pattern to check
* @size: buffer size in bytes
*
* This function returns %1 in there are only @patt bytes in @buf, and %0 if
* something else was also found.
*/
int ubi_check_pattern(const void *buf, uint8_t patt, int size)
{
int i;
for (i = 0; i < size; i++)
if (((const uint8_t *)buf)[i] != patt)
return 0;
return 1;
}

View File

@ -0,0 +1,71 @@
/*
* Header file for UBI support for U-Boot
*
* Adaptation from kernel to U-Boot
*
* Copyright (C) 2005-2007 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __UBOOT_UBI_H
#define __UBOOT_UBI_H
#include <common.h>
#include <malloc.h>
#include <asm-generic/div64.h>
#include <errno.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/rbtree.h>
#include <linux/string.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/ubi.h>
#define crc32(seed, data, length) crc32_no_comp(seed, (unsigned char const *)data, length)
/* configurable */
#define CONFIG_MTD_UBI_WL_THRESHOLD 4096
#define UBI_IO_DEBUG 0
#define DUMP_PREFIX_OFFSET 0
static inline void print_hex_dump(const char *level, const char *prefix_str,
int prefix_type, int rowsize, int groupsize,
const void *buf, size_t len, bool ascii)
{
memory_display(buf, 0, len, 4, 0);
}
/* upd.c */
static inline unsigned long copy_from_user(void *dest, const void *src,
unsigned long count)
{
memcpy((void *)dest, (void *)src, count);
return 0;
}
/* common */
#define GFP_NOFS 1
#define wake_up_process(...) do { } while (0)
#define BUS_ID_SIZE 20
#define MAX_ERRNO 4095
#ifndef __UBIFS_H__
#include "ubi.h"
#endif
/* functions */
extern struct ubi_device *ubi_devices[];
int ubi_cdev_add(struct ubi_device *ubi);
#endif

515
drivers/mtd/ubi/ubi-media.h Normal file
View File

@ -0,0 +1,515 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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
*
* Authors: Artem Bityutskiy (Битюцкий Артём)
* Thomas Gleixner
* Frank Haverkamp
* Oliver Lohmann
* Andreas Arnez
*/
/*
* This file defines the layout of UBI headers and all the other UBI on-flash
* data structures.
*/
#ifndef __UBI_MEDIA_H__
#define __UBI_MEDIA_H__
#include <asm/byteorder.h>
/* The version of UBI images supported by this implementation */
#define UBI_VERSION 1
/* The highest erase counter value supported by this implementation */
#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF
/* The initial CRC32 value used when calculating CRC checksums */
#define UBI_CRC32_INIT 0xFFFFFFFFU
/* Erase counter header magic number (ASCII "UBI#") */
#define UBI_EC_HDR_MAGIC 0x55424923
/* Volume identifier header magic number (ASCII "UBI!") */
#define UBI_VID_HDR_MAGIC 0x55424921
/*
* Volume type constants used in the volume identifier header.
*
* @UBI_VID_DYNAMIC: dynamic volume
* @UBI_VID_STATIC: static volume
*/
enum {
UBI_VID_DYNAMIC = 1,
UBI_VID_STATIC = 2
};
/*
* Volume flags used in the volume table record.
*
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
*
* %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
* table. UBI automatically re-sizes the volume which has this flag and makes
* the volume to be of largest possible size. This means that if after the
* initialization UBI finds out that there are available physical eraseblocks
* present on the device, it automatically appends all of them to the volume
* (the physical eraseblocks reserved for bad eraseblocks handling and other
* reserved physical eraseblocks are not taken). So, if there is a volume with
* the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical
* eraseblocks will be zero after UBI is loaded, because all of them will be
* reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared
* after the volume had been initialized.
*
* The auto-resize feature is useful for device production purposes. For
* example, different NAND flash chips may have different amount of initial bad
* eraseblocks, depending of particular chip instance. Manufacturers of NAND
* chips usually guarantee that the amount of initial bad eraseblocks does not
* exceed certain percent, e.g. 2%. When one creates an UBI image which will be
* flashed to the end devices in production, he does not know the exact amount
* of good physical eraseblocks the NAND chip on the device will have, but this
* number is required to calculate the volume sized and put them to the volume
* table of the UBI image. In this case, one of the volumes (e.g., the one
* which will store the root file system) is marked as "auto-resizable", and
* UBI will adjust its size on the first boot if needed.
*
* Note, first UBI reserves some amount of physical eraseblocks for bad
* eraseblock handling, and then re-sizes the volume, not vice-versa. This
* means that the pool of reserved physical eraseblocks will always be present.
*/
enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01,
};
/*
* Compatibility constants used by internal volumes.
*
* @UBI_COMPAT_DELETE: delete this internal volume before anything is written
* to the flash
* @UBI_COMPAT_RO: attach this device in read-only mode
* @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its
* physical eraseblocks, don't allow the wear-leveling
* sub-system to move them
* @UBI_COMPAT_REJECT: reject this UBI image
*/
enum {
UBI_COMPAT_DELETE = 1,
UBI_COMPAT_RO = 2,
UBI_COMPAT_PRESERVE = 4,
UBI_COMPAT_REJECT = 5
};
/* Sizes of UBI headers */
#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr)
#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr)
/* Sizes of UBI headers without the ending CRC */
#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32))
#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32))
/**
* struct ubi_ec_hdr - UBI erase counter header.
* @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC)
* @version: version of UBI implementation which is supposed to accept this
* UBI image
* @padding1: reserved for future, zeroes
* @ec: the erase counter
* @vid_hdr_offset: where the VID header starts
* @data_offset: where the user data start
* @image_seq: image sequence number
* @padding2: reserved for future, zeroes
* @hdr_crc: erase counter header CRC checksum
*
* The erase counter header takes 64 bytes and has a plenty of unused space for
* future usage. The unused fields are zeroed. The @version field is used to
* indicate the version of UBI implementation which is supposed to be able to
* work with this UBI image. If @version is greater than the current UBI
* version, the image is rejected. This may be useful in future if something
* is changed radically. This field is duplicated in the volume identifier
* header.
*
* The @vid_hdr_offset and @data_offset fields contain the offset of the the
* volume identifier header and user data, relative to the beginning of the
* physical eraseblock. These values have to be the same for all physical
* eraseblocks.
*
* The @image_seq field is used to validate a UBI image that has been prepared
* for a UBI device. The @image_seq value can be any value, but it must be the
* same on all eraseblocks. UBI will ensure that all new erase counter headers
* also contain this value, and will check the value when attaching the flash.
* One way to make use of @image_seq is to increase its value by one every time
* an image is flashed over an existing image, then, if the flashing does not
* complete, UBI will detect the error when attaching the media.
*/
struct ubi_ec_hdr {
__be32 magic;
__u8 version;
__u8 padding1[3];
__be64 ec; /* Warning: the current limit is 31-bit anyway! */
__be32 vid_hdr_offset;
__be32 data_offset;
__be32 image_seq;
__u8 padding2[32];
__be32 hdr_crc;
} __packed;
/**
* struct ubi_vid_hdr - on-flash UBI volume identifier header.
* @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC)
* @version: UBI implementation version which is supposed to accept this UBI
* image (%UBI_VERSION)
* @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC)
* @copy_flag: if this logical eraseblock was copied from another physical
* eraseblock (for wear-leveling reasons)
* @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE,
* %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT)
* @vol_id: ID of this volume
* @lnum: logical eraseblock number
* @padding1: reserved for future, zeroes
* @data_size: how many bytes of data this logical eraseblock contains
* @used_ebs: total number of used logical eraseblocks in this volume
* @data_pad: how many bytes at the end of this physical eraseblock are not
* used
* @data_crc: CRC checksum of the data stored in this logical eraseblock
* @padding2: reserved for future, zeroes
* @sqnum: sequence number
* @padding3: reserved for future, zeroes
* @hdr_crc: volume identifier header CRC checksum
*
* The @sqnum is the value of the global sequence counter at the time when this
* VID header was created. The global sequence counter is incremented each time
* UBI writes a new VID header to the flash, i.e. when it maps a logical
* eraseblock to a new physical eraseblock. The global sequence counter is an
* unsigned 64-bit integer and we assume it never overflows. The @sqnum
* (sequence number) is used to distinguish between older and newer versions of
* logical eraseblocks.
*
* There are 2 situations when there may be more than one physical eraseblock
* corresponding to the same logical eraseblock, i.e., having the same @vol_id
* and @lnum values in the volume identifier header. Suppose we have a logical
* eraseblock L and it is mapped to the physical eraseblock P.
*
* 1. Because UBI may erase physical eraseblocks asynchronously, the following
* situation is possible: L is asynchronously erased, so P is scheduled for
* erasure, then L is written to,i.e. mapped to another physical eraseblock P1,
* so P1 is written to, then an unclean reboot happens. Result - there are 2
* physical eraseblocks P and P1 corresponding to the same logical eraseblock
* L. But P1 has greater sequence number, so UBI picks P1 when it attaches the
* flash.
*
* 2. From time to time UBI moves logical eraseblocks to other physical
* eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P
* to P1, and an unclean reboot happens before P is physically erased, there
* are two physical eraseblocks P and P1 corresponding to L and UBI has to
* select one of them when the flash is attached. The @sqnum field says which
* PEB is the original (obviously P will have lower @sqnum) and the copy. But
* it is not enough to select the physical eraseblock with the higher sequence
* number, because the unclean reboot could have happen in the middle of the
* copying process, so the data in P is corrupted. It is also not enough to
* just select the physical eraseblock with lower sequence number, because the
* data there may be old (consider a case if more data was added to P1 after
* the copying). Moreover, the unclean reboot may happen when the erasure of P
* was just started, so it result in unstable P, which is "mostly" OK, but
* still has unstable bits.
*
* UBI uses the @copy_flag field to indicate that this logical eraseblock is a
* copy. UBI also calculates data CRC when the data is moved and stores it at
* the @data_crc field of the copy (P1). So when UBI needs to pick one physical
* eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is
* examined. If it is cleared, the situation* is simple and the newer one is
* picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC
* checksum is correct, this physical eraseblock is selected (P1). Otherwise
* the older one (P) is selected.
*
* There are 2 sorts of volumes in UBI: user volumes and internal volumes.
* Internal volumes are not seen from outside and are used for various internal
* UBI purposes. In this implementation there is only one internal volume - the
* layout volume. Internal volumes are the main mechanism of UBI extensions.
* For example, in future one may introduce a journal internal volume. Internal
* volumes have their own reserved range of IDs.
*
* The @compat field is only used for internal volumes and contains the "degree
* of their compatibility". It is always zero for user volumes. This field
* provides a mechanism to introduce UBI extensions and to be still compatible
* with older UBI binaries. For example, if someone introduced a journal in
* future, he would probably use %UBI_COMPAT_DELETE compatibility for the
* journal volume. And in this case, older UBI binaries, which know nothing
* about the journal volume, would just delete this volume and work perfectly
* fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image
* - it just ignores the Ext3fs journal.
*
* The @data_crc field contains the CRC checksum of the contents of the logical
* eraseblock if this is a static volume. In case of dynamic volumes, it does
* not contain the CRC checksum as a rule. The only exception is when the
* data of the physical eraseblock was moved by the wear-leveling sub-system,
* then the wear-leveling sub-system calculates the data CRC and stores it in
* the @data_crc field. And of course, the @copy_flag is %in this case.
*
* The @data_size field is used only for static volumes because UBI has to know
* how many bytes of data are stored in this eraseblock. For dynamic volumes,
* this field usually contains zero. The only exception is when the data of the
* physical eraseblock was moved to another physical eraseblock for
* wear-leveling reasons. In this case, UBI calculates CRC checksum of the
* contents and uses both @data_crc and @data_size fields. In this case, the
* @data_size field contains data size.
*
* The @used_ebs field is used only for static volumes and indicates how many
* eraseblocks the data of the volume takes. For dynamic volumes this field is
* not used and always contains zero.
*
* The @data_pad is calculated when volumes are created using the alignment
* parameter. So, effectively, the @data_pad field reduces the size of logical
* eraseblocks of this volume. This is very handy when one uses block-oriented
* software (say, cramfs) on top of the UBI volume.
*/
struct ubi_vid_hdr {
__be32 magic;
__u8 version;
__u8 vol_type;
__u8 copy_flag;
__u8 compat;
__be32 vol_id;
__be32 lnum;
__u8 padding1[4];
__be32 data_size;
__be32 used_ebs;
__be32 data_pad;
__be32 data_crc;
__u8 padding2[4];
__be64 sqnum;
__u8 padding3[12];
__be32 hdr_crc;
} __packed;
/* Internal UBI volumes count */
#define UBI_INT_VOL_COUNT 1
/*
* Starting ID of internal volumes: 0x7fffefff.
* There is reserved room for 4096 internal volumes.
*/
#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096)
/* The layout volume contains the volume table */
#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START
#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC
#define UBI_LAYOUT_VOLUME_ALIGN 1
#define UBI_LAYOUT_VOLUME_EBS 2
#define UBI_LAYOUT_VOLUME_NAME "layout volume"
#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT
/* The maximum number of volumes per one UBI device */
#define UBI_MAX_VOLUMES 128
/* The maximum volume name length */
#define UBI_VOL_NAME_MAX 127
/* Size of the volume table record */
#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record)
/* Size of the volume table record without the ending CRC */
#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32))
/**
* struct ubi_vtbl_record - a record in the volume table.
* @reserved_pebs: how many physical eraseblocks are reserved for this volume
* @alignment: volume alignment
* @data_pad: how many bytes are unused at the end of the each physical
* eraseblock to satisfy the requested alignment
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
* @upd_marker: if volume update was started but not finished
* @name_len: volume name length
* @name: the volume name
* @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG)
* @padding: reserved, zeroes
* @crc: a CRC32 checksum of the record
*
* The volume table records are stored in the volume table, which is stored in
* the layout volume. The layout volume consists of 2 logical eraseblock, each
* of which contains a copy of the volume table (i.e., the volume table is
* duplicated). The volume table is an array of &struct ubi_vtbl_record
* objects indexed by the volume ID.
*
* If the size of the logical eraseblock is large enough to fit
* %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES
* records. Otherwise, it contains as many records as it can fit (i.e., size of
* logical eraseblock divided by sizeof(struct ubi_vtbl_record)).
*
* The @upd_marker flag is used to implement volume update. It is set to %1
* before update and set to %0 after the update. So if the update operation was
* interrupted, UBI knows that the volume is corrupted.
*
* The @alignment field is specified when the volume is created and cannot be
* later changed. It may be useful, for example, when a block-oriented file
* system works on top of UBI. The @data_pad field is calculated using the
* logical eraseblock size and @alignment. The alignment must be multiple to the
* minimal flash I/O unit. If @alignment is 1, all the available space of
* the physical eraseblocks is used.
*
* Empty records contain all zeroes and the CRC checksum of those zeroes.
*/
struct ubi_vtbl_record {
__be32 reserved_pebs;
__be32 alignment;
__be32 data_pad;
__u8 vol_type;
__u8 upd_marker;
__be16 name_len;
__u8 name[UBI_VOL_NAME_MAX+1];
__u8 flags;
__u8 padding[23];
__be32 crc;
} __packed;
/* UBI fastmap on-flash data structures */
#define UBI_FM_SB_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 1)
#define UBI_FM_DATA_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 2)
/* fastmap on-flash data structure format version */
#define UBI_FM_FMT_VERSION 1
#define UBI_FM_SB_MAGIC 0x7B11D69F
#define UBI_FM_HDR_MAGIC 0xD4B82EF7
#define UBI_FM_VHDR_MAGIC 0xFA370ED1
#define UBI_FM_POOL_MAGIC 0x67AF4D08
#define UBI_FM_EBA_MAGIC 0xf0c040a8
/* A fastmap supber block can be located between PEB 0 and
* UBI_FM_MAX_START */
#define UBI_FM_MAX_START 64
/* A fastmap can use up to UBI_FM_MAX_BLOCKS PEBs */
#define UBI_FM_MAX_BLOCKS 32
/* 5% of the total number of PEBs have to be scanned while attaching
* from a fastmap.
* But the size of this pool is limited to be between UBI_FM_MIN_POOL_SIZE and
* UBI_FM_MAX_POOL_SIZE */
#define UBI_FM_MIN_POOL_SIZE 8
#define UBI_FM_MAX_POOL_SIZE 256
#define UBI_FM_WL_POOL_SIZE 25
/**
* struct ubi_fm_sb - UBI fastmap super block
* @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC)
* @version: format version of this fastmap
* @data_crc: CRC over the fastmap data
* @used_blocks: number of PEBs used by this fastmap
* @block_loc: an array containing the location of all PEBs of the fastmap
* @block_ec: the erase counter of each used PEB
* @sqnum: highest sequence number value at the time while taking the fastmap
*
*/
struct ubi_fm_sb {
__be32 magic;
__u8 version;
__u8 padding1[3];
__be32 data_crc;
__be32 used_blocks;
__be32 block_loc[UBI_FM_MAX_BLOCKS];
__be32 block_ec[UBI_FM_MAX_BLOCKS];
__be64 sqnum;
__u8 padding2[32];
} __packed;
/**
* struct ubi_fm_hdr - header of the fastmap data set
* @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC)
* @free_peb_count: number of free PEBs known by this fastmap
* @used_peb_count: number of used PEBs known by this fastmap
* @scrub_peb_count: number of to be scrubbed PEBs known by this fastmap
* @bad_peb_count: number of bad PEBs known by this fastmap
* @erase_peb_count: number of bad PEBs which have to be erased
* @vol_count: number of UBI volumes known by this fastmap
*/
struct ubi_fm_hdr {
__be32 magic;
__be32 free_peb_count;
__be32 used_peb_count;
__be32 scrub_peb_count;
__be32 bad_peb_count;
__be32 erase_peb_count;
__be32 vol_count;
__u8 padding[4];
} __packed;
/* struct ubi_fm_hdr is followed by two struct ubi_fm_scan_pool */
/**
* struct ubi_fm_scan_pool - Fastmap pool PEBs to be scanned while attaching
* @magic: pool magic numer (%UBI_FM_POOL_MAGIC)
* @size: current pool size
* @max_size: maximal pool size
* @pebs: an array containing the location of all PEBs in this pool
*/
struct ubi_fm_scan_pool {
__be32 magic;
__be16 size;
__be16 max_size;
__be32 pebs[UBI_FM_MAX_POOL_SIZE];
__be32 padding[4];
} __packed;
/* ubi_fm_scan_pool is followed by nfree+nused struct ubi_fm_ec records */
/**
* struct ubi_fm_ec - stores the erase counter of a PEB
* @pnum: PEB number
* @ec: ec of this PEB
*/
struct ubi_fm_ec {
__be32 pnum;
__be32 ec;
} __packed;
/**
* struct ubi_fm_volhdr - Fastmap volume header
* it identifies the start of an eba table
* @magic: Fastmap volume header magic number (%UBI_FM_VHDR_MAGIC)
* @vol_id: volume id of the fastmapped volume
* @vol_type: type of the fastmapped volume
* @data_pad: data_pad value of the fastmapped volume
* @used_ebs: number of used LEBs within this volume
* @last_eb_bytes: number of bytes used in the last LEB
*/
struct ubi_fm_volhdr {
__be32 magic;
__be32 vol_id;
__u8 vol_type;
__u8 padding1[3];
__be32 data_pad;
__be32 used_ebs;
__be32 last_eb_bytes;
__u8 padding2[8];
} __packed;
/* struct ubi_fm_volhdr is followed by one struct ubi_fm_eba records */
/**
* struct ubi_fm_eba - denotes an association beween a PEB and LEB
* @magic: EBA table magic number
* @reserved_pebs: number of table entries
* @pnum: PEB number of LEB (LEB is the index)
*/
struct ubi_fm_eba {
__be32 magic;
__be32 reserved_pebs;
__be32 pnum[0];
} __packed;
#endif /* !__UBI_MEDIA_H__ */

974
drivers/mtd/ubi/ubi.h Normal file
View File

@ -0,0 +1,974 @@
/*
* 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 (Битюцкий Артём)
*/
#ifndef __UBI_UBI_H__
#define __UBI_UBI_H__
#include <common.h>
#include <malloc.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/rbtree.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/ubi.h>
#include <mtd/ubi-media.h>
#include "ubi-barebox.h"
/* Maximum number of supported UBI devices */
#define UBI_MAX_DEVICES 32
/* UBI name used for character devices, sysfs, etc */
#define UBI_NAME_STR "ubi"
/* Normal UBI messages */
#define ubi_msg(fmt, ...) pr_info("UBI: " fmt "\n", ##__VA_ARGS__)
/* UBI warning messages */
#define ubi_warn(fmt, ...) pr_warn("UBI warning: %s: " fmt "\n", \
__func__, ##__VA_ARGS__)
/* UBI error messages */
#define ubi_err(fmt, ...) pr_err("UBI error: %s: " fmt "\n", \
__func__, ##__VA_ARGS__)
/* Background thread name pattern */
#define UBI_BGT_NAME_PATTERN "ubi_bgt%dd"
/*
* This marker in the EBA table means that the LEB is um-mapped.
* NOTE! It has to have the same value as %UBI_ALL.
*/
#define UBI_LEB_UNMAPPED -1
/*
* In case of errors, UBI tries to repeat the operation several times before
* returning error. The below constant defines how many times UBI re-tries.
*/
#define UBI_IO_RETRIES 3
/*
* Length of the protection queue. The length is effectively equivalent to the
* number of (global) erase cycles PEBs are protected from the wear-leveling
* worker.
*/
#define UBI_PROT_QUEUE_LEN 10
/* The volume ID/LEB number/erase counter is unknown */
#define UBI_UNKNOWN -1
/*
* The UBI debugfs directory name pattern and maximum name length (3 for "ubi"
* + 2 for the number plus 1 for the trailing zero byte.
*/
#define UBI_DFS_DIR_NAME "ubi%d"
#define UBI_DFS_DIR_LEN (3 + 2 + 1)
/*
* Error codes returned by the I/O sub-system.
*
* UBI_IO_FF: the read region of flash contains only 0xFFs
* UBI_IO_FF_BITFLIPS: the same as %UBI_IO_FF, but also also there was a data
* integrity error reported by the MTD driver
* (uncorrectable ECC error in case of NAND)
* UBI_IO_BAD_HDR: the EC or VID header is corrupted (bad magic or CRC)
* UBI_IO_BAD_HDR_EBADMSG: the same as %UBI_IO_BAD_HDR, but also there was a
* data integrity error reported by the MTD driver
* (uncorrectable ECC error in case of NAND)
* UBI_IO_BITFLIPS: bit-flips were detected and corrected
*
* Note, it is probably better to have bit-flip and ebadmsg as flags which can
* be or'ed with other error code. But this is a big change because there are
* may callers, so it does not worth the risk of introducing a bug
*/
enum {
UBI_IO_FF = 1,
UBI_IO_FF_BITFLIPS,
UBI_IO_BAD_HDR,
UBI_IO_BAD_HDR_EBADMSG,
UBI_IO_BITFLIPS,
};
/*
* Return codes of the 'ubi_eba_copy_leb()' function.
*
* MOVE_CANCEL_RACE: canceled because the volume is being deleted, the source
* PEB was put meanwhile, or there is I/O on the source PEB
* MOVE_SOURCE_RD_ERR: canceled because there was a read error from the source
* PEB
* MOVE_TARGET_RD_ERR: canceled because there was a read error from the target
* PEB
* MOVE_TARGET_WR_ERR: canceled because there was a write error to the target
* PEB
* MOVE_TARGET_BITFLIPS: canceled because a bit-flip was detected in the
* target PEB
* MOVE_RETRY: retry scrubbing the PEB
*/
enum {
MOVE_CANCEL_RACE = 1,
MOVE_SOURCE_RD_ERR,
MOVE_TARGET_RD_ERR,
MOVE_TARGET_WR_ERR,
MOVE_TARGET_BITFLIPS,
MOVE_RETRY,
};
/*
* Return codes of the fastmap sub-system
*
* UBI_NO_FASTMAP: No fastmap super block was found
* UBI_BAD_FASTMAP: A fastmap was found but it's unusable
*/
enum {
UBI_NO_FASTMAP = 1,
UBI_BAD_FASTMAP,
};
/**
* struct ubi_wl_entry - wear-leveling entry.
* @u.rb: link in the corresponding (free/used) RB-tree
* @u.list: link in the protection queue
* @ec: erase counter
* @pnum: physical eraseblock number
*
* This data structure is used in the WL sub-system. Each physical eraseblock
* has a corresponding &struct wl_entry object which may be kept in different
* RB-trees. See WL sub-system for details.
*/
struct ubi_wl_entry {
union {
struct rb_node rb;
struct list_head list;
} u;
int ec;
int pnum;
};
/**
* struct ubi_ltree_entry - an entry in the lock tree.
* @rb: links RB-tree nodes
* @vol_id: volume ID of the locked logical eraseblock
* @lnum: locked logical eraseblock number
* @users: how many tasks are using this logical eraseblock or wait for it
* @mutex: read/write mutex to implement read/write access serialization to
* the (@vol_id, @lnum) logical eraseblock
*
* This data structure is used in the EBA sub-system to implement per-LEB
* locking. When a logical eraseblock is being locked - corresponding
* &struct ubi_ltree_entry object is inserted to the lock tree (@ubi->ltree).
* See EBA sub-system for details.
*/
struct ubi_ltree_entry {
struct rb_node rb;
int vol_id;
int lnum;
int users;
};
/**
* struct ubi_rename_entry - volume re-name description data structure.
* @new_name_len: new volume name length
* @new_name: new volume name
* @remove: if not zero, this volume should be removed, not re-named
* @desc: descriptor of the volume
* @list: links re-name entries into a list
*
* This data structure is utilized in the multiple volume re-name code. Namely,
* UBI first creates a list of &struct ubi_rename_entry objects from the
* &struct ubi_rnvol_req request object, and then utilizes this list to do all
* the job.
*/
struct ubi_rename_entry {
int new_name_len;
char new_name[UBI_VOL_NAME_MAX + 1];
int remove;
struct ubi_volume_desc *desc;
struct list_head list;
};
struct ubi_volume_desc;
/**
* struct ubi_fastmap_layout - in-memory fastmap data structure.
* @e: PEBs used by the current fastmap
* @to_be_tortured: if non-zero tortured this PEB
* @used_blocks: number of used PEBs
* @max_pool_size: maximal size of the user pool
* @max_wl_pool_size: maximal size of the pool used by the WL sub-system
*/
struct ubi_fastmap_layout {
struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS];
int to_be_tortured[UBI_FM_MAX_BLOCKS];
int used_blocks;
int max_pool_size;
int max_wl_pool_size;
};
/**
* struct ubi_fm_pool - in-memory fastmap pool
* @pebs: PEBs in this pool
* @used: number of used PEBs
* @size: total number of PEBs in this pool
* @max_size: maximal size of the pool
*
* A pool gets filled with up to max_size.
* If all PEBs within the pool are used a new fastmap will be written
* to the flash and the pool gets refilled with empty PEBs.
*
*/
struct ubi_fm_pool {
int pebs[UBI_FM_MAX_POOL_SIZE];
int used;
int size;
int max_size;
};
/**
* struct ubi_volume - UBI volume description data structure.
* @dev: device object to make use of the the Linux device model
* @cdev: character device object to create character device
* @ubi: reference to the UBI device description object
* @vol_id: volume ID
* @ref_count: volume reference count
* @readers: number of users holding this volume in read-only mode
* @writers: number of users holding this volume in read-write mode
* @exclusive: whether somebody holds this volume in exclusive mode
*
* @reserved_pebs: how many physical eraseblocks are reserved for this volume
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
* @usable_leb_size: logical eraseblock size without padding
* @used_ebs: how many logical eraseblocks in this volume contain data
* @last_eb_bytes: how many bytes are stored in the last logical eraseblock
* @used_bytes: how many bytes of data this volume contains
* @alignment: volume alignment
* @data_pad: how many bytes are not used at the end of physical eraseblocks to
* satisfy the requested alignment
* @name_len: volume name length
* @name: volume name
*
* @upd_ebs: how many eraseblocks are expected to be updated
* @ch_lnum: LEB number which is being changing by the atomic LEB change
* operation
* @upd_bytes: how many bytes are expected to be received for volume update or
* atomic LEB change
* @upd_received: how many bytes were already received for volume update or
* atomic LEB change
* @upd_buf: update buffer which is used to collect update data or data for
* atomic LEB change
*
* @eba_tbl: EBA table of this volume (LEB->PEB mapping)
* @checked: %1 if this static volume was checked
* @corrupted: %1 if the volume is corrupted (static volumes only)
* @upd_marker: %1 if the update marker is set for this volume
* @updating: %1 if the volume is being updated
* @changing_leb: %1 if the atomic LEB change ioctl command is in progress
* @direct_writes: %1 if direct writes are enabled for this volume
*
* The @corrupted field indicates that the volume's contents is corrupted.
* Since UBI protects only static volumes, this field is not relevant to
* dynamic volumes - it is user's responsibility to assure their data
* integrity.
*
* The @upd_marker flag indicates that this volume is either being updated at
* the moment or is damaged because of an unclean reboot.
*/
struct ubi_volume {
struct device_d dev;
struct cdev cdev;
struct ubi_device *ubi;
int vol_id;
int ref_count;
int readers;
int writers;
int exclusive;
int reserved_pebs;
int vol_type;
int usable_leb_size;
int used_ebs;
int last_eb_bytes;
long long used_bytes;
int alignment;
int data_pad;
int name_len;
char name[UBI_VOL_NAME_MAX + 1];
int upd_ebs;
int ch_lnum;
long long upd_bytes;
long long upd_received;
void *upd_buf;
int *eba_tbl;
unsigned int checked:1;
unsigned int corrupted:1;
unsigned int upd_marker:1;
unsigned int updating:1;
unsigned int changing_leb:1;
unsigned int direct_writes:1;
};
/**
* struct ubi_volume_desc - UBI volume descriptor returned when it is opened.
* @vol: reference to the corresponding volume description object
* @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE)
*/
struct ubi_volume_desc {
struct ubi_volume *vol;
int mode;
};
struct ubi_wl_entry;
/**
* struct ubi_debug_info - debugging information for an UBI device.
*
* @chk_gen: if UBI general extra checks are enabled
* @chk_io: if UBI I/O extra checks are enabled
* @disable_bgt: disable the background task for testing purposes
* @emulate_bitflips: emulate bit-flips for testing purposes
* @emulate_io_failures: emulate write/erase failures for testing purposes
* @dfs_dir_name: name of debugfs directory containing files of this UBI device
* @dfs_dir: direntry object of the UBI device debugfs directory
* @dfs_chk_gen: debugfs knob to enable UBI general extra checks
* @dfs_chk_io: debugfs knob to enable UBI I/O extra checks
* @dfs_disable_bgt: debugfs knob to disable the background task
* @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
* @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
*/
struct ubi_debug_info {
unsigned int chk_gen:1;
unsigned int chk_io:1;
unsigned int disable_bgt:1;
unsigned int emulate_bitflips:1;
unsigned int emulate_io_failures:1;
char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_chk_gen;
struct dentry *dfs_chk_io;
struct dentry *dfs_disable_bgt;
struct dentry *dfs_emulate_bitflips;
struct dentry *dfs_emulate_io_failures;
};
/**
* struct ubi_device - UBI device description structure
* @dev: UBI device object to use the the Linux device model
* @cdev: character device object to create character device
* @ubi_num: UBI device number
* @ubi_name: UBI device name
* @vol_count: number of volumes in this UBI device
* @volumes: volumes of this UBI device
* @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs,
* @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count,
* @vol->readers, @vol->writers, @vol->exclusive,
* @vol->ref_count, @vol->mapping and @vol->eba_tbl.
* @ref_count: count of references on the UBI device
* @image_seq: image sequence number recorded on EC headers
*
* @rsvd_pebs: count of reserved physical eraseblocks
* @avail_pebs: count of available physical eraseblocks
* @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB
* handling
* @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling
*
* @autoresize_vol_id: ID of the volume which has to be auto-resized at the end
* of UBI initialization
* @vtbl_slots: how many slots are available in the volume table
* @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy
* @device_mutex: protects on-flash volume table and serializes volume
* creation, deletion, update, re-size, re-name and set
* property
*
* @max_ec: current highest erase counter value
* @mean_ec: current mean erase counter value
*
* @global_sqnum: global sequence number
* @ltree_lock: protects the lock tree and @global_sqnum
* @ltree: the lock tree
* @alc_mutex: serializes "atomic LEB change" operations
*
* @fm_disabled: non-zero if fastmap is disabled (default)
* @fm: in-memory data structure of the currently used fastmap
* @fm_pool: in-memory data structure of the fastmap pool
* @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL
* sub-system
* @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf
* @fm_buf: vmalloc()'d buffer which holds the raw fastmap
* @fm_size: fastmap size in bytes
* @fm_sem: allows ubi_update_fastmap() to block EBA table changes
* @fm_work: fastmap work queue
*
* @used: RB-tree of used physical eraseblocks
* @erroneous: RB-tree of erroneous used physical eraseblocks
* @free: RB-tree of free physical eraseblocks
* @free_count: Contains the number of elements in @free
* @scrub: RB-tree of physical eraseblocks which need scrubbing
* @pq: protection queue (contain physical eraseblocks which are temporarily
* protected from the wear-leveling worker)
* @pq_head: protection queue head
* @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from,
* @move_to, @move_to_put @erase_pending, @wl_scheduled, @works,
* @erroneous, and @erroneous_peb_count fields
* @move_mutex: serializes eraseblock moves
* @work_sem: synchronizes the WL worker with use tasks
* @wl_scheduled: non-zero if the wear-leveling was scheduled
* @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any
* physical eraseblock
* @move_from: physical eraseblock from where the data is being moved
* @move_to: physical eraseblock where the data is being moved to
* @move_to_put: if the "to" PEB was put
* @works: list of pending works
* @works_count: count of pending works
* @bgt_thread: background thread description object
* @thread_enabled: if the background thread is enabled
* @bgt_name: background thread name
*
* @flash_size: underlying MTD device size (in bytes)
* @peb_count: count of physical eraseblocks on the MTD device
* @peb_size: physical eraseblock size
* @bad_peb_limit: top limit of expected bad physical eraseblocks
* @bad_peb_count: count of bad physical eraseblocks
* @good_peb_count: count of good physical eraseblocks
* @corr_peb_count: count of corrupted physical eraseblocks (preserved and not
* used by UBI)
* @erroneous_peb_count: count of erroneous physical eraseblocks in @erroneous
* @max_erroneous: maximum allowed amount of erroneous physical eraseblocks
* @min_io_size: minimal input/output unit size of the underlying MTD device
* @hdrs_min_io_size: minimal I/O unit size used for VID and EC headers
* @ro_mode: if the UBI device is in read-only mode
* @leb_size: logical eraseblock size
* @leb_start: starting offset of logical eraseblocks within physical
* eraseblocks
* @ec_hdr_alsize: size of the EC header aligned to @hdrs_min_io_size
* @vid_hdr_alsize: size of the VID header aligned to @hdrs_min_io_size
* @vid_hdr_offset: starting offset of the volume identifier header (might be
* unaligned)
* @vid_hdr_aloffset: starting offset of the VID header aligned to
* @hdrs_min_io_size
* @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset
* @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
* not
* @nor_flash: non-zero if working on top of NOR flash
* @max_write_size: maximum amount of bytes the underlying flash can write at a
* time (MTD write buffer size)
* @mtd: MTD device descriptor
*
* @peb_buf: a buffer of PEB size used for different purposes
* @buf_mutex: protects @peb_buf
* @ckvol_mutex: serializes static volume checking when opening
*
* @dbg: debugging information for this UBI device
*/
struct ubi_device {
struct cdev cdev;
struct device_d dev;
int ubi_num;
char ubi_name[sizeof(UBI_NAME_STR)+5];
int vol_count;
struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT];
int ref_count;
int image_seq;
int rsvd_pebs;
int avail_pebs;
int beb_rsvd_pebs;
int beb_rsvd_level;
int bad_peb_limit;
int autoresize_vol_id;
int vtbl_slots;
int vtbl_size;
struct ubi_vtbl_record *vtbl;
int max_ec;
/* Note, mean_ec is not updated run-time - should be fixed */
int mean_ec;
/* EBA sub-system's stuff */
unsigned long long global_sqnum;
struct rb_root ltree;
/* Fastmap stuff */
int fm_disabled;
struct ubi_fastmap_layout *fm;
struct ubi_fm_pool fm_pool;
struct ubi_fm_pool fm_wl_pool;
void *fm_buf;
size_t fm_size;
/* Wear-leveling sub-system's stuff */
struct rb_root used;
struct rb_root erroneous;
struct rb_root free;
int free_count;
struct rb_root scrub;
struct list_head pq[UBI_PROT_QUEUE_LEN];
int pq_head;
int wl_scheduled;
struct ubi_wl_entry **lookuptbl;
struct ubi_wl_entry *move_from;
struct ubi_wl_entry *move_to;
int move_to_put;
struct list_head works;
int works_count;
struct task_struct *bgt_thread;
int thread_enabled;
char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2];
/* I/O sub-system's stuff */
long long flash_size;
int peb_count;
int peb_size;
int bad_peb_count;
int good_peb_count;
int corr_peb_count;
int erroneous_peb_count;
int max_erroneous;
int min_io_size;
int hdrs_min_io_size;
int ro_mode;
int leb_size;
int leb_start;
int ec_hdr_alsize;
int vid_hdr_alsize;
int vid_hdr_offset;
int vid_hdr_aloffset;
int vid_hdr_shift;
unsigned int bad_allowed:1;
unsigned int nor_flash:1;
int max_write_size;
struct mtd_info *mtd;
void *peb_buf;
struct ubi_debug_info dbg;
};
/**
* struct ubi_ainf_peb - attach information about a physical eraseblock.
* @ec: erase counter (%UBI_UNKNOWN if it is unknown)
* @pnum: physical eraseblock number
* @vol_id: ID of the volume this LEB belongs to
* @lnum: logical eraseblock number
* @scrub: if this physical eraseblock needs scrubbing
* @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
* @sqnum: sequence number
* @u: unions RB-tree or @list links
* @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects
* @u.list: link in one of the eraseblock lists
*
* One object of this type is allocated for each physical eraseblock when
* attaching an MTD device. Note, if this PEB does not belong to any LEB /
* volume, the @vol_id and @lnum fields are initialized to %UBI_UNKNOWN.
*/
struct ubi_ainf_peb {
int ec;
int pnum;
int vol_id;
int lnum;
unsigned int scrub:1;
unsigned int copy_flag:1;
unsigned long long sqnum;
union {
struct rb_node rb;
struct list_head list;
} u;
};
/**
* struct ubi_ainf_volume - attaching information about a volume.
* @vol_id: volume ID
* @highest_lnum: highest logical eraseblock number in this volume
* @leb_count: number of logical eraseblocks in this volume
* @vol_type: volume type
* @used_ebs: number of used logical eraseblocks in this volume (only for
* static volumes)
* @last_data_size: amount of data in the last logical eraseblock of this
* volume (always equivalent to the usable logical eraseblock
* size in case of dynamic volumes)
* @data_pad: how many bytes at the end of logical eraseblocks of this volume
* are not used (due to volume alignment)
* @compat: compatibility flags of this volume
* @rb: link in the volume RB-tree
* @root: root of the RB-tree containing all the eraseblock belonging to this
* volume (&struct ubi_ainf_peb objects)
*
* One object of this type is allocated for each volume when attaching an MTD
* device.
*/
struct ubi_ainf_volume {
int vol_id;
int highest_lnum;
int leb_count;
int vol_type;
int used_ebs;
int last_data_size;
int data_pad;
int compat;
struct rb_node rb;
struct rb_root root;
};
/**
* struct ubi_attach_info - MTD device attaching information.
* @volumes: root of the volume RB-tree
* @corr: list of corrupted physical eraseblocks
* @free: list of free physical eraseblocks
* @erase: list of physical eraseblocks which have to be erased
* @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
* those belonging to "preserve"-compatible internal volumes)
* @corr_peb_count: count of PEBs in the @corr list
* @empty_peb_count: count of PEBs which are presumably empty (contain only
* 0xFF bytes)
* @alien_peb_count: count of PEBs in the @alien list
* @bad_peb_count: count of bad physical eraseblocks
* @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked
* as bad yet, but which look like bad
* @vols_found: number of volumes found
* @highest_vol_id: highest volume ID
* @is_empty: flag indicating whether the MTD device is empty or not
* @min_ec: lowest erase counter value
* @max_ec: highest erase counter value
* @max_sqnum: highest sequence number value
* @mean_ec: mean erase counter value
* @ec_sum: a temporary variable used when calculating @mean_ec
* @ec_count: a temporary variable used when calculating @mean_ec
* @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects
*
* This data structure contains the result of attaching an MTD device and may
* be used by other UBI sub-systems to build final UBI data structures, further
* error-recovery and so on.
*/
struct ubi_attach_info {
struct rb_root volumes;
struct list_head corr;
struct list_head free;
struct list_head erase;
struct list_head alien;
int corr_peb_count;
int empty_peb_count;
int alien_peb_count;
int bad_peb_count;
int maybe_bad_peb_count;
int vols_found;
int highest_vol_id;
int is_empty;
int min_ec;
int max_ec;
unsigned long long max_sqnum;
int mean_ec;
uint64_t ec_sum;
int ec_count;
struct kmem_cache *aeb_slab_cache;
};
/**
* struct ubi_work - UBI work description data structure.
* @list: a link in the list of pending works
* @func: worker function
* @e: physical eraseblock to erase
* @vol_id: the volume ID on which this erasure is being performed
* @lnum: the logical eraseblock number
* @torture: if the physical eraseblock has to be tortured
* @anchor: produce a anchor PEB to by used by fastmap
*
* The @func pointer points to the worker function. If the @cancel argument is
* not zero, the worker has to free the resources and exit immediately. The
* worker has to return zero in case of success and a negative error code in
* case of failure.
*/
struct ubi_work {
struct list_head list;
int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
/* The below fields are only relevant to erasure works */
struct ubi_wl_entry *e;
int vol_id;
int lnum;
int torture;
int anchor;
};
#include "debug.h"
extern struct kmem_cache *ubi_wl_entry_slab;
extern const struct file_operations ubi_ctrl_cdev_operations;
extern const struct file_operations ubi_cdev_operations;
extern const struct file_operations ubi_vol_cdev_operations;
extern struct class *ubi_class;
extern struct blocking_notifier_head ubi_notifiers;
/* attach.c */
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
int vol_id);
void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
struct ubi_attach_info *ai);
int ubi_attach(struct ubi_device *ubi, int force_scan);
void ubi_destroy_ai(struct ubi_attach_info *ai);
/* vtbl.c */
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
struct ubi_vtbl_record *vtbl_rec);
int ubi_vtbl_rename_volumes(struct ubi_device *ubi,
struct list_head *rename_list);
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai);
/* vmt.c */
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req);
int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl);
int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs);
int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list);
int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol);
void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol);
/* upd.c */
int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes);
int ubi_finish_update(struct ubi_device *ubi, struct ubi_volume *vol);
int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count);
int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
const struct ubi_leb_change_req *req);
int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count);
/* misc.c */
int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
int length);
int ubi_check_volume(struct ubi_device *ubi, int vol_id);
void ubi_update_reserved(struct ubi_device *ubi);
void ubi_calculate_reserved(struct ubi_device *ubi);
int ubi_check_pattern(const void *buf, uint8_t patt, int size);
/* eba.c */
int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum);
int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
void *buf, int offset, int len, int check);
int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
const void *buf, int offset, int len);
int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len, int used_ebs);
int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len);
int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
struct ubi_vid_hdr *vid_hdr);
int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
unsigned long long ubi_next_sqnum(struct ubi_device *ubi);
int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
struct ubi_attach_info *ai_scan);
/* wl.c */
int ubi_wl_get_peb(struct ubi_device *ubi);
int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum,
int pnum, int torture);
int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum);
int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum);
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
void ubi_wl_close(struct ubi_device *ubi);
int ubi_thread(void *u);
struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor);
int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e,
int lnum, int torture);
int ubi_is_erase_work(struct ubi_work *wrk);
void ubi_refill_pools(struct ubi_device *ubi);
int ubi_ensure_anchor_pebs(struct ubi_device *ubi);
/* io.c */
int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
int len);
int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
int len);
int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture);
int ubi_io_is_bad(const struct ubi_device *ubi, int pnum);
int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum);
int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
struct ubi_ec_hdr *ec_hdr, int verbose);
int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
struct ubi_ec_hdr *ec_hdr);
int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr, int verbose);
int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr);
/* build.c */
struct ubi_device *ubi_get_device(int ubi_num);
void ubi_put_device(struct ubi_device *ubi);
struct ubi_device *ubi_get_by_major(int major);
int ubi_major2num(int major);
void ubi_free_internal_volumes(struct ubi_device *ubi);
/* cdev.c */
int ubi_cdev_add(struct ubi_device *ubi);
void ubi_cdev_remove(struct ubi_device *ubi);
int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol);
void ubi_volume_cdev_remove(struct ubi_volume *vol);
/* kapi.c */
void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
struct ubi_volume_info *vi);
/* scan.c */
int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
int pnum, const struct ubi_vid_hdr *vid_hdr);
/* fastmap.c */
size_t ubi_calc_fm_size(struct ubi_device *ubi);
int ubi_update_fastmap(struct ubi_device *ubi);
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
int fm_anchor);
void ubi_free_fastmap(struct ubi_device *ubi);
/*
* ubi_rb_for_each_entry - walk an RB-tree.
* @rb: a pointer to type 'struct rb_node' to use as a loop counter
* @pos: a pointer to RB-tree entry type to use as a loop counter
* @root: RB-tree's root
* @member: the name of the 'struct rb_node' within the RB-tree entry
*/
#define ubi_rb_for_each_entry(rb, pos, root, member) \
for (rb = rb_first(root), \
pos = (rb ? container_of(rb, typeof(*pos), member) : NULL); \
rb; \
rb = rb_next(rb), \
pos = (rb ? container_of(rb, typeof(*pos), member) : NULL))
/*
* ubi_move_aeb_to_list - move a PEB from the volume tree to a list.
*
* @av: volume attaching information
* @aeb: attaching eraseblock information
* @list: the list to move to
*/
static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av,
struct ubi_ainf_peb *aeb,
struct list_head *list)
{
rb_erase(&aeb->u.rb, &av->root);
list_add_tail(&aeb->u.list, list);
}
/**
* ubi_zalloc_vid_hdr - allocate a volume identifier header object.
* @ubi: UBI device description object
* @gfp_flags: GFP flags to allocate with
*
* This function returns a pointer to the newly allocated and zero-filled
* volume identifier header object in case of success and %NULL in case of
* failure.
*/
static inline struct ubi_vid_hdr *
ubi_zalloc_vid_hdr(const struct ubi_device *ubi, gfp_t gfp_flags)
{
void *vid_hdr;
vid_hdr = kzalloc(ubi->vid_hdr_alsize, gfp_flags);
if (!vid_hdr)
return NULL;
/*
* VID headers may be stored at un-aligned flash offsets, so we shift
* the pointer.
*/
return vid_hdr + ubi->vid_hdr_shift;
}
/**
* ubi_free_vid_hdr - free a volume identifier header object.
* @ubi: UBI device description object
* @vid_hdr: the object to free
*/
static inline void ubi_free_vid_hdr(const struct ubi_device *ubi,
struct ubi_vid_hdr *vid_hdr)
{
void *p = vid_hdr;
if (!p)
return;
kfree(p - ubi->vid_hdr_shift);
}
/*
* This function is equivalent to 'ubi_io_read()', but @offset is relative to
* the beginning of the logical eraseblock, not to the beginning of the
* physical eraseblock.
*/
static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf,
int pnum, int offset, int len)
{
ubi_assert(offset >= 0);
return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
}
/*
* This function is equivalent to 'ubi_io_write()', but @offset is relative to
* the beginning of the logical eraseblock, not to the beginning of the
* physical eraseblock.
*/
static inline int ubi_io_write_data(struct ubi_device *ubi, const void *buf,
int pnum, int offset, int len)
{
ubi_assert(offset >= 0);
return ubi_io_write(ubi, buf, pnum, offset + ubi->leb_start, len);
}
/**
* ubi_ro_mode - switch to read-only mode.
* @ubi: UBI device description object
*/
static inline void ubi_ro_mode(struct ubi_device *ubi)
{
if (!ubi->ro_mode) {
ubi->ro_mode = 1;
ubi_warn("switch to read-only mode");
dump_stack();
}
}
/**
* vol_id2idx - get table index by volume ID.
* @ubi: UBI device description object
* @vol_id: volume ID
*/
static inline int vol_id2idx(const struct ubi_device *ubi, int vol_id)
{
if (vol_id >= UBI_INTERNAL_VOL_START)
return vol_id - UBI_INTERNAL_VOL_START + ubi->vtbl_slots;
else
return vol_id;
}
/**
* idx2vol_id - get volume ID by table index.
* @ubi: UBI device description object
* @idx: table index
*/
static inline int idx2vol_id(const struct ubi_device *ubi, int idx)
{
if (idx >= ubi->vtbl_slots)
return idx - ubi->vtbl_slots + UBI_INTERNAL_VOL_START;
else
return idx;
}
#endif /* !__UBI_UBI_H__ */

443
drivers/mtd/ubi/upd.c Normal file
View File

@ -0,0 +1,443 @@
/*
* Copyright (c) International Business Machines Corp., 2006
* Copyright (c) Nokia Corporation, 2006
*
* 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 (Битюцкий Артём)
*
* Jan 2007: Alexander Schmidt, hacked per-volume update.
*/
/*
* This file contains implementation of the volume update and atomic LEB change
* functionality.
*
* The update operation is based on the per-volume update marker which is
* stored in the volume table. The update marker is set before the update
* starts, and removed after the update has been finished. So if the update was
* interrupted by an unclean re-boot or due to some other reasons, the update
* marker stays on the flash media and UBI finds it when it attaches the MTD
* device next time. If the update marker is set for a volume, the volume is
* treated as damaged and most I/O operations are prohibited. Only a new update
* operation is allowed.
*
* Note, in general it is possible to implement the update operation as a
* transaction with a roll-back capability.
*/
#include <linux/err.h>
#include <linux/math64.h>
#include "ubi.h"
/**
* set_update_marker - set update marker.
* @ubi: UBI device description object
* @vol: volume description object
*
* This function sets the update marker flag for volume @vol. Returns zero
* in case of success and a negative error code in case of failure.
*/
static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol)
{
int err;
struct ubi_vtbl_record vtbl_rec;
dbg_gen("set update marker for volume %d", vol->vol_id);
if (vol->upd_marker) {
ubi_assert(ubi->vtbl[vol->vol_id].upd_marker);
dbg_gen("already set");
return 0;
}
vtbl_rec = ubi->vtbl[vol->vol_id];
vtbl_rec.upd_marker = 1;
err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
vol->upd_marker = 1;
return err;
}
/**
* clear_update_marker - clear update marker.
* @ubi: UBI device description object
* @vol: volume description object
* @bytes: new data size in bytes
*
* This function clears the update marker for volume @vol, sets new volume
* data size and clears the "corrupted" flag (static volumes only). Returns
* zero in case of success and a negative error code in case of failure.
*/
static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int err;
struct ubi_vtbl_record vtbl_rec;
dbg_gen("clear update marker for volume %d", vol->vol_id);
vtbl_rec = ubi->vtbl[vol->vol_id];
ubi_assert(vol->upd_marker && vtbl_rec.upd_marker);
vtbl_rec.upd_marker = 0;
if (vol->vol_type == UBI_STATIC_VOLUME) {
vol->corrupted = 0;
vol->used_bytes = bytes;
vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size,
&vol->last_eb_bytes);
if (vol->last_eb_bytes)
vol->used_ebs += 1;
else
vol->last_eb_bytes = vol->usable_leb_size;
}
err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
vol->upd_marker = 0;
return err;
}
/**
* ubi_start_update - start volume update.
* @ubi: UBI device description object
* @vol: volume description object
* @bytes: update bytes
*
* This function starts volume update operation. If @bytes is zero, the volume
* is just wiped out. Returns zero in case of success and a negative error code
* in case of failure.
*/
int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int i, err;
dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes);
ubi_assert(!vol->updating && !vol->changing_leb);
vol->updating = 1;
err = set_update_marker(ubi, vol);
if (err)
return err;
/* Before updating - wipe out the volume */
for (i = 0; i < vol->reserved_pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol, i);
if (err)
return err;
}
if (bytes == 0) {
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;
err = clear_update_marker(ubi, vol, 0);
if (err)
return err;
vol->updating = 0;
return 0;
}
vol->upd_buf = vmalloc(ubi->leb_size);
if (!vol->upd_buf)
return -ENOMEM;
vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1,
vol->usable_leb_size);
vol->upd_bytes = bytes;
vol->upd_received = 0;
return 0;
}
int ubi_finish_update(struct ubi_device *ubi, struct ubi_volume *vol)
{
int err;
/* The update is finished, clear the update marker */
err = clear_update_marker(ubi, vol, vol->upd_bytes);
if (err)
return err;
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err == 0) {
vol->updating = 0;
vfree(vol->upd_buf);
}
return err;
}
/**
* ubi_start_leb_change - start atomic LEB change.
* @ubi: UBI device description object
* @vol: volume description object
* @req: operation request
*
* This function starts atomic LEB change operation. Returns zero in case of
* success and a negative error code in case of failure.
*/
int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
const struct ubi_leb_change_req *req)
{
ubi_assert(!vol->updating && !vol->changing_leb);
dbg_gen("start changing LEB %d:%d, %u bytes",
vol->vol_id, req->lnum, req->bytes);
if (req->bytes == 0)
return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0);
vol->upd_bytes = req->bytes;
vol->upd_received = 0;
vol->changing_leb = 1;
vol->ch_lnum = req->lnum;
vol->upd_buf = vmalloc(req->bytes);
if (!vol->upd_buf)
return -ENOMEM;
return 0;
}
/**
* write_leb - write update data.
* @ubi: UBI device description object
* @vol: volume description object
* @lnum: logical eraseblock number
* @buf: data to write
* @len: data size
* @used_ebs: how many logical eraseblocks will this volume contain (static
* volumes only)
*
* This function writes update data to corresponding logical eraseblock. In
* case of dynamic volume, this function checks if the data contains 0xFF bytes
* at the end. If yes, the 0xFF bytes are cut and not written. So if the whole
* buffer contains only 0xFF bytes, the LEB is left unmapped.
*
* The reason why we skip the trailing 0xFF bytes in case of dynamic volume is
* that we want to make sure that more data may be appended to the logical
* eraseblock in future. Indeed, writing 0xFF bytes may have side effects and
* this PEB won't be writable anymore. So if one writes the file-system image
* to the UBI volume where 0xFFs mean free space - UBI makes sure this free
* space is writable after the update.
*
* We do not do this for static volumes because they are read-only. But this
* also cannot be done because we have to store per-LEB CRC and the correct
* data length.
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
void *buf, int len, int used_ebs)
{
int err;
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
int l = ALIGN(len, ubi->min_io_size);
memset(buf + len, 0xFF, l - len);
len = ubi_calc_data_len(ubi, buf, l);
if (len == 0) {
dbg_gen("all %d bytes contain 0xFF - skip", len);
return 0;
}
err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len);
} else {
/*
* When writing static volume, and this is the last logical
* eraseblock, the length (@len) does not have to be aligned to
* the minimal flash I/O unit. The 'ubi_eba_write_leb_st()'
* function accepts exact (unaligned) length and stores it in
* the VID header. And it takes care of proper alignment by
* padding the buffer. Here we just make sure the padding will
* contain zeros, not random trash.
*/
memset(buf + len, 0, vol->usable_leb_size - len);
err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs);
}
return err;
}
/**
* ubi_more_update_data - write more update data.
* @ubi: UBI device description object
* @vol: volume description object
* @buf: write data (user-space memory buffer)
* @count: how much bytes to write
*
* This function writes more data to the volume which is being updated. It may
* be called arbitrary number of times until all the update data arriveis. This
* function returns %0 in case of success, number of bytes written during the
* last call if the whole volume update has been successfully finished, and a
* negative error code in case of failure.
*/
int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count)
{
int lnum, offs, err = 0, len, to_write = count;
dbg_gen("write %d of %lld bytes, %lld already passed",
count, vol->upd_bytes, vol->upd_received);
if (ubi->ro_mode)
return -EROFS;
lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs);
if (vol->upd_received + count > vol->upd_bytes)
to_write = count = vol->upd_bytes - vol->upd_received;
/*
* When updating volumes, we accumulate whole logical eraseblock of
* data and write it at once.
*/
if (offs != 0) {
/*
* This is a write to the middle of the logical eraseblock. We
* copy the data to our update buffer and wait for more data or
* flush it if the whole eraseblock is written or the update
* is finished.
*/
len = vol->usable_leb_size - offs;
if (len > count)
len = count;
err = copy_from_user(vol->upd_buf + offs, buf, len);
if (err)
return -EFAULT;
if (offs + len == vol->usable_leb_size ||
vol->upd_received + len == vol->upd_bytes) {
int flush_len = offs + len;
/*
* OK, we gathered either the whole eraseblock or this
* is the last chunk, it's time to flush the buffer.
*/
ubi_assert(flush_len <= vol->usable_leb_size);
err = write_leb(ubi, vol, lnum, vol->upd_buf, flush_len,
vol->upd_ebs);
if (err)
return err;
}
vol->upd_received += len;
count -= len;
buf += len;
lnum += 1;
}
/*
* If we've got more to write, let's continue. At this point we know we
* are starting from the beginning of an eraseblock.
*/
while (count) {
if (count > vol->usable_leb_size)
len = vol->usable_leb_size;
else
len = count;
err = copy_from_user(vol->upd_buf, buf, len);
if (err)
return -EFAULT;
if (len == vol->usable_leb_size ||
vol->upd_received + len == vol->upd_bytes) {
err = write_leb(ubi, vol, lnum, vol->upd_buf,
len, vol->upd_ebs);
if (err)
break;
}
vol->upd_received += len;
count -= len;
lnum += 1;
buf += len;
}
ubi_assert(vol->upd_received <= vol->upd_bytes);
if (vol->upd_received == vol->upd_bytes) {
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;
/* The update is finished, clear the update marker */
err = clear_update_marker(ubi, vol, vol->upd_bytes);
if (err)
return err;
vol->updating = 0;
err = to_write;
vfree(vol->upd_buf);
}
return err;
}
/**
* ubi_more_leb_change_data - accept more data for atomic LEB change.
* @ubi: UBI device description object
* @vol: volume description object
* @buf: write data (user-space memory buffer)
* @count: how much bytes to write
*
* This function accepts more data to the volume which is being under the
* "atomic LEB change" operation. It may be called arbitrary number of times
* until all data arrives. This function returns %0 in case of success, number
* of bytes written during the last call if the whole "atomic LEB change"
* operation has been successfully finished, and a negative error code in case
* of failure.
*/
int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count)
{
int err;
dbg_gen("write %d of %lld bytes, %lld already passed",
count, vol->upd_bytes, vol->upd_received);
if (ubi->ro_mode)
return -EROFS;
if (vol->upd_received + count > vol->upd_bytes)
count = vol->upd_bytes - vol->upd_received;
err = copy_from_user(vol->upd_buf + vol->upd_received, buf, count);
if (err)
return -EFAULT;
vol->upd_received += count;
if (vol->upd_received == vol->upd_bytes) {
int len = ALIGN((int)vol->upd_bytes, ubi->min_io_size);
memset(vol->upd_buf + vol->upd_bytes, 0xFF,
len - vol->upd_bytes);
len = ubi_calc_data_len(ubi, vol->upd_buf, len);
err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum,
vol->upd_buf, len);
if (err)
return err;
}
ubi_assert(vol->upd_received <= vol->upd_bytes);
if (vol->upd_received == vol->upd_bytes) {
vol->changing_leb = 0;
err = count;
vfree(vol->upd_buf);
}
return err;
}

620
drivers/mtd/ubi/vmt.c Normal file
View File

@ -0,0 +1,620 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
/*
* This file contains implementation of volume creation, deletion, updating and
* resizing.
*/
#include <linux/err.h>
#include <linux/math64.h>
#include "ubi.h"
static int self_check_volumes(struct ubi_device *ubi);
/**
* ubi_create_volume - create volume.
* @ubi: UBI device description object
* @req: volume creation request
*
* This function creates volume described by @req. If @req->vol_id id
* %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume
* and saves it in @req->vol_id. Returns zero in case of success and a negative
* error code in case of failure. Note, the caller has to have the
* @ubi->device_mutex locked.
*/
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
{
int i, err, vol_id = req->vol_id, do_free = 1;
struct ubi_volume *vol;
struct ubi_vtbl_record vtbl_rec;
if (ubi->ro_mode)
return -EROFS;
vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
if (!vol)
return -ENOMEM;
if (vol_id == UBI_VOL_NUM_AUTO) {
/* Find unused volume ID */
dbg_gen("search for vacant volume ID");
for (i = 0; i < ubi->vtbl_slots; i++)
if (!ubi->volumes[i]) {
vol_id = i;
break;
}
if (vol_id == UBI_VOL_NUM_AUTO) {
ubi_err("out of volume IDs");
err = -ENFILE;
goto out_unlock;
}
req->vol_id = vol_id;
}
dbg_gen("create device %d, volume %d, %llu bytes, type %d, name %s",
ubi->ubi_num, vol_id, (unsigned long long)req->bytes,
(int)req->vol_type, req->name);
/* Ensure that this volume does not exist */
err = -EEXIST;
if (ubi->volumes[vol_id]) {
ubi_err("volume %d already exists", vol_id);
goto out_unlock;
}
/* Ensure that the name is unique */
for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i] &&
ubi->volumes[i]->name_len == req->name_len &&
!strcmp(ubi->volumes[i]->name, req->name)) {
ubi_err("volume \"%s\" exists (ID %d)", req->name, i);
goto out_unlock;
}
/* Calculate how many eraseblocks are requested */
vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1,
vol->usable_leb_size);
/* Reserve physical eraseblocks */
if (vol->reserved_pebs > ubi->avail_pebs) {
ubi_err("not enough PEBs, only %d available", ubi->avail_pebs);
if (ubi->corr_peb_count)
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
err = -ENOSPC;
goto out_unlock;
}
ubi->avail_pebs -= vol->reserved_pebs;
ubi->rsvd_pebs += vol->reserved_pebs;
vol->vol_id = vol_id;
vol->alignment = req->alignment;
vol->data_pad = ubi->leb_size % vol->alignment;
vol->vol_type = req->vol_type;
vol->name_len = req->name_len;
memcpy(vol->name, req->name, vol->name_len);
vol->ubi = ubi;
/*
* Finish all pending erases because there may be some LEBs belonging
* to the same volume ID.
*/
err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
if (err)
goto out_acc;
vol->eba_tbl = kmalloc(vol->reserved_pebs * sizeof(int), GFP_KERNEL);
if (!vol->eba_tbl) {
err = -ENOMEM;
goto out_acc;
}
for (i = 0; i < vol->reserved_pebs; i++)
vol->eba_tbl[i] = UBI_LEB_UNMAPPED;
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
vol->used_ebs = vol->reserved_pebs;
vol->last_eb_bytes = vol->usable_leb_size;
vol->used_bytes =
(long long)vol->used_ebs * vol->usable_leb_size;
} else {
vol->used_ebs = div_u64_rem(vol->used_bytes,
vol->usable_leb_size,
&vol->last_eb_bytes);
if (vol->last_eb_bytes != 0)
vol->used_ebs += 1;
else
vol->last_eb_bytes = vol->usable_leb_size;
}
/* Register character device for the volume */
err = ubi_volume_cdev_add(ubi, vol);
if (err) {
ubi_err("cannot add character device");
goto out_mapping;
}
/* Fill volume table record */
memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record));
vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs);
vtbl_rec.alignment = cpu_to_be32(vol->alignment);
vtbl_rec.data_pad = cpu_to_be32(vol->data_pad);
vtbl_rec.name_len = cpu_to_be16(vol->name_len);
if (vol->vol_type == UBI_DYNAMIC_VOLUME)
vtbl_rec.vol_type = UBI_VID_DYNAMIC;
else
vtbl_rec.vol_type = UBI_VID_STATIC;
memcpy(vtbl_rec.name, vol->name, vol->name_len);
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
goto out_sysfs;
ubi->volumes[vol_id] = vol;
ubi->vol_count += 1;
self_check_volumes(ubi);
return err;
out_sysfs:
/*
* We have registered our device, we should not free the volume
* description object in this function in case of an error - it is
* freed by the release function.
*
* Get device reference to prevent the release function from being
* called just after sysfs has been closed.
*/
do_free = 0;
out_mapping:
if (do_free)
kfree(vol->eba_tbl);
out_acc:
ubi->rsvd_pebs -= vol->reserved_pebs;
ubi->avail_pebs += vol->reserved_pebs;
out_unlock:
if (do_free)
kfree(vol);
ubi_err("cannot create volume %d, error %d", vol_id, err);
return err;
}
/**
* ubi_remove_volume - remove volume.
* @desc: volume descriptor
* @no_vtbl: do not change volume table if not zero
*
* This function removes volume described by @desc. The volume has to be opened
* in "exclusive" mode. Returns zero in case of success and a negative error
* code in case of failure. The caller has to have the @ubi->device_mutex
* locked.
*/
int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int i, err, vol_id = vol->vol_id, reserved_pebs = vol->reserved_pebs;
dbg_gen("remove device %d, volume %d", ubi->ubi_num, vol_id);
ubi_assert(desc->mode == UBI_EXCLUSIVE);
ubi_assert(vol == ubi->volumes[vol_id]);
if (ubi->ro_mode)
return -EROFS;
if (vol->ref_count > 1) {
/*
* The volume is busy, probably someone is reading one of its
* sysfs files.
*/
err = -EBUSY;
goto out_unlock;
}
ubi->volumes[vol_id] = NULL;
if (!no_vtbl) {
err = ubi_change_vtbl_record(ubi, vol_id, NULL);
if (err)
goto out_err;
}
for (i = 0; i < vol->reserved_pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol, i);
if (err)
goto out_err;
}
devfs_remove(&vol->cdev);
ubi->rsvd_pebs -= reserved_pebs;
ubi->avail_pebs += reserved_pebs;
ubi_update_reserved(ubi);
ubi->vol_count -= 1;
if (!no_vtbl)
self_check_volumes(ubi);
return err;
out_err:
ubi_err("cannot remove volume %d, error %d", vol_id, err);
ubi->volumes[vol_id] = vol;
out_unlock:
return err;
}
/**
* ubi_resize_volume - re-size volume.
* @desc: volume descriptor
* @reserved_pebs: new size in physical eraseblocks
*
* This function re-sizes the volume and returns zero in case of success, and a
* negative error code in case of failure. The caller has to have the
* @ubi->device_mutex locked.
*/
int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
{
int i, err, pebs, *new_mapping;
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
struct ubi_vtbl_record vtbl_rec;
int vol_id = vol->vol_id;
if (ubi->ro_mode)
return -EROFS;
dbg_gen("re-size device %d, volume %d to from %d to %d PEBs",
ubi->ubi_num, vol_id, vol->reserved_pebs, reserved_pebs);
if (vol->vol_type == UBI_STATIC_VOLUME &&
reserved_pebs < vol->used_ebs) {
ubi_err("too small size %d, %d LEBs contain data",
reserved_pebs, vol->used_ebs);
return -EINVAL;
}
/* If the size is the same, we have nothing to do */
if (reserved_pebs == vol->reserved_pebs)
return 0;
new_mapping = kmalloc(reserved_pebs * sizeof(int), GFP_KERNEL);
if (!new_mapping)
return -ENOMEM;
for (i = 0; i < reserved_pebs; i++)
new_mapping[i] = UBI_LEB_UNMAPPED;
if (vol->ref_count > 1) {
err = -EBUSY;
goto out_free;
}
/* Reserve physical eraseblocks */
pebs = reserved_pebs - vol->reserved_pebs;
if (pebs > 0) {
if (pebs > ubi->avail_pebs) {
ubi_err("not enough PEBs: requested %d, available %d",
pebs, ubi->avail_pebs);
if (ubi->corr_peb_count)
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
err = -ENOSPC;
goto out_free;
}
ubi->avail_pebs -= pebs;
ubi->rsvd_pebs += pebs;
for (i = 0; i < vol->reserved_pebs; i++)
new_mapping[i] = vol->eba_tbl[i];
kfree(vol->eba_tbl);
vol->eba_tbl = new_mapping;
}
/* Change volume table record */
vtbl_rec = ubi->vtbl[vol_id];
vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
goto out_acc;
if (pebs < 0) {
for (i = 0; i < -pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
if (err)
goto out_acc;
}
ubi->rsvd_pebs += pebs;
ubi->avail_pebs -= pebs;
ubi_update_reserved(ubi);
for (i = 0; i < reserved_pebs; i++)
new_mapping[i] = vol->eba_tbl[i];
kfree(vol->eba_tbl);
vol->eba_tbl = new_mapping;
}
vol->reserved_pebs = reserved_pebs;
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
vol->used_ebs = reserved_pebs;
vol->last_eb_bytes = vol->usable_leb_size;
vol->used_bytes =
(long long)vol->used_ebs * vol->usable_leb_size;
}
self_check_volumes(ubi);
return err;
out_acc:
if (pebs > 0) {
ubi->rsvd_pebs -= pebs;
ubi->avail_pebs += pebs;
}
out_free:
kfree(new_mapping);
return err;
}
/**
* ubi_rename_volumes - re-name UBI volumes.
* @ubi: UBI device description object
* @rename_list: list of &struct ubi_rename_entry objects
*
* This function re-names or removes volumes specified in the re-name list.
* Returns zero in case of success and a negative error code in case of
* failure.
*/
int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list)
{
int err;
struct ubi_rename_entry *re;
err = ubi_vtbl_rename_volumes(ubi, rename_list);
if (err)
return err;
list_for_each_entry(re, rename_list, list) {
if (re->remove) {
err = ubi_remove_volume(re->desc, 1);
if (err)
break;
} else {
struct ubi_volume *vol = re->desc->vol;
vol->name_len = re->new_name_len;
memcpy(vol->name, re->new_name, re->new_name_len + 1);
}
}
if (!err)
self_check_volumes(ubi);
return err;
}
/**
* ubi_add_volume - add volume.
* @ubi: UBI device description object
* @vol: volume description object
*
* This function adds an existing volume and initializes all its data
* structures. Returns zero in case of success and a negative error code in
* case of failure.
*/
int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
{
int err = 0;
dbg_gen("add volume");
/* Register character device for the volume */
err = ubi_volume_cdev_add(ubi, vol);
if (err) {
ubi_err("cannot add character device for volume, error %d",
err);
return err;
}
self_check_volumes(ubi);
return err;
return err;
}
/**
* ubi_free_volume - free volume.
* @ubi: UBI device description object
* @vol: volume description object
*
* This function frees all resources for volume @vol but does not remove it.
* Used only when the UBI device is detached.
*/
void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)
{
dbg_gen("free volume %d", vol->vol_id);
ubi->volumes[vol->vol_id] = NULL;
devfs_remove(&vol->cdev);
}
/**
* self_check_volume - check volume information.
* @ubi: UBI device description object
* @vol_id: volume ID
*
* Returns zero if volume is all right and a a negative error code if not.
*/
static int self_check_volume(struct ubi_device *ubi, int vol_id)
{
int idx = vol_id2idx(ubi, vol_id);
int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker;
const struct ubi_volume *vol;
long long n;
const char *name;
reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs);
vol = ubi->volumes[idx];
if (!vol) {
if (reserved_pebs) {
ubi_err("no volume info, but volume exists");
goto fail;
}
return 0;
}
if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 ||
vol->name_len < 0) {
ubi_err("negative values");
goto fail;
}
if (vol->alignment > ubi->leb_size || vol->alignment == 0) {
ubi_err("bad alignment");
goto fail;
}
n = vol->alignment & (ubi->min_io_size - 1);
if (vol->alignment != 1 && n) {
ubi_err("alignment is not multiple of min I/O unit");
goto fail;
}
n = ubi->leb_size % vol->alignment;
if (vol->data_pad != n) {
ubi_err("bad data_pad, has to be %lld", n);
goto fail;
}
if (vol->vol_type != UBI_DYNAMIC_VOLUME &&
vol->vol_type != UBI_STATIC_VOLUME) {
ubi_err("bad vol_type");
goto fail;
}
if (vol->upd_marker && vol->corrupted) {
ubi_err("update marker and corrupted simultaneously");
goto fail;
}
if (vol->reserved_pebs > ubi->good_peb_count) {
ubi_err("too large reserved_pebs");
goto fail;
}
n = ubi->leb_size - vol->data_pad;
if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) {
ubi_err("bad usable_leb_size, has to be %lld", n);
goto fail;
}
if (vol->name_len > UBI_VOL_NAME_MAX) {
ubi_err("too long volume name, max is %d", UBI_VOL_NAME_MAX);
goto fail;
}
n = strnlen(vol->name, vol->name_len + 1);
if (n != vol->name_len) {
ubi_err("bad name_len %lld", n);
goto fail;
}
n = (long long)vol->used_ebs * vol->usable_leb_size;
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
if (vol->corrupted) {
ubi_err("corrupted dynamic volume");
goto fail;
}
if (vol->used_ebs != vol->reserved_pebs) {
ubi_err("bad used_ebs");
goto fail;
}
if (vol->last_eb_bytes != vol->usable_leb_size) {
ubi_err("bad last_eb_bytes");
goto fail;
}
if (vol->used_bytes != n) {
ubi_err("bad used_bytes");
goto fail;
}
} else {
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
ubi_err("bad used_ebs");
goto fail;
}
if (vol->last_eb_bytes < 0 ||
vol->last_eb_bytes > vol->usable_leb_size) {
ubi_err("bad last_eb_bytes");
goto fail;
}
if (vol->used_bytes < 0 || vol->used_bytes > n ||
vol->used_bytes < n - vol->usable_leb_size) {
ubi_err("bad used_bytes");
goto fail;
}
}
alignment = be32_to_cpu(ubi->vtbl[vol_id].alignment);
data_pad = be32_to_cpu(ubi->vtbl[vol_id].data_pad);
name_len = be16_to_cpu(ubi->vtbl[vol_id].name_len);
upd_marker = ubi->vtbl[vol_id].upd_marker;
name = &ubi->vtbl[vol_id].name[0];
if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC)
vol_type = UBI_DYNAMIC_VOLUME;
else
vol_type = UBI_STATIC_VOLUME;
if (alignment != vol->alignment || data_pad != vol->data_pad ||
upd_marker != vol->upd_marker || vol_type != vol->vol_type ||
name_len != vol->name_len || strncmp(name, vol->name, name_len)) {
ubi_err("volume info is different");
goto fail;
}
return 0;
fail:
ubi_err("self-check failed for volume %d", vol_id);
if (vol)
ubi_dump_vol_info(vol);
ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
dump_stack();
return -EINVAL;
}
/**
* self_check_volumes - check information about all volumes.
* @ubi: UBI device description object
*
* Returns zero if volumes are all right and a a negative error code if not.
*/
static int self_check_volumes(struct ubi_device *ubi)
{
int i, err = 0;
if (!ubi_dbg_chk_gen(ubi))
return 0;
for (i = 0; i < ubi->vtbl_slots; i++) {
err = self_check_volume(ubi, i);
if (err)
break;
}
return err;
}

859
drivers/mtd/ubi/vtbl.c Normal file
View File

@ -0,0 +1,859 @@
/*
* 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 (Битюцкий Артём)
*/
/*
* This file includes volume table manipulation code. The volume table is an
* on-flash table containing volume meta-data like name, number of reserved
* physical eraseblocks, type, etc. The volume table is stored in the so-called
* "layout volume".
*
* The layout volume is an internal volume which is organized as follows. It
* consists of two logical eraseblocks - LEB 0 and LEB 1. Each logical
* eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each
* other. This redundancy guarantees robustness to unclean reboots. The volume
* table is basically an array of volume table records. Each record contains
* full information about the volume and protected by a CRC checksum.
*
* The volume table is changed, it is first changed in RAM. Then LEB 0 is
* erased, and the updated volume table is written back to LEB 0. Then same for
* LEB 1. This scheme guarantees recoverability from unclean reboots.
*
* In this UBI implementation the on-flash volume table does not contain any
* information about how much data static volumes contain.
*
* But it would still be beneficial to store this information in the volume
* table. For example, suppose we have a static volume X, and all its physical
* eraseblocks became bad for some reasons. Suppose we are attaching the
* corresponding MTD device, for some reason we find no logical eraseblocks
* corresponding to the volume X. According to the volume table volume X does
* exist. So we don't know whether it is just empty or all its physical
* eraseblocks went bad. So we cannot alarm the user properly.
*
* The volume table also stores so-called "update marker", which is used for
* volume updates. Before updating the volume, the update marker is set, and
* after the update operation is finished, the update marker is cleared. So if
* the update operation was interrupted (e.g. by an unclean reboot) - the
* update marker is still there and we know that the volume's contents is
* damaged.
*/
#include <linux/err.h>
#include "ubi.h"
static void self_vtbl_check(const struct ubi_device *ubi);
/* Empty volume table record */
static struct ubi_vtbl_record empty_vtbl_record;
/**
* ubi_change_vtbl_record - change volume table record.
* @ubi: UBI device description object
* @idx: table index to change
* @vtbl_rec: new volume table record
*
* This function changes volume table record @idx. If @vtbl_rec is %NULL, empty
* volume table record is written. The caller does not have to calculate CRC of
* the record as it is done by this function. Returns zero in case of success
* and a negative error code in case of failure.
*/
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
struct ubi_vtbl_record *vtbl_rec)
{
int i, err;
uint32_t crc;
struct ubi_volume *layout_vol;
ubi_assert(idx >= 0 && idx < ubi->vtbl_slots);
layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)];
if (!vtbl_rec)
vtbl_rec = &empty_vtbl_record;
else {
crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC);
vtbl_rec->crc = cpu_to_be32(crc);
}
memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
err = ubi_eba_unmap_leb(ubi, layout_vol, i);
if (err)
return err;
err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
ubi->vtbl_size);
if (err)
return err;
}
self_vtbl_check(ubi);
return 0;
}
/**
* ubi_vtbl_rename_volumes - rename UBI volumes in the volume table.
* @ubi: UBI device description object
* @rename_list: list of &struct ubi_rename_entry objects
*
* This function re-names multiple volumes specified in @req in the volume
* table. Returns zero in case of success and a negative error code in case of
* failure.
*/
int ubi_vtbl_rename_volumes(struct ubi_device *ubi,
struct list_head *rename_list)
{
int i, err;
struct ubi_rename_entry *re;
struct ubi_volume *layout_vol;
list_for_each_entry(re, rename_list, list) {
uint32_t crc;
struct ubi_volume *vol = re->desc->vol;
struct ubi_vtbl_record *vtbl_rec = &ubi->vtbl[vol->vol_id];
if (re->remove) {
memcpy(vtbl_rec, &empty_vtbl_record,
sizeof(struct ubi_vtbl_record));
continue;
}
vtbl_rec->name_len = cpu_to_be16(re->new_name_len);
memcpy(vtbl_rec->name, re->new_name, re->new_name_len);
memset(vtbl_rec->name + re->new_name_len, 0,
UBI_VOL_NAME_MAX + 1 - re->new_name_len);
crc = crc32(UBI_CRC32_INIT, vtbl_rec,
UBI_VTBL_RECORD_SIZE_CRC);
vtbl_rec->crc = cpu_to_be32(crc);
}
layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)];
for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
err = ubi_eba_unmap_leb(ubi, layout_vol, i);
if (err)
return err;
err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
ubi->vtbl_size);
if (err)
return err;
}
return 0;
}
/**
* vtbl_check - check if volume table is not corrupted and sensible.
* @ubi: UBI device description object
* @vtbl: volume table
*
* This function returns zero if @vtbl is all right, %1 if CRC is incorrect,
* and %-EINVAL if it contains inconsistent data.
*/
static int vtbl_check(const struct ubi_device *ubi,
const struct ubi_vtbl_record *vtbl)
{
int i, n, reserved_pebs, alignment, data_pad, vol_type, name_len;
int upd_marker, err;
uint32_t crc;
const char *name;
for (i = 0; i < ubi->vtbl_slots; i++) {
reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
alignment = be32_to_cpu(vtbl[i].alignment);
data_pad = be32_to_cpu(vtbl[i].data_pad);
upd_marker = vtbl[i].upd_marker;
vol_type = vtbl[i].vol_type;
name_len = be16_to_cpu(vtbl[i].name_len);
name = &vtbl[i].name[0];
crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC);
if (be32_to_cpu(vtbl[i].crc) != crc) {
ubi_err("bad CRC at record %u: %#08x, not %#08x",
i, crc, be32_to_cpu(vtbl[i].crc));
ubi_dump_vtbl_record(&vtbl[i], i);
return 1;
}
if (reserved_pebs == 0) {
if (memcmp(&vtbl[i], &empty_vtbl_record,
UBI_VTBL_RECORD_SIZE)) {
err = 2;
goto bad;
}
continue;
}
if (reserved_pebs < 0 || alignment < 0 || data_pad < 0 ||
name_len < 0) {
err = 3;
goto bad;
}
if (alignment > ubi->leb_size || alignment == 0) {
err = 4;
goto bad;
}
n = alignment & (ubi->min_io_size - 1);
if (alignment != 1 && n) {
err = 5;
goto bad;
}
n = ubi->leb_size % alignment;
if (data_pad != n) {
ubi_err("bad data_pad, has to be %d", n);
err = 6;
goto bad;
}
if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) {
err = 7;
goto bad;
}
if (upd_marker != 0 && upd_marker != 1) {
err = 8;
goto bad;
}
if (reserved_pebs > ubi->good_peb_count) {
ubi_err("too large reserved_pebs %d, good PEBs %d",
reserved_pebs, ubi->good_peb_count);
err = 9;
goto bad;
}
if (name_len > UBI_VOL_NAME_MAX) {
err = 10;
goto bad;
}
if (name[0] == '\0') {
err = 11;
goto bad;
}
if (name_len != strnlen(name, name_len + 1)) {
err = 12;
goto bad;
}
}
/* Checks that all names are unique */
for (i = 0; i < ubi->vtbl_slots - 1; i++) {
for (n = i + 1; n < ubi->vtbl_slots; n++) {
int len1 = be16_to_cpu(vtbl[i].name_len);
int len2 = be16_to_cpu(vtbl[n].name_len);
if (len1 > 0 && len1 == len2 &&
!strncmp(vtbl[i].name, vtbl[n].name, len1)) {
ubi_err("volumes %d and %d have the same name \"%s\"",
i, n, vtbl[i].name);
ubi_dump_vtbl_record(&vtbl[i], i);
ubi_dump_vtbl_record(&vtbl[n], n);
return -EINVAL;
}
}
}
return 0;
bad:
ubi_err("volume table check failed: record %d, error %d", i, err);
ubi_dump_vtbl_record(&vtbl[i], i);
return -EINVAL;
}
/**
* create_vtbl - create a copy of volume table.
* @ubi: UBI device description object
* @ai: attaching information
* @copy: number of the volume table copy
* @vtbl: contents of the volume table
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai,
int copy, void *vtbl)
{
int err, tries = 0;
struct ubi_vid_hdr *vid_hdr;
struct ubi_ainf_peb *new_aeb;
dbg_gen("create volume table (copy #%d)", copy + 1);
vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
if (!vid_hdr)
return -ENOMEM;
retry:
new_aeb = ubi_early_get_peb(ubi, ai);
if (IS_ERR(new_aeb)) {
err = PTR_ERR(new_aeb);
goto out_free;
}
vid_hdr->vol_type = UBI_LAYOUT_VOLUME_TYPE;
vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOLUME_ID);
vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT;
vid_hdr->data_size = vid_hdr->used_ebs =
vid_hdr->data_pad = cpu_to_be32(0);
vid_hdr->lnum = cpu_to_be32(copy);
vid_hdr->sqnum = cpu_to_be64(++ai->max_sqnum);
/* The EC header is already there, write the VID header */
err = ubi_io_write_vid_hdr(ubi, new_aeb->pnum, vid_hdr);
if (err)
goto write_error;
/* Write the layout volume contents */
err = ubi_io_write_data(ubi, vtbl, new_aeb->pnum, 0, ubi->vtbl_size);
if (err)
goto write_error;
/*
* And add it to the attaching information. Don't delete the old version
* of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.
*/
err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0);
kfree(new_aeb);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
write_error:
if (err == -EIO && ++tries <= 5) {
/*
* Probably this physical eraseblock went bad, try to pick
* another one.
*/
list_add(&new_aeb->u.list, &ai->erase);
goto retry;
}
kfree(new_aeb);
out_free:
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
}
/**
* process_lvol - process the layout volume.
* @ubi: UBI device description object
* @ai: attaching information
* @av: layout volume attaching information
*
* This function is responsible for reading the layout volume, ensuring it is
* not corrupted, and recovering from corruptions if needed. Returns volume
* table in case of success and a negative error code in case of failure.
*/
static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
struct ubi_attach_info *ai,
struct ubi_ainf_volume *av)
{
int err;
struct rb_node *rb;
struct ubi_ainf_peb *aeb;
struct ubi_vtbl_record *leb[UBI_LAYOUT_VOLUME_EBS] = { NULL, NULL };
int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1};
/*
* UBI goes through the following steps when it changes the layout
* volume:
* a. erase LEB 0;
* b. write new data to LEB 0;
* c. erase LEB 1;
* d. write new data to LEB 1.
*
* Before the change, both LEBs contain the same data.
*
* Due to unclean reboots, the contents of LEB 0 may be lost, but there
* should LEB 1. So it is OK if LEB 0 is corrupted while LEB 1 is not.
* Similarly, LEB 1 may be lost, but there should be LEB 0. And
* finally, unclean reboots may result in a situation when neither LEB
* 0 nor LEB 1 are corrupted, but they are different. In this case, LEB
* 0 contains more recent information.
*
* So the plan is to first check LEB 0. Then
* a. if LEB 0 is OK, it must be containing the most recent data; then
* we compare it with LEB 1, and if they are different, we copy LEB
* 0 to LEB 1;
* b. if LEB 0 is corrupted, but LEB 1 has to be OK, and we copy LEB 1
* to LEB 0.
*/
dbg_gen("check layout volume");
/* Read both LEB 0 and LEB 1 into memory */
ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) {
leb[aeb->lnum] = vzalloc(ubi->vtbl_size);
if (!leb[aeb->lnum]) {
err = -ENOMEM;
goto out_free;
}
err = ubi_io_read_data(ubi, leb[aeb->lnum], aeb->pnum, 0,
ubi->vtbl_size);
if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err))
/*
* Scrub the PEB later. Note, -EBADMSG indicates an
* uncorrectable ECC error, but we have our own CRC and
* the data will be checked later. If the data is OK,
* the PEB will be scrubbed (because we set
* aeb->scrub). If the data is not OK, the contents of
* the PEB will be recovered from the second copy, and
* aeb->scrub will be cleared in
* 'ubi_add_to_av()'.
*/
aeb->scrub = 1;
else if (err)
goto out_free;
}
err = -EINVAL;
if (leb[0]) {
leb_corrupted[0] = vtbl_check(ubi, leb[0]);
if (leb_corrupted[0] < 0)
goto out_free;
}
if (!leb_corrupted[0]) {
/* LEB 0 is OK */
if (leb[1])
leb_corrupted[1] = memcmp(leb[0], leb[1],
ubi->vtbl_size);
if (leb_corrupted[1]) {
ubi_warn("volume table copy #2 is corrupted");
err = create_vtbl(ubi, ai, 1, leb[0]);
if (err)
goto out_free;
ubi_msg("volume table was restored");
}
/* Both LEB 1 and LEB 2 are OK and consistent */
vfree(leb[1]);
return leb[0];
} else {
/* LEB 0 is corrupted or does not exist */
if (leb[1]) {
leb_corrupted[1] = vtbl_check(ubi, leb[1]);
if (leb_corrupted[1] < 0)
goto out_free;
}
if (leb_corrupted[1]) {
/* Both LEB 0 and LEB 1 are corrupted */
ubi_err("both volume tables are corrupted");
goto out_free;
}
ubi_warn("volume table copy #1 is corrupted");
err = create_vtbl(ubi, ai, 0, leb[1]);
if (err)
goto out_free;
ubi_msg("volume table was restored");
vfree(leb[0]);
return leb[1];
}
out_free:
vfree(leb[0]);
vfree(leb[1]);
return ERR_PTR(err);
}
/**
* create_empty_lvol - create empty layout volume.
* @ubi: UBI device description object
* @ai: attaching information
*
* This function returns volume table contents in case of success and a
* negative error code in case of failure.
*/
static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
struct ubi_attach_info *ai)
{
int i;
struct ubi_vtbl_record *vtbl;
vtbl = vzalloc(ubi->vtbl_size);
if (!vtbl)
return ERR_PTR(-ENOMEM);
for (i = 0; i < ubi->vtbl_slots; i++)
memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE);
for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
int err;
err = create_vtbl(ubi, ai, i, vtbl);
if (err) {
vfree(vtbl);
return ERR_PTR(err);
}
}
return vtbl;
}
/**
* init_volumes - initialize volume information for existing volumes.
* @ubi: UBI device description object
* @ai: scanning information
* @vtbl: volume table
*
* This function allocates volume description objects for existing volumes.
* Returns zero in case of success and a negative error code in case of
* failure.
*/
static int init_volumes(struct ubi_device *ubi,
const struct ubi_attach_info *ai,
const struct ubi_vtbl_record *vtbl)
{
int i, reserved_pebs = 0;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
for (i = 0; i < ubi->vtbl_slots; i++) {
if (be32_to_cpu(vtbl[i].reserved_pebs) == 0)
continue; /* Empty record */
vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
if (!vol)
return -ENOMEM;
vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
vol->alignment = be32_to_cpu(vtbl[i].alignment);
vol->data_pad = be32_to_cpu(vtbl[i].data_pad);
vol->upd_marker = vtbl[i].upd_marker;
vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ?
UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
vol->name_len = be16_to_cpu(vtbl[i].name_len);
vol->usable_leb_size = ubi->leb_size - vol->data_pad;
memcpy(vol->name, vtbl[i].name, vol->name_len);
vol->name[vol->name_len] = '\0';
vol->vol_id = i;
if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
/* Auto re-size flag may be set only for one volume */
if (ubi->autoresize_vol_id != -1) {
ubi_err("more than one auto-resize volume (%d and %d)",
ubi->autoresize_vol_id, i);
kfree(vol);
return -EINVAL;
}
ubi->autoresize_vol_id = i;
}
ubi_assert(!ubi->volumes[i]);
ubi->volumes[i] = vol;
ubi->vol_count += 1;
vol->ubi = ubi;
reserved_pebs += vol->reserved_pebs;
/*
* In case of dynamic volume UBI knows nothing about how many
* data is stored there. So assume the whole volume is used.
*/
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
vol->used_ebs = vol->reserved_pebs;
vol->last_eb_bytes = vol->usable_leb_size;
vol->used_bytes =
(long long)vol->used_ebs * vol->usable_leb_size;
continue;
}
/* Static volumes only */
av = ubi_find_av(ai, i);
if (!av) {
/*
* No eraseblocks belonging to this volume found. We
* don't actually know whether this static volume is
* completely corrupted or just contains no data. And
* we cannot know this as long as data size is not
* stored on flash. So we just assume the volume is
* empty. FIXME: this should be handled.
*/
continue;
}
if (av->leb_count != av->used_ebs) {
/*
* We found a static volume which misses several
* eraseblocks. Treat it as corrupted.
*/
ubi_warn("static volume %d misses %d LEBs - corrupted",
av->vol_id, av->used_ebs - av->leb_count);
vol->corrupted = 1;
continue;
}
vol->used_ebs = av->used_ebs;
vol->used_bytes =
(long long)(vol->used_ebs - 1) * vol->usable_leb_size;
vol->used_bytes += av->last_data_size;
vol->last_eb_bytes = av->last_data_size;
}
/* And add the layout volume */
vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
if (!vol)
return -ENOMEM;
vol->reserved_pebs = UBI_LAYOUT_VOLUME_EBS;
vol->alignment = UBI_LAYOUT_VOLUME_ALIGN;
vol->vol_type = UBI_DYNAMIC_VOLUME;
vol->name_len = sizeof(UBI_LAYOUT_VOLUME_NAME) - 1;
memcpy(vol->name, UBI_LAYOUT_VOLUME_NAME, vol->name_len + 1);
vol->usable_leb_size = ubi->leb_size;
vol->used_ebs = vol->reserved_pebs;
vol->last_eb_bytes = vol->reserved_pebs;
vol->used_bytes =
(long long)vol->used_ebs * (ubi->leb_size - vol->data_pad);
vol->vol_id = UBI_LAYOUT_VOLUME_ID;
vol->ref_count = 1;
ubi_assert(!ubi->volumes[i]);
ubi->volumes[vol_id2idx(ubi, vol->vol_id)] = vol;
reserved_pebs += vol->reserved_pebs;
ubi->vol_count += 1;
vol->ubi = ubi;
if (reserved_pebs > ubi->avail_pebs) {
ubi_err("not enough PEBs, required %d, available %d",
reserved_pebs, ubi->avail_pebs);
if (ubi->corr_peb_count)
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
}
ubi->rsvd_pebs += reserved_pebs;
ubi->avail_pebs -= reserved_pebs;
return 0;
}
/**
* check_av - check volume attaching information.
* @vol: UBI volume description object
* @av: volume attaching information
*
* This function returns zero if the volume attaching information is consistent
* to the data read from the volume tabla, and %-EINVAL if not.
*/
static int check_av(const struct ubi_volume *vol,
const struct ubi_ainf_volume *av)
{
int err;
if (av->highest_lnum >= vol->reserved_pebs) {
err = 1;
goto bad;
}
if (av->leb_count > vol->reserved_pebs) {
err = 2;
goto bad;
}
if (av->vol_type != vol->vol_type) {
err = 3;
goto bad;
}
if (av->used_ebs > vol->reserved_pebs) {
err = 4;
goto bad;
}
if (av->data_pad != vol->data_pad) {
err = 5;
goto bad;
}
return 0;
bad:
ubi_err("bad attaching information, error %d", err);
ubi_dump_av(av);
ubi_dump_vol_info(vol);
return -EINVAL;
}
/**
* check_attaching_info - check that attaching information.
* @ubi: UBI device description object
* @ai: attaching information
*
* Even though we protect on-flash data by CRC checksums, we still don't trust
* the media. This function ensures that attaching information is consistent to
* the information read from the volume table. Returns zero if the attaching
* information is OK and %-EINVAL if it is not.
*/
static int check_attaching_info(const struct ubi_device *ubi,
struct ubi_attach_info *ai)
{
int err, i;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) {
ubi_err("found %d volumes while attaching, maximum is %d + %d",
ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots);
return -EINVAL;
}
if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT &&
ai->highest_vol_id < UBI_INTERNAL_VOL_START) {
ubi_err("too large volume ID %d found", ai->highest_vol_id);
return -EINVAL;
}
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
av = ubi_find_av(ai, i);
vol = ubi->volumes[i];
if (!vol) {
if (av)
ubi_remove_av(ai, av);
continue;
}
if (vol->reserved_pebs == 0) {
ubi_assert(i < ubi->vtbl_slots);
if (!av)
continue;
/*
* During attaching we found a volume which does not
* exist according to the information in the volume
* table. This must have happened due to an unclean
* reboot while the volume was being removed. Discard
* these eraseblocks.
*/
ubi_msg("finish volume %d removal", av->vol_id);
ubi_remove_av(ai, av);
} else if (av) {
err = check_av(vol, av);
if (err)
return err;
}
}
return 0;
}
/**
* ubi_read_volume_table - read the volume table.
* @ubi: UBI device description object
* @ai: attaching information
*
* This function reads volume table, checks it, recover from errors if needed,
* or creates it if needed. Returns zero in case of success and a negative
* error code in case of failure.
*/
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
{
int i, err;
struct ubi_ainf_volume *av;
empty_vtbl_record.crc = cpu_to_be32(0xf116c36b);
/*
* The number of supported volumes is limited by the eraseblock size
* and by the UBI_MAX_VOLUMES constant.
*/
ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE;
if (ubi->vtbl_slots > UBI_MAX_VOLUMES)
ubi->vtbl_slots = UBI_MAX_VOLUMES;
ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE;
ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size);
av = ubi_find_av(ai, UBI_LAYOUT_VOLUME_ID);
if (!av) {
/*
* No logical eraseblocks belonging to the layout volume were
* found. This could mean that the flash is just empty. In
* this case we create empty layout volume.
*
* But if flash is not empty this must be a corruption or the
* MTD device just contains garbage.
*/
if (ai->is_empty) {
ubi->vtbl = create_empty_lvol(ubi, ai);
if (IS_ERR(ubi->vtbl))
return PTR_ERR(ubi->vtbl);
} else {
ubi_err("the layout volume was not found");
return -EINVAL;
}
} else {
if (av->leb_count > UBI_LAYOUT_VOLUME_EBS) {
/* This must not happen with proper UBI images */
ubi_err("too many LEBs (%d) in layout volume",
av->leb_count);
return -EINVAL;
}
ubi->vtbl = process_lvol(ubi, ai, av);
if (IS_ERR(ubi->vtbl))
return PTR_ERR(ubi->vtbl);
}
ubi->avail_pebs = ubi->good_peb_count - ubi->corr_peb_count;
/*
* The layout volume is OK, initialize the corresponding in-RAM data
* structures.
*/
err = init_volumes(ubi, ai, ubi->vtbl);
if (err)
goto out_free;
/*
* Make sure that the attaching information is consistent to the
* information stored in the volume table.
*/
err = check_attaching_info(ubi, ai);
if (err)
goto out_free;
return 0;
out_free:
vfree(ubi->vtbl);
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
kfree(ubi->volumes[i]);
ubi->volumes[i] = NULL;
}
return err;
}
/**
* self_vtbl_check - check volume table.
* @ubi: UBI device description object
*/
static void self_vtbl_check(const struct ubi_device *ubi)
{
if (!ubi_dbg_chk_gen(ubi))
return;
if (vtbl_check(ubi, ubi->vtbl)) {
ubi_err("self-check failed");
BUG();
}
}

1949
drivers/mtd/ubi/wl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#define kzalloc(len, mode) xzalloc(len)
#define vmalloc(len) malloc(len)
#define kfree(ptr) free(ptr)
#define vzalloc(len) kzalloc(len, 0)
#define vfree(ptr) free(ptr)
#define KERN_EMERG "" /* system is unusable */
@ -17,6 +18,11 @@
#define KERN_NOTICE "" /* normal but significant condition */
#define KERN_INFO "" /* informational */
#define KERN_DEBUG "" /* debug-level messages */
#define KERN_CONT ""
#define GFP_KERNEL 0
typedef int gfp_t;
#define printk printf

View File

@ -105,5 +105,17 @@
} \
)
/*
* Multiplies an integer by a fraction, while avoiding unnecessary
* overflow or loss of precision.
*/
#define mult_frac(x, numer, denom)( \
{ \
typeof(x) quot = (x) / (denom); \
typeof(x) rem = (x) % (denom); \
(quot * (numer)) + ((rem * (numer)) / (denom)); \
} \
)
#endif /* _LINUX_KERNEL_H */

View File

@ -237,6 +237,11 @@ static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
return mtd->write_oob(mtd, to, ops);
}
static inline int mtd_can_have_bb(const struct mtd_info *mtd)
{
return !!mtd->block_isbad;
}
static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
{
do_div(sz, mtd->erasesize);

228
include/linux/mtd/ubi.h Normal file
View File

@ -0,0 +1,228 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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 (Битюцкий Артём)
*/
#ifndef __LINUX_UBI_H__
#define __LINUX_UBI_H__
#include <linux/types.h>
#include <mtd/ubi-user.h>
/* All voumes/LEBs */
#define UBI_ALL -1
/*
* enum ubi_open_mode - UBI volume open mode constants.
*
* UBI_READONLY: read-only mode
* UBI_READWRITE: read-write mode
* UBI_EXCLUSIVE: exclusive mode
*/
enum {
UBI_READONLY = 1,
UBI_READWRITE,
UBI_EXCLUSIVE
};
/**
* struct ubi_volume_info - UBI volume description data structure.
* @vol_id: volume ID
* @ubi_num: UBI device number this volume belongs to
* @size: how many physical eraseblocks are reserved for this volume
* @used_bytes: how many bytes of data this volume contains
* @used_ebs: how many physical eraseblocks of this volume actually contain any
* data
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
* @corrupted: non-zero if the volume is corrupted (static volumes only)
* @upd_marker: non-zero if the volume has update marker set
* @alignment: volume alignment
* @usable_leb_size: how many bytes are available in logical eraseblocks of
* this volume
* @name_len: volume name length
* @name: volume name
* @cdev: UBI volume character device major and minor numbers
*
* The @corrupted flag is only relevant to static volumes and is always zero
* for dynamic ones. This is because UBI does not care about dynamic volume
* data protection and only cares about protecting static volume data.
*
* The @upd_marker flag is set if the volume update operation was interrupted.
* Before touching the volume data during the update operation, UBI first sets
* the update marker flag for this volume. If the volume update operation was
* further interrupted, the update marker indicates this. If the update marker
* is set, the contents of the volume is certainly damaged and a new volume
* update operation has to be started.
*
* To put it differently, @corrupted and @upd_marker fields have different
* semantics:
* o the @corrupted flag means that this static volume is corrupted for some
* reasons, but not because an interrupted volume update
* o the @upd_marker field means that the volume is damaged because of an
* interrupted update operation.
*
* I.e., the @corrupted flag is never set if the @upd_marker flag is set.
*
* The @used_bytes and @used_ebs fields are only really needed for static
* volumes and contain the number of bytes stored in this static volume and how
* many eraseblock this data occupies. In case of dynamic volumes, the
* @used_bytes field is equivalent to @size*@usable_leb_size, and the @used_ebs
* field is equivalent to @size.
*
* In general, logical eraseblock size is a property of the UBI device, not
* of the UBI volume. Indeed, the logical eraseblock size depends on the
* physical eraseblock size and on how much bytes UBI headers consume. But
* because of the volume alignment (@alignment), the usable size of logical
* eraseblocks if a volume may be less. The following equation is true:
* @usable_leb_size = LEB size - (LEB size mod @alignment),
* where LEB size is the logical eraseblock size defined by the UBI device.
*
* The alignment is multiple to the minimal flash input/output unit size or %1
* if all the available space is used.
*
* To put this differently, alignment may be considered is a way to change
* volume logical eraseblock sizes.
*/
struct ubi_volume_info {
int ubi_num;
int vol_id;
int size;
long long used_bytes;
int used_ebs;
int vol_type;
int corrupted;
int upd_marker;
int alignment;
int usable_leb_size;
int name_len;
const char *name;
dev_t cdev;
};
/**
* struct ubi_device_info - UBI device description data structure.
* @ubi_num: ubi device number
* @leb_size: logical eraseblock size on this UBI device
* @leb_start: starting offset of logical eraseblocks within physical
* eraseblocks
* @min_io_size: minimal I/O unit size
* @max_write_size: maximum amount of bytes the underlying flash can write at a
* time (MTD write buffer size)
* @ro_mode: if this device is in read-only mode
* @cdev: UBI character device major and minor numbers
*
* Note, @leb_size is the logical eraseblock size offered by the UBI device.
* Volumes of this UBI device may have smaller logical eraseblock size if their
* alignment is not equivalent to %1.
*
* The @max_write_size field describes flash write maximum write unit. For
* example, NOR flash allows for changing individual bytes, so @min_io_size is
* %1. However, it does not mean than NOR flash has to write data byte-by-byte.
* Instead, CFI NOR flashes have a write-buffer of, e.g., 64 bytes, and when
* writing large chunks of data, they write 64-bytes at a time. Obviously, this
* improves write throughput.
*
* Also, the MTD device may have N interleaved (striped) flash chips
* underneath, in which case @min_io_size can be physical min. I/O size of
* single flash chip, while @max_write_size can be N * @min_io_size.
*
* The @max_write_size field is always greater or equivalent to @min_io_size.
* E.g., some NOR flashes may have (@min_io_size = 1, @max_write_size = 64). In
* contrast, NAND flashes usually have @min_io_size = @max_write_size = NAND
* page size.
*/
struct ubi_device_info {
int ubi_num;
int leb_size;
int leb_start;
int min_io_size;
int max_write_size;
int ro_mode;
dev_t cdev;
};
/*
* Volume notification types.
* @UBI_VOLUME_ADDED: a volume has been added (an UBI device was attached or a
* volume was created)
* @UBI_VOLUME_REMOVED: a volume has been removed (an UBI device was detached
* or a volume was removed)
* @UBI_VOLUME_RESIZED: a volume has been re-sized
* @UBI_VOLUME_RENAMED: a volume has been re-named
* @UBI_VOLUME_UPDATED: data has been written to a volume
*
* These constants define which type of event has happened when a volume
* notification function is invoked.
*/
enum {
UBI_VOLUME_ADDED,
UBI_VOLUME_REMOVED,
UBI_VOLUME_RESIZED,
UBI_VOLUME_RENAMED,
UBI_VOLUME_UPDATED,
};
/*
* struct ubi_notification - UBI notification description structure.
* @di: UBI device description object
* @vi: UBI volume description object
*
* UBI notifiers are called with a pointer to an object of this type. The
* object describes the notification. Namely, it provides a description of the
* UBI device and UBI volume the notification informs about.
*/
struct ubi_notification {
struct ubi_device_info di;
struct ubi_volume_info vi;
};
/* UBI descriptor given to users when they open UBI volumes */
struct ubi_volume_desc;
int ubi_get_device_info(int ubi_num, struct ubi_device_info *di);
void ubi_get_volume_info(struct ubi_volume_desc *desc,
struct ubi_volume_info *vi);
struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode);
struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
int mode);
struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode);
void ubi_close_volume(struct ubi_volume_desc *desc);
int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
int len, int check);
int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
int offset, int len);
int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len);
int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum);
int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum);
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum);
int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
int ubi_sync(int ubi_num);
int ubi_flush(int ubi_num, int vol_id, int lnum);
/*
* This function is the same as the 'ubi_leb_read()' function, but it does not
* provide the checking capability.
*/
static inline int ubi_read(struct ubi_volume_desc *desc, int lnum, char *buf,
int offset, int len)
{
return ubi_leb_read(desc, lnum, buf, offset, len, 0);
}
#endif /* !__LINUX_UBI_H__ */

515
include/mtd/ubi-media.h Normal file
View File

@ -0,0 +1,515 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* 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
*
* Authors: Artem Bityutskiy (Битюцкий Артём)
* Thomas Gleixner
* Frank Haverkamp
* Oliver Lohmann
* Andreas Arnez
*/
/*
* This file defines the layout of UBI headers and all the other UBI on-flash
* data structures.
*/
#ifndef __UBI_MEDIA_H__
#define __UBI_MEDIA_H__
#include <asm/byteorder.h>
/* The version of UBI images supported by this implementation */
#define UBI_VERSION 1
/* The highest erase counter value supported by this implementation */
#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF
/* The initial CRC32 value used when calculating CRC checksums */
#define UBI_CRC32_INIT 0xFFFFFFFFU
/* Erase counter header magic number (ASCII "UBI#") */
#define UBI_EC_HDR_MAGIC 0x55424923
/* Volume identifier header magic number (ASCII "UBI!") */
#define UBI_VID_HDR_MAGIC 0x55424921
/*
* Volume type constants used in the volume identifier header.
*
* @UBI_VID_DYNAMIC: dynamic volume
* @UBI_VID_STATIC: static volume
*/
enum {
UBI_VID_DYNAMIC = 1,
UBI_VID_STATIC = 2
};
/*
* Volume flags used in the volume table record.
*
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
*
* %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
* table. UBI automatically re-sizes the volume which has this flag and makes
* the volume to be of largest possible size. This means that if after the
* initialization UBI finds out that there are available physical eraseblocks
* present on the device, it automatically appends all of them to the volume
* (the physical eraseblocks reserved for bad eraseblocks handling and other
* reserved physical eraseblocks are not taken). So, if there is a volume with
* the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical
* eraseblocks will be zero after UBI is loaded, because all of them will be
* reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared
* after the volume had been initialized.
*
* The auto-resize feature is useful for device production purposes. For
* example, different NAND flash chips may have different amount of initial bad
* eraseblocks, depending of particular chip instance. Manufacturers of NAND
* chips usually guarantee that the amount of initial bad eraseblocks does not
* exceed certain percent, e.g. 2%. When one creates an UBI image which will be
* flashed to the end devices in production, he does not know the exact amount
* of good physical eraseblocks the NAND chip on the device will have, but this
* number is required to calculate the volume sized and put them to the volume
* table of the UBI image. In this case, one of the volumes (e.g., the one
* which will store the root file system) is marked as "auto-resizable", and
* UBI will adjust its size on the first boot if needed.
*
* Note, first UBI reserves some amount of physical eraseblocks for bad
* eraseblock handling, and then re-sizes the volume, not vice-versa. This
* means that the pool of reserved physical eraseblocks will always be present.
*/
enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01,
};
/*
* Compatibility constants used by internal volumes.
*
* @UBI_COMPAT_DELETE: delete this internal volume before anything is written
* to the flash
* @UBI_COMPAT_RO: attach this device in read-only mode
* @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its
* physical eraseblocks, don't allow the wear-leveling
* sub-system to move them
* @UBI_COMPAT_REJECT: reject this UBI image
*/
enum {
UBI_COMPAT_DELETE = 1,
UBI_COMPAT_RO = 2,
UBI_COMPAT_PRESERVE = 4,
UBI_COMPAT_REJECT = 5
};
/* Sizes of UBI headers */
#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr)
#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr)
/* Sizes of UBI headers without the ending CRC */
#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32))
#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32))
/**
* struct ubi_ec_hdr - UBI erase counter header.
* @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC)
* @version: version of UBI implementation which is supposed to accept this
* UBI image
* @padding1: reserved for future, zeroes
* @ec: the erase counter
* @vid_hdr_offset: where the VID header starts
* @data_offset: where the user data start
* @image_seq: image sequence number
* @padding2: reserved for future, zeroes
* @hdr_crc: erase counter header CRC checksum
*
* The erase counter header takes 64 bytes and has a plenty of unused space for
* future usage. The unused fields are zeroed. The @version field is used to
* indicate the version of UBI implementation which is supposed to be able to
* work with this UBI image. If @version is greater than the current UBI
* version, the image is rejected. This may be useful in future if something
* is changed radically. This field is duplicated in the volume identifier
* header.
*
* The @vid_hdr_offset and @data_offset fields contain the offset of the the
* volume identifier header and user data, relative to the beginning of the
* physical eraseblock. These values have to be the same for all physical
* eraseblocks.
*
* The @image_seq field is used to validate a UBI image that has been prepared
* for a UBI device. The @image_seq value can be any value, but it must be the
* same on all eraseblocks. UBI will ensure that all new erase counter headers
* also contain this value, and will check the value when attaching the flash.
* One way to make use of @image_seq is to increase its value by one every time
* an image is flashed over an existing image, then, if the flashing does not
* complete, UBI will detect the error when attaching the media.
*/
struct ubi_ec_hdr {
__be32 magic;
__u8 version;
__u8 padding1[3];
__be64 ec; /* Warning: the current limit is 31-bit anyway! */
__be32 vid_hdr_offset;
__be32 data_offset;
__be32 image_seq;
__u8 padding2[32];
__be32 hdr_crc;
} __packed;
/**
* struct ubi_vid_hdr - on-flash UBI volume identifier header.
* @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC)
* @version: UBI implementation version which is supposed to accept this UBI
* image (%UBI_VERSION)
* @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC)
* @copy_flag: if this logical eraseblock was copied from another physical
* eraseblock (for wear-leveling reasons)
* @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE,
* %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT)
* @vol_id: ID of this volume
* @lnum: logical eraseblock number
* @padding1: reserved for future, zeroes
* @data_size: how many bytes of data this logical eraseblock contains
* @used_ebs: total number of used logical eraseblocks in this volume
* @data_pad: how many bytes at the end of this physical eraseblock are not
* used
* @data_crc: CRC checksum of the data stored in this logical eraseblock
* @padding2: reserved for future, zeroes
* @sqnum: sequence number
* @padding3: reserved for future, zeroes
* @hdr_crc: volume identifier header CRC checksum
*
* The @sqnum is the value of the global sequence counter at the time when this
* VID header was created. The global sequence counter is incremented each time
* UBI writes a new VID header to the flash, i.e. when it maps a logical
* eraseblock to a new physical eraseblock. The global sequence counter is an
* unsigned 64-bit integer and we assume it never overflows. The @sqnum
* (sequence number) is used to distinguish between older and newer versions of
* logical eraseblocks.
*
* There are 2 situations when there may be more than one physical eraseblock
* corresponding to the same logical eraseblock, i.e., having the same @vol_id
* and @lnum values in the volume identifier header. Suppose we have a logical
* eraseblock L and it is mapped to the physical eraseblock P.
*
* 1. Because UBI may erase physical eraseblocks asynchronously, the following
* situation is possible: L is asynchronously erased, so P is scheduled for
* erasure, then L is written to,i.e. mapped to another physical eraseblock P1,
* so P1 is written to, then an unclean reboot happens. Result - there are 2
* physical eraseblocks P and P1 corresponding to the same logical eraseblock
* L. But P1 has greater sequence number, so UBI picks P1 when it attaches the
* flash.
*
* 2. From time to time UBI moves logical eraseblocks to other physical
* eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P
* to P1, and an unclean reboot happens before P is physically erased, there
* are two physical eraseblocks P and P1 corresponding to L and UBI has to
* select one of them when the flash is attached. The @sqnum field says which
* PEB is the original (obviously P will have lower @sqnum) and the copy. But
* it is not enough to select the physical eraseblock with the higher sequence
* number, because the unclean reboot could have happen in the middle of the
* copying process, so the data in P is corrupted. It is also not enough to
* just select the physical eraseblock with lower sequence number, because the
* data there may be old (consider a case if more data was added to P1 after
* the copying). Moreover, the unclean reboot may happen when the erasure of P
* was just started, so it result in unstable P, which is "mostly" OK, but
* still has unstable bits.
*
* UBI uses the @copy_flag field to indicate that this logical eraseblock is a
* copy. UBI also calculates data CRC when the data is moved and stores it at
* the @data_crc field of the copy (P1). So when UBI needs to pick one physical
* eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is
* examined. If it is cleared, the situation* is simple and the newer one is
* picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC
* checksum is correct, this physical eraseblock is selected (P1). Otherwise
* the older one (P) is selected.
*
* There are 2 sorts of volumes in UBI: user volumes and internal volumes.
* Internal volumes are not seen from outside and are used for various internal
* UBI purposes. In this implementation there is only one internal volume - the
* layout volume. Internal volumes are the main mechanism of UBI extensions.
* For example, in future one may introduce a journal internal volume. Internal
* volumes have their own reserved range of IDs.
*
* The @compat field is only used for internal volumes and contains the "degree
* of their compatibility". It is always zero for user volumes. This field
* provides a mechanism to introduce UBI extensions and to be still compatible
* with older UBI binaries. For example, if someone introduced a journal in
* future, he would probably use %UBI_COMPAT_DELETE compatibility for the
* journal volume. And in this case, older UBI binaries, which know nothing
* about the journal volume, would just delete this volume and work perfectly
* fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image
* - it just ignores the Ext3fs journal.
*
* The @data_crc field contains the CRC checksum of the contents of the logical
* eraseblock if this is a static volume. In case of dynamic volumes, it does
* not contain the CRC checksum as a rule. The only exception is when the
* data of the physical eraseblock was moved by the wear-leveling sub-system,
* then the wear-leveling sub-system calculates the data CRC and stores it in
* the @data_crc field. And of course, the @copy_flag is %in this case.
*
* The @data_size field is used only for static volumes because UBI has to know
* how many bytes of data are stored in this eraseblock. For dynamic volumes,
* this field usually contains zero. The only exception is when the data of the
* physical eraseblock was moved to another physical eraseblock for
* wear-leveling reasons. In this case, UBI calculates CRC checksum of the
* contents and uses both @data_crc and @data_size fields. In this case, the
* @data_size field contains data size.
*
* The @used_ebs field is used only for static volumes and indicates how many
* eraseblocks the data of the volume takes. For dynamic volumes this field is
* not used and always contains zero.
*
* The @data_pad is calculated when volumes are created using the alignment
* parameter. So, effectively, the @data_pad field reduces the size of logical
* eraseblocks of this volume. This is very handy when one uses block-oriented
* software (say, cramfs) on top of the UBI volume.
*/
struct ubi_vid_hdr {
__be32 magic;
__u8 version;
__u8 vol_type;
__u8 copy_flag;
__u8 compat;
__be32 vol_id;
__be32 lnum;
__u8 padding1[4];
__be32 data_size;
__be32 used_ebs;
__be32 data_pad;
__be32 data_crc;
__u8 padding2[4];
__be64 sqnum;
__u8 padding3[12];
__be32 hdr_crc;
} __packed;
/* Internal UBI volumes count */
#define UBI_INT_VOL_COUNT 1
/*
* Starting ID of internal volumes: 0x7fffefff.
* There is reserved room for 4096 internal volumes.
*/
#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096)
/* The layout volume contains the volume table */
#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START
#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC
#define UBI_LAYOUT_VOLUME_ALIGN 1
#define UBI_LAYOUT_VOLUME_EBS 2
#define UBI_LAYOUT_VOLUME_NAME "layout volume"
#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT
/* The maximum number of volumes per one UBI device */
#define UBI_MAX_VOLUMES 128
/* The maximum volume name length */
#define UBI_VOL_NAME_MAX 127
/* Size of the volume table record */
#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record)
/* Size of the volume table record without the ending CRC */
#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32))
/**
* struct ubi_vtbl_record - a record in the volume table.
* @reserved_pebs: how many physical eraseblocks are reserved for this volume
* @alignment: volume alignment
* @data_pad: how many bytes are unused at the end of the each physical
* eraseblock to satisfy the requested alignment
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
* @upd_marker: if volume update was started but not finished
* @name_len: volume name length
* @name: the volume name
* @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG)
* @padding: reserved, zeroes
* @crc: a CRC32 checksum of the record
*
* The volume table records are stored in the volume table, which is stored in
* the layout volume. The layout volume consists of 2 logical eraseblock, each
* of which contains a copy of the volume table (i.e., the volume table is
* duplicated). The volume table is an array of &struct ubi_vtbl_record
* objects indexed by the volume ID.
*
* If the size of the logical eraseblock is large enough to fit
* %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES
* records. Otherwise, it contains as many records as it can fit (i.e., size of
* logical eraseblock divided by sizeof(struct ubi_vtbl_record)).
*
* The @upd_marker flag is used to implement volume update. It is set to %1
* before update and set to %0 after the update. So if the update operation was
* interrupted, UBI knows that the volume is corrupted.
*
* The @alignment field is specified when the volume is created and cannot be
* later changed. It may be useful, for example, when a block-oriented file
* system works on top of UBI. The @data_pad field is calculated using the
* logical eraseblock size and @alignment. The alignment must be multiple to the
* minimal flash I/O unit. If @alignment is 1, all the available space of
* the physical eraseblocks is used.
*
* Empty records contain all zeroes and the CRC checksum of those zeroes.
*/
struct ubi_vtbl_record {
__be32 reserved_pebs;
__be32 alignment;
__be32 data_pad;
__u8 vol_type;
__u8 upd_marker;
__be16 name_len;
__u8 name[UBI_VOL_NAME_MAX+1];
__u8 flags;
__u8 padding[23];
__be32 crc;
} __packed;
/* UBI fastmap on-flash data structures */
#define UBI_FM_SB_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 1)
#define UBI_FM_DATA_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 2)
/* fastmap on-flash data structure format version */
#define UBI_FM_FMT_VERSION 1
#define UBI_FM_SB_MAGIC 0x7B11D69F
#define UBI_FM_HDR_MAGIC 0xD4B82EF7
#define UBI_FM_VHDR_MAGIC 0xFA370ED1
#define UBI_FM_POOL_MAGIC 0x67AF4D08
#define UBI_FM_EBA_MAGIC 0xf0c040a8
/* A fastmap supber block can be located between PEB 0 and
* UBI_FM_MAX_START */
#define UBI_FM_MAX_START 64
/* A fastmap can use up to UBI_FM_MAX_BLOCKS PEBs */
#define UBI_FM_MAX_BLOCKS 32
/* 5% of the total number of PEBs have to be scanned while attaching
* from a fastmap.
* But the size of this pool is limited to be between UBI_FM_MIN_POOL_SIZE and
* UBI_FM_MAX_POOL_SIZE */
#define UBI_FM_MIN_POOL_SIZE 8
#define UBI_FM_MAX_POOL_SIZE 256
#define UBI_FM_WL_POOL_SIZE 25
/**
* struct ubi_fm_sb - UBI fastmap super block
* @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC)
* @version: format version of this fastmap
* @data_crc: CRC over the fastmap data
* @used_blocks: number of PEBs used by this fastmap
* @block_loc: an array containing the location of all PEBs of the fastmap
* @block_ec: the erase counter of each used PEB
* @sqnum: highest sequence number value at the time while taking the fastmap
*
*/
struct ubi_fm_sb {
__be32 magic;
__u8 version;
__u8 padding1[3];
__be32 data_crc;
__be32 used_blocks;
__be32 block_loc[UBI_FM_MAX_BLOCKS];
__be32 block_ec[UBI_FM_MAX_BLOCKS];
__be64 sqnum;
__u8 padding2[32];
} __packed;
/**
* struct ubi_fm_hdr - header of the fastmap data set
* @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC)
* @free_peb_count: number of free PEBs known by this fastmap
* @used_peb_count: number of used PEBs known by this fastmap
* @scrub_peb_count: number of to be scrubbed PEBs known by this fastmap
* @bad_peb_count: number of bad PEBs known by this fastmap
* @erase_peb_count: number of bad PEBs which have to be erased
* @vol_count: number of UBI volumes known by this fastmap
*/
struct ubi_fm_hdr {
__be32 magic;
__be32 free_peb_count;
__be32 used_peb_count;
__be32 scrub_peb_count;
__be32 bad_peb_count;
__be32 erase_peb_count;
__be32 vol_count;
__u8 padding[4];
} __packed;
/* struct ubi_fm_hdr is followed by two struct ubi_fm_scan_pool */
/**
* struct ubi_fm_scan_pool - Fastmap pool PEBs to be scanned while attaching
* @magic: pool magic numer (%UBI_FM_POOL_MAGIC)
* @size: current pool size
* @max_size: maximal pool size
* @pebs: an array containing the location of all PEBs in this pool
*/
struct ubi_fm_scan_pool {
__be32 magic;
__be16 size;
__be16 max_size;
__be32 pebs[UBI_FM_MAX_POOL_SIZE];
__be32 padding[4];
} __packed;
/* ubi_fm_scan_pool is followed by nfree+nused struct ubi_fm_ec records */
/**
* struct ubi_fm_ec - stores the erase counter of a PEB
* @pnum: PEB number
* @ec: ec of this PEB
*/
struct ubi_fm_ec {
__be32 pnum;
__be32 ec;
} __packed;
/**
* struct ubi_fm_volhdr - Fastmap volume header
* it identifies the start of an eba table
* @magic: Fastmap volume header magic number (%UBI_FM_VHDR_MAGIC)
* @vol_id: volume id of the fastmapped volume
* @vol_type: type of the fastmapped volume
* @data_pad: data_pad value of the fastmapped volume
* @used_ebs: number of used LEBs within this volume
* @last_eb_bytes: number of bytes used in the last LEB
*/
struct ubi_fm_volhdr {
__be32 magic;
__be32 vol_id;
__u8 vol_type;
__u8 padding1[3];
__be32 data_pad;
__be32 used_ebs;
__be32 last_eb_bytes;
__u8 padding2[8];
} __packed;
/* struct ubi_fm_volhdr is followed by one struct ubi_fm_eba records */
/**
* struct ubi_fm_eba - denotes an association beween a PEB and LEB
* @magic: EBA table magic number
* @reserved_pebs: number of table entries
* @pnum: PEB number of LEB (LEB is the index)
*/
struct ubi_fm_eba {
__be32 magic;
__be32 reserved_pebs;
__be32 pnum[0];
} __packed;
#endif /* !__UBI_MEDIA_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) International Business Machines Corp., 2006
* Copyright © International Business Machines Corp., 2006
*
* 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
@ -11,6 +11,9 @@
* 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 (Битюцкий Артём)
*/
@ -18,6 +21,9 @@
#ifndef __UBI_USER_H__
#define __UBI_USER_H__
#include <linux/types.h>
#include <linux/compiler.h>
/*
* UBI device creation (the same as MTD device attachment)
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -37,30 +43,37 @@
* UBI volume creation
* ~~~~~~~~~~~~~~~~~~~
*
* UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character
* UBI volumes are created via the %UBI_IOCMKVOL ioctl command of UBI character
* device. A &struct ubi_mkvol_req object has to be properly filled and a
* pointer to it has to be passed to the IOCTL.
* pointer to it has to be passed to the ioctl.
*
* UBI volume deletion
* ~~~~~~~~~~~~~~~~~~~
*
* To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character
* To delete a volume, the %UBI_IOCRMVOL ioctl command of the UBI character
* device should be used. A pointer to the 32-bit volume ID hast to be passed
* to the IOCTL.
* to the ioctl.
*
* UBI volume re-size
* ~~~~~~~~~~~~~~~~~~
*
* To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character
* To re-size a volume, the %UBI_IOCRSVOL ioctl command of the UBI character
* device should be used. A &struct ubi_rsvol_req object has to be properly
* filled and a pointer to it has to be passed to the IOCTL.
* filled and a pointer to it has to be passed to the ioctl.
*
* UBI volumes re-name
* ~~~~~~~~~~~~~~~~~~~
*
* To re-name several volumes atomically at one go, the %UBI_IOCRNVOL command
* of the UBI character device should be used. A &struct ubi_rnvol_req object
* has to be properly filled and a pointer to it has to be passed to the ioctl.
*
* UBI volume update
* ~~~~~~~~~~~~~~~~~
*
* Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the
* Volume update should be done via the %UBI_IOCVOLUP ioctl command of the
* corresponding UBI volume character device. A pointer to a 64-bit update
* size should be passed to the IOCTL. After this, UBI expects user to write
* size should be passed to the ioctl. After this, UBI expects user to write
* this number of bytes to the volume character device. The update is finished
* when the claimed number of bytes is passed. So, the volume update sequence
* is something like:
@ -70,14 +83,58 @@
* write(fd, buf, image_size);
* close(fd);
*
* Atomic eraseblock change
* Logical eraseblock erase
* ~~~~~~~~~~~~~~~~~~~~~~~~
*
* Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL
* command of the corresponding UBI volume character device. A pointer to
* &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is
* expected to write the requested amount of bytes. This is similar to the
* "volume update" IOCTL.
* To erase a logical eraseblock, the %UBI_IOCEBER ioctl command of the
* corresponding UBI volume character device should be used. This command
* unmaps the requested logical eraseblock, makes sure the corresponding
* physical eraseblock is successfully erased, and returns.
*
* Atomic logical eraseblock change
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Atomic logical eraseblock change operation is called using the %UBI_IOCEBCH
* ioctl command of the corresponding UBI volume character device. A pointer to
* a &struct ubi_leb_change_req object has to be passed to the ioctl. Then the
* user is expected to write the requested amount of bytes (similarly to what
* should be done in case of the "volume update" ioctl).
*
* Logical eraseblock map
* ~~~~~~~~~~~~~~~~~~~~~
*
* To map a logical eraseblock to a physical eraseblock, the %UBI_IOCEBMAP
* ioctl command should be used. A pointer to a &struct ubi_map_req object is
* expected to be passed. The ioctl maps the requested logical eraseblock to
* a physical eraseblock and returns. Only non-mapped logical eraseblocks can
* be mapped. If the logical eraseblock specified in the request is already
* mapped to a physical eraseblock, the ioctl fails and returns error.
*
* Logical eraseblock unmap
* ~~~~~~~~~~~~~~~~~~~~~~~~
*
* To unmap a logical eraseblock to a physical eraseblock, the %UBI_IOCEBUNMAP
* ioctl command should be used. The ioctl unmaps the logical eraseblocks,
* schedules corresponding physical eraseblock for erasure, and returns. Unlike
* the "LEB erase" command, it does not wait for the physical eraseblock being
* erased. Note, the side effect of this is that if an unclean reboot happens
* after the unmap ioctl returns, you may find the LEB mapped again to the same
* physical eraseblock after the UBI is run again.
*
* Check if logical eraseblock is mapped
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To check if a logical eraseblock is mapped to a physical eraseblock, the
* %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is
* not mapped, and %1 if it is mapped.
*
* Set an UBI volume property
* ~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be
* used. A pointer to a &struct ubi_set_vol_prop_req object is expected to be
* passed. The object describes which property should be set, and to which value
* it should be set.
*/
/*
@ -91,56 +148,53 @@
/* Maximum volume name length */
#define UBI_MAX_VOLUME_NAME 127
/* IOCTL commands of UBI character devices */
/* ioctl commands of UBI character devices */
#define UBI_IOC_MAGIC 'o'
/* Create an UBI volume */
#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req)
/* Remove an UBI volume */
#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t)
#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, __s32)
/* Re-size an UBI volume */
#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req)
/* Re-name volumes */
#define UBI_IOCRNVOL _IOW(UBI_IOC_MAGIC, 3, struct ubi_rnvol_req)
/* IOCTL commands of the UBI control character device */
/* ioctl commands of the UBI control character device */
#define UBI_CTRL_IOC_MAGIC 'o'
/* Attach an MTD device */
#define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req)
/* Detach an MTD device */
#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t)
#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, __s32)
/* IOCTL commands of UBI volume character devices */
/* ioctl commands of UBI volume character devices */
#define UBI_VOL_IOC_MAGIC 'O'
/* Start UBI volume update */
#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t)
/* An eraseblock erasure command, used for debugging, disabled by default */
#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t)
/* An atomic eraseblock change command */
#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t)
#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, __s64)
/* LEB erasure command, used for debugging, disabled by default */
#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, __s32)
/* Atomic LEB change command */
#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, __s32)
/* Map LEB command */
#define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req)
/* Unmap LEB command */
#define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, __s32)
/* Check if LEB is mapped command */
#define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, __s32)
/* Set an UBI volume property */
#define UBI_IOCSETVOLPROP _IOW(UBI_VOL_IOC_MAGIC, 6, \
struct ubi_set_vol_prop_req)
/* Maximum MTD device name length supported by UBI */
#define MAX_UBI_MTD_NAME_LEN 127
/*
* UBI data type hint constants.
*
* UBI_LONGTERM: long-term data
* UBI_SHORTTERM: short-term data
* UBI_UNKNOWN: data persistence is unknown
*
* These constants are used when data is written to UBI volumes in order to
* help the UBI wear-leveling unit to find more appropriate physical
* eraseblocks.
*/
enum {
UBI_LONGTERM = 1,
UBI_SHORTTERM = 2,
UBI_UNKNOWN = 3,
};
/* Maximum amount of UBI volumes that can be re-named at one go */
#define UBI_MAX_RNVOL 32
/*
* UBI volume type constants.
@ -153,6 +207,17 @@ enum {
UBI_STATIC_VOLUME = 4,
};
/*
* UBI set volume property ioctl constants.
*
* @UBI_VOL_PROP_DIRECT_WRITE: allow (any non-zero value) or disallow (value 0)
* user to directly write and erase individual
* eraseblocks on dynamic volumes
*/
enum {
UBI_VOL_PROP_DIRECT_WRITE = 1,
};
/**
* struct ubi_attach_req - attach MTD device request.
* @ubi_num: UBI device number to create
@ -173,20 +238,20 @@ enum {
* it will be 512 in case of a 2KiB page NAND flash with 4 512-byte sub-pages.
*
* But in rare cases, if this optimizes things, the VID header may be placed to
* a different offset. For example, the boot-loader might do things faster if the
* VID header sits at the end of the first 2KiB NAND page with 4 sub-pages. As
* the boot-loader would not normally need to read EC headers (unless it needs
* UBI in RW mode), it might be faster to calculate ECC. This is weird example,
* but it real-life example. So, in this example, @vid_hdr_offer would be
* 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes
* aligned, which is OK, as UBI is clever enough to realize this is 4th sub-page
* of the first page and add needed padding.
* a different offset. For example, the boot-loader might do things faster if
* the VID header sits at the end of the first 2KiB NAND page with 4 sub-pages.
* As the boot-loader would not normally need to read EC headers (unless it
* needs UBI in RW mode), it might be faster to calculate ECC. This is weird
* example, but it real-life example. So, in this example, @vid_hdr_offer would
* be 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes
* aligned, which is OK, as UBI is clever enough to realize this is 4th
* sub-page of the first page and add needed padding.
*/
struct ubi_attach_req {
int32_t ubi_num;
int32_t mtd_num;
int32_t vid_hdr_offset;
uint8_t padding[12];
__s32 ubi_num;
__s32 mtd_num;
__s32 vid_hdr_offset;
__s8 padding[12];
};
/**
@ -221,15 +286,15 @@ struct ubi_attach_req {
* BLOBs, without caring about how to properly align them.
*/
struct ubi_mkvol_req {
int32_t vol_id;
int32_t alignment;
int64_t bytes;
int8_t vol_type;
int8_t padding1;
int16_t name_len;
int8_t padding2[4];
__s32 vol_id;
__s32 alignment;
__s64 bytes;
__s8 vol_type;
__s8 padding1;
__s16 name_len;
__s8 padding2[4];
char name[UBI_MAX_VOLUME_NAME + 1];
} __attribute__ ((packed));
} __packed;
/**
* struct ubi_rsvol_req - a data structure used in volume re-size requests.
@ -238,60 +303,109 @@ struct ubi_mkvol_req {
*
* Re-sizing is possible for both dynamic and static volumes. But while dynamic
* volumes may be re-sized arbitrarily, static volumes cannot be made to be
* smaller then the number of bytes they bear. To arbitrarily shrink a static
* smaller than the number of bytes they bear. To arbitrarily shrink a static
* volume, it must be wiped out first (by means of volume update operation with
* zero number of bytes).
*/
struct ubi_rsvol_req {
int64_t bytes;
int32_t vol_id;
} __attribute__ ((packed));
__s64 bytes;
__s32 vol_id;
} __packed;
/**
* struct ubi_leb_change_req - a data structure used in atomic logical
* eraseblock change requests.
* struct ubi_rnvol_req - volumes re-name request.
* @count: count of volumes to re-name
* @padding1: reserved for future, not used, has to be zeroed
* @vol_id: ID of the volume to re-name
* @name_len: name length
* @padding2: reserved for future, not used, has to be zeroed
* @name: new volume name
*
* UBI allows to re-name up to %32 volumes at one go. The count of volumes to
* re-name is specified in the @count field. The ID of the volumes to re-name
* and the new names are specified in the @vol_id and @name fields.
*
* The UBI volume re-name operation is atomic, which means that should power cut
* happen, the volumes will have either old name or new name. So the possible
* use-cases of this command is atomic upgrade. Indeed, to upgrade, say, volumes
* A and B one may create temporary volumes %A1 and %B1 with the new contents,
* then atomically re-name A1->A and B1->B, in which case old %A and %B will
* be removed.
*
* If it is not desirable to remove old A and B, the re-name request has to
* contain 4 entries: A1->A, A->A1, B1->B, B->B1, in which case old A1 and B1
* become A and B, and old A and B will become A1 and B1.
*
* It is also OK to request: A1->A, A1->X, B1->B, B->Y, in which case old A1
* and B1 become A and B, and old A and B become X and Y.
*
* In other words, in case of re-naming into an existing volume name, the
* existing volume is removed, unless it is re-named as well at the same
* re-name request.
*/
struct ubi_rnvol_req {
__s32 count;
__s8 padding1[12];
struct {
__s32 vol_id;
__s16 name_len;
__s8 padding2[2];
char name[UBI_MAX_VOLUME_NAME + 1];
} ents[UBI_MAX_RNVOL];
} __packed;
/**
* struct ubi_leb_change_req - a data structure used in atomic LEB change
* requests.
* @lnum: logical eraseblock number to change
* @bytes: how many bytes will be written to the logical eraseblock
* @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
* @dtype: pass "3" for better compatibility with old kernels
* @padding: reserved for future, not used, has to be zeroed
*
* The @dtype field used to inform UBI about what kind of data will be written
* to the LEB: long term (value 1), short term (value 2), unknown (value 3).
* UBI tried to pick a PEB with lower erase counter for short term data and a
* PEB with higher erase counter for long term data. But this was not really
* used because users usually do not know this and could easily mislead UBI. We
* removed this feature in May 2012. UBI currently just ignores the @dtype
* field. But for better compatibility with older kernels it is recommended to
* set @dtype to 3 (unknown).
*/
struct ubi_leb_change_req {
int32_t lnum;
int32_t bytes;
uint8_t dtype;
uint8_t padding[7];
} __attribute__ ((packed));
__s32 lnum;
__s32 bytes;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[7];
} __packed;
/**
* ubi_attach_mtd_dev - attach an MTD device.
* @mtd_dev: MTD device description object
* @ubi_num: number to assign to the new UBI device
* @vid_hdr_offset: VID header offset
*
* This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number
* to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in
* which case this function finds a vacant device nubert and assings it
* automatically. Returns the new UBI device number in case of success and a
* negative error code in case of failure.
*
* This of course is originally not exported but is now part of the UBI
* interface to barebox.
* struct ubi_map_req - a data structure used in map LEB requests.
* @dtype: pass "3" for better compatibility with old kernels
* @lnum: logical eraseblock number to unmap
* @padding: reserved for future, not used, has to be zeroed
*/
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset);
struct ubi_map_req {
__s32 lnum;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[3];
} __packed;
/**
* ubi_detach_mtd_dev - detach an MTD device.
* @ubi_num: UBI device number to detach from
* @anyway: detach MTD even if device reference count is not zero
*
* This function destroys an UBI device number @ubi_num and detaches the
* underlying MTD device. Returns zero in case of success and %-EBUSY if the
* UBI device is busy and cannot be destroyed, and %-EINVAL if it does not
* exist.
*
* This of course is originally not exported but is now part of the UBI
* interface to barebox.
* struct ubi_set_vol_prop_req - a data structure used to set an UBI volume
* property.
* @property: property to set (%UBI_VOL_PROP_DIRECT_WRITE)
* @padding: reserved for future, not used, has to be zeroed
* @value: value to set
*/
int ubi_detach_mtd_dev(struct mtd_info *mtd, int anyway);
struct ubi_set_vol_prop_req {
__u8 property;
__u8 padding[7];
__u64 value;
} __packed;
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024);
int ubi_detach_mtd_dev(int ubi_num, int anyway);
#endif /* __UBI_USER_H__ */

View File

@ -10,7 +10,15 @@ unsigned int rand(void);
void srand(unsigned int seed);
/* fill a buffer with pseudo-random data */
void get_random_bytes(char *buf, int len);
void get_random_bytes(void *buf, int len);
static inline u32 random32(void)
{
u32 ret;
get_random_bytes(&ret, 4);
return ret;
}
#endif /* __STDLIB_H */

View File

@ -18,8 +18,10 @@ void srand(unsigned int seed)
random_seed = seed;
}
void get_random_bytes(char *buf, int len)
void get_random_bytes(void *_buf, int len)
{
char *buf = _buf;
while (len--)
*buf++ = rand() % 256;
}