From 6ccd7242c4c1404dafb64cd937adc3c65ce02385 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 21 Jun 2006 14:26:02 +0200 Subject: [MTD] UBI: Removed automake, autoconf, added ubi userspace headers. Signed-off-by: Frank Haverkamp --- ubi-utils/src/pfi.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 ubi-utils/src/pfi.c (limited to 'ubi-utils/src/pfi.c') diff --git a/ubi-utils/src/pfi.c b/ubi-utils/src/pfi.c new file mode 100644 index 0000000..c8d5ee4 --- /dev/null +++ b/ubi-utils/src/pfi.c @@ -0,0 +1,461 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * @file pfi.c + * + * @author Oliver Lohmann + * Andreas Arnez + * Joern Engel + * Frank Haverkamp + * + * @brief libpfi holds all code to create and process pfi files. + * + * Wed Feb 8 11:38:22 CET 2006: Initial creation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pfi.h" + +#define PFI_MAGIC "PFI!\n" +#define PFI_DATA "DATA\n" /* The same size as PFI_MAGIC */ +#define PFI_MAGIC_LEN 5 + +static const char copyright [] __attribute__((unused)) = + "Copyright (c) International Business Machines Corp., 2006"; + +enum key_id { + /* version 1 */ + key_version, /* must be index position 0! */ + key_mode, + key_size, + key_crc, + key_label, + key_flags, + key_ubi_ids, + key_ubi_size, + key_ubi_type, + key_ubi_names, + key_ubi_alignment, + key_raw_starts, + key_raw_total_size, + num_keys, +}; + +struct pfi_header { + char defined[num_keys]; /* reserve all possible keys even if + version does not require this. */ + int mode_no; /* current mode no. -> can only increase */ + union { + char *str; + uint32_t num; + } value[num_keys]; +}; + + +#define PFI_MANDATORY 0x0001 +#define PFI_STRING 0x0002 +#define PFI_LISTVALUE 0x0004 /* comma seperated list of nums */ +#define PFI_MANDATORY_UBI 0x0008 +#define PFI_MANDATORY_RAW 0x0010 + +struct key_descriptor { + enum key_id id; + const char *name; + uint32_t flags; +}; + +static const struct key_descriptor key_desc_v1[] = { + { key_version, "version", PFI_MANDATORY }, + { key_mode, "mode", PFI_MANDATORY | PFI_STRING }, + { key_size, "size", PFI_MANDATORY }, + { key_crc, "crc", PFI_MANDATORY }, + { key_label, "label", PFI_MANDATORY | PFI_STRING }, + { key_flags, "flags", PFI_MANDATORY }, + { key_ubi_ids, "ubi_ids", PFI_MANDATORY_UBI | PFI_STRING }, + { key_ubi_size, "ubi_size", PFI_MANDATORY_UBI }, + { key_ubi_type, "ubi_type", PFI_MANDATORY_UBI | PFI_STRING }, + { key_ubi_names, "ubi_names", PFI_MANDATORY_UBI | PFI_STRING }, + { key_ubi_alignment, "ubi_alignment", PFI_MANDATORY_UBI }, + { key_raw_starts, "raw_starts", PFI_MANDATORY_RAW | PFI_STRING }, + { key_raw_total_size, "raw_total_size", PFI_MANDATORY_RAW }, +}; + +static const struct key_descriptor *key_descriptors[] = { + NULL, + key_desc_v1, /* version 1 */ +}; + +static const int key_descriptors_max[] = { + 0, /* version 0 */ + sizeof(key_desc_v1)/sizeof(struct key_descriptor), /* version 1 */ +}; + +static const char* modes[] = {"raw", "ubi", NULL}; /* order isn't arbitrary! */ + +/* latest version contains all possible keys */ +static const struct key_descriptor *key_desc = key_desc_v1; + +#define PFI_IS_UBI(mode) \ + (((mode) != NULL) && (strcmp("ubi", (mode)) == 0)) + +#define PFI_IS_RAW(mode) \ + (((mode) != NULL) && (strcmp("raw", (mode)) == 0)) + +/** + * @return <0 On Error. + * >=0 Mode no. + */ +static int +get_mode_no(const char* mode) +{ + const char* ptr = modes[0]; + int i = 0; + while (ptr != NULL) { + if(strcmp(ptr, mode) == 0) { + return i; + } + ptr++; + i++; + } + + return -1; +} + +static int +find_key_by_name (const char *name) +{ + int i; + + for (i = 0; i < num_keys; i++) { + if (strcmp(name, key_desc[i].name) == 0) + return i; + } + return -1; +} + +static int +check_valid (pfi_header head) +{ + int i; + int max_keys; + uint32_t version; + const char *mode; + const struct key_descriptor *desc; + uint32_t to_check = PFI_MANDATORY; + + /* + * For the validity check the list of possible keys depends on + * the version of the PFI file used. + */ + version = head->value[key_version].num; + if (version > PFI_HDRVERSION) + return PFI_ENOHEADER; + + max_keys = key_descriptors_max[version]; + desc = key_descriptors[version]; + + if (!desc) + return PFI_ENOVERSION; + + mode = head->value[key_mode].str; + if (PFI_IS_UBI(mode)) { + to_check |= PFI_MANDATORY_UBI; + } + else if (PFI_IS_RAW(mode)) { + to_check |= PFI_MANDATORY_RAW; + } + else { /* neither UBI nor RAW == ERR */ + return PFI_EINSUFF; + } + + for (i = 0; i < max_keys; i++) { + if ((desc[i].flags & to_check) && !head->defined[i]) { + fprintf(stderr, "libpfi: %s missing\n", desc[i].name); + return PFI_EINSUFF; + } + } + + return 0; +} + +int pfi_header_init (pfi_header *head) +{ + int i; + pfi_header self = (pfi_header) malloc(sizeof(*self)); + + *head = self; + if (self == NULL) + return PFI_ENOMEM; + + /* initialize maximum number of possible keys */ + for (i = 0; i < num_keys; i++) { + memset(self, 0, sizeof(*self)); + self->defined[i] = 0; + } + + return 0; +} + +int pfi_header_destroy (pfi_header *head) +{ + int i; + pfi_header self = *head; + + for (i = 0; i < num_keys; i++) { + if (self->defined[i] && (key_desc[i].flags & PFI_STRING) && + self->value[i].str) { + free(self->value[i].str); + } + } + free(*head); + *head = NULL; + return 0; +} + +int pfi_header_setnumber (pfi_header head, + const char *key, uint32_t value) +{ + int key_id = find_key_by_name(key); + + if (key_id < 0) + return PFI_EUNDEF; + + if (key_desc[key_id].flags & PFI_STRING) + return PFI_EBADTYPE; + + head->value[key_id].num = value; + head->defined[key_id] = 1; + return 0; +} + +int pfi_header_setvalue (pfi_header head, + const char *key, const char *value) +{ + int key_id = find_key_by_name(key); + + if ((uint32_t)value == (uint32_t)NULL) + return PFI_EINSUFF; + + if ((key_id < 0) || (key_id >= num_keys)) + return PFI_EUNDEF; + + if (key_desc[key_id].flags & PFI_STRING) { + /* + * The value is a string. Copy to a newly allocated + * buffer. Delete the old value, if already set. + */ + size_t len = strlen(value) + 1; + char *old_str = NULL; + char *str; + + old_str = head->value[key_id].str; + if (old_str != NULL) + free(old_str); + + str = head->value[key_id].str = (char *) malloc(len); + if (str == NULL) + return PFI_ENOMEM; + + strcpy(str, value); + } else { + int len; + int ret; + /* FIXME: here we assume that the value is always + given in hex and starts with '0x'. */ + ret = sscanf(value, "0x%x%n", &head->value[key_id].num, &len); + if (ret < 1 || value[len] != '\0') + return PFI_EBADTYPE; + } + head->defined[key_id] = 1; + return 0; +} + +int pfi_header_getnumber (pfi_header head, + const char *key, uint32_t *value) +{ + int key_id = find_key_by_name(key); + + if (key_id < 0) + return PFI_EUNDEF; + + if (key_desc[key_id].flags & PFI_STRING) + return PFI_EBADTYPE; + + if (!head->defined[key_id]) + return PFI_EUNDEF; + + *value = head->value[key_id].num; + return 0; +} + +int pfi_header_getstring (pfi_header head, + const char *key, char *value, size_t size) +{ + int key_id = find_key_by_name(key); + + if (key_id < 0) + return PFI_EUNDEF; + + if (!(key_desc[key_id].flags & PFI_STRING)) + return PFI_EBADTYPE; + + if (!head->defined[key_id]) + return PFI_EUNDEF; + + strncpy(value, head->value[key_id].str, size-1); + value[size-1] = '\0'; + return 0; +} + +int pfi_header_write (FILE *out, pfi_header head) +{ + int i; + int ret; + + pfi_header_setnumber(head, "version", PFI_HDRVERSION); + + if ((ret = check_valid(head)) != 0) + return ret; + + /* OK. Now write the header. */ + + ret = fwrite(PFI_MAGIC, 1, PFI_MAGIC_LEN, out); + if (ret < PFI_MAGIC_LEN) + return ret; + + + for (i = 0; i < num_keys; i++) { + if (!head->defined[i]) + continue; + + ret = fprintf(out, "%s=", key_desc[i].name); + if (ret < 0) + return PFI_EFILE; + + if (key_desc[i].flags & PFI_STRING) { + ret = fprintf(out, "%s", head->value[i].str); + if (ret < 0) + return PFI_EFILE; + } else { + ret = fprintf(out, "0x%8x", head->value[i].num); + if (ret < 0) + return PFI_EFILE; + + } + ret = fprintf(out, "\n"); + if (ret < 0) + return PFI_EFILE; + } + ret = fprintf(out, "\n"); + if (ret < 0) + return PFI_EFILE; + + ret = fflush(out); + if (ret != 0) + return PFI_EFILE; + + return 0; +} + +int pfi_header_read (FILE *in, pfi_header head) +{ + char magic[PFI_MAGIC_LEN]; + char mode[PFI_KEYWORD_LEN]; + char buf[256]; + + if (PFI_MAGIC_LEN != fread(magic, 1, PFI_MAGIC_LEN, in)) + return PFI_EFILE; + if (memcmp(magic, PFI_MAGIC, PFI_MAGIC_LEN) != 0) { + if (memcmp(magic, PFI_DATA, PFI_MAGIC_LEN) == 0) { + return PFI_DATA_START; + } + return PFI_ENOHEADER; + } + + while (fgets(buf, sizeof(buf), in) != NULL && buf[0] != '\n') { + char *value; + char *end; + value = strchr(buf, '='); + if (value == NULL) + return PFI_ENOHEADER; + + *value = '\0'; + value++; + end = strchr(value, '\n'); + if (end) + *end = '\0'; + + if (pfi_header_setvalue(head, buf, value)) + return PFI_ENOHEADER; + } + + if (check_valid(head) != 0) + return PFI_ENOHEADER; + + /* set current mode no. in head */ + pfi_header_getstring(head, "mode", mode, PFI_KEYWORD_LEN); + if (head->mode_no > get_mode_no(mode)) { + return PFI_EMODE; + } + head->mode_no = get_mode_no(mode); + return 0; +} + +int pfi_header_dump (FILE *out, pfi_header head __attribute__((__unused__))) +{ + fprintf(out, "Sorry not implemented yet. Write mail to " + "Andreas Arnez and complain!\n"); + return 0; +} + +int pfi_read (FILE *in, pfi_read_func func, void *priv_data) +{ + int rc; + pfi_header header; + + rc = pfi_header_init (&header); + if (0 != rc) + return rc; + if (!func) + return PFI_EINVAL; + + while ((0 == rc) && !feof(in)) { + /* + * Read header and check consistency of the fields. + */ + rc = pfi_header_read( in, header ); + if (0 != rc) + break; + if (func) { + rc = func(in, header, priv_data); + if (rc != 0) + break; + } + } + + pfi_header_destroy(&header); + return rc; +} -- cgit v1.2.3 From 084fb764956460b5e67865b6072ea9cc4a2b5af9 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Mon, 11 Dec 2006 14:34:23 +0100 Subject: [MTD] UBI Utils: Fix wrong handling of table containing strings --- ubi-utils/src/pfi.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'ubi-utils/src/pfi.c') diff --git a/ubi-utils/src/pfi.c b/ubi-utils/src/pfi.c index c8d5ee4..7b57559 100644 --- a/ubi-utils/src/pfi.c +++ b/ubi-utils/src/pfi.c @@ -113,7 +113,9 @@ static const int key_descriptors_max[] = { sizeof(key_desc_v1)/sizeof(struct key_descriptor), /* version 1 */ }; -static const char* modes[] = {"raw", "ubi", NULL}; /* order isn't arbitrary! */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static const char* modes[] = {"raw", "ubi"}; /* order isn't arbitrary! */ /* latest version contains all possible keys */ static const struct key_descriptor *key_desc = key_desc_v1; @@ -131,16 +133,11 @@ static const struct key_descriptor *key_desc = key_desc_v1; static int get_mode_no(const char* mode) { - const char* ptr = modes[0]; - int i = 0; - while (ptr != NULL) { - if(strcmp(ptr, mode) == 0) { - return i; - } - ptr++; - i++; - } + int i; + for (i = 0; i < (int)ARRAY_SIZE(modes); i++) + if (strcmp(mode, modes[i]) == 0) + return i; return -1; } -- cgit v1.2.3 From 9fe86e65fb6bd77a02955d07d6f336ace4984e2d Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 12 Feb 2007 20:41:17 -0600 Subject: Fix several issues when compiling for 64bit systems Signed-off-by: Josh Boyer --- ubi-utils/src/hashmap.c | 2 +- ubi-utils/src/libubi.c | 4 ++-- ubi-utils/src/nand2bin.c | 2 +- ubi-utils/src/pfi.c | 2 +- ubi-utils/src/reader.c | 7 ++++--- ubi-utils/src/unubi.c | 2 +- ubi-utils/src/unubi_analyze.c | 20 ++++++++++---------- 7 files changed, 20 insertions(+), 19 deletions(-) (limited to 'ubi-utils/src/pfi.c') diff --git a/ubi-utils/src/hashmap.c b/ubi-utils/src/hashmap.c index 250f71f..3511d56 100644 --- a/ubi-utils/src/hashmap.c +++ b/ubi-utils/src/hashmap.c @@ -323,7 +323,7 @@ hashmap_dump(hashmap_t map) for(i = 0; i < map->maxsize; i++) { if (map->data[i] != NULL) { - printf("[%d]: ", i); + printf("[%zd]: ", i); print_all(map->data[i]); } } diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c index 979f157..7cb74bf 100644 --- a/ubi-utils/src/libubi.c +++ b/ubi-utils/src/libubi.c @@ -698,8 +698,8 @@ ubi_vol_update(int vol_fd, unsigned long long bytes) err = ioctl(vol_fd, UBI_IOCVOLUP, &bytes); if (err) { ubi_err("%s failure calling update ioctl\n" - " IOCTL(%08x) err=%d errno=%d\n", - __func__, UBI_IOCVOLUP, err, errno); + " IOCTL(%08lx) err=%d errno=%d\n", + __func__, (long unsigned int)UBI_IOCVOLUP, err, errno); } return err; } diff --git a/ubi-utils/src/nand2bin.c b/ubi-utils/src/nand2bin.c index 636ee6f..b8e4ea3 100644 --- a/ubi-utils/src/nand2bin.c +++ b/ubi-utils/src/nand2bin.c @@ -203,7 +203,7 @@ process_page(uint8_t* buf, uint8_t *oobbuf, size_t pagesize) case 2048: oobsize = 64; eccpoi = 64 / 2; break; case 512: oobsize = 16; eccpoi = 16 / 2; break; default: - fprintf(stderr, "Unsupported page size: %d\n", pagesize); + fprintf(stderr, "Unsupported page size: %zd\n", pagesize); return -EINVAL; } memset(oobbuf, 0xff, oobsize); diff --git a/ubi-utils/src/pfi.c b/ubi-utils/src/pfi.c index 7b57559..fa835e2 100644 --- a/ubi-utils/src/pfi.c +++ b/ubi-utils/src/pfi.c @@ -253,7 +253,7 @@ int pfi_header_setvalue (pfi_header head, { int key_id = find_key_by_name(key); - if ((uint32_t)value == (uint32_t)NULL) + if (value == NULL) return PFI_EINSUFF; if ((key_id < 0) || (key_id >= num_keys)) diff --git a/ubi-utils/src/reader.c b/ubi-utils/src/reader.c index 975caa1..7935a15 100644 --- a/ubi-utils/src/reader.c +++ b/ubi-utils/src/reader.c @@ -178,7 +178,8 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw, } rc = bootenv_list_to_num_vector(raw_start_list, - &(res->starts_size), &(res->starts)); + (void *) &(res->starts_size), + &(res->starts)); if (rc != 0) { EBUF_PFI("Cannot create numeric value array: %s", tmp_str); goto err; @@ -246,7 +247,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, goto err; } - rc = bootenv_list_to_num_vector(ubi_id_list, &(res->ids_size), + rc = bootenv_list_to_num_vector(ubi_id_list, (void *) &(res->ids_size), &(res->ids)); if (rc != 0) { EBUF_PFI("Cannot create numeric value array: %s", tmp_str); @@ -298,7 +299,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, EBUF_PFI("Cannot translate PFI value: %s", tmp_str); goto err; } - rc = bootenv_list_to_vector(ubi_name_list, &(res->names_size), + rc = bootenv_list_to_vector(ubi_name_list, (void *) &(res->names_size), &(tmp_names)); if (rc != 0) { EBUF_PFI("Cannot create string array: %s", tmp_str); diff --git a/ubi-utils/src/unubi.c b/ubi-utils/src/unubi.c index cade1e1..811a6db 100644 --- a/ubi-utils/src/unubi.c +++ b/ubi-utils/src/unubi.c @@ -102,7 +102,7 @@ static const char *usage = #define FN_INVAL "%s/eb%04u%s" /* invalid eraseblock */ #define FN_NSURE "%s/eb%04u_%03u_%03u_%03x%s" /* unsure eraseblock */ #define FN_VALID "%s/eb%04u_%03u_%03u_%03x%s" /* valid eraseblock */ -#define FN_VOLSP "%s/vol%03u_%03u_%03u_%04u" /* split volume */ +#define FN_VOLSP "%s/vol%03u_%03u_%03u_%04zu" /* split volume */ #define FN_VOLWH "%s/volume%03u" /* whole volume */ static uint32_t crc32_table[256]; diff --git a/ubi-utils/src/unubi_analyze.c b/ubi-utils/src/unubi_analyze.c index 2e94ca9..6009fc0 100644 --- a/ubi-utils/src/unubi_analyze.c +++ b/ubi-utils/src/unubi_analyze.c @@ -167,9 +167,9 @@ unubi_analyze_ec_hdr(eb_info_t first, const char *path) (crc != ubi32_to_cpu(cur->outer.hdr_crc))) fprintf(fpdata, "# "); - fprintf(fpdata, "%u %llu %llu", count, - ubi64_to_cpu(cur->outer.ec), - erase_counts[count]); + fprintf(fpdata, "%zu %llu %llu", count, + (unsigned long long) ubi64_to_cpu(cur->outer.ec), + (unsigned long long) erase_counts[count]); if (ubi32_to_cpu(cur->outer.magic) != UBI_EC_HDR_MAGIC) fprintf(fpdata, " ## bad magic: %08x", @@ -198,7 +198,7 @@ unubi_analyze_ec_hdr(eb_info_t first, const char *path) if ((count % EC_X_INT) == 0) { if (count > 0) fprintf(fpplot, ", "); - fprintf(fpplot, "%d", count); + fprintf(fpplot, "%zd", count); } cur = cur->next; @@ -207,9 +207,9 @@ unubi_analyze_ec_hdr(eb_info_t first, const char *path) fprintf(fpplot, ")\n"); fprintf(fpplot, "set ylabel \"erase count\"\n"); - fprintf(fpplot, "set xrange [-1:%u]\n", eraseblocks + 1); + fprintf(fpplot, "set xrange [-1:%zu]\n", eraseblocks + 1); fprintf(fpplot, "# set yrange [-1:%llu]\n", - erase_counts[eraseblocks - 1] + 1); + (unsigned long long) erase_counts[eraseblocks - 1] + 1); fprintf(fpplot, "plot \"%s\" u 1:2 t \"unsorted: %s\" with boxes\n", FN_EH_DATA, FN_EH_DATA); fprintf(fpplot, "# replot \"%s\" u 1:3 t \"sorted: %s\" with lines\n", @@ -299,7 +299,7 @@ unubi_analyze_vid_hdr(eb_info_t *head, const char *path) if ((y1 == -1) || (y2 == -1)) return -1; - fprintf(fpdata, "%u %u %u %u %u %u %u\n", + fprintf(fpdata, "%zu %u %u %u %u %u %u\n", count, ubi32_to_cpu(cur->inner.vol_id), ubi32_to_cpu(cur->inner.lnum), @@ -325,10 +325,10 @@ unubi_analyze_vid_hdr(eb_info_t *head, const char *path) fprintf(fpplot, ", "); if (step != ubi32_to_cpu(cur->inner.vol_id)) { step = ubi32_to_cpu(cur->inner.vol_id); - fprintf(fpplot, "\"%d\" %d 0", step, count); + fprintf(fpplot, "\"%zd\" %zd 0", step, count); } else - fprintf(fpplot, "\"%d\" %d 1", + fprintf(fpplot, "\"%d\" %zd 1", ubi32_to_cpu(cur->inner.lnum), count); cur = cur->next; count++; @@ -384,7 +384,7 @@ unubi_analyze_vid_hdr(eb_info_t *head, const char *path) y1 = norm_index(leb_versions[breadth - 1], leb_versions, breadth); y2 = norm_index(data_sizes[breadth - 1], data_sizes, breadth); - fprintf(fpplot, "set xrange [-1:%u]\n", count + 1); + fprintf(fpplot, "set xrange [-1:%zu]\n", count + 1); fprintf(fpplot, "set yrange [-1:%u]\n", y1 + 1); fprintf(fpplot, "set y2range [-1:%u]\n", y2 + 1); fprintf(fpplot, "plot \"%s\" u 1:4 t \"leb version: %s\" " -- cgit v1.2.3