diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-02-19 14:54:17 +0200 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-02-19 16:41:16 +0200 |
commit | 86dd9696d3a1acb036d65909d93d73455b8aed3a (patch) | |
tree | 9e8bb6797b3bebd0bf83ae1fab2151a6dfeafe6a /ubi-utils/src/libubigen.c | |
parent | ef644090223e5983ca2492850354c1390e3368d1 (diff) |
Revert ubi-tools changes
Restore ubi tools to their "original" state, which means to
the state they were before I stareted cleaning them up.
Instead, create a "new-utils" subdirectory and move my work
there.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'ubi-utils/src/libubigen.c')
-rw-r--r-- | ubi-utils/src/libubigen.c | 660 |
1 files changed, 413 insertions, 247 deletions
diff --git a/ubi-utils/src/libubigen.c b/ubi-utils/src/libubigen.c index 8d71fde..1fce3f9 100644 --- a/ubi-utils/src/libubigen.c +++ b/ubi-utils/src/libubigen.c @@ -1,6 +1,5 @@ /* * Copyright (c) International Business Machines Corp., 2006 - * Copyright (C) 2008 Nokia Corporation * * 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 @@ -15,307 +14,474 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Generating UBI images. * - * Authors: Oliver Lohmann - * Artem Bityutskiy + * Author: Oliver Lohmann + * + * Add UBI headers to binary data. */ #include <stdlib.h> #include <stdint.h> #include <stdio.h> -#include <unistd.h> +#include <errno.h> #include <string.h> - #include <mtd/ubi-header.h> -#include <libubigen.h> +#include <mtd_swab.h> + +#include "config.h" +#include "ubigen.h" #include "crc32.h" -#include "common.h" - -#define PROGRAM_NAME "libubigen" - -/** - * ubigen_info_init - initialize libubigen. - * @ui: libubigen information - * @peb_size: flash physical eraseblock size - * @min_io_size: flash minimum input/output unit size - * @subpage_size: flash sub-page, if present (has to be equivalent to - * @min_io_size if does not exist) - * @vid_hdr_offs: offset of the VID header - * @ubi_ver: UBI version - * @ec: initial erase counter - */ -void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size, - int subpage_size, int vid_hdr_offs, int ubi_ver, - long long ec) + +#define UBI_NAME_SIZE 256 +#define DEFAULT_VID_OFFSET ((DEFAULT_PAGESIZE) - (UBI_VID_HDR_SIZE)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +static uint32_t crc32_table[256]; + +struct ubi_info { + struct ubi_vid_hdr* v; /* Volume ID header */ + struct ubi_ec_hdr* ec; /* Erase count header */ + + FILE* fp_in; /* Input Stream */ + FILE* fp_out; /* Output stream */ + + size_t eb_size; /* Physical EB size in bytes */ + size_t leb_size; /* Size of a logical EB in a physical EB */ + size_t leb_total; /* Total input size in logical EB */ + size_t alignment; /* Block alignment */ + size_t data_pad; /* Size of padding in each physical EB */ + + size_t bytes_total; /* Total input size in bytes */ + size_t bytes_read; /* Nymber of read bytes (total) */ + + uint32_t blks_written; /* Number of written logical EB */ + + uint8_t* buf; /* Allocated buffer */ + uint8_t* ptr_ec_hdr; /* Pointer to EC hdr in buf */ + uint8_t* ptr_vid_hdr; /* Pointer to VID hdr in buf */ + uint8_t* ptr_data; /* Pointer to data region in buf */ +}; + + +static uint32_t +byte_to_blk(uint64_t byte, uint32_t eb_size) { - if (!vid_hdr_offs) - vid_hdr_offs = subpage_size; - - ui->peb_size = peb_size; - ui->min_io_size = min_io_size; - ui->vid_hdr_offs = vid_hdr_offs; - ui->data_offs = vid_hdr_offs + UBI_VID_HDR_SIZE + min_io_size - 1; - ui->data_offs /= min_io_size; - ui->data_offs *= min_io_size; - ui->leb_size = peb_size - ui->data_offs; - ui->ubi_ver = ubi_ver; - ui->ec = ec; - - ui->vtbl_size = ui->leb_size; - if (ui->vtbl_size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE) - ui->vtbl_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE; - ui->max_volumes = ui->vtbl_size / UBI_VTBL_RECORD_SIZE; + return (byte % eb_size) == 0 + ? (byte / eb_size) + : (byte / eb_size) + 1; } -/** - * ubigen_create_empty_vtbl - creates empty volume table. - * - * This function creates an empty volume table and returns a pointer to it in - * case of success and %NULL in case of failure. The returned object has to be - * freed with 'free()' call. - */ -struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui) +static int +validate_ubi_info(ubi_info_t u) { - struct ubi_vtbl_record *vtbl; - int i; - - vtbl = calloc(1, ui->vtbl_size); - if (!vtbl) { - errmsg("cannot allocate %d bytes of memory", ui->vtbl_size); - return NULL; + if ((u->v->vol_type != UBI_VID_DYNAMIC) && + (u->v->vol_type != UBI_VID_STATIC)) { + return EUBIGEN_INVALID_TYPE; } - for (i = 0; i < UBI_MAX_VOLUMES; i++) { - uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i], - UBI_VTBL_RECORD_SIZE_CRC); - vtbl[i].crc = cpu_to_be32(crc); + if (be32_to_cpu(u->ec->vid_hdr_offset) < UBI_VID_HDR_SIZE) { + return EUBIGEN_INVALID_HDR_OFFSET; } - return vtbl; + return 0; } -/** - * ubigen_add_volume - add a volume to the volume table. - * @ui: libubigen information - * @vi: volume information - * @vtbl: volume table to add to - * - * This function adds volume described by input parameters to the volume table - * @vtbl. - */ -int ubigen_add_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vtbl_record *vtbl) +static int +skip_blks(ubi_info_t u, uint32_t blks) { - struct ubi_vtbl_record *vtbl_rec = &vtbl[vi->id]; - uint32_t tmp; - - if (vi->id >= ui->max_volumes) - return errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); - - if (vi->alignment >= ui->leb_size) - return errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); - - memset(vtbl_rec, '\0', sizeof(struct ubi_vtbl_record)); - tmp = (vi->bytes + ui->leb_size - 1) / ui->leb_size; - vtbl_rec->reserved_pebs = cpu_to_be32(tmp); - vtbl_rec->alignment = cpu_to_be32(vi->alignment); - vtbl_rec->vol_type = vi->type; - tmp = ui->leb_size % vi->alignment; - vtbl_rec->data_pad = cpu_to_be32(tmp); - vtbl_rec->flags = vi->flags; - - memcpy(vtbl_rec->name, vi->name, vi->name_len); - vtbl_rec->name[vi->name_len] = '\0'; - vtbl_rec->name_len = cpu_to_be16(vi->name_len); - - tmp = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); - vtbl_rec->crc = cpu_to_be32(tmp); + uint32_t i; + size_t read = 0, to_read = 0; + + /* Step to a maximum of leb_total - 1 to keep the + restrictions. */ + for (i = 0; i < MIN(blks, u->leb_total-1); i++) { + /* Read in data */ + to_read = MIN(u->leb_size, + (u->bytes_total - u->bytes_read)); + read = fread(u->ptr_data, 1, to_read, u->fp_in); + if (read != to_read) { + return -EIO; + } + u->bytes_read += read; + u->blks_written++; + } + return 0; } -/** - * init_ec_hdr - initialize EC header. - * @ui: libubigen information - * @hdr: the EC header to initialize - */ -static void init_ec_hdr(const struct ubigen_info *ui, - struct ubi_ec_hdr *hdr) +static void +clear_buf(ubi_info_t u) { - uint32_t crc; + memset(u->buf, 0xff, u->eb_size); +} - memset(hdr, '\0', sizeof(struct ubi_ec_hdr)); +static void +write_ec_hdr(ubi_info_t u) +{ + memcpy(u->ptr_ec_hdr, u->ec, UBI_EC_HDR_SIZE); +} - hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); - hdr->version = ui->ubi_ver; - hdr->ec = cpu_to_be64(ui->ec); - hdr->vid_hdr_offset = cpu_to_be32(ui->vid_hdr_offs); +static int +fill_data_buffer_from_file(ubi_info_t u, size_t* read) +{ + size_t to_read = 0; - hdr->data_offset = cpu_to_be32(ui->data_offs); + if (u-> fp_in == NULL) + return -EIO; - crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); + to_read = MIN(u->leb_size, (u->bytes_total - u->bytes_read)); + *read = fread(u->ptr_data, 1, to_read, u->fp_in); + if (*read != to_read) { + return -EIO; + } + return 0; } -/** - * init_vid_hdr - initialize VID header. - * @ui: libubigen information - * @vi: volume information - * @hdr: the VID header to initialize - * @lnum: logical eraseblock number - * @data: the contents of the LEB (static volumes only) - * @data_size: amount of data in this LEB (static volumes only) - * - * Note, @used_ebs, @data and @data_size are ignored in case of dynamic - * volumes. - */ -static void init_vid_hdr(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vid_hdr *hdr, int lnum, - const void *data, int data_size) +static void +add_static_info(ubi_info_t u, size_t data_size, ubigen_action_t action) { - uint32_t crc; + uint32_t crc = clc_crc32(crc32_table, UBI_CRC32_INIT, + u->ptr_data, data_size); - memset(hdr, '\0', sizeof(struct ubi_vid_hdr)); - - hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); - hdr->version = ui->ubi_ver; - hdr->vol_type = vi->type; - hdr->vol_id = cpu_to_be32(vi->id); - hdr->lnum = cpu_to_be32(lnum); - hdr->data_pad = cpu_to_be32(vi->data_pad); - hdr->compat = vi->compat; - - if (vi->type == UBI_VID_STATIC) { - hdr->data_size = cpu_to_be32(data_size); - hdr->used_ebs = cpu_to_be32(vi->used_ebs); - crc = crc32(UBI_CRC32_INIT, data, data_size); - hdr->data_crc = cpu_to_be32(crc); + u->v->data_size = cpu_to_be32(data_size); + u->v->data_crc = cpu_to_be32(crc); + + if (action & BROKEN_DATA_CRC) { + u->v->data_crc = + cpu_to_be32(be32_to_cpu(u->v->data_crc) + 1); + } + if (action & BROKEN_DATA_SIZE) { + u->v->data_size = + cpu_to_be32(be32_to_cpu(u->v->data_size) + 1); } +} - crc = crc32(UBI_CRC32_INIT, hdr, UBI_VID_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); +static void +write_vid_hdr(ubi_info_t u, ubigen_action_t action) +{ + uint32_t crc = clc_crc32(crc32_table, UBI_CRC32_INIT, + u->v, UBI_VID_HDR_SIZE_CRC); + /* Write VID header */ + u->v->hdr_crc = cpu_to_be32(crc); + if (action & BROKEN_HDR_CRC) { + u->v->hdr_crc = cpu_to_be32(be32_to_cpu(u->v->hdr_crc) + 1); + } + memcpy(u->ptr_vid_hdr, u->v, UBI_VID_HDR_SIZE); } -/** - * ubigen_write_volume - write UBI volume. - * @ui: libubigen information - * @vi: volume information - * @bytes: volume size in bytes - * @in: input file descriptor (has to be properly seeked) - * @out: output file descriptor - * - * This function reads the contents of the volume from the input file @in and - * writes the UBI volume to the output file @out. Returns zero on success and - * %-1 on failure. - */ -int ubigen_write_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - long long bytes, FILE *in, FILE *out) +static int +write_to_output_stream(ubi_info_t u) { - int len = vi->usable_leb_size, rd, lnum = 0; - char inbuf[ui->leb_size], outbuf[ui->peb_size]; + size_t written; - if (vi->id >= ui->max_volumes) - return errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); + written = fwrite(u->buf, 1, u->eb_size, u->fp_out); + if (written != u->eb_size) { + return -EIO; + } + return 0; +} - if (vi->alignment >= ui->leb_size) - return errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); +int +ubigen_write_leb(ubi_info_t u, ubigen_action_t action) +{ + int rc = 0; + size_t read = 0; - memset(outbuf, 0xFF, ui->data_offs); - init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf); + clear_buf(u); + write_ec_hdr(u); - while (bytes) { - int l; - struct ubi_vid_hdr *vid_hdr; + rc = fill_data_buffer_from_file(u, &read); + if (rc != 0) + return rc; - if (bytes < len) - len = bytes; - bytes -= len; + if (u->v->vol_type == UBI_VID_STATIC) { + add_static_info(u, read, action); + } - l = len; - do { - rd = fread(inbuf + len - l, 1, l, in); - if (rd == 0) { - if (ferror(in)) - return errmsg("cannot read %d bytes from the input file", l); - else - return errmsg("not enough data in the input file"); - } + u->v->lnum = cpu_to_be32(u->blks_written); - l -= rd; - } while (l); + if (action & MARK_AS_UPDATE) { + u->v->copy_flag = (u->v->copy_flag)++; + } - vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); - init_vid_hdr(ui, vi, vid_hdr, lnum, inbuf, len); + write_vid_hdr(u, action); + rc = write_to_output_stream(u); + if (rc != 0) + return rc; - memcpy(outbuf + ui->data_offs, inbuf, len); - memset(outbuf + ui->data_offs + len, 0xFF, - ui->peb_size - ui->data_offs - len); + /* Update current handle */ + u->bytes_read += read; + u->blks_written++; + return 0; +} - if (fwrite(outbuf, 1, ui->peb_size, out) != ui->peb_size) - return errmsg("cannot write %d bytes from the output file", l); +int +ubigen_write_complete(ubi_info_t u) +{ + size_t i; + int rc = 0; - lnum += 1; + for (i = 0; i < u->leb_total; i++) { + rc = ubigen_write_leb(u, NO_ERROR); + if (rc != 0) + return rc; } return 0; } -/** - * ubigen_write_layout_vol - write UBI layout volume - * @ui: libubigen information - * @vtbl: volume table - * @out: output file stream - * - * This function creates the UBI layout volume which contains 2 copies of the - * volume table. Returns zero in case of success and %-1 in case of failure. - */ -int ubigen_write_layout_vol(const struct ubigen_info *ui, - struct ubi_vtbl_record *vtbl, FILE *out) +int +ubigen_write_broken_update(ubi_info_t u, uint32_t blk) { - int size = ui->leb_size; - struct ubigen_vol_info vi; - char outbuf[ui->peb_size]; - struct ubi_vid_hdr *vid_hdr; - - if (size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE) - size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE; - - vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS; - vi.id = UBI_LAYOUT_VOLUME_ID; - vi.alignment = UBI_LAYOUT_VOLUME_ALIGN; - vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN; - vi.usable_leb_size = ui->leb_size - vi.data_pad; - vi.data_pad = ui->leb_size - vi.usable_leb_size; - vi.type = UBI_LAYOUT_VOLUME_TYPE; - vi.name = UBI_LAYOUT_VOLUME_NAME; - vi.name_len = strlen(UBI_LAYOUT_VOLUME_NAME); - vi.compat = UBI_LAYOUT_VOLUME_COMPAT; - - memset(outbuf, 0xFF, ui->data_offs); - vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); - init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf); - memcpy(outbuf + ui->data_offs, vtbl, size); - memset(outbuf + ui->data_offs + size, 0xFF, - ui->peb_size - ui->data_offs - size); - - init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0); - size = fwrite(outbuf, 1, ui->peb_size, out); - if (size == ui->peb_size) { - init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0); - size = fwrite(outbuf, 1, ui->peb_size, out); - if (size != ui->peb_size) - return sys_errmsg("cannot write %d bytes", ui->peb_size); + int rc = 0; + + rc = skip_blks(u, blk); + if (rc != 0) + return rc; + + rc = ubigen_write_leb(u, MARK_AS_UPDATE | BROKEN_DATA_CRC); + if (rc != 0) + return rc; + + + return 0; +} + +void +dump_info(ubi_info_t u ubi_unused) +{ +#ifdef DEBUG + int err = 0; + if (!u) { + fprintf(stderr, "<empty>"); + return; + } + if (!u->ec) { + fprintf(stderr, "<ec-empty>"); + err = 1; + } + if (!u->v) { + fprintf(stderr, "<v-empty>"); + err = 1; + } + if (err) return; + + fprintf(stderr, "ubi volume\n"); + fprintf(stderr, "version : %8d\n", u->v->version); + fprintf(stderr, "vol_id : %8d\n", be32_to_cpu(u->v->vol_id)); + fprintf(stderr, "vol_type : %8s\n", + u->v->vol_type == UBI_VID_STATIC ? + "static" : "dynamic"); + fprintf(stderr, "used_ebs : %8d\n", + be32_to_cpu(u->v->used_ebs)); + fprintf(stderr, "eb_size : 0x%08x\n", u->eb_size); + fprintf(stderr, "leb_size : 0x%08x\n", u->leb_size); + fprintf(stderr, "data_pad : 0x%08x\n", + be32_to_cpu(u->v->data_pad)); + fprintf(stderr, "leb_total : %8d\n", u->leb_total); + fprintf(stderr, "header offs : 0x%08x\n", + be32_to_cpu(u->ec->vid_hdr_offset)); + fprintf(stderr, "bytes_total : %8d\n", u->bytes_total); + fprintf(stderr, " + in MiB : %8.2f M\n", + ((float)(u->bytes_total)) / 1024 / 1024); + fprintf(stderr, "-------------------------------\n\n"); +#else + return; +#endif +} + +int +ubigen_destroy(ubi_info_t *u) +{ + if (u == NULL) + return -EINVAL; + + ubi_info_t tmp = *u; + + if (tmp) { + if (tmp->v) + free(tmp->v); + if (tmp->ec) + free(tmp->ec); + if (tmp->buf) + free(tmp->buf); + free(tmp); + } + *u = NULL; + return 0; +} + +void +ubigen_init(void) +{ + init_crc32_table(crc32_table); +} + +int +ubigen_create(ubi_info_t* u, uint32_t vol_id, uint8_t vol_type, + uint32_t eb_size, uint64_t ec, uint32_t alignment, + uint8_t version, uint32_t vid_hdr_offset, uint8_t compat_flag, + size_t data_size, FILE* fp_in, FILE* fp_out) +{ + int rc = 0; + ubi_info_t res = NULL; + uint32_t crc; + uint32_t data_offset; + + if (alignment == 0) { + rc = EUBIGEN_INVALID_ALIGNMENT; + goto ubigen_create_err; + } + if ((fp_in == NULL) || (fp_out == NULL)) { + rc = -EINVAL; + goto ubigen_create_err; + } + + res = (ubi_info_t) calloc(1, sizeof(struct ubi_info)); + if (res == NULL) { + rc = -ENOMEM; + goto ubigen_create_err; + } + + res->v = (struct ubi_vid_hdr*) calloc(1, sizeof(struct ubi_vid_hdr)); + if (res->v == NULL) { + rc = -ENOMEM; + goto ubigen_create_err; } + res->ec = (struct ubi_ec_hdr*) calloc(1, sizeof(struct ubi_ec_hdr)); + if (res->ec == NULL) { + rc = -ENOMEM; + goto ubigen_create_err; + } + + /* data which is needed in the general process */ + vid_hdr_offset = vid_hdr_offset ? vid_hdr_offset : DEFAULT_VID_OFFSET; + data_offset = vid_hdr_offset + UBI_VID_HDR_SIZE; + res->bytes_total = data_size; + res->eb_size = eb_size ? eb_size : DEFAULT_BLOCKSIZE; + res->data_pad = (res->eb_size - data_offset) % alignment; + res->leb_size = res->eb_size - data_offset - res->data_pad; + res->leb_total = byte_to_blk(data_size, res->leb_size); + res->alignment = alignment; + + if ((res->eb_size < (vid_hdr_offset + UBI_VID_HDR_SIZE))) { + rc = EUBIGEN_TOO_SMALL_EB; + goto ubigen_create_err; + } + res->fp_in = fp_in; + res->fp_out = fp_out; + + /* vid hdr data which doesn't change */ + res->v->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); + res->v->version = version ? version : UBI_VERSION; + res->v->vol_type = vol_type; + res->v->vol_id = cpu_to_be32(vol_id); + res->v->compat = compat_flag; + res->v->data_pad = cpu_to_be32(res->data_pad); + + /* static only: used_ebs */ + if (res->v->vol_type == UBI_VID_STATIC) { + res->v->used_ebs = cpu_to_be32(byte_to_blk + (res->bytes_total, + res->leb_size)); + } + + /* ec hdr (fixed, doesn't change) */ + res->ec->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); + res->ec->version = version ? version : UBI_VERSION; + res->ec->ec = cpu_to_be64(ec); + res->ec->vid_hdr_offset = cpu_to_be32(vid_hdr_offset); + + res->ec->data_offset = cpu_to_be32(data_offset); + + crc = clc_crc32(crc32_table, UBI_CRC32_INIT, res->ec, + UBI_EC_HDR_SIZE_CRC); + res->ec->hdr_crc = cpu_to_be32(crc); + + /* prepare a read buffer */ + res->buf = (uint8_t*) malloc (res->eb_size * sizeof(uint8_t)); + if (res->buf == NULL) { + rc = -ENOMEM; + goto ubigen_create_err; + } + + /* point to distinct regions within the buffer */ + res->ptr_ec_hdr = res->buf; + res->ptr_vid_hdr = res->buf + be32_to_cpu(res->ec->vid_hdr_offset); + res->ptr_data = res->buf + be32_to_cpu(res->ec->vid_hdr_offset) + + UBI_VID_HDR_SIZE; + + rc = validate_ubi_info(res); + if (rc != 0) { + fprintf(stderr, "Volume validation failed: %d\n", rc); + goto ubigen_create_err; + } + + dump_info(res); + *u = res; + return rc; + + ubigen_create_err: + if (res) { + if (res->v) + free(res->v); + if (res->ec) + free(res->ec); + if (res->buf) + free(res->buf); + free(res); + } + *u = NULL; + return rc; +} + +int +ubigen_get_leb_size(ubi_info_t u, size_t* size) +{ + if (u == NULL) + return -EINVAL; + + *size = u->leb_size; + return 0; +} + + +int +ubigen_get_leb_total(ubi_info_t u, size_t* total) +{ + if (u == NULL) + return -EINVAL; + + *total = u->leb_total; + return 0; +} + +int +ubigen_set_lvol_rec(ubi_info_t u, size_t reserved_bytes, + const char* vol_name, struct ubi_vtbl_record *lvol_rec) +{ + uint32_t crc; + + if ((u == NULL) || (vol_name == NULL)) + return -EINVAL; + + memset(lvol_rec, 0x0, UBI_VTBL_RECORD_SIZE); + + lvol_rec->reserved_pebs = + cpu_to_be32(byte_to_blk(reserved_bytes, u->leb_size)); + lvol_rec->alignment = cpu_to_be32(u->alignment); + lvol_rec->data_pad = u->v->data_pad; + lvol_rec->vol_type = u->v->vol_type; + + lvol_rec->name_len = + cpu_to_be16((uint16_t)strlen((const char*)vol_name)); + + memcpy(lvol_rec->name, vol_name, UBI_VOL_NAME_MAX + 1); + + crc = clc_crc32(crc32_table, UBI_CRC32_INIT, + lvol_rec, UBI_VTBL_RECORD_SIZE_CRC); + lvol_rec->crc = cpu_to_be32(crc); + return 0; } |