summaryrefslogtreecommitdiffstats
path: root/common/cmd_ubi.c
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2011-03-14 14:34:21 +0100
committerStefan Roese <sr@denx.de>2011-03-21 10:02:16 +0100
commit7f5d8a4d8e0ef7aee08476f0a3b9eb40974efaee (patch)
tree9ea2d2bb6d71f222cc06481e5fae581ed4db5fcd /common/cmd_ubi.c
parentcc1dd33f273f8c96cbd7539b4a2d1d7aa12773cd (diff)
downloadtalos-obmc-uboot-7f5d8a4d8e0ef7aee08476f0a3b9eb40974efaee.tar.gz
talos-obmc-uboot-7f5d8a4d8e0ef7aee08476f0a3b9eb40974efaee.zip
UBI: Fix error code handling in ubi commands
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>
Diffstat (limited to 'common/cmd_ubi.c')
-rw-r--r--common/cmd_ubi.c137
1 files changed, 65 insertions, 72 deletions
diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
index b486ca8fef..629758fdf5 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(
OpenPOWER on IntegriCloud