12d262c48SKyungmin Park /* 22d262c48SKyungmin Park * Copyright (c) International Business Machines Corp., 2006 32d262c48SKyungmin Park * 42d262c48SKyungmin Park * This program is free software; you can redistribute it and/or modify 52d262c48SKyungmin Park * it under the terms of the GNU General Public License as published by 62d262c48SKyungmin Park * the Free Software Foundation; either version 2 of the License, or 72d262c48SKyungmin Park * (at your option) any later version. 82d262c48SKyungmin Park * 92d262c48SKyungmin Park * This program is distributed in the hope that it will be useful, 102d262c48SKyungmin Park * but WITHOUT ANY WARRANTY; without even the implied warranty of 112d262c48SKyungmin Park * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 122d262c48SKyungmin Park * the GNU General Public License for more details. 132d262c48SKyungmin Park * 142d262c48SKyungmin Park * You should have received a copy of the GNU General Public License 152d262c48SKyungmin Park * along with this program; if not, write to the Free Software 162d262c48SKyungmin Park * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 172d262c48SKyungmin Park * 182d262c48SKyungmin Park * Author: Artem Bityutskiy (Битюцкий Артём) 192d262c48SKyungmin Park */ 202d262c48SKyungmin Park 212d262c48SKyungmin Park /* Here we keep miscellaneous functions which are used all over the UBI code */ 222d262c48SKyungmin Park 232d262c48SKyungmin Park #include <ubi_uboot.h> 242d262c48SKyungmin Park #include "ubi.h" 252d262c48SKyungmin Park 262d262c48SKyungmin Park /** 272d262c48SKyungmin Park * calc_data_len - calculate how much real data is stored in a buffer. 282d262c48SKyungmin Park * @ubi: UBI device description object 292d262c48SKyungmin Park * @buf: a buffer with the contents of the physical eraseblock 302d262c48SKyungmin Park * @length: the buffer length 312d262c48SKyungmin Park * 322d262c48SKyungmin Park * This function calculates how much "real data" is stored in @buf and returnes 332d262c48SKyungmin Park * the length. Continuous 0xFF bytes at the end of the buffer are not 342d262c48SKyungmin Park * considered as "real data". 352d262c48SKyungmin Park */ 362d262c48SKyungmin Park int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, 372d262c48SKyungmin Park int length) 382d262c48SKyungmin Park { 392d262c48SKyungmin Park int i; 402d262c48SKyungmin Park 412d262c48SKyungmin Park ubi_assert(!(length & (ubi->min_io_size - 1))); 422d262c48SKyungmin Park 432d262c48SKyungmin Park for (i = length - 1; i >= 0; i--) 442d262c48SKyungmin Park if (((const uint8_t *)buf)[i] != 0xFF) 452d262c48SKyungmin Park break; 462d262c48SKyungmin Park 472d262c48SKyungmin Park /* The resulting length must be aligned to the minimum flash I/O size */ 482d262c48SKyungmin Park length = ALIGN(i + 1, ubi->min_io_size); 492d262c48SKyungmin Park return length; 502d262c48SKyungmin Park } 512d262c48SKyungmin Park 522d262c48SKyungmin Park /** 532d262c48SKyungmin Park * ubi_check_volume - check the contents of a static volume. 542d262c48SKyungmin Park * @ubi: UBI device description object 552d262c48SKyungmin Park * @vol_id: ID of the volume to check 562d262c48SKyungmin Park * 572d262c48SKyungmin Park * This function checks if static volume @vol_id is corrupted by fully reading 582d262c48SKyungmin Park * it and checking data CRC. This function returns %0 if the volume is not 592d262c48SKyungmin Park * corrupted, %1 if it is corrupted and a negative error code in case of 602d262c48SKyungmin Park * failure. Dynamic volumes are not checked and zero is returned immediately. 612d262c48SKyungmin Park */ 622d262c48SKyungmin Park int ubi_check_volume(struct ubi_device *ubi, int vol_id) 632d262c48SKyungmin Park { 642d262c48SKyungmin Park void *buf; 652d262c48SKyungmin Park int err = 0, i; 662d262c48SKyungmin Park struct ubi_volume *vol = ubi->volumes[vol_id]; 672d262c48SKyungmin Park 682d262c48SKyungmin Park if (vol->vol_type != UBI_STATIC_VOLUME) 692d262c48SKyungmin Park return 0; 702d262c48SKyungmin Park 712d262c48SKyungmin Park buf = vmalloc(vol->usable_leb_size); 722d262c48SKyungmin Park if (!buf) 732d262c48SKyungmin Park return -ENOMEM; 742d262c48SKyungmin Park 752d262c48SKyungmin Park for (i = 0; i < vol->used_ebs; i++) { 762d262c48SKyungmin Park int size; 772d262c48SKyungmin Park 782d262c48SKyungmin Park if (i == vol->used_ebs - 1) 792d262c48SKyungmin Park size = vol->last_eb_bytes; 802d262c48SKyungmin Park else 812d262c48SKyungmin Park size = vol->usable_leb_size; 822d262c48SKyungmin Park 832d262c48SKyungmin Park err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1); 842d262c48SKyungmin Park if (err) { 85*dfe64e2cSSergey Lapin if (mtd_is_eccerr(err)) 862d262c48SKyungmin Park err = 1; 872d262c48SKyungmin Park break; 882d262c48SKyungmin Park } 892d262c48SKyungmin Park } 902d262c48SKyungmin Park 912d262c48SKyungmin Park vfree(buf); 922d262c48SKyungmin Park return err; 932d262c48SKyungmin Park } 942d262c48SKyungmin Park 952d262c48SKyungmin Park /** 962d262c48SKyungmin Park * ubi_calculate_rsvd_pool - calculate how many PEBs must be reserved for bad 972d262c48SKyungmin Park * eraseblock handling. 982d262c48SKyungmin Park * @ubi: UBI device description object 992d262c48SKyungmin Park */ 1002d262c48SKyungmin Park void ubi_calculate_reserved(struct ubi_device *ubi) 1012d262c48SKyungmin Park { 1022d262c48SKyungmin Park ubi->beb_rsvd_level = ubi->good_peb_count/100; 1032d262c48SKyungmin Park ubi->beb_rsvd_level *= CONFIG_MTD_UBI_BEB_RESERVE; 1042d262c48SKyungmin Park if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS) 1052d262c48SKyungmin Park ubi->beb_rsvd_level = MIN_RESEVED_PEBS; 1062d262c48SKyungmin Park } 107