diff options
| author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2007-03-21 11:53:25 +0200 | 
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-03-29 17:17:18 +0300 | 
| commit | 9c37b558705b776e51f7d522f376de019a6ea203 (patch) | |
| tree | a5f7a547feeb817be1b3ed7c9ac362d2344f4bda /ubi-utils | |
| parent | db0fa8cfb0fae8c07c4c88f73bbc71176df36d7c (diff) | |
UBI-Utils: Convert to new ubi library
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Diffstat (limited to 'ubi-utils')
| -rw-r--r-- | ubi-utils/Makefile | 20 | ||||
| -rw-r--r-- | ubi-utils/inc/libubi.h | 268 | ||||
| -rw-r--r-- | ubi-utils/src/libpfiflash.c | 2 | ||||
| -rw-r--r-- | ubi-utils/src/libubi.c | 917 | ||||
| -rw-r--r-- | ubi-utils/src/libubi_int.h | 129 | ||||
| -rw-r--r-- | ubi-utils/src/libubimirror.c | 10 | ||||
| -rw-r--r-- | ubi-utils/src/libubiold.c | 6 | ||||
| -rw-r--r-- | ubi-utils/src/libubiold_sysfs.c | 2 | ||||
| -rw-r--r-- | ubi-utils/src/pddcustomize.c | 2 | ||||
| -rw-r--r-- | ubi-utils/src/reader.c | 13 | ||||
| -rw-r--r-- | ubi-utils/src/ubimkvol.c | 33 | ||||
| -rw-r--r-- | ubi-utils/src/ubirmvol.c | 24 | ||||
| -rw-r--r-- | ubi-utils/src/ubiupdatevol.c | 46 | 
13 files changed, 1409 insertions, 63 deletions
| diff --git a/ubi-utils/Makefile b/ubi-utils/Makefile index 0818a9b..797807d 100644 --- a/ubi-utils/Makefile +++ b/ubi-utils/Makefile @@ -16,11 +16,12 @@ CFLAGS := -I./inc -I./src -I$(KERNELHDR) -O2 -g -Wall -Werror \  	-Wwrite-strings -W -std=gnu99 \          -DHOST_OS_NAME=\"$(HOST_OS_NAME)\" \          -DHOST_VERSION_NAME=\"$(HOST_VERSION_NAME)\" \ -	-DBUILD_CPU=\"$(BUILD_CPU)\" -DBUILD_OS=\"$(BUILD_OS)\" +	-DBUILD_CPU=\"$(BUILD_CPU)\" -DBUILD_OS=\"$(BUILD_OS)\" \ +	-DPACKAGE_VERSION=\"1.0\"  PERLPROGS = mkpfi ubicrc32.pl  TARGETS = ubiupdatevol ubimkvol ubirmvol pfiflash pddcustomize ubimirror \ -	bin2nand nand2bin ubigen mkbootenv unubi pfi2bin +	bin2nand nand2bin ubigen mkbootenv unubi pfi2bin ubicrc32  vpath   %.c ./src @@ -38,25 +39,25 @@ IGNORE=${wildcard .*.c.dep}  clean:  	rm -rf *.o $(TARGETS) .*.c.dep -ubiupdatevol: ubiupdatevol.o error.o libubi.o libubi_sysfs.o +ubiupdatevol: ubiupdatevol.o error.o libubi.o  	$(CC) $(LDFLAGS) -o $@ $^ -ubimkvol: ubimkvol.o error.o libubi.o libubi_sysfs.o +ubimkvol: ubimkvol.o error.o libubi.o  	$(CC) $(LDFLAGS) -o $@ $^ -ubirmvol: ubirmvol.o error.o libubi.o libubi_sysfs.o +ubirmvol: ubirmvol.o error.o libubi.o  	$(CC) $(LDFLAGS) -o $@ $^  pddcustomize: pddcustomize.o error.o libubimirror.o bootenv.o hashmap.o \ -		libubi.o libubi_sysfs.o crc32.o +		libubiold.o libubiold_sysfs.o crc32.o  	$(CC) $(LDFLAGS) -o $@ $^  pfiflash: pfiflash.o libpfiflash.o list.o reader.o error.o libubimirror.o \ -		bootenv.o hashmap.o pfi.o libubi.o libubi_sysfs.o crc32.o +		bootenv.o hashmap.o pfi.o libubiold.o libubiold_sysfs.o crc32.o  	$(CC) $(LDFLAGS) -o $@ $^  ubimirror: ubimirror.o error.o libubimirror.o bootenv.o hashmap.o \ -		libubi.o libubi_sysfs.o crc32.o +		libubiold.o libubiold_sysfs.o crc32.o  	$(CC) $(LDFLAGS) -o $@ $^  nand2bin: nand2bin.o nandecc.o nandcorr.o @@ -78,6 +79,9 @@ pfi2bin: pfi2bin.o peb.o error.o list.o crc32.o libubigen.o bootenv.o \  		hashmap.o reader.o pfi.o  	$(CC) $(LDFLAGS) -o $@ $^ +ubicrc32: ubicrc32.o crc32.o +	$(CC) $(LDFLAGS) -o $@ $^ +  install: ${TARGETS}  	mkdir -p ${DESTDIR}/${SBINDIR}  	install -m0755 ${TARGETS} ${DESTDIR}/${SBINDIR}/ diff --git a/ubi-utils/inc/libubi.h b/ubi-utils/inc/libubi.h new file mode 100644 index 0000000..d39c1b9 --- /dev/null +++ b/ubi-utils/inc/libubi.h @@ -0,0 +1,268 @@ +/* + * 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. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_H__ +#define __LIBUBI_H__ + +#include <stdint.h> +#include <mtd/ubi-user.h> +#include <ctype.h> +#include <mtd/ubi-header.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* UBI version libubi is made for */ +#define LIBUBI_UBI_VERSION 1 + +/* UBI library descriptor */ +typedef void * libubi_t; + +/** + * struct ubi_mkvol_request - volume creation request. + * */ +struct ubi_mkvol_request +{ +	int vol_id; +	int alignment; +	long long bytes; +	int vol_type; +	const char *name; +}; + +/** + * struct ubi_info - general UBI information. + * + * @dev_count        count of UBI devices in system + * @lowest_dev_num   lowest UBI device number + * @highest_dev_num  highest UBI device number + * @version          UBI version + */ +struct ubi_info +{ +	int dev_count; +	int lowest_dev_num; +	int highest_dev_num; +	int version; +}; + +/** + * struct ubi_dev_info - UBI device information. + * + * @vol_count        count of volumes on this UBI device + * @lowest_vol_num   lowest volume number + * @highest_vol_num  highest volume number + * @total_ebs        total number of eraseblocks on this UBI device + * @avail_ebs        how many eraseblocks are not used and available for new + *                   volumes + * @total_bytes      @total_ebs * @eb_size + * @avail_bytes      @avail_ebs * @eb_size + * @bad_count        count of bad eraseblocks + * @eb_size          size of UBI eraseblock + * @max_ec           current highest erase counter value + * @bad_rsvd         how many physical eraseblocks of the underlying flash + *                   device are reserved for bad eraseblocks handling + * @max_vol_count    maximum count of volumes on this UBI device + * @min_io_size      minimum input/output size of the UBI device + */ +struct ubi_dev_info +{ +	int dev_num; +	int vol_count; +	int lowest_vol_num; +	int highest_vol_num; +	int total_ebs; +	int avail_ebs; +	long long total_bytes; +	long long avail_bytes; +	int bad_count; +	int eb_size; +	long long max_ec; +	int bad_rsvd; +	int max_vol_count; +	int min_io_size; +}; + +/** + * struct ubi_vol_info - UBI volume information. + * + * @dev_num      UBI device number the volume resides on + * @vol_id       ID of this volume + * @type         volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @alignment    alignemnt of this volume + * @data_bytes   how many data bytes are stored on this volume (equivalent to + *               @rsvd_bytes for dynamic volumes) + * @rsvd_bytes   how many bytes are reserved for this volume + * @rsvd_ebs     how many eraseblocks are reserved for this volume + * @eb_size      logical eraseblock size of this volume (may be less then + *               device's logical eraseblock size due to alignment) + * @corrupted    the volume is corrupted if this flag is not zero + * @name         volume name (null-terminated) + */ +struct ubi_vol_info +{ +	int dev_num; +	int vol_id; +	int type; +	int alignment; +	long long data_bytes; +	long long rsvd_bytes; +	int rsvd_ebs; +	int eb_size; +	int corrupted; +	char name[UBI_VOL_NAME_MAX + 1]; +}; + +/** + * libubi_open - open UBI library. + * + * This function initializes and opens the UBI library and returns UBI library + * descriptor in case of success and %NULL in case of failure. + */ +libubi_t libubi_open(void); + +/** + * libubi_close - close UBI library + * + * @desc UBI library descriptor + */ +void libubi_close(libubi_t desc); + +/** + * ubi_get_info - get general UBI information. + * + * @info  pointer to the &struct ubi_info object to fill + * @desc  UBI library descriptor + * + * This function fills the passed @info object with general UBI information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_info(libubi_t desc, struct ubi_info *info); + +/** + * ubi_mkvol - create an UBI volume. + * + * @desc  UBI library descriptor + * @node  name of the UBI character device to create a volume at + * @req   UBI volume creation request (defined at <mtd/ubi-user.h>) + * + * This function creates a UBI volume as described at @req and returns %0 in + * case of success and %-1 in case of failure. The assigned volume ID is + * returned in @req->vol_id. + */ +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); + +/** + * ubi_rmvol - remove a UBI volume. + * + * @desc    UBI library descriptor + * @node    name of the UBI character device to remove a volume from + * @vol_id  ID of the volume to remove + * + * This function removes volume @vol_id from UBI device @node and returns %0 in + * case of success and %-1 in case of failure. + */ +int ubi_rmvol(libubi_t desc, const char *node, int vol_id); + +/** + * ubi_rsvol - re-size UBI volume. + * + * @desc   UBI library descriptor + * @node   name of the UBI character device owning the volume which should be + *         re-sized + * @vol_id volume ID to re-size + * @bytes  new volume size in bytes + * + * This function returns %0 in case of success and %-1 in case of error. + */ +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); + +/** + * ubi_get_dev_info - get UBI device information. + * + * @desc  UBI library descriptor + * @node  name of the UBI character device to fetch information about + * @info  pointer to the &struct ubi_dev_info object to fill + * + * This function fills the passed @info object with UBI device information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_dev_info(libubi_t desc, const char *node, +		     struct ubi_dev_info *info); + +/** + * ubi_get_dev_info1 - get UBI device information. + * + * @desc     UBI library descriptor + * @dev_num  UBI device number to fetch information about + * @info     pointer to the &struct ubi_dev_info object to fill + * + * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI + * device number, not UBI character device. + */ +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); + +/** + * ubi_get_vol_info - get UBI volume information. + * + * @desc     UBI library descriptor + * @node     name of the UBI volume character device to fetch information about + * @info     pointer to the &struct ubi_vol_info object to fill + * + * This function fills the passed @info object with UBI volume information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_vol_info(libubi_t desc, const char *node, +		     struct ubi_vol_info *info); + +/** + * ubi_get_vol_info1 - get UBI volume information. + * + * @desc     UBI library descriptor + * @dev_num  UBI device number + * @vol_id   ID of the UBI volume to fetch information about + * @info     pointer to the &struct ubi_vol_info object to fill + * + * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI + * volume number, not UBI volume character device. + */ +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, +		      struct ubi_vol_info *info); + +/** + * ubi_update_start - start UBI volume update. + * + * @desc   UBI library descriptor + * @fd     volume character devie file descriptor + * @bytes  how many bytes will be written to the volume + * + * This function initiates UBI volume update and returns %0 in case of success + * and %-1 in case of error. + */ +int ubi_update_start(libubi_t desc, int fd, long long bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_H__ */ diff --git a/ubi-utils/src/libpfiflash.c b/ubi-utils/src/libpfiflash.c index 4dfafea..4f1f5cd 100644 --- a/ubi-utils/src/libpfiflash.c +++ b/ubi-utils/src/libpfiflash.c @@ -36,7 +36,7 @@  #include <stdlib.h>  #include <sys/ioctl.h> -#include <libubi.h> +#include <libubiold.h>  #include <pfiflash.h>  #include <mtd/ubi-user.h>	/* FIXME Is this ok here? */ diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c new file mode 100644 index 0000000..17ab4ee --- /dev/null +++ b/ubi-utils/src/libubi.c @@ -0,0 +1,917 @@ +/* + * 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. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <limits.h> +#include "libubi.h" +#include "libubi_int.h" + +libubi_t libubi_open(void) +{ +	int fd, version; +	struct libubi *lib; + +	lib = calloc(1, sizeof(struct libubi)); +	if (!lib) +		return NULL; + +	/* TODO: this must be discovered instead */ +	lib->sysfs = strdup("/sys"); +	if (!lib->sysfs) +		goto error; + +	lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI); +	if (!lib->sysfs_ubi) +		goto error; + +	/* Make sure UBI is present */ +	fd = open(lib->sysfs_ubi, O_RDONLY); +	if (fd == -1) +		goto error; +	close(fd); + +	lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); +	if (!lib->ubi_dev) +		goto error; + +	lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); +	if (!lib->ubi_version) +		goto error; + +	lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); +	if (!lib->dev_dev) +		goto error; + +	lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); +	if (!lib->dev_avail_ebs) +		goto error; + +	lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); +	if (!lib->dev_total_ebs) +		goto error; + +	lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); +	if (!lib->dev_bad_count) +		goto error; + +	lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); +	if (!lib->dev_eb_size) +		goto error; + +	lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); +	if (!lib->dev_max_ec) +		goto error; + +	lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); +	if (!lib->dev_bad_rsvd) +		goto error; + +	lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); +	if (!lib->dev_max_vols) +		goto error; + +	lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); +	if (!lib->dev_min_io_size) +		goto error; + +	lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); +	if (!lib->ubi_vol) +		goto error; + +	lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); +	if (!lib->vol_type) +		goto error; + +	lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); +	if (!lib->vol_dev) +		goto error; + +	lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); +	if (!lib->vol_alignment) +		goto error; + +	lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); +	if (!lib->vol_data_bytes) +		goto error; + +	lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); +	if (!lib->vol_rsvd_ebs) +		goto error; + +	lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); +	if (!lib->vol_eb_size) +		goto error; + +	lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); +	if (!lib->vol_corrupted) +		goto error; + +	lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); +	if (!lib->vol_name) +		goto error; + +	if (read_int(lib->ubi_version, &version)) +		goto error; +	if (version != LIBUBI_UBI_VERSION) { +		fprintf(stderr, "LIBUBI: this library was made for UBI version " +				"%d, but UBI version %d is detected\n", +			LIBUBI_UBI_VERSION, version); +		goto error; +	} + +	return lib; + +error: +	free(lib->vol_corrupted); +	free(lib->vol_eb_size); +	free(lib->vol_rsvd_ebs); +	free(lib->vol_data_bytes); +	free(lib->vol_alignment); +	free(lib->vol_dev); +	free(lib->vol_type); +	free(lib->ubi_vol); +	free(lib->dev_min_io_size); +	free(lib->dev_max_vols); +	free(lib->dev_bad_rsvd); +	free(lib->dev_max_ec); +	free(lib->dev_eb_size); +	free(lib->dev_bad_count); +	free(lib->dev_total_ebs); +	free(lib->dev_avail_ebs); +	free(lib->dev_dev); +	free(lib->ubi_version); +	free(lib->ubi_dev); +	free(lib->sysfs_ubi); +	free(lib->sysfs); +	free(lib); +	return NULL; +} + +void libubi_close(libubi_t desc) +{ +	struct libubi *lib = (struct libubi *)desc; + +	free(lib->vol_name); +	free(lib->vol_corrupted); +	free(lib->vol_eb_size); +	free(lib->vol_rsvd_ebs); +	free(lib->vol_data_bytes); +	free(lib->vol_alignment); +	free(lib->vol_dev); +	free(lib->vol_type); +	free(lib->ubi_vol); +	free(lib->dev_min_io_size); +	free(lib->dev_max_vols); +	free(lib->dev_bad_rsvd); +	free(lib->dev_max_ec); +	free(lib->dev_eb_size); +	free(lib->dev_bad_count); +	free(lib->dev_total_ebs); +	free(lib->dev_avail_ebs); +	free(lib->dev_dev); +	free(lib->ubi_version); +	free(lib->ubi_dev); +	free(lib->sysfs_ubi); +	free(lib->sysfs); +	free(lib); +} + +int ubi_get_info(libubi_t desc, struct ubi_info *info) +{ +	DIR *sysfs_ubi; +	struct dirent *dirent; +	struct libubi *lib = (struct libubi *)desc; + +	memset(info, '\0', sizeof(struct ubi_info)); + +	/* +	 * We have to scan the UBI sysfs directory to identify how many UBI +	 * devices are present. +	 */ +	sysfs_ubi = opendir(lib->sysfs_ubi); +	if (!sysfs_ubi) +		return -1; + +	info->lowest_dev_num = INT_MAX; +	while ((dirent = readdir(sysfs_ubi))) { +		char *name = &dirent->d_name[0]; +		int dev_num, ret; + +		ret = sscanf(name, UBI_DEV_NAME_PATT, &dev_num); +		if (ret == 1) { +			info->dev_count += 1; +			if (dev_num > info->highest_dev_num) +				info->highest_dev_num = dev_num; +			if (dev_num < info->lowest_dev_num) +				info->lowest_dev_num = dev_num; +		} +	} + +	if (info->lowest_dev_num == INT_MAX) +		info->lowest_dev_num = 0; + +	if (read_int(lib->ubi_version, &info->version)) +		goto close; + +	return closedir(sysfs_ubi); + +close: +	closedir(sysfs_ubi); +	return -1; +} + +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) +{ +	int fd, ret; +	struct ubi_mkvol_req r; +	size_t n; + +	desc = desc; +	r.vol_id = req->vol_id; +	r.alignment = req->alignment; +	r.bytes = req->bytes; +	r.vol_type = req->vol_type; + +	n = strlen(req->name); +	if (n > UBI_MAX_VOLUME_NAME) +		return -1; + +	strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); +	r.name_len = n; + +	fd = open(node, O_RDONLY); +	if (fd == -1) +		return -1; + +	ret = ioctl(fd, UBI_IOCMKVOL, &r); + +	if (!ret) +		req->vol_id = r.vol_id; + +	close(fd); +	return ret; +} + +int ubi_rmvol(libubi_t desc, const char *node, int vol_id) +{ +	int fd, ret; + +	desc = desc; +	fd = open(node, O_RDONLY); +	if (fd == -1) +		return -1; + +	ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); +	close(fd); +	return ret; +} + +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) +{ +	int fd, ret; +	struct ubi_rsvol_req req; + +	desc = desc; +	fd = open(node, O_RDONLY); +	if (fd == -1) +		return -1; + +	req.bytes = bytes; +	req.vol_id = vol_id; + +	ret = ioctl(fd, UBI_IOCRSVOL, &req); +	close(fd); +	return ret; +} + +int ubi_update_start(libubi_t desc, int fd, long long bytes) +{ +	desc = desc; +	if (ioctl(fd, UBI_IOCVOLUP, &bytes)) +		return -1; +	return 0; +} + +int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) +{ +	int dev_num; +	struct libubi *lib = (struct libubi *)desc; + +	dev_num = find_dev_num(lib, node); +	if (dev_num == -1) +		return -1; + +	return ubi_get_dev_info1(desc, dev_num, info); +} + +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) +{ +	DIR *sysfs_ubi; +	struct dirent *dirent; +	struct libubi *lib = (struct libubi *)desc; + +	memset(info, '\0', sizeof(struct ubi_dev_info)); +	info->dev_num = dev_num; + +	sysfs_ubi = opendir(lib->sysfs_ubi); +	if (!sysfs_ubi) +		return -1; + +	info->lowest_vol_num = INT_MAX; +	while ((dirent = readdir(sysfs_ubi))) { +		char *name = &dirent->d_name[0]; +		int vol_id, ret, devno; + +		ret = sscanf(name, UBI_VOL_NAME_PATT, &devno, &vol_id); +		if (ret == 2 && devno == dev_num) { +			info->vol_count += 1; +			if (vol_id > info->highest_vol_num) +				info->highest_vol_num = vol_id; +			if (vol_id < info->lowest_vol_num) +				info->lowest_vol_num = vol_id; +		} +	} + +	closedir(sysfs_ubi); + +	if (info->lowest_vol_num == INT_MAX) +		info->lowest_vol_num = 0; + +	if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_ebs)) +		return -1; +	if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_ebs)) +		return -1; +	if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) +		return -1; +	if (dev_read_int(lib->dev_eb_size, dev_num, &info->eb_size)) +		return -1; +	if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) +		return -1; +	if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) +		return -1; +	if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) +		return -1; +	if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) +		return -1; + +	info->avail_bytes = info->avail_ebs * info->eb_size; +	info->total_bytes = info->total_ebs * info->eb_size; + +	return 0; +} + +int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) +{ +	int vol_id, dev_num; +	struct libubi *lib = (struct libubi *)desc; + +	dev_num = find_dev_num_vol(lib, node); +	if (dev_num == -1) +		return -1; + +	vol_id = find_vol_num(lib, dev_num, node); +	if (vol_id == -1) +		return -1; + +	return ubi_get_vol_info1(desc, dev_num, vol_id, info); +} + +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, +		      struct ubi_vol_info *info) +{ +	int ret; +	struct libubi *lib = (struct libubi *)desc; +	char buf[50]; + +	memset(info, '\0', sizeof(struct ubi_vol_info)); +	info->dev_num = dev_num; +	info->vol_id = vol_id; + +	ret = vol_read_data(lib->vol_type, dev_num, vol_id, &buf[0], 50); +	if (ret < 0) +		return -1; + +	if (strncmp(&buf[0], "static\n", ret) == 0) +		info->type = UBI_STATIC_VOLUME; +	else if (strncmp(&buf[0], "dynamic\n", ret) == 0) +		info->type = UBI_DYNAMIC_VOLUME; +	else { +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		return -1; +	} + +	ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, +			   &info->alignment); +	if (ret) +		return -1; +	ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, +			  &info->data_bytes); +	if (ret) +		return -1; +	ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_ebs); +	if (ret) +		return -1; +	ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->eb_size); +	if (ret) +		return -1; +	ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, +			   &info->corrupted); +	if (ret) +		return -1; +	info->rsvd_bytes = info->eb_size * info->rsvd_ebs; + +	ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, +			    UBI_VOL_NAME_MAX + 2); +	if (ret < 0) +		return -1; + +	info->name[ret - 1] = '\0'; + +	return 0; +} + +/** + * read_int - read an 'int' value from a file. + * + * @file   the file to read from + * @value  the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int read_int(const char *file, int *value) +{ +	int fd, rd; +	char buf[50]; + +	fd = open(file, O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, &buf[0], 50); +	if (rd == -1) +		goto error; + +	if (sscanf(&buf[0], "%d\n", value) != 1) { +		/* This must be a UBI bug */ +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		goto error; +	} + +	close(fd); +	return 0; + +error: +	close(fd); +	return -1; +} + +/** + * dev_read_int - read an 'int' value from an UBI device's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @value    the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_int(const char *patt, int dev_num, int *value) +{ +	int fd, rd; +	char buf[50]; +	char file[strlen(patt) + 50]; + +	sprintf(&file[0], patt, dev_num); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, &buf[0], 50); +	if (rd == -1) +		goto error; + +	if (sscanf(&buf[0], "%d\n", value) != 1) { +		/* This must be a UBI bug */ +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		goto error; +	} + +	close(fd); +	return 0; + +error: +	close(fd); +	return -1; +} + +/** + * dev_read_ll - read a 'long long' value from an UBI device's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @value    the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_ll(const char *patt, int dev_num, long long *value) +{ +	int fd, rd; +	char buf[50]; +	char file[strlen(patt) + 50]; + +	sprintf(&file[0], patt, dev_num); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, &buf[0], 50); +	if (rd == -1) +		goto error; + +	if (sscanf(&buf[0], "%lld\n", value) != 1) { +		/* This must be a UBI bug */ +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		goto error; +	} + +	close(fd); +	return 0; + +error: +	close(fd); +	return -1; +} + +/** + * dev_read_data - read data from an UBI device's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @buf      buffer to read data to + * @buf_len  buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. + */ +static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len) +{ +	int fd, rd; +	char file[strlen(patt) + 50]; + +	sprintf(&file[0], patt, dev_num); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, buf, buf_len); +	if (rd == -1) { +		close(fd); +		return -1; +	} + +	close(fd); +	return rd; +} + +/** + * vol_read_int - read an 'int' value from an UBI volume's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @vol_id   volume identifier + * @value    the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) +{ +	int fd, rd; +	char buf[50]; +	char file[strlen(patt) + 100]; + +	sprintf(&file[0], patt, dev_num, vol_id); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, &buf[0], 50); +	if (rd == -1) +		goto error; + +	if (sscanf(&buf[0], "%d\n", value) != 1) { +		/* This must be a UBI bug */ +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		goto error; +	} + +	close(fd); +	return 0; + +error: +	close(fd); +	return -1; +} + +/** + * vol_read_ll - read a 'long long' value from an UBI volume's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @vol_id   volume identifier + * @value    the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_ll(const char *patt, int dev_num, int vol_id, +		       long long *value) +{ +	int fd, rd; +	char buf[50]; +	char file[strlen(patt) + 100]; + +	sprintf(&file[0], patt, dev_num, vol_id); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, &buf[0], 50); +	if (rd == -1) +		goto error; + +	if (sscanf(&buf[0], "%lld\n", value) != 1) { +		/* This must be a UBI bug */ +		fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +		errno = EINVAL; +		goto error; +	} + +	close(fd); +	return 0; + +error: +	close(fd); +	return -1; +} + +/** + * vol_read_data - read data from an UBI volume's sysfs file. + * + * @patt     the file pattern to read from + * @dev_num  UBI device number + * @vol_id   volume identifier + * @buf      buffer to read to + * @buf_len  buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. + */ +static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, +			 int buf_len) +{ +	int fd, rd; +	char file[strlen(patt) + 100]; + +	sprintf(&file[0], patt, dev_num, vol_id); +	fd = open(&file[0], O_RDONLY); +	if (fd == -1) +		return -1; + +	rd = read(fd, buf, buf_len); +	if (rd == -1) { +		close(fd); +		return -1; +	} + +	close(fd); +	return rd; +} + +/** + * mkpath - compose full path from 2 given components. + * + * @path  first component + * @name  second component + * + * This function returns the resulting path in case of success and %NULL in + * case of failure. + */ +static char *mkpath(const char *path, const char *name) +{ +	char *n; +	int len1 = strlen(path); +	int len2 = strlen(name); + +	n = malloc(len1 + len2 + 2); +	if (!n) +		return NULL; + +	memcpy(n, path, len1); +	if (n[len1 - 1] != '/') +		n[len1++] = '/'; + +	memcpy(n + len1, name, len2 + 1); +	return n; +} + +/** + * find_dev_num - find UBI device number by its character device node. + * + * @lib   UBI library descriptor + * @node  UBI character device node name + * + * This function returns positive UBI device number in case of success and %-1 + * in case of failure. + */ +static int find_dev_num(struct libubi *lib, const char *node) +{ +	struct stat stat; +	struct ubi_info info; +	int i, major, minor; + +	if (lstat(node, &stat)) +		return -1; + +	if (!S_ISCHR(stat.st_mode)) { +		errno = EINVAL; +		return -1; +	} + +	major = major(stat.st_rdev); +	minor = minor(stat.st_rdev); + +	if (minor != 0) { +		errno = -EINVAL; +		return -1; +	} + +	if (ubi_get_info((libubi_t *)lib, &info)) +		return -1; + +	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { +		int major1, minor1, ret; +		char buf[50]; + +		ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); +		if (ret < 0) +			return -1; + +		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); +		if (ret != 2) { +			fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +			errno = EINVAL; +			return -1; +		} + +		if (minor1 == minor && major1 == major) +			return i; +	} + +	errno = ENOENT; +	return -1; +} + +/** + * find_dev_num_vol - find UBI device number by volume character device node. + * + * @lib   UBI library descriptor + * @node  UBI character device node name + * + * This function returns positive UBI device number in case of success and %-1 + * in case of failure. + */ +static int find_dev_num_vol(struct libubi *lib, const char *node) +{ +	struct stat stat; +	struct ubi_info info; +	int i, major; + +	if (lstat(node, &stat)) +		return -1; + +	if (!S_ISCHR(stat.st_mode)) { +		errno = EINVAL; +		return -1; +	} + +	major = major(stat.st_rdev); + +	if (minor(stat.st_rdev) == 0) { +		errno = -EINVAL; +		return -1; +	} + +	if (ubi_get_info((libubi_t *)lib, &info)) +		return -1; + +	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { +		int major1, minor1, ret; +		char buf[50]; + +		ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); +		if (ret < 0) +			return -1; + +		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); +		if (ret != 2) { +			fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +			errno = EINVAL; +			return -1; +		} + +		if (major1 == major) +			return i; +	} + +	errno = ENOENT; +	return -1; +} + +/** + * find_vol_num - find UBI volume number by its character device node. + * + * @lib      UBI library descriptor + * @dev_num  UBI device number + * @node     UBI volume character device node name + * + * This function returns positive UBI volume number in case of success and %-1 + * in case of failure. + */ +static int find_vol_num(struct libubi *lib, int dev_num, const char *node) +{ +	struct stat stat; +	struct ubi_dev_info info; +	int i, major, minor; + +	if (lstat(node, &stat)) +		return -1; + +	if (!S_ISCHR(stat.st_mode)) { +		errno = EINVAL; +		return -1; +	} + +	major = major(stat.st_rdev); +	minor = minor(stat.st_rdev); + +	if (minor == 0) { +		errno = -EINVAL; +		return -1; +	} + +	if (ubi_get_dev_info1((libubi_t *)lib, dev_num, &info)) +		return -1; + +	for (i = info.lowest_vol_num; i <= info.highest_vol_num; i++) { +		int major1, minor1, ret; +		char buf[50]; + +		ret = vol_read_data(lib->vol_dev,  dev_num, i, &buf[0], 50); +		if (ret < 0) +			return -1; + +		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); +		if (ret != 2) { +			fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); +			errno = EINVAL; +			return -1; +		} + +		if (minor1 == minor && major1 == major) +			return i; +	} + +	errno = ENOENT; +	return -1; +} diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h new file mode 100644 index 0000000..e68b791 --- /dev/null +++ b/ubi-utils/src/libubi_int.h @@ -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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_INT_H__ +#define __LIBUBI_INT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * UBI heavily makes use of the sysfs file system to interact with users-pace. + * The below are pre-define UBI file and directory names. + */ + +#define SYSFS_UBI         "class/ubi" +#define UBI_DEV_NAME_PATT "ubi%d" +#define UBI_VER           "version" +#define DEV_DEV           "dev" +#define UBI_VOL_NAME_PATT "ubi%d_%d" +#define DEV_AVAIL_EBS     "avail_eraseblocks" +#define DEV_TOTAL_EBS     "total_eraseblocks" +#define DEV_BAD_COUNT     "bad_peb_count" +#define DEV_EB_SIZE       "eraseblock_size" +#define DEV_MAX_EC        "max_ec" +#define DEV_MAX_RSVD      "reserved_for_bad" +#define DEV_MAX_VOLS      "max_vol_count" +#define DEV_MIN_IO_SIZE   "min_io_size" +#define VOL_TYPE          "type" +#define VOL_DEV           "dev" +#define VOL_ALIGNMENT     "alignment" +#define VOL_DATA_BYTES    "data_bytes" +#define VOL_RSVD_EBS      "reserved_ebs" +#define VOL_EB_SIZE       "usable_eb_size" +#define VOL_CORRUPTED     "corrupted" +#define VOL_NAME          "name" + +/** + * libubi - UBI library description data structure. + * + * @sysfs            sysfs file system path + * @sysfs_ubi        UBI directory in sysfs + * @ubi_dev          UBI device sysfs directory pattern + * @ubi_version      UBI version file sysfs path + * @dev_dev          UBI device's major/minor numbers file pattern + * @dev_avail_ebs    count of available eraseblocks sysfs path pattern + * @dev_total_ebs    total eraseblocks count sysfs path pattern + * @dev_bad_count    count of bad eraseblocks sysfs path pattern + * @dev_eb_size      size of UBI device's eraseblocks sysfs path pattern + * @dev_max_ec       maximum erase counter sysfs path pattern + * @dev_bad_rsvd     count of physical eraseblock reserved for bad eraseblocks + *                   handling + * @dev_max_vols     maximum volumes number count sysfs path pattern + * @dev_min_io_size  minimum I/O unit size sysfs path pattern + * @ubi_vol          UBI volume sysfs directory pattern + * @vol_type         volume type sysfs path pattern + * @vol_dev          volume's major/minor numbers file pattern + * @vol_alignment    volume alignment sysfs path pattern + * @vol_data_bytes   volume data size sysfs path pattern + * @vol_rsvd_ebs     volume reserved size sysfs path pattern + * @vol_eb_size      volume eraseblock size sysfs path pattern + * @vol_corrupted    volume corruption flag sysfs path pattern + * @vol_name         volume name sysfs path pattern + */ +struct libubi +{ +	char *sysfs; +	char *sysfs_ubi; +	char *ubi_dev; +	char *ubi_version; +	char *dev_dev; +	char *dev_avail_ebs; +	char *dev_total_ebs; +	char *dev_bad_count; +	char *dev_eb_size; +	char *dev_max_ec; +	char *dev_bad_rsvd; +	char *dev_max_vols; +	char *dev_min_io_size; +	char *ubi_vol; +	char *vol_type; +	char *vol_dev; +	char *vol_alignment; +	char *vol_data_bytes; +	char *vol_rsvd_ebs; +	char *vol_eb_size; +	char *vol_corrupted; +	char *vol_name; +	char *vol_max_count; +}; + +static int read_int(const char *file, int *value); +static int dev_read_int(const char *patt, int dev_num, int *value); +static int dev_read_ll(const char *patt, int dev_num, long long *value); +static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len); +static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value); +static int vol_read_ll(const char *patt, int dev_num, int vol_id, +		       long long *value); +static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, +			 int buf_len); +static char *mkpath(const char *path, const char *name); +static int find_dev_num(struct libubi *lib, const char *node); +static int find_dev_num_vol(struct libubi *lib, const char *node); +static int find_vol_num(struct libubi *lib, int dev_num, const char *node); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_INT_H__ */ diff --git a/ubi-utils/src/libubimirror.c b/ubi-utils/src/libubimirror.c index e5715fc..d8ea548 100644 --- a/ubi-utils/src/libubimirror.c +++ b/ubi-utils/src/libubimirror.c @@ -22,7 +22,7 @@  #include <memory.h>  #include <fcntl.h> -#include <libubi.h> +#include <libubiold.h>  #include "ubimirror.h"  #define COMPARE_BUF_SIZE    (128 * 1024) @@ -207,11 +207,11 @@ ubimirror(uint32_t devno, int seqnum, uint32_t *ids, ssize_t ids_size,  			fd_out = -1;  	}  err: -	if (ulib != NULL) -		ubi_close(&ulib); -	if (fd_in != -1) -		ubi_vol_close(fd_in);  	if (fd_out != -1)  		ubi_vol_close(fd_out); +	if (fd_in != -1) +		ubi_vol_close(fd_in); +	if (ulib != NULL) +		ubi_close(&ulib);  	return rc;  } diff --git a/ubi-utils/src/libubiold.c b/ubi-utils/src/libubiold.c index da4919b..0ff8bae 100644 --- a/ubi-utils/src/libubiold.c +++ b/ubi-utils/src/libubiold.c @@ -36,9 +36,9 @@  #include <mtd/ubi-user.h>  #include <mtd/ubi-header.h> -#include "libubi.h" -#include "libubi_int.h" -#include "libubi_sysfs.h" +#include "libubiold.h" +#include "libubiold_int.h" +#include "libubiold_sysfs.h"  /**   * struct ubi_lib - UBI library descriptor. diff --git a/ubi-utils/src/libubiold_sysfs.c b/ubi-utils/src/libubiold_sysfs.c index 95fd3de..c4860f6 100644 --- a/ubi-utils/src/libubiold_sysfs.c +++ b/ubi-utils/src/libubiold_sysfs.c @@ -33,7 +33,7 @@  #include <stdarg.h>  #include "config.h" -#include "libubi_int.h" +#include "libubiold_int.h"  int  sysfs_read_data(const char *file, void *buf, int len) diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c index 764f2e7..a86e942 100644 --- a/ubi-utils/src/pddcustomize.c +++ b/ubi-utils/src/pddcustomize.c @@ -41,7 +41,7 @@  #include "bootenv.h"  #include "error.h"  #include "example_ubi.h" -#include "libubi.h" +#include "libubiold.h"  #include "ubimirror.h"  #define PROGRAM_VERSION "1.4" diff --git a/ubi-utils/src/reader.c b/ubi-utils/src/reader.c index 7935a15..0ea8c6d 100644 --- a/ubi-utils/src/reader.c +++ b/ubi-utils/src/reader.c @@ -142,6 +142,7 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw,  	char tmp_str[PFI_KEYWORD_LEN];  	bootenv_list_t raw_start_list = NULL;  	pfi_raw_t res; +	size_t size;  	res = (pfi_raw_t) malloc(sizeof(struct pfi_raw));  	if (!res) @@ -178,8 +179,9 @@ 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, -					(void *) &(res->starts_size), -					&(res->starts)); +					&size, &(res->starts)); +	res->starts_size = size; +  	if (rc != 0) {  		EBUF_PFI("Cannot create numeric value array: %s", tmp_str);  		goto err; @@ -209,6 +211,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,  	bootenv_list_t ubi_name_list = NULL;  	pfi_ubi_t res;  	uint32_t i; +	size_t size;  	res = (pfi_ubi_t) calloc(1, sizeof(struct pfi_ubi));  	if (!res) @@ -247,8 +250,9 @@ 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, (void *) &(res->ids_size), +	rc = bootenv_list_to_num_vector(ubi_id_list, &size,  					&(res->ids)); +	res->ids_size = size;  	if (rc != 0) {  		EBUF_PFI("Cannot create numeric value array: %s", tmp_str);  		goto err; @@ -299,8 +303,9 @@ 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, (void *) &(res->names_size), +	rc = bootenv_list_to_vector(ubi_name_list, &size,  				    &(tmp_names)); +	res->names_size = size;  	if (rc != 0) {  		EBUF_PFI("Cannot create string array: %s", tmp_str);  		goto err; diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index 879dcb6..1368671 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -28,6 +28,7 @@   * 1.2 Reworked the user-interface to use argp.   * 1.3 Removed argp because we want to use uClibc.   * 1.4 Minor cleanups + * 1.5 Use a different libubi   */  #include <stdio.h> @@ -40,7 +41,7 @@  #include <config.h>  #include <libubi.h> -#define PROGRAM_VERSION "1.4" +#define PROGRAM_VERSION "1.5"  /*   * The variables below	are set by command line arguments. @@ -53,6 +54,7 @@ struct args {  	int alignment;  	char *name;  	int nlen; +	char node[256];  	/* special stuff needed to get additional arguments */  	char *arg1; @@ -69,7 +71,7 @@ static struct args myargs = {  	.nlen = 0,  }; -static int param_sanity_check(struct args *args, ubi_lib_t lib); +static int param_sanity_check(struct args *args, libubi_t libubi);  static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"  	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" @@ -177,6 +179,7 @@ parse_opt(int argc, char **argv, struct args *args)  						"\"%s\"\n", optarg);  					goto out;  				} +				sprintf(args->node, "/dev/ubi%d", args->devn);  				break;  			case 'n': /* --volid=<volume id> */  				args->vol_id = strtoul(optarg, &endp, 0); @@ -224,7 +227,7 @@ parse_opt(int argc, char **argv, struct args *args)  	return -1;  } -static int param_sanity_check(struct args *args, ubi_lib_t lib) +static int param_sanity_check(struct args *args, libubi_t libubi)  {  	int err, len;  	struct ubi_info ubi; @@ -239,7 +242,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)  		goto out;  	} -	err = ubi_get_info(lib, &ubi); +	err = ubi_get_info(libubi, &ubi);  	if (err)  		return -1; @@ -264,7 +267,8 @@ out:  int main(int argc, char * const argv[])  {  	int err; -	ubi_lib_t lib; +	libubi_t libubi; +	struct ubi_mkvol_request req;  	err = parse_opt(argc, (char **)argv, &myargs);  	if (err) { @@ -278,21 +282,26 @@ int main(int argc, char * const argv[])  		return -1;  	} -	err = ubi_open(&lib); -	if (err) { +	libubi = libubi_open(); +	if (libubi == NULL) {  		perror("Cannot open libubi");  		return -1;  	} -	err = param_sanity_check(&myargs, lib); +	err = param_sanity_check(&myargs, libubi);  	if (err) {  		perror("Input parameters check");  		fprintf(stderr, "Use -h option for help\n");  		goto out_libubi;  	} -	err = ubi_mkvol(lib, myargs.devn, myargs.vol_id, myargs.vol_type, -			myargs.bytes, myargs.alignment, myargs.name); +	req.vol_id = myargs.vol_id; +	req.alignment = myargs.alignment; +	req.bytes = myargs.bytes; +	req.vol_type = myargs.vol_type; +	req.name = myargs.name; + +	err = ubi_mkvol(libubi, myargs.node, &req);  	if (err < 0) {  		perror("Cannot create volume");  		fprintf(stderr, "  err=%d\n", err); @@ -304,10 +313,10 @@ int main(int argc, char * const argv[])  	   "dynamic" : "static", name); */  	myargs.vol_id = err; -	ubi_close(&lib); +	libubi_close(libubi);  	return 0;  out_libubi: -	ubi_close(&lib); +	libubi_close(libubi);  	return -1;  } diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index f458e8a..f32cbe0 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -25,6 +25,7 @@   * 1.1 Reworked the userinterface to use argp.   * 1.2 Removed argp because we want to use uClibc.   * 1.3 Minor cleanups + * 1.4 Use a different libubi   */  #include <stdio.h> @@ -37,7 +38,7 @@  #include <config.h>  #include <libubi.h> -#define PROGRAM_VERSION "1.3" +#define PROGRAM_VERSION "1.4"  /*   * The below variables are set by command line options. @@ -45,6 +46,7 @@  struct args {  	int devn;  	int vol_id; +	char node[256];  	/* special stuff needed to get additional arguments */  	char *arg1; @@ -59,7 +61,7 @@ static struct args myargs = {  	.options = NULL,  }; -static int param_sanity_check(struct args *args, ubi_lib_t lib); +static int param_sanity_check(struct args *args, libubi_t libubi);  static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"  	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" @@ -118,6 +120,7 @@ parse_opt(int argc, char **argv, struct args *args)  						"\"%s\"\n", optarg);  					goto out;  				} +				sprintf(args->node, "/dev/ubi%d", args->devn);  				break;  			case 'n': /* --volid=<volume id> */  				args->vol_id = strtoul(optarg, &endp, 0); @@ -156,7 +159,7 @@ parse_opt(int argc, char **argv, struct args *args)  	return -1;  } -static int param_sanity_check(struct args *args, ubi_lib_t lib) +static int param_sanity_check(struct args *args, libubi_t libubi)  {  	int err;  	struct ubi_info ubi; @@ -166,7 +169,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)  		goto out;  	} -	err = ubi_get_info(lib, &ubi); +	err = ubi_get_info(libubi, &ubi);  	if (err)  		return -1; @@ -185,7 +188,7 @@ out:  int main(int argc, char * const argv[])  {  	int err, old_errno; -	ubi_lib_t lib; +	libubi_t libubi;  	err = parse_opt(argc, (char **)argv, &myargs);  	if (err) @@ -197,20 +200,20 @@ int main(int argc, char * const argv[])  		return -1;  	} -	err = ubi_open(&lib); -	if (err) { +	libubi = libubi_open(); +	if (libubi == NULL) {  		perror("Cannot open libubi");  		return -1;  	} -	err = param_sanity_check(&myargs, lib); +	err = param_sanity_check(&myargs, libubi);  	if (err) {  		perror("Input parameters check");  		fprintf(stderr, "Use -h option for help\n");  		goto out_libubi;  	} -	err = ubi_rmvol(lib, myargs.devn, myargs.vol_id); +	err = ubi_rmvol(libubi, myargs.node, myargs.vol_id);  	old_errno = errno;  	if (err < 0) {  		perror("Cannot remove volume"); @@ -218,9 +221,10 @@ int main(int argc, char * const argv[])  		goto out_libubi;  	} +	libubi_close(libubi);  	return 0;  out_libubi: -	ubi_close(&lib); +	libubi_close(libubi);  	return -1;  } diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index c0b4178..5401eb1 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -25,6 +25,7 @@   * 1.0 Reworked the userinterface to use argp.   * 1.1 Removed argp parsing because we want to use uClib.   * 1.2 Minor cleanups + * 1.3 Use a different libubi   */  #include <errno.h> @@ -36,14 +37,12 @@  #include <stdlib.h>  #include <string.h>  #include <unistd.h> -#include <sys/ioctl.h>  #include <sys/stat.h> -#include <sys/types.h>  #include <config.h>  #include <libubi.h> -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3"  #define MAXPATH		1024  #define BUFSIZE		128 * 1024 @@ -174,7 +173,7 @@ parse_opt(int argc, char **argv, struct args *args)   * some reason nothing is written. The volume is unusable after this.   */  static int -ubi_truncate_volume(struct args *args, int64_t bytes) +ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi)  {  	int rc, ofd;  	char path[MAXPATH]; @@ -188,7 +187,7 @@ ubi_truncate_volume(struct args *args, int64_t bytes)  		fprintf(stderr, "Cannot open volume %s\n", path);  		exit(EXIT_FAILURE);  	} -	rc = ioctl(ofd, UBI_IOCVOLUP, &bytes); +	rc = ubi_update_start(libubi, ofd, bytes);  	old_errno = errno;  	if (rc < 0) {  		perror("UBI volume update ioctl"); @@ -220,7 +219,7 @@ static ssize_t ubi_write(int fd, const void *buf, size_t count)  }  static int -ubi_update_volume(struct args *args) +ubi_update_volume(struct args *args, libubi_t libubi)  {  	int rc, ofd;  	FILE *ifp = NULL; @@ -263,7 +262,7 @@ ubi_update_volume(struct args *args)  		exit(EXIT_FAILURE);  	} -	rc = ioctl(ofd, UBI_IOCVOLUP, &bytes); +	rc = ubi_update_start(libubi, ofd, bytes);  	old_errno = errno;  	if (rc < 0) {  		perror("UBI volume update ioctl"); @@ -304,24 +303,35 @@ int  main(int argc, char *argv[])  {  	int rc; +	libubi_t libubi;  	parse_opt(argc, argv, &myargs); +	libubi = libubi_open(); +	if (libubi == NULL) { +		perror("Cannot open libubi"); +		return -1; +	} +  	if (myargs.truncate) { -		rc = ubi_truncate_volume(&myargs, 0LL); +		rc = ubi_truncate_volume(&myargs, 0LL, libubi);  		if (rc < 0) -			exit(EXIT_FAILURE); -		exit(EXIT_SUCCESS); +			goto out_libubi;  	} -	if (myargs.broken_update) { -		rc = ubi_truncate_volume(&myargs, 1LL); +	else if (myargs.broken_update) { +		rc = ubi_truncate_volume(&myargs, 1LL, libubi);  		if (rc < 0) -			exit(EXIT_FAILURE); -		exit(EXIT_SUCCESS); +			goto out_libubi; +	} else { +		rc = ubi_update_volume(&myargs, libubi); +		if (rc < 0) +			goto out_libubi;  	} -	rc = ubi_update_volume(&myargs); -	if (rc < 0) -		exit(EXIT_FAILURE); -	exit(EXIT_SUCCESS); +	libubi_close(libubi); +	return 0; +	 +out_libubi: +	libubi_close(libubi); +	return -1;  } | 
