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("mtdparts support missing.\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, uint64_t 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, 63 uint64_t chipsize) 64 { 65 int ret; 66 67 if (argc == 0) { 68 *off = 0; 69 *size = chipsize; 70 *maxsize = *size; 71 goto print; 72 } 73 74 ret = mtd_arg_off(argv[0], idx, off, size, maxsize, devtype, 75 chipsize); 76 if (ret) 77 return ret; 78 79 if (argc == 1) 80 goto print; 81 82 if (!str2off(argv[1], size)) { 83 printf("'%s' is not a number\n", argv[1]); 84 return -1; 85 } 86 87 if (*size > *maxsize) { 88 puts("Size exceeds partition or device limit\n"); 89 return -1; 90 } 91 92 print: 93 printf("device %d ", *idx); 94 if (*size == chipsize) 95 puts("whole chip\n"); 96 else 97 printf("offset 0x%llx, size 0x%llx\n", 98 (unsigned long long)*off, (unsigned long long)*size); 99 return 0; 100 } 101