xref: /openbmc/u-boot/cmd/part.c (revision 9d466f2f)
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 enum cmd_part_info {
26 	CMD_PART_INFO_START = 0,
27 	CMD_PART_INFO_SIZE,
28 };
29 
30 static int do_part_uuid(int argc, char * const argv[])
31 {
32 	int part;
33 	struct blk_desc *dev_desc;
34 	disk_partition_t info;
35 
36 	if (argc < 2)
37 		return CMD_RET_USAGE;
38 	if (argc > 3)
39 		return CMD_RET_USAGE;
40 
41 	part = blk_get_device_part_str(argv[0], argv[1], &dev_desc, &info, 0);
42 	if (part < 0)
43 		return 1;
44 
45 	if (argc > 2)
46 		env_set(argv[2], info.uuid);
47 	else
48 		printf("%s\n", info.uuid);
49 
50 	return 0;
51 }
52 
53 static int do_part_list(int argc, char * const argv[])
54 {
55 	int ret;
56 	struct blk_desc *desc;
57 	char *var = NULL;
58 	bool bootable = false;
59 	int i;
60 
61 	if (argc < 2)
62 		return CMD_RET_USAGE;
63 
64 	if (argc > 2) {
65 		for (i = 2; i < argc ; i++) {
66 			if (argv[i][0] == '-') {
67 				if (!strcmp(argv[i], "-bootable")) {
68 					bootable = true;
69 				} else {
70 					printf("Unknown option %s\n", argv[i]);
71 					return CMD_RET_USAGE;
72 				}
73 			} else {
74 				var = argv[i];
75 				break;
76 			}
77 		}
78 
79 		/* Loops should have been exited at the last argument, which
80 		 * as it contained the variable */
81 		if (argc != i + 1)
82 			return CMD_RET_USAGE;
83 	}
84 
85 	ret = blk_get_device_by_str(argv[0], argv[1], &desc);
86 	if (ret < 0)
87 		return 1;
88 
89 	if (var != NULL) {
90 		int p;
91 		char str[512] = { '\0', };
92 		disk_partition_t info;
93 
94 		for (p = 1; p < 128; p++) {
95 			char t[5];
96 			int r = part_get_info(desc, p, &info);
97 
98 			if (r != 0)
99 				continue;
100 
101 			if (bootable && !info.bootable)
102 				continue;
103 
104 			sprintf(t, "%s%x", str[0] ? " " : "", p);
105 			strcat(str, t);
106 		}
107 		env_set(var, str);
108 		return 0;
109 	}
110 
111 	part_print(desc);
112 
113 	return 0;
114 }
115 
116 static int do_part_info(int argc, char * const argv[], enum cmd_part_info param)
117 {
118 	struct blk_desc *desc;
119 	disk_partition_t info;
120 	char buf[512] = { 0 };
121 	char *endp;
122 	int part;
123 	int err;
124 	int ret;
125 
126 	if (argc < 3)
127 		return CMD_RET_USAGE;
128 	if (argc > 4)
129 		return CMD_RET_USAGE;
130 
131 	ret = blk_get_device_by_str(argv[0], argv[1], &desc);
132 	if (ret < 0)
133 		return 1;
134 
135 	part = simple_strtoul(argv[2], &endp, 0);
136 	if (*endp == '\0') {
137 		err = part_get_info(desc, part, &info);
138 		if (err)
139 			return 1;
140 	} else {
141 		part = part_get_info_by_name(desc, argv[2], &info);
142 		if (part == -1)
143 			return 1;
144 	}
145 
146 	switch (param) {
147 	case CMD_PART_INFO_START:
148 		snprintf(buf, sizeof(buf), LBAF, info.start);
149 		break;
150 	case CMD_PART_INFO_SIZE:
151 		snprintf(buf, sizeof(buf), LBAF, info.size);
152 		break;
153 	default:
154 		printf("** Unknown cmd_part_info value: %d\n", param);
155 		return 1;
156 	}
157 
158 	if (argc > 3)
159 		env_set(argv[3], buf);
160 	else
161 		printf("%s\n", buf);
162 
163 	return 0;
164 }
165 
166 static int do_part_start(int argc, char * const argv[])
167 {
168 	return do_part_info(argc, argv, CMD_PART_INFO_START);
169 }
170 
171 static int do_part_size(int argc, char * const argv[])
172 {
173 	return do_part_info(argc, argv, CMD_PART_INFO_SIZE);
174 }
175 
176 static int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
177 {
178 	if (argc < 2)
179 		return CMD_RET_USAGE;
180 
181 	if (!strcmp(argv[1], "uuid"))
182 		return do_part_uuid(argc - 2, argv + 2);
183 	else if (!strcmp(argv[1], "list"))
184 		return do_part_list(argc - 2, argv + 2);
185 	else if (!strcmp(argv[1], "start"))
186 		return do_part_start(argc - 2, argv + 2);
187 	else if (!strcmp(argv[1], "size"))
188 		return do_part_size(argc - 2, argv + 2);
189 
190 	return CMD_RET_USAGE;
191 }
192 
193 U_BOOT_CMD(
194 	part,	CONFIG_SYS_MAXARGS,	1,	do_part,
195 	"disk partition related commands",
196 	"uuid <interface> <dev>:<part>\n"
197 	"    - print partition UUID\n"
198 	"part uuid <interface> <dev>:<part> <varname>\n"
199 	"    - set environment variable to partition UUID\n"
200 	"part list <interface> <dev>\n"
201 	"    - print a device's partition table\n"
202 	"part list <interface> <dev> [flags] <varname>\n"
203 	"    - set environment variable to the list of partitions\n"
204 	"      flags can be -bootable (list only bootable partitions)\n"
205 	"part start <interface> <dev> <part> <varname>\n"
206 	"    - set environment variable to the start of the partition (in blocks)\n"
207 	"      part can be either partition number or partition name\n"
208 	"part size <interface> <dev> <part> <varname>\n"
209 	"    - set environment variable to the size of the partition (in blocks)\n"
210 	"      part can be either partition number or partition name"
211 );
212