xref: /openbmc/u-boot/cmd/part.c (revision 36df616a)
1 /*
2  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * made from cmd_ext2, which was:
5  *
6  * (C) Copyright 2004
7  * esd gmbh <www.esd-electronics.com>
8  * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
9  *
10  * made from cmd_reiserfs by
11  *
12  * (C) Copyright 2003 - 2004
13  * Sysgo Real-Time Solutions, AG <www.elinos.com>
14  * Pavel Bartusek <pba@sysgo.com>
15  *
16  * SPDX-License-Identifier:	GPL-2.0+
17  */
18 
19 #include <common.h>
20 #include <config.h>
21 #include <command.h>
22 #include <part.h>
23 #include <vsprintf.h>
24 
25 static int do_part_uuid(int argc, char * const argv[])
26 {
27 	int part;
28 	struct blk_desc *dev_desc;
29 	disk_partition_t info;
30 
31 	if (argc < 2)
32 		return CMD_RET_USAGE;
33 	if (argc > 3)
34 		return CMD_RET_USAGE;
35 
36 	part = blk_get_device_part_str(argv[0], argv[1], &dev_desc, &info, 0);
37 	if (part < 0)
38 		return 1;
39 
40 	if (argc > 2)
41 		env_set(argv[2], info.uuid);
42 	else
43 		printf("%s\n", info.uuid);
44 
45 	return 0;
46 }
47 
48 static int do_part_list(int argc, char * const argv[])
49 {
50 	int ret;
51 	struct blk_desc *desc;
52 	char *var = NULL;
53 	bool bootable = false;
54 	int i;
55 
56 	if (argc < 2)
57 		return CMD_RET_USAGE;
58 
59 	if (argc > 2) {
60 		for (i = 2; i < argc ; i++) {
61 			if (argv[i][0] == '-') {
62 				if (!strcmp(argv[i], "-bootable")) {
63 					bootable = true;
64 				} else {
65 					printf("Unknown option %s\n", argv[i]);
66 					return CMD_RET_USAGE;
67 				}
68 			} else {
69 				var = argv[i];
70 				break;
71 			}
72 		}
73 
74 		/* Loops should have been exited at the last argument, which
75 		 * as it contained the variable */
76 		if (argc != i + 1)
77 			return CMD_RET_USAGE;
78 	}
79 
80 	ret = blk_get_device_by_str(argv[0], argv[1], &desc);
81 	if (ret < 0)
82 		return 1;
83 
84 	if (var != NULL) {
85 		int p;
86 		char str[512] = { '\0', };
87 		disk_partition_t info;
88 
89 		for (p = 1; p < 128; p++) {
90 			char t[5];
91 			int r = part_get_info(desc, p, &info);
92 
93 			if (r != 0)
94 				continue;
95 
96 			if (bootable && !info.bootable)
97 				continue;
98 
99 			sprintf(t, "%s%x", str[0] ? " " : "", p);
100 			strcat(str, t);
101 		}
102 		env_set(var, str);
103 		return 0;
104 	}
105 
106 	part_print(desc);
107 
108 	return 0;
109 }
110 
111 static int do_part_start(int argc, char * const argv[])
112 {
113 	struct blk_desc *desc;
114 	disk_partition_t info;
115 	char buf[512] = { 0 };
116 	char *endp;
117 	int part;
118 	int err;
119 	int ret;
120 
121 	if (argc < 3)
122 		return CMD_RET_USAGE;
123 	if (argc > 4)
124 		return CMD_RET_USAGE;
125 
126 	ret = blk_get_device_by_str(argv[0], argv[1], &desc);
127 	if (ret < 0)
128 		return 1;
129 
130 	part = simple_strtoul(argv[2], &endp, 0);
131 	if (*endp == '\0') {
132 		err = part_get_info(desc, part, &info);
133 		if (err)
134 			return 1;
135 	} else {
136 		part = part_get_info_by_name(desc, argv[2], &info);
137 		if (part == -1)
138 			return 1;
139 	}
140 
141 	snprintf(buf, sizeof(buf), LBAF, info.start);
142 
143 	if (argc > 3)
144 		env_set(argv[3], buf);
145 	else
146 		printf("%s\n", buf);
147 
148 	return 0;
149 }
150 
151 static int do_part_size(int argc, char * const argv[])
152 {
153 	struct blk_desc *desc;
154 	disk_partition_t info;
155 	char buf[512] = { 0 };
156 	char *endp;
157 	int part;
158 	int err;
159 	int ret;
160 
161 	if (argc < 3)
162 		return CMD_RET_USAGE;
163 	if (argc > 4)
164 		return CMD_RET_USAGE;
165 
166 	ret = blk_get_device_by_str(argv[0], argv[1], &desc);
167 	if (ret < 0)
168 		return 1;
169 
170 	part = simple_strtoul(argv[2], &endp, 0);
171 	if (*endp == '\0') {
172 		err = part_get_info(desc, part, &info);
173 		if (err)
174 			return 1;
175 	} else {
176 		part = part_get_info_by_name(desc, argv[2], &info);
177 		if (part == -1)
178 			return 1;
179 	}
180 
181 	snprintf(buf, sizeof(buf), LBAF, info.size);
182 
183 	if (argc > 3)
184 		env_set(argv[3], buf);
185 	else
186 		printf("%s\n", buf);
187 
188 	return 0;
189 }
190 
191 static int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
192 {
193 	if (argc < 2)
194 		return CMD_RET_USAGE;
195 
196 	if (!strcmp(argv[1], "uuid"))
197 		return do_part_uuid(argc - 2, argv + 2);
198 	else if (!strcmp(argv[1], "list"))
199 		return do_part_list(argc - 2, argv + 2);
200 	else if (!strcmp(argv[1], "start"))
201 		return do_part_start(argc - 2, argv + 2);
202 	else if (!strcmp(argv[1], "size"))
203 		return do_part_size(argc - 2, argv + 2);
204 
205 	return CMD_RET_USAGE;
206 }
207 
208 U_BOOT_CMD(
209 	part,	CONFIG_SYS_MAXARGS,	1,	do_part,
210 	"disk partition related commands",
211 	"uuid <interface> <dev>:<part>\n"
212 	"    - print partition UUID\n"
213 	"part uuid <interface> <dev>:<part> <varname>\n"
214 	"    - set environment variable to partition UUID\n"
215 	"part list <interface> <dev>\n"
216 	"    - print a device's partition table\n"
217 	"part list <interface> <dev> [flags] <varname>\n"
218 	"    - set environment variable to the list of partitions\n"
219 	"      flags can be -bootable (list only bootable partitions)\n"
220 	"part start <interface> <dev> <part> <varname>\n"
221 	"    - set environment variable to the start of the partition (in blocks)\n"
222 	"      part can be either partition number or partition name\n"
223 	"part size <interface> <dev> <part> <varname>\n"
224 	"    - set environment variable to the size of the partition (in blocks)\n"
225 	"      part can be either partition number or partition name"
226 );
227