1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2014 4 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 5 */ 6 #include <common.h> 7 #include <linux/mtd/mtd.h> 8 #include <jffs2/jffs2.h> 9 10 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, 11 loff_t *maxsize, int devtype) 12 { 13 #ifdef CONFIG_CMD_MTDPARTS 14 struct mtd_device *dev; 15 struct part_info *part; 16 u8 pnum; 17 int ret; 18 19 ret = mtdparts_init(); 20 if (ret) 21 return ret; 22 23 ret = find_dev_and_part(partname, &dev, &pnum, &part); 24 if (ret) 25 return ret; 26 27 if (dev->id->type != devtype) { 28 printf("not same typ %d != %d\n", dev->id->type, devtype); 29 return -1; 30 } 31 32 *off = part->offset; 33 *size = part->size; 34 *maxsize = part->size; 35 *idx = dev->id->num; 36 37 return 0; 38 #else 39 puts("mtdparts support missing.\n"); 40 return -1; 41 #endif 42 } 43 44 int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, 45 loff_t *maxsize, int devtype, uint64_t chipsize) 46 { 47 if (!str2off(arg, off)) 48 return get_part(arg, idx, off, size, maxsize, devtype); 49 50 if (*off >= chipsize) { 51 puts("Offset exceeds device limit\n"); 52 return -1; 53 } 54 55 *maxsize = chipsize - *off; 56 *size = *maxsize; 57 return 0; 58 } 59 60 int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off, 61 loff_t *size, loff_t *maxsize, int devtype, 62 uint64_t 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