[U-Boot] [PATCH] [UBI] UBI command support v3

Kyungmin Park kmpark at infradead.org
Mon Nov 3 00:39:55 CET 2008


On Mon, Nov 3, 2008 at 6:01 AM, Magnus Lilja <lilja.magnus at gmail.com> wrote:
> Dear Kyungmin Park,
>
> Some more comments.
>
> 2008/10/28 Kyungmin Park <kmpark at infradead.org>:
>> It supports basic operation such as create, remove, read, and write.
>>
>> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
>> ---
>> diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
>> new file mode 100644
>> index 0000000..8c46cca
>> --- /dev/null
>> +++ b/common/cmd_ubi.c
>> +static int ubi_volume_read(char *volume, char *buf, size_t size)
>> +{
>> +       int err, lnum, off, len, tbuf_size, i = 0;
>> +       size_t count_save = size;
>> +       void *tbuf;
>> +       unsigned long long tmp;
>> +       struct ubi_volume *vol = NULL;
>> +       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 voume not found\n", volume);
>> +               return 0;
>> +       }
>> +
>> +       printf("read %i bytes from volume %d to %x(buf address)\n",
>> +              (int) size, vol->vol_id, (unsigned)buf);
>> +
>> +       if (vol->updating) {
>> +               printf("updating");
>> +               return -EBUSY;
>> +       }
>> +       if (vol->upd_marker) {
>> +               printf("damaged volume, update marker is set");
>> +               return -EBADF;
>> +       }
>> +       if (offp == vol->used_bytes)
>> +               return 0;
>> +
>> +       if (size == 0) {
>> +               printf("Read [%lu] bytes\n", (unsigned long) vol->used_bytes);
>> +               size = vol->used_bytes;
>> +       }
>> +
>> +       if (vol->corrupted)
>> +               printf("read from corrupted volume %d", vol->vol_id);
>> +       if (offp + size > vol->used_bytes)
>> +               count_save = size = vol->used_bytes - offp;
>> +
>> +       tbuf_size = vol->usable_leb_size;
>> +       if (size < tbuf_size)
>> +               tbuf_size = ALIGN(size, ubi->min_io_size);
>> +       tbuf = malloc(tbuf_size);
>> +       if (!tbuf) {
>> +               printf("NO MEM\n");
>> +               return -ENOMEM;
>> +       }
>> +       len = size > tbuf_size ? tbuf_size : size;
>> +
>> +       tmp = offp;
>> +       off = do_div(tmp, vol->usable_leb_size);
>> +       lnum = tmp;
>> +       printf("off=%d lnum=%d\n", off, lnum);
>> +       do {
>> +               if (off + len >= vol->usable_leb_size)
>> +                       len = vol->usable_leb_size - off;
>> +
>> +               err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
>> +               if (err) {
>> +                       printf("read err %x\n", err);
>> +                       break;
>> +               }
>> +               off += len;
>> +               if (off == vol->usable_leb_size) {
>> +                       lnum += 1;
>> +                       off -= vol->usable_leb_size;
>> +               }
>> +
>> +               size -= len;
>> +               offp += len;
>> +
>> +               printf("buf = %x\n", (unsigned)buf);
>> +               memcpy(buf, tbuf, len);
>> +               printf("buf[0] = %x\n", buf[0]);
>
> The printf()'s before and after memcpy() looks like stuff used during
> development of this file and they should be removed.

Yes, correct, I'll remove it

>
>> +
>> +               buf += len;
>> +               len = size > tbuf_size ? tbuf_size : size;
>> +       } while (size);
>> +
>> +       free(tbuf);
>> +       return err ? err : count_save - size;
>> +}
>> +
>> +static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
>> +{
>> +       size_t size = 0;
>> +       ulong addr = 0;
>> +       int err = 0;
>> +
>> +       if (!ubi_initialized) {
>> +               err = ubi_board_scan();
>> +               if (err) {
>> +                       printf("UBI init error %d\n", err);
>> +                       return err;
>> +               }
>> +               ubi = ubi_devices[0];
>> +               ubi_initialized = 1;
>> +       }
>> +
>> +       if (argc < 2) {
>> +               printf("Usage:\n%s\n", cmdtp->usage);
>> +               return 1;
>> +       }
>> +       if (strcmp(argv[1], "info") == 0) {
>> +               int layout = 0;
>> +               if (argc > 2 && !strncmp(argv[2], "l", 1))
>> +                       layout = 1;
>> +               return ubi_info(layout);
>> +       }
>> +       if (strncmp(argv[1], "create", 6) == 0) {
>> +               int dynamic = 1;        /* default: dynamic volume */
>> +
>> +               /* Use maximum available size */
>> +               size = 0;
>> +
>> +               /* E.g., create volume size type */
>> +               if (argc == 5) {
>> +                       if (strncmp(argv[4], "s", 1) == 0)
>> +                               dynamic = 0;
>> +                       else if (strncmp(argv[4], "d", 1) != 0) {
>> +                               printf("Incorrect type\n");
>> +                               return 1;
>> +                       }
>> +                       argc--;
>> +               }
>> +               /* E.g., create volume size */
>> +               if (argc == 4) {
>> +                       err = parse_num(&size, argv[3]);
>> +                       if (err) {
>> +                               printf("Incorrect type\n");
>> +                               return err;
>> +                       }
>> +                       argc--;
>> +               }
>> +               /* Use maximum available size */
>> +               if (!size)
>> +                       size = ubi->avail_pebs * ubi->leb_size;
>> +               /* E.g., create volume */
>> +               if (argc == 3)
>> +                       return ubi_create_vol(argv[2], size, dynamic);
>> +       }
>> +       if (strncmp(argv[1], "remove", 6) == 0) {
>> +               /* E.g., remove volume */
>> +               if (argc == 3)
>> +                       return ubi_remove_vol(argv[2]);
>> +       }
>> +       if (strncmp(argv[1], "write", 5) == 0) {
>> +               if (argc < 5) {
>> +                       printf("Please see usage\n");
>> +                       return 1;
>> +               }
>> +
>> +               addr = simple_strtoul(argv[2], NULL, 16);
>> +               err = parse_num(&size, argv[4]);
>> +               if (err) {
>> +                       printf("Please see usage\n");
>> +                       return err;
>> +               }
>> +
>> +               return ubi_volume_write(argv[3], (void *)addr, size);
>> +       }
>> +       if (strncmp(argv[1], "read", 4) == 0) {
>> +               size = 0;
>> +
>> +               /* E.g., read volume size */
>> +               if (argc == 5) {
>> +                       err = parse_num(&size, argv[4]);
>> +                       if (err) {
>> +                               printf("Please see usage\n");
>> +                               return err;
>> +                       }
>> +                       argc--;
>> +               }
>> +
>> +               /* E.g., read volume */
>> +               if (argc == 4) {
>> +                       addr = simple_strtoul(argv[2], NULL, 16);
>> +                       argc--;
>> +               }
>> +
>> +               if (argc == 3)
>> +                       return ubi_volume_read(argv[3], (char *)addr, size);
>
> It seems to me that ubi_volume_read() can return 0 when there is an
> error, so it may not be correct to use that return value here. AFAIK

Really? I will check the return value.

> do_ubi()-like functions return 0 upon success and non-zero otherwise.
Agreed

Thank you,
Kyungmin Park


More information about the U-Boot mailing list