summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/cmd_mtdparts.c54
-rw-r--r--common/cmd_ubi.c79
2 files changed, 85 insertions, 48 deletions
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index f791372de15..40b6333ebf4 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -93,13 +93,13 @@
DECLARE_GLOBAL_DATA_PTR;
/* special size referring to all the remaining space in a partition */
-#define SIZE_REMAINING 0xFFFFFFFF
+#define SIZE_REMAINING (~0llu)
/* special offset value, it is used when not provided by user
*
* this value is used temporarily during parsing, later such offests
* are recalculated */
-#define OFFSET_NOT_SPECIFIED 0xFFFFFFFF
+#define OFFSET_NOT_SPECIFIED (~0llu)
/* minimum partition size */
#define MIN_PART_SIZE 4096
@@ -160,9 +160,9 @@ static int device_del(struct mtd_device *dev);
* @param retptr output pointer to next char after parse completes (output)
* @return resulting unsigned int
*/
-static unsigned long memsize_parse (const char *const ptr, const char **retptr)
+static u64 memsize_parse (const char *const ptr, const char **retptr)
{
- unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
+ u64 ret = simple_strtoull(ptr, (char **)retptr, 0);
switch (**retptr) {
case 'G':
@@ -193,20 +193,20 @@ static unsigned long memsize_parse (const char *const ptr, const char **retptr)
* @param buf output buffer
* @param size size to be converted to string
*/
-static void memsize_format(char *buf, u32 size)
+static void memsize_format(char *buf, u64 size)
{
#define SIZE_GB ((u32)1024*1024*1024)
#define SIZE_MB ((u32)1024*1024)
#define SIZE_KB ((u32)1024)
if ((size % SIZE_GB) == 0)
- sprintf(buf, "%ug", size/SIZE_GB);
+ sprintf(buf, "%llug", size/SIZE_GB);
else if ((size % SIZE_MB) == 0)
- sprintf(buf, "%um", size/SIZE_MB);
+ sprintf(buf, "%llum", size/SIZE_MB);
else if (size % SIZE_KB == 0)
- sprintf(buf, "%uk", size/SIZE_KB);
+ sprintf(buf, "%lluk", size/SIZE_KB);
else
- sprintf(buf, "%u", size);
+ sprintf(buf, "%llu", size);
}
/**
@@ -310,6 +310,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
struct mtd_info *mtd = NULL;
int i, j;
ulong start;
+ u64 offset, size;
if (get_mtd_info(id->type, id->num, &mtd))
return 1;
@@ -321,14 +322,16 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
* Only one eraseregion (NAND, OneNAND or uniform NOR),
* checking for alignment is easy here
*/
- if ((unsigned long)part->offset % mtd->erasesize) {
+ offset = part->offset;
+ if (do_div(offset, mtd->erasesize)) {
printf("%s%d: partition (%s) start offset"
"alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
}
- if (part->size % mtd->erasesize) {
+ size = part->size;
+ if (do_div(size, mtd->erasesize)) {
printf("%s%d: partition (%s) size alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
@@ -395,7 +398,7 @@ static int part_validate(struct mtdids *id, struct part_info *part)
part->size = id->size - part->offset;
if (part->offset > id->size) {
- printf("%s: offset %08x beyond flash size %08x\n",
+ printf("%s: offset %08llx beyond flash size %08llx\n",
id->mtd_id, part->offset, id->size);
return 1;
}
@@ -578,8 +581,8 @@ static int part_add(struct mtd_device *dev, struct part_info *part)
static int part_parse(const char *const partdef, const char **ret, struct part_info **retpart)
{
struct part_info *part;
- unsigned long size;
- unsigned long offset;
+ u64 size;
+ u64 offset;
const char *name;
int name_len;
unsigned int mask_flags;
@@ -598,7 +601,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
} else {
size = memsize_parse(p, &p);
if (size < MIN_PART_SIZE) {
- printf("partition size too small (%lx)\n", size);
+ printf("partition size too small (%llx)\n", size);
return 1;
}
}
@@ -670,14 +673,14 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
part->auto_name = 0;
} else {
/* auto generated name in form of size@offset */
- sprintf(part->name, "0x%08lx@0x%08lx", size, offset);
+ sprintf(part->name, "0x%08llx@0x%08llx", size, offset);
part->auto_name = 1;
}
part->name[name_len - 1] = '\0';
INIT_LIST_HEAD(&part->link);
- debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n",
+ debug("+ partition: name %-22s size 0x%08llx offset 0x%08llx mask flags %d\n",
part->name, part->size,
part->offset, part->mask_flags);
@@ -693,7 +696,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
* @param size a pointer to the size of the mtd device (output)
* @return 0 if device is valid, 1 otherwise
*/
-static int mtd_device_validate(u8 type, u8 num, u32 *size)
+static int mtd_device_validate(u8 type, u8 num, u64 *size)
{
struct mtd_info *mtd = NULL;
@@ -826,7 +829,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_
LIST_HEAD(tmp_list);
struct list_head *entry, *n;
u16 num_parts;
- u32 offset;
+ u64 offset;
int err = 1;
debug("===device_parse===\n");
@@ -1071,7 +1074,8 @@ static int generate_mtdparts(char *buf, u32 buflen)
struct part_info *part, *prev_part;
char *p = buf;
char tmpbuf[32];
- u32 size, offset, len, part_cnt;
+ u64 size, offset;
+ u32 len, part_cnt;
u32 maxlen = buflen - 1;
debug("--- generate_mtdparts ---\n");
@@ -1270,7 +1274,7 @@ static void print_partition_table(void)
list_for_each(pentry, &dev->parts) {
part = list_entry(pentry, struct part_info, link);
- printf("%2d: %-20s0x%08x\t0x%08x\t%d\n",
+ printf("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
part_num, part->name, part->size,
part->offset, part->mask_flags);
#endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */
@@ -1297,7 +1301,7 @@ static void list_partitions(void)
if (current_mtd_dev) {
part = mtd_part_info(current_mtd_dev, current_mtd_partnum);
if (part) {
- printf("\nactive partition: %s%d,%d - (%s) 0x%08x @ 0x%08x\n",
+ printf("\nactive partition: %s%d,%d - (%s) 0x%08llx @ 0x%08llx\n",
MTD_DEV_TYPE(current_mtd_dev->id->type),
current_mtd_dev->id->num, current_mtd_partnum,
part->name, part->size, part->offset);
@@ -1397,7 +1401,7 @@ static int delete_partition(const char *id)
if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {
- debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08x@0x%08x\n",
+ debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08llx@0x%08llx\n",
MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum,
part->name, part->size, part->offset);
@@ -1589,7 +1593,7 @@ static int parse_mtdids(const char *const ids)
struct list_head *entry, *n;
struct mtdids *id_tmp;
u8 type, num;
- u32 size;
+ u64 size;
int ret = 1;
debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
@@ -1663,7 +1667,7 @@ static int parse_mtdids(const char *const ids)
id->mtd_id[mtd_id_len - 1] = '\0';
INIT_LIST_HEAD(&id->link);
- debug("+ id %s%d\t%16d bytes\t%s\n",
+ debug("+ id %s%d\t%16lld bytes\t%s\n",
MTD_DEV_TYPE(id->type), id->num,
id->size, id->mtd_id);
diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
index 5ba4feb485b..122ba7e171c 100644
--- a/common/cmd_ubi.c
+++ b/common/cmd_ubi.c
@@ -167,7 +167,7 @@ bad:
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;
@@ -191,7 +191,7 @@ static int ubi_create_vol(char *volume, int size, int dynamic)
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);
@@ -266,28 +266,15 @@ out_err:
return err;
}
-int ubi_volume_write(char *volume, void *buf, size_t size)
+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");
@@ -314,6 +301,37 @@ int ubi_volume_write(char *volume, void *buf, size_t size)
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;
@@ -498,7 +516,7 @@ int ubi_part(char *part_name, const char *vid_header_offset)
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)
@@ -558,13 +576,13 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
/* 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)
@@ -588,9 +606,22 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
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]);
}
@@ -613,7 +644,7 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
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);
@@ -636,6 +667,8 @@ U_BOOT_CMD(
" - 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"