1 /* 2 * (C) Copyright 2014 3 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <linux/mtd/mtd.h> 9 #include <jffs2/jffs2.h> 10 11 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, 12 loff_t *maxsize, int devtype) 13 { 14 #ifdef CONFIG_CMD_MTDPARTS 15 struct mtd_device *dev; 16 struct part_info *part; 17 u8 pnum; 18 int ret; 19 20 ret = mtdparts_init(); 21 if (ret) 22 return ret; 23 24 ret = find_dev_and_part(partname, &dev, &pnum, &part); 25 if (ret) 26 return ret; 27 28 if (dev->id->type != devtype) { 29 printf("not same typ %d != %d\n", dev->id->type, devtype); 30 return -1; 31 } 32 33 *off = part->offset; 34 *size = part->size; 35 *maxsize = part->size; 36 *idx = dev->id->num; 37 38 return 0; 39 #else 40 puts("offset is not a number\n"); 41 return -1; 42 #endif 43 } 44 45 int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, 46 loff_t *maxsize, int devtype, int chipsize) 47 { 48 if (!str2off(arg, off)) 49 return get_part(arg, idx, off, size, maxsize, devtype); 50 51 if (*off >= chipsize) { 52 puts("Offset exceeds device limit\n"); 53 return -1; 54 } 55 56 *maxsize = chipsize - *off; 57 *size = *maxsize; 58 return 0; 59 } 60 61 int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off, 62 loff_t *size, loff_t *maxsize, int devtype, int chipsize) 63 { 64 int ret; 65 66 if (argc == 0) { 67 *off = 0; 68 *size = chipsize; 69 *maxsize = *size; 70 goto print; 71 } 72 73 ret = mtd_arg_off(argv[0], idx, off, size, maxsize, devtype, 74 chipsize); 75 if (ret) 76 return ret; 77 78 if (argc == 1) 79 goto print; 80 81 if (!str2off(argv[1], size)) { 82 printf("'%s' is not a number\n", argv[1]); 83 return -1; 84 } 85 86 if (*size > *maxsize) { 87 puts("Size exceeds partition or device limit\n"); 88 return -1; 89 } 90 91 print: 92 printf("device %d ", *idx); 93 if (*size == chipsize) 94 puts("whole chip\n"); 95 else 96 printf("offset 0x%llx, size 0x%llx\n", 97 (unsigned long long)*off, (unsigned long long)*size); 98 return 0; 99 } 100