UBI: Fix error code handling in ubi commands
authorStefan Roese <sr@denx.de>
Mon, 14 Mar 2011 13:34:21 +0000 (14:34 +0100)
committerStefan Roese <sr@denx.de>
Mon, 21 Mar 2011 09:02:16 +0000 (10:02 +0100)
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>
common/cmd_ubi.c

index b486ca8fefa0c625fcfbd545a7c407d5426668b2..629758fdf5e7aa7ae98ea70cdb8a6ccde0c4b818 100644 (file)
@@ -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(