#include <onenand_uboot.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/err.h>
#include <ubi_uboot.h>
#include <asm/errno.h>
#include <jffs2/load_kernel.h>
+#undef ubi_msg
+#define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__)
+
#define DEV_TYPE_NONE 0
#define DEV_TYPE_NAND 1
#define DEV_TYPE_ONENAND 2
void cmd_ubifs_umount(void);
#endif
-static void ubi_dump_vol_info(const struct ubi_volume *vol)
-{
- ubi_msg("volume information dump:");
- ubi_msg("vol_id %d", vol->vol_id);
- ubi_msg("reserved_pebs %d", vol->reserved_pebs);
- ubi_msg("alignment %d", vol->alignment);
- ubi_msg("data_pad %d", vol->data_pad);
- ubi_msg("vol_type %d", vol->vol_type);
- ubi_msg("name_len %d", vol->name_len);
- ubi_msg("usable_leb_size %d", vol->usable_leb_size);
- ubi_msg("used_ebs %d", vol->used_ebs);
- ubi_msg("used_bytes %lld", vol->used_bytes);
- ubi_msg("last_eb_bytes %d", vol->last_eb_bytes);
- ubi_msg("corrupted %d", vol->corrupted);
- ubi_msg("upd_marker %d", vol->upd_marker);
-
- if (vol->name_len <= UBI_VOL_NAME_MAX &&
- strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
- ubi_msg("name %s", vol->name);
- } else {
- ubi_msg("the 1st 5 characters of the name: %c%c%c%c%c",
- vol->name[0], vol->name[1], vol->name[2],
- vol->name[3], vol->name[4]);
- }
- printf("\n");
-}
-
static void display_volume_info(struct ubi_device *ubi)
{
int i;
return 0;
}
+static int ubi_check_volumename(const struct ubi_volume *vol, char *name)
+{
+ return strcmp(vol->name, name);
+}
+
+static int ubi_check(char *name)
+{
+ int i;
+
+ for (i = 0; i < (ubi->vtbl_slots + 1); i++) {
+ if (!ubi->volumes[i])
+ continue; /* Empty record */
+
+ if (!ubi_check_volumename(ubi->volumes[i], name))
+ return 0;
+ }
+
+ return 1;
+}
+
+
static int verify_mkvol_req(const struct ubi_device *ubi,
const struct ubi_mkvol_req *req)
{
return err;
}
-static int ubi_create_vol(char *volume, int size, int dynamic)
+static int ubi_create_vol(char *volume, int64_t size, int dynamic)
{
struct ubi_mkvol_req req;
int err;
printf("verify_mkvol_req failed %d\n", err);
return err;
}
- printf("Creating %s volume %s of size %d\n",
+ printf("Creating %s volume %s of size %lld\n",
dynamic ? "dynamic" : "static", volume, size);
/* Call real ubi create volume */
return ubi_create_volume(ubi, &req);
return err;
}
-int ubi_volume_write(char *volume, void *buf, size_t size)
+static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
{
int err = 1;
- int rsvd_bytes = 0;
struct ubi_volume *vol;
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("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;
- }
-
err = ubi_more_update_data(ubi, vol, buf, size);
if (err < 0) {
printf("Couldnt or partially wrote data\n");
return 0;
}
+int ubi_volume_begin_write(char *volume, void *buf, size_t size,
+ size_t full_size)
+{
+ int err = 1;
+ int rsvd_bytes = 0;
+ struct ubi_volume *vol;
+
+ 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("size > volume size! Aborting!\n");
+ return EINVAL;
+ }
+
+ err = ubi_start_update(ubi, vol, full_size);
+ if (err < 0) {
+ printf("Cannot start volume update\n");
+ return -err;
+ }
+
+ return ubi_volume_continue_write(volume, buf, size);
+}
+
+int ubi_volume_write(char *volume, void *buf, size_t size)
+{
+ return ubi_volume_begin_write(volume, buf, size, size);
+}
+
int ubi_volume_read(char *volume, char *buf, size_t size)
{
int err, lnum, off, len, tbuf_size;
tbuf_size = vol->usable_leb_size;
if (size < tbuf_size)
tbuf_size = ALIGN(size, ubi->min_io_size);
- tbuf = malloc(tbuf_size);
+ tbuf = malloc_cache_aligned(tbuf_size);
if (!tbuf) {
printf("NO MEM\n");
return ENOMEM;
static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- size_t size = 0;
+ int64_t size = 0;
ulong addr = 0;
if (argc < 2)
return ubi_info(layout);
}
+ if (strcmp(argv[1], "check") == 0) {
+ if (argc > 2)
+ return ubi_check(argv[2]);
+
+ printf("Error, no volume name passed\n");
+ return 1;
+ }
+
if (strncmp(argv[1], "create", 6) == 0) {
int dynamic = 1; /* default: dynamic volume */
}
/* E.g., create volume size */
if (argc == 4) {
- size = simple_strtoul(argv[3], NULL, 16);
+ size = simple_strtoull(argv[3], NULL, 16);
argc--;
}
/* Use maximum available size */
if (!size) {
- size = ubi->avail_pebs * ubi->leb_size;
- printf("No size specified -> Using max size (%u)\n", size);
+ size = (int64_t)ubi->avail_pebs * ubi->leb_size;
+ printf("No size specified -> Using max size (%lld)\n", size);
}
/* E.g., create volume */
if (argc == 3)
addr = simple_strtoul(argv[2], NULL, 16);
size = simple_strtoul(argv[4], NULL, 16);
- ret = ubi_volume_write(argv[3], (void *)addr, size);
+ if (strlen(argv[1]) == 10 &&
+ strncmp(argv[1] + 5, ".part", 5) == 0) {
+ if (argc < 6) {
+ ret = ubi_volume_continue_write(argv[3],
+ (void *)addr, size);
+ } else {
+ size_t full_size;
+ full_size = simple_strtoul(argv[5], NULL, 16);
+ ret = ubi_volume_begin_write(argv[3],
+ (void *)addr, size, full_size);
+ }
+ } else {
+ ret = ubi_volume_write(argv[3], (void *)addr, size);
+ }
if (!ret) {
- printf("%d bytes written to volume %s\n", size,
+ printf("%lld bytes written to volume %s\n", size,
argv[3]);
}
}
if (argc == 3) {
- printf("Read %d bytes from volume %s to %lx\n", size,
+ printf("Read %lld bytes from volume %s to %lx\n", size,
argv[3], addr);
return ubi_volume_read(argv[3], (char *)addr, size);
" header offset)\n"
"ubi info [l[ayout]]"
" - Display volume and ubi layout information\n"
+ "ubi check volumename"
+ " - check if volumename exists\n"
"ubi create[vol] volume [size] [type]"
" - create volume name with size\n"
"ubi write[vol] address volume size"
" - Write volume from address with size\n"
+ "ubi write.part address volume size [fullsize]\n"
+ " - Write part of a volume from address\n"
"ubi read[vol] address volume [size]"
" - Read volume to address with size\n"
"ubi remove[vol] volume"