/* Here we keep miscellaneous functions which are used all over the UBI code */
#include"ubi.h"
/** *ubi_calc_data_len-calculatehowmuchrealdataisstoredinabuffer. *@ubi:UBIdevicedescriptionobject *@buf:abufferwiththecontentsofthephysicaleraseblock *@length:thebufferlength * *Thisfunctioncalculateshowmuch"realdata"isstoredin@bufandreturnes *thelength.Continuous0xFFbytesattheendofthebufferarenot *consideredas"realdata".
*/ int ubi_calc_data_len(conststruct ubi_device *ubi, constvoid *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-checkthecontentsofastaticvolume. *@ubi:UBIdevicedescriptionobject *@vol_id:IDofthevolumetocheck * *Thisfunctionchecksifstaticvolume@vol_idiscorruptedbyfullyreading *itandcheckingdataCRC.Thisfunctionreturns%0ifthevolumeisnot *corrupted,%1ifitiscorruptedandanegativeerrorcodeincaseof *failure.Dynamicvolumesarenotcheckedandzeroisreturnedimmediately.
*/ 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) return0;
buf = vmalloc(vol->usable_leb_size); if (!buf) return -ENOMEM;
for (i = 0; i < vol->used_ebs; i++) { int size;
cond_resched();
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-updatebaderaseblockhandlingaccountingdata. *@ubi:UBIdevicedescriptionobject * *ThisfunctioncalculatesthegapbetweencurrentnumberofPEBsreservedfor *baderaseblockhandlingandtherequiredlevelofPEBsthatmustbe *reserved,andifnecessary,reservesmorePEBstofillthatgap,according *toavailability.Shouldbecalledwithubi->volumes_lockheld.
*/ 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(ubi, "reserved more %d PEBs for bad PEB handling", need);
}
/** *ubi_calculate_reserved-calculatehowmanyPEBsmustbereservedforbad *eraseblockhandling. *@ubi:UBIdevicedescriptionobject
*/ void ubi_calculate_reserved(struct ubi_device *ubi)
{ /* *CalculatetheactualnumberofPEBscurrentlyneededtobereserved *forfuturebaderaseblockhandling.
*/
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(ubi, "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-checkifbuffercontainsonlyacertainbytepattern. *@buf:buffertocheck *@patt:thepatterntocheck *@size:buffersizeinbytes * *Thisfunctionreturns%1inthereareonly@pattbytesin@buf,and%0if *somethingelsewasalsofound.
*/ int ubi_check_pattern(constvoid *buf, uint8_t patt, int size)
{ int i;
for (i = 0; i < size; i++) if (((const uint8_t *)buf)[i] != patt) return0; return1;
}
/* Normal UBI messages */ void ubi_msg(conststruct ubi_device *ubi, constchar *fmt, ...)
{ struct va_format vaf;
va_list args;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.