summaryrefslogtreecommitdiff
path: root/cmd/read.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-03-20 16:31:52 -0400
committerTom Rini <trini@konsulko.com>2023-03-20 16:31:52 -0400
commit95e0f9ac095bb250024c7648c3b0733d0a61a189 (patch)
treed2b62604ad6de6ea81afd15a5dc41a5921de1a8f /cmd/read.c
parentcefd0449d6df77eb0edb8a6800a441f9cd4e3653 (diff)
parent20c5c45e1c81657ef79dfc6e29f07e5f45f5b01f (diff)
Merge branch '2023-03-17-improve-read-command-add-write-command' into next
To quote the author: The first patch simplies do_read somewhat by making use of an existing helper instead of parsing the dev_part string manually. As a bonus (and my actual motivation), it now understands dev#partname syntax - hard-coded partition numbers are so last decade. I also need the symmetrical operation, being able to write to a named raw partition, and fortunately it doesn't require that many lines of code to implement that. There's a very minor change in the error reporting due to using cmdtp->name to generate the new messages, but I don't think "Error reading blocks" offers much that "read error" doesn't. New in v2: the last three patches add documentation, ensure CMD_WRITE is set for sandbox and adds some basic test cases for the various ways of accessing the partitions (by number, name, or as raw offset within the whole disk). v3: Add Simon's R-b to patches 2, 4, 5, fixup whitespace in patch 5. I don't want to duplicate the documentation, but I can see the value in 'write' having its own entry in the TOC, so I added a stub write.rst that just refers to the read.rst, which then explicitly documents both.
Diffstat (limited to 'cmd/read.c')
-rw-r--r--cmd/read.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/cmd/read.c b/cmd/read.c
index fecfadaa1fa..1218e7acfd0 100644
--- a/cmd/read.c
+++ b/cmd/read.c
@@ -13,70 +13,69 @@
#include <mapmem.h>
#include <part.h>
-int do_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+static int
+do_rw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- char *ep;
struct blk_desc *dev_desc = NULL;
- int dev;
- int part = 0;
struct disk_partition part_info;
- ulong offset = 0u;
- ulong limit = 0u;
+ ulong offset, limit;
+ uint blk, cnt, res;
void *addr;
- uint blk;
- uint cnt;
+ int part;
if (argc != 6) {
cmd_usage(cmdtp);
return 1;
}
- dev = (int)hextoul(argv[2], &ep);
- if (*ep) {
- if (*ep != ':') {
- printf("Invalid block device %s\n", argv[2]);
- return 1;
- }
- part = (int)hextoul(++ep, NULL);
- }
-
- dev_desc = blk_get_dev(argv[1], dev);
- if (dev_desc == NULL) {
- printf("Block device %s %d not supported\n", argv[1], dev);
+ part = part_get_info_by_dev_and_name_or_num(argv[1], argv[2],
+ &dev_desc, &part_info, 1);
+ if (part < 0)
return 1;
- }
addr = map_sysmem(hextoul(argv[3], NULL), 0);
blk = hextoul(argv[4], NULL);
cnt = hextoul(argv[5], NULL);
- if (part != 0) {
- if (part_get_info(dev_desc, part, &part_info)) {
- printf("Cannot find partition %d\n", part);
- return 1;
- }
+ if (part > 0) {
offset = part_info.start;
limit = part_info.size;
} else {
/* Largest address not available in struct blk_desc. */
+ offset = 0;
limit = ~0;
}
if (cnt + blk > limit) {
- printf("Read out of range\n");
+ printf("%s out of range\n", cmdtp->name);
return 1;
}
- if (blk_dread(dev_desc, offset + blk, cnt, addr) != cnt) {
- printf("Error reading blocks\n");
+ if (IS_ENABLED(CONFIG_CMD_WRITE) && !strcmp(cmdtp->name, "write"))
+ res = blk_dwrite(dev_desc, offset + blk, cnt, addr);
+ else
+ res = blk_dread(dev_desc, offset + blk, cnt, addr);
+
+ if (res != cnt) {
+ printf("%s error\n", cmdtp->name);
return 1;
}
return 0;
}
+#ifdef CONFIG_CMD_READ
U_BOOT_CMD(
- read, 6, 0, do_read,
+ read, 6, 0, do_rw,
"Load binary data from a partition",
- "<interface> <dev[:part]> addr blk# cnt"
+ "<interface> <dev[:part|#partname]> addr blk# cnt"
+);
+#endif
+
+#ifdef CONFIG_CMD_WRITE
+U_BOOT_CMD(
+ write, 6, 0, do_rw,
+ "Store binary data to a partition",
+ "<interface> <dev[:part|#partname]> addr blk# cnt"
);
+#endif