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