109c32807SHeiko Schocher /* 209c32807SHeiko Schocher * (C) Copyright 2014 309c32807SHeiko Schocher * Heiko Schocher, DENX Software Engineering, hs@denx.de. 409c32807SHeiko Schocher * 509c32807SHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 609c32807SHeiko Schocher */ 709c32807SHeiko Schocher #include <common.h> 809c32807SHeiko Schocher #include <linux/mtd/mtd.h> 909c32807SHeiko Schocher #include <jffs2/jffs2.h> 1009c32807SHeiko Schocher 1109c32807SHeiko Schocher static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, 1209c32807SHeiko Schocher loff_t *maxsize, int devtype) 1309c32807SHeiko Schocher { 1409c32807SHeiko Schocher #ifdef CONFIG_CMD_MTDPARTS 1509c32807SHeiko Schocher struct mtd_device *dev; 1609c32807SHeiko Schocher struct part_info *part; 1709c32807SHeiko Schocher u8 pnum; 1809c32807SHeiko Schocher int ret; 1909c32807SHeiko Schocher 2009c32807SHeiko Schocher ret = mtdparts_init(); 2109c32807SHeiko Schocher if (ret) 2209c32807SHeiko Schocher return ret; 2309c32807SHeiko Schocher 2409c32807SHeiko Schocher ret = find_dev_and_part(partname, &dev, &pnum, &part); 2509c32807SHeiko Schocher if (ret) 2609c32807SHeiko Schocher return ret; 2709c32807SHeiko Schocher 2809c32807SHeiko Schocher if (dev->id->type != devtype) { 2909c32807SHeiko Schocher printf("not same typ %d != %d\n", dev->id->type, devtype); 3009c32807SHeiko Schocher return -1; 3109c32807SHeiko Schocher } 3209c32807SHeiko Schocher 3309c32807SHeiko Schocher *off = part->offset; 3409c32807SHeiko Schocher *size = part->size; 3509c32807SHeiko Schocher *maxsize = part->size; 3609c32807SHeiko Schocher *idx = dev->id->num; 3709c32807SHeiko Schocher 3809c32807SHeiko Schocher return 0; 3909c32807SHeiko Schocher #else 4009c32807SHeiko Schocher puts("offset is not a number\n"); 4109c32807SHeiko Schocher return -1; 4209c32807SHeiko Schocher #endif 4309c32807SHeiko Schocher } 4409c32807SHeiko Schocher 4509c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, 46*f18d1116SMasahiro Yamada loff_t *maxsize, int devtype, uint64_t chipsize) 4709c32807SHeiko Schocher { 4809c32807SHeiko Schocher if (!str2off(arg, off)) 4909c32807SHeiko Schocher return get_part(arg, idx, off, size, maxsize, devtype); 5009c32807SHeiko Schocher 5109c32807SHeiko Schocher if (*off >= chipsize) { 5209c32807SHeiko Schocher puts("Offset exceeds device limit\n"); 5309c32807SHeiko Schocher return -1; 5409c32807SHeiko Schocher } 5509c32807SHeiko Schocher 5609c32807SHeiko Schocher *maxsize = chipsize - *off; 5709c32807SHeiko Schocher *size = *maxsize; 5809c32807SHeiko Schocher return 0; 5909c32807SHeiko Schocher } 6009c32807SHeiko Schocher 6109c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off, 62*f18d1116SMasahiro Yamada loff_t *size, loff_t *maxsize, int devtype, 63*f18d1116SMasahiro Yamada uint64_t chipsize) 6409c32807SHeiko Schocher { 6509c32807SHeiko Schocher int ret; 6609c32807SHeiko Schocher 6709c32807SHeiko Schocher if (argc == 0) { 6809c32807SHeiko Schocher *off = 0; 6909c32807SHeiko Schocher *size = chipsize; 7009c32807SHeiko Schocher *maxsize = *size; 7109c32807SHeiko Schocher goto print; 7209c32807SHeiko Schocher } 7309c32807SHeiko Schocher 7409c32807SHeiko Schocher ret = mtd_arg_off(argv[0], idx, off, size, maxsize, devtype, 7509c32807SHeiko Schocher chipsize); 7609c32807SHeiko Schocher if (ret) 7709c32807SHeiko Schocher return ret; 7809c32807SHeiko Schocher 7909c32807SHeiko Schocher if (argc == 1) 8009c32807SHeiko Schocher goto print; 8109c32807SHeiko Schocher 8209c32807SHeiko Schocher if (!str2off(argv[1], size)) { 8309c32807SHeiko Schocher printf("'%s' is not a number\n", argv[1]); 8409c32807SHeiko Schocher return -1; 8509c32807SHeiko Schocher } 8609c32807SHeiko Schocher 8709c32807SHeiko Schocher if (*size > *maxsize) { 8809c32807SHeiko Schocher puts("Size exceeds partition or device limit\n"); 8909c32807SHeiko Schocher return -1; 9009c32807SHeiko Schocher } 9109c32807SHeiko Schocher 9209c32807SHeiko Schocher print: 9309c32807SHeiko Schocher printf("device %d ", *idx); 9409c32807SHeiko Schocher if (*size == chipsize) 9509c32807SHeiko Schocher puts("whole chip\n"); 9609c32807SHeiko Schocher else 9709c32807SHeiko Schocher printf("offset 0x%llx, size 0x%llx\n", 9809c32807SHeiko Schocher (unsigned long long)*off, (unsigned long long)*size); 9909c32807SHeiko Schocher return 0; 10009c32807SHeiko Schocher } 101