cfi new: fix new disabling buffer support
[barebox-mini2440.git] / commands / partition.c
blob09991a24497c650fd96572e66c6201aff2a7803d
1 /*
2 * partition.c - parse a linux-like mtd partition definition and register
3 * the new partitions
5 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
7 * See file CREDITS for list of people who contributed to this
8 * project.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /**
25 * @file
26 * @brief partition handling and addpart and delpart command
29 #ifdef CONFIG_ENABLE_PARTITION_NOISE
30 # define DEBUG
31 #endif
33 #include <common.h>
34 #include <command.h>
35 #include <driver.h>
36 #include <malloc.h>
37 #include <partition.h>
38 #include <errno.h>
39 #include <xfuncs.h>
40 #include <fs.h>
41 #include <linux/stat.h>
42 #include <libgen.h>
44 static int mtd_part_do_parse_one(char *devname, const char *partstr,
45 char **endp, unsigned long offset,
46 off_t devsize, size_t *retsize)
48 ulong size;
49 char *end;
50 char buf[PATH_MAX];
51 unsigned long flags = 0;
52 int ret;
54 memset(buf, 0, PATH_MAX);
56 if (*partstr == '-') {
57 size = devsize - offset;
58 end = (char *)partstr + 1;
59 } else {
60 size = strtoul_suffix(partstr, &end, 0);
63 partstr = end;
65 if (*partstr == '(') {
66 partstr++;
67 end = strchr((char *) partstr, ')');
68 if (!end) {
69 printf("could not find matching ')'\n");
70 return -EINVAL;
73 sprintf(buf, "%s.", devname);
74 memcpy(buf + strlen(buf), partstr, end - partstr);
76 end++;
79 if (size + offset > devsize) {
80 printf("%s: partition end is beyond device\n", buf);
81 return -EINVAL;
84 partstr = end;
86 if (*partstr == 'r' && *(partstr + 1) == 'o') {
87 flags |= PARTITION_READONLY;
88 end = (char *)(partstr + 2);
91 if (endp)
92 *endp = end;
94 *retsize = size;
96 ret = devfs_add_partition(devname, offset, size, flags, buf);
97 if (ret)
98 printf("cannot create %s: %s\n", buf, strerror(-ret));
99 return ret;
102 static int do_addpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
104 char *devname;
105 char *endp;
106 unsigned long offset = 0;
107 off_t devsize;
108 struct stat s;
110 if (argc != 3)
111 return COMMAND_ERROR_USAGE;
113 if (stat(argv[1], &s)) {
114 perror("addpart");
115 return 1;
117 devsize = s.st_size;
119 devname = basename(argv[1]);
121 endp = argv[2];
123 while (1) {
124 size_t size = 0;
126 if (mtd_part_do_parse_one(devname, endp, &endp, offset, devsize, &size))
127 return 1;
129 offset += size;
131 if (!*endp)
132 break;
134 if (*endp != ',') {
135 printf("parse error\n");
136 return 1;
138 endp++;
141 return 0;
144 static const __maybe_unused char cmd_addpart_help[] =
145 "Usage: addpart <device> <partition description>\n"
146 "\n"
147 "addpart adds a partition description to a device. The partition description\n"
148 "has the form\n"
149 "size1(name1)[ro],size2(name2)[ro],...\n"
150 "<device> is the device name under. Size can be given in decimal or if prefixed\n"
151 "with 0x in hex. Sizes can have an optional suffix K,M,G. The size of the last\n"
152 "partition can be specified as '-' for the remaining space of the device.\n"
153 "This format is the same as used in the Linux kernel for cmdline mtd partitions.\n"
154 "\n"
155 "Note: That this command has to be reworked and will probably change it's API.";
157 U_BOOT_CMD_START(addpart)
158 .cmd = do_addpart,
159 .usage = "adds a partition table to a device",
160 U_BOOT_CMD_HELP(cmd_addpart_help)
161 U_BOOT_CMD_END
163 /** @page addpart_command addpart Add a partition to a device
165 * Usage is: addpart \<device> \<partition description>
167 * Adds a partition description to a device. The partition description has the
168 * form
170 * size1(name1)[ro],size2(name2)[ro],...
172 * \<device> is the device name under. Sizes can be given in decimal or - if
173 * prefixed with 0x - in hex. Sizes can have an optional suffix K,M,G. The
174 * size of the last partition can be specified as '-' for the remaining space
175 * of the device.
177 * @note The format is the same as used in the Linux kernel for cmdline mtd
178 * partitions.
180 * @note This command has to be reworked and will probably change it's API.
183 static int do_delpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
185 int i, err;
187 for (i = 1; i < argc; i++) {
188 err = devfs_del_partition(basename(argv[i]));
189 if (err) {
190 printf("cannot delete %s: %s\n", argv[i], strerror(-err));
191 break;
195 return 1;
198 static const __maybe_unused char cmd_delpart_help[] =
199 "Usage: delpart FILE...\n"
200 "Delete partitions previously added to a device with addpart.\n";
202 U_BOOT_CMD_START(delpart)
203 .cmd = do_delpart,
204 .usage = "delete partition(s)",
205 U_BOOT_CMD_HELP(cmd_delpart_help)
206 U_BOOT_CMD_END
208 /** @page delpart_command delpart Delete a partition
210 * Usage is: delpart \<partions>
212 * Delete a partition previously added to a device with addpart.