From patchwork Tue Mar 15 09:47:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 86923 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 0AF69B6F82 for ; Tue, 15 Mar 2011 20:47:35 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9CBCD28137; Tue, 15 Mar 2011 10:47:31 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SOQHuX0vMl0r; Tue, 15 Mar 2011 10:47:30 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7C4D128130; Tue, 15 Mar 2011 10:47:30 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A0E6628130 for ; Tue, 15 Mar 2011 10:47:24 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DTpQpglw6ooY for ; Tue, 15 Mar 2011 10:47:22 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mo-p05-ob.rzone.de (mo-p05-ob.rzone.de [81.169.146.182]) by theia.denx.de (Postfix) with ESMTPS id 107A4280C0 for ; Tue, 15 Mar 2011 10:47:20 +0100 (CET) X-RZG-AUTH: :IW0NeWC7b/q2i6W/qstXb1SBUuFnrGohdvpEkce+Ub4+ReKfHDOmCJlC6f0AAg== X-RZG-CLASS-ID: mo05 Received: from quad.fritz.box (p57BD4F8C.dip.t-dialin.net [87.189.79.140]) by post.strato.de (mrclete mo14) (RZmta 25.8) with ESMTPA id d069d4n2F9Lmrh ; Tue, 15 Mar 2011 10:47:16 +0100 (MET) From: Stefan Roese To: u-boot@lists.denx.de Date: Tue, 15 Mar 2011 10:47:14 +0100 Message-Id: <1300182434-31295-1-git-send-email-sr@denx.de> X-Mailer: git-send-email 1.7.4.1 Subject: [U-Boot] [PATCH v2] UBI: Fix error code handling in ubi commands X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 Cc: Wolfgang Denk --- 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(-) 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(