diff mbox

[U-Boot,v2] UBI: Fix error code handling in ubi commands

Message ID 1300182434-31295-1-git-send-email-sr@denx.de
State Accepted
Commit 7f5d8a4d8e0ef7aee08476f0a3b9eb40974efaee
Delegated to: Stefan Roese
Headers show

Commit Message

Stefan Roese March 15, 2011, 9:47 a.m. UTC
Some ubi commands returned negative error codes, resulting in
the following error message on the prompt:

"exit not allowed from main input shell."

Negative error codes are not allowed.

This patch now changes the UBI code to return positive error codes.
Additionally "better" error codes are used, for example "ENOMEM" when
no memory is available for the UBI volume creation any more.

Also the output of some commands is enhanced:

Before:

=> ubi read 100000 testvol 100000
Volume testvol found at volume id 0
read 1048576 bytes from volume 0 to 100000(buf address)
=> ubi write 100000 testvol 1000
Volume testvol found at volume id 0

After:

=> ubi read 100000 testvol 100000
Read 1048576 bytes from volume testvol to 00100000
=> ubi write 100000 testvol 1000
4096 bytes written to volume testvol

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
---
v2:
- More negative return codes replaced
- Enhancements to some command outputs
- Common code extraced into function ubi_find_volume() to reduce code size

 common/cmd_ubi.c |  137 +++++++++++++++++++++++++----------------------------
 1 files changed, 65 insertions(+), 72 deletions(-)

Comments

Stefan Roese March 21, 2011, 12:56 p.m. UTC | #1
On Tuesday 15 March 2011 10:47:14 Stefan Roese wrote:
> Some ubi commands returned negative error codes, resulting in
> the following error message on the prompt:
> 
> "exit not allowed from main input shell."
> 
> Negative error codes are not allowed.

Applied to u-boot-ubi/master.
 
Cheers,
Stefan

--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-0 Fax: (+49)-8142-66989-80 Email: office@denx.de
diff mbox

Patch

diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
index b486ca8..629758f 100644
--- a/common/cmd_ubi.c
+++ b/common/cmd_ubi.c
@@ -123,7 +123,7 @@  static int ubi_info(int layout)
 static int verify_mkvol_req(const struct ubi_device *ubi,
 			    const struct ubi_mkvol_req *req)
 {
-	int n, err = -EINVAL;
+	int n, err = EINVAL;
 
 	if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 ||
 	    req->name_len < 0)
@@ -136,8 +136,11 @@  static int verify_mkvol_req(const struct ubi_device *ubi,
 	if (req->alignment == 0)
 		goto bad;
 
-	if (req->bytes == 0)
+	if (req->bytes == 0) {
+		printf("No space left in UBI device!\n");
+		err = ENOMEM;
 		goto bad;
+	}
 
 	if (req->vol_type != UBI_DYNAMIC_VOLUME &&
 	    req->vol_type != UBI_STATIC_VOLUME)
@@ -151,13 +154,13 @@  static int verify_mkvol_req(const struct ubi_device *ubi,
 		goto bad;
 
 	if (req->name_len > UBI_VOL_NAME_MAX) {
-		err = -ENAMETOOLONG;
+		printf("Name too long!\n");
+		err = ENAMETOOLONG;
 		goto bad;
 	}
 
 	return 0;
 bad:
-	printf("bad volume creation request");
 	return err;
 }
 
@@ -191,34 +194,39 @@  static int ubi_create_vol(char *volume, int size, int dynamic)
 	return ubi_create_volume(ubi, &req);
 }
 
-static int ubi_remove_vol(char *volume)
+static struct ubi_volume *ubi_find_volume(char *volume)
 {
-	int i, err, reserved_pebs;
-	int found = 0, vol_id = 0;
 	struct ubi_volume *vol = NULL;
+	int i;
 
 	for (i = 0; i < ubi->vtbl_slots; i++) {
 		vol = ubi->volumes[i];
-		if (vol && !strcmp(vol->name, volume)) {
-			printf("Volume %s found at valid %d\n", volume, i);
-			vol_id = i;
-			found = 1;
-			break;
-		}
+		if (vol && !strcmp(vol->name, volume))
+			return vol;
 	}
-	if (!found) {
-		printf("%s volume not found\n", volume);
-		return -ENODEV;
-	}
-	printf("remove UBI volume %s (id %d)\n", vol->name, vol->vol_id);
+
+	printf("Volume %s not found!\n", volume);
+	return NULL;
+}
+
+static int ubi_remove_vol(char *volume)
+{
+	int err, reserved_pebs, i;
+	struct ubi_volume *vol;
+
+	vol = ubi_find_volume(volume);
+	if (vol == NULL)
+		return ENODEV;
+
+	printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id);
 
 	if (ubi->ro_mode) {
 		printf("It's read-only mode\n");
-		err = -EROFS;
+		err = EROFS;
 		goto out_err;
 	}
 
-	err = ubi_change_vtbl_record(ubi, vol_id, NULL);
+	err = ubi_change_vtbl_record(ubi, vol->vol_id, NULL);
 	if (err) {
 		printf("Error changing Vol tabel record err=%x\n", err);
 		goto out_err;
@@ -231,8 +239,8 @@  static int ubi_remove_vol(char *volume)
 	}
 
 	kfree(vol->eba_tbl);
-	ubi->volumes[vol_id]->eba_tbl = NULL;
-	ubi->volumes[vol_id] = NULL;
+	ubi->volumes[vol->vol_id]->eba_tbl = NULL;
+	ubi->volumes[vol->vol_id] = NULL;
 
 	ubi->rsvd_pebs -= reserved_pebs;
 	ubi->avail_pebs += reserved_pebs;
@@ -249,56 +257,46 @@  static int ubi_remove_vol(char *volume)
 
 	return 0;
 out_err:
-	ubi_err("cannot remove volume %d, error %d", vol_id, err);
+	ubi_err("cannot remove volume %s, error %d", volume, err);
+	if (err < 0)
+		err = -err;
 	return err;
 }
 
 static int ubi_volume_write(char *volume, void *buf, size_t size)
 {
-	int i = 0, err = -1;
+	int err = 1;
 	int rsvd_bytes = 0;
-	int found = 0;
 	struct ubi_volume *vol;
 
-	for (i = 0; i < ubi->vtbl_slots; i++) {
-		vol = ubi->volumes[i];
-		if (vol && !strcmp(vol->name, volume)) {
-			printf("Volume \"%s\" found at volume id %d\n", volume, i);
-			found = 1;
-			break;
-		}
-	}
-	if (!found) {
-		printf("%s volume not found\n", volume);
-		return 1;
-	}
+	vol = ubi_find_volume(volume);
+	if (vol == NULL)
+		return ENODEV;
+
 	rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
 	if (size < 0 || size > rsvd_bytes) {
-		printf("rsvd_bytes=%d vol->reserved_pebs=%d ubi->leb_size=%d\n",
-		     rsvd_bytes, vol->reserved_pebs, ubi->leb_size);
-		printf("vol->data_pad=%d\n", vol->data_pad);
-		printf("Size > volume size !!\n");
-		return 1;
+		printf("size > volume size! Aborting!\n");
+		return EINVAL;
 	}
 
 	err = ubi_start_update(ubi, vol, size);
 	if (err < 0) {
 		printf("Cannot start volume update\n");
-		return err;
+		return -err;
 	}
 
 	err = ubi_more_update_data(ubi, vol, buf, size);
 	if (err < 0) {
-		printf("Couldnt or partially wrote data \n");
-		return err;
+		printf("Couldnt or partially wrote data\n");
+		return -err;
 	}
 
 	if (err) {
 		size = err;
 
 		err = ubi_check_volume(ubi, vol->vol_id);
-		if ( err < 0 )
-			return err;
+		if (err < 0)
+			return -err;
 
 		if (err) {
 			ubi_warn("volume %d on UBI device %d is corrupted",
@@ -310,47 +308,39 @@  static int ubi_volume_write(char *volume, void *buf, size_t size)
 		ubi_gluebi_updated(vol);
 	}
 
+	printf("%d bytes written to volume %s\n", size, volume);
+
 	return 0;
 }
 
 static int ubi_volume_read(char *volume, char *buf, size_t size)
 {
-	int err, lnum, off, len, tbuf_size, i = 0;
+	int err, lnum, off, len, tbuf_size;
 	size_t count_save = size;
 	void *tbuf;
 	unsigned long long tmp;
-	struct ubi_volume *vol = NULL;
+	struct ubi_volume *vol;
 	loff_t offp = 0;
 
-	for (i = 0; i < ubi->vtbl_slots; i++) {
-		vol = ubi->volumes[i];
-		if (vol && !strcmp(vol->name, volume)) {
-			printf("Volume %s found at volume id %d\n",
-				volume, vol->vol_id);
-			break;
-		}
-	}
-	if (i == ubi->vtbl_slots) {
-		printf("%s volume not found\n", volume);
-		return -ENODEV;
-	}
+	vol = ubi_find_volume(volume);
+	if (vol == NULL)
+		return ENODEV;
 
-	printf("read %i bytes from volume %d to %x(buf address)\n",
-	       (int) size, vol->vol_id, (unsigned)buf);
+	printf("Read %d bytes from volume %s to %p\n", size, volume, buf);
 
 	if (vol->updating) {
 		printf("updating");
-		return -EBUSY;
+		return EBUSY;
 	}
 	if (vol->upd_marker) {
 		printf("damaged volume, update marker is set");
-		return -EBADF;
+		return EBADF;
 	}
 	if (offp == vol->used_bytes)
 		return 0;
 
 	if (size == 0) {
-		printf("Read [%lu] bytes\n", (unsigned long) vol->used_bytes);
+		printf("No size specified -> Using max size (%lld)\n", vol->used_bytes);
 		size = vol->used_bytes;
 	}
 
@@ -365,7 +355,7 @@  static int ubi_volume_read(char *volume, char *buf, size_t size)
 	tbuf = malloc(tbuf_size);
 	if (!tbuf) {
 		printf("NO MEM\n");
-		return -ENOMEM;
+		return ENOMEM;
 	}
 	len = size > tbuf_size ? tbuf_size : size;
 
@@ -379,6 +369,7 @@  static int ubi_volume_read(char *volume, char *buf, size_t size)
 		err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
 		if (err) {
 			printf("read err %x\n", err);
+			err = -err;
 			break;
 		}
 		off += len;
@@ -397,7 +388,7 @@  static int ubi_volume_read(char *volume, char *buf, size_t size)
 	} while (size);
 
 	free(tbuf);
-	return err ? err : count_save - size;
+	return err;
 }
 
 static int ubi_dev_scan(struct mtd_info *info, char *ubidev,
@@ -427,13 +418,13 @@  static int ubi_dev_scan(struct mtd_info *info, char *ubidev,
 	err = ubi_mtd_param_parse(ubi_mtd_param_buffer, NULL);
 	if (err) {
 		del_mtd_partitions(info);
-		return err;
+		return -err;
 	}
 
 	err = ubi_init();
 	if (err) {
 		del_mtd_partitions(info);
-		return err;
+		return -err;
 	}
 
 	ubi_initialized = 1;
@@ -565,8 +556,10 @@  static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 			argc--;
 		}
 		/* Use maximum available size */
-		if (!size)
+		if (!size) {
 			size = ubi->avail_pebs * ubi->leb_size;
+			printf("No size specified -> Using max size (%u)\n", size);
+		}
 		/* E.g., create volume */
 		if (argc == 3)
 			return ubi_create_vol(argv[2], size, dynamic);
@@ -610,7 +603,7 @@  static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 	}
 
 	printf("Please see usage\n");
-	return -1;
+	return 1;
 }
 
 U_BOOT_CMD(