123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (c) 2012, Google Inc.
- */
- #include <common.h>
- #include <command.h>
- #include <dm.h>
- #include <fs.h>
- #include <part.h>
- #include <sandbox_host.h>
- #include <dm/device_compat.h>
- #include <dm/device-internal.h>
- #include <dm/uclass-internal.h>
- #include <linux/errno.h>
- static int do_host_load(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
- }
- static int do_host_ls(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
- }
- static int do_host_size(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- return do_size(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
- }
- static int do_host_save(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
- }
- static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- bool removable = false;
- struct udevice *dev;
- const char *label;
- char *file;
- int ret;
- /* Skip 'bind' */
- argc--;
- argv++;
- if (argc < 2)
- return CMD_RET_USAGE;
- if (!strcmp(argv[0], "-r")) {
- removable = true;
- argc--;
- argv++;
- }
- if (argc > 2)
- return CMD_RET_USAGE;
- label = argv[0];
- file = argc > 1 ? argv[1] : NULL;
- ret = host_create_attach_file(label, file, removable, &dev);
- if (ret) {
- printf("Cannot create device / bind file\n");
- return CMD_RET_FAILURE;
- }
- return 0;
- }
- /**
- * parse_host_label() - Parse a device label or sequence number
- *
- * This shows an error if it returns NULL
- *
- * @label: String containing the label or sequence number
- * Returns: Associated device, or NULL if not found
- */
- static struct udevice *parse_host_label(const char *label)
- {
- struct udevice *dev;
- dev = host_find_by_label(label);
- if (!dev) {
- int devnum;
- char *ep;
- devnum = hextoul(label, &ep);
- if (*ep ||
- uclass_find_device_by_seq(UCLASS_HOST, devnum, &dev)) {
- printf("No such device '%s'\n", label);
- return NULL;
- }
- }
- return dev;
- }
- static int do_host_unbind(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- struct udevice *dev;
- const char *label;
- int ret;
- if (argc < 2)
- return CMD_RET_USAGE;
- label = argv[1];
- dev = parse_host_label(label);
- if (!dev)
- return CMD_RET_FAILURE;
- ret = host_detach_file(dev);
- if (ret) {
- printf("Cannot detach file (err=%d)\n", ret);
- return CMD_RET_FAILURE;
- }
- ret = device_unbind(dev);
- if (ret) {
- printf("Cannot attach file\n");
- ret = device_unbind(dev);
- if (ret)
- printf("Cannot unbind device '%s'\n", dev->name);
- return CMD_RET_FAILURE;
- }
- return 0;
- }
- static void show_host_dev(struct udevice *dev)
- {
- struct host_sb_plat *plat = dev_get_plat(dev);
- struct blk_desc *desc;
- struct udevice *blk;
- int ret;
- printf("%3d ", dev_seq(dev));
- if (!plat->fd) {
- printf("Not bound to a backing file\n");
- return;
- }
- ret = blk_get_from_parent(dev, &blk);
- if (ret) /* cannot happen */
- return;
- desc = dev_get_uclass_plat(blk);
- printf("%12lu %-15s %s\n", (unsigned long)desc->lba, plat->label,
- plat->filename);
- }
- static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- struct udevice *dev;
- if (argc < 1)
- return CMD_RET_USAGE;
- dev = NULL;
- if (argc >= 2) {
- dev = parse_host_label(argv[1]);
- if (!dev)
- return CMD_RET_FAILURE;
- }
- printf("%3s %12s %-15s %s\n", "dev", "blocks", "label", "path");
- if (dev) {
- show_host_dev(dev);
- } else {
- struct uclass *uc;
- uclass_id_foreach_dev(UCLASS_HOST, dev, uc)
- show_host_dev(dev);
- }
- return 0;
- }
- static int do_host_dev(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- struct udevice *dev;
- const char *label;
- if (argc < 1 || argc > 3)
- return CMD_RET_USAGE;
- if (argc == 1) {
- struct host_sb_plat *plat;
- dev = host_get_cur_dev();
- if (!dev) {
- printf("No current host device\n");
- return CMD_RET_FAILURE;
- }
- plat = dev_get_plat(dev);
- printf("Current host device: %d: %s\n", dev_seq(dev),
- plat->label);
- return 0;
- }
- label = argv[1];
- dev = parse_host_label(argv[1]);
- if (!dev)
- return CMD_RET_FAILURE;
- host_set_cur_dev(dev);
- return 0;
- }
- static struct cmd_tbl cmd_host_sub[] = {
- U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""),
- U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
- U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
- U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
- U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
- U_BOOT_CMD_MKENT(unbind, 4, 0, do_host_unbind, "", ""),
- U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
- U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
- };
- static int do_host(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- struct cmd_tbl *c;
- /* Skip past 'host' */
- argc--;
- argv++;
- c = find_cmd_tbl(argv[0], cmd_host_sub, ARRAY_SIZE(cmd_host_sub));
- if (c)
- return c->cmd(cmdtp, flag, argc, argv);
- else
- return CMD_RET_USAGE;
- }
- U_BOOT_CMD(
- host, 8, 1, do_host,
- "Miscellaneous host commands",
- "load hostfs - <addr> <filename> [<bytes> <offset>] - "
- "load a file from host\n"
- "host ls hostfs - <filename> - list files on host\n"
- "host save hostfs - <addr> <filename> <bytes> [<offset>] - "
- "save a file to host\n"
- "host size hostfs - <filename> - determine size of file on host\n"
- "host bind [-r] <label> [<filename>] - bind \"host\" device to file\n"
- " -r = mark as removable\n"
- "host unbind <label> - unbind file from \"host\" device\n"
- "host info [<label>] - show device binding & info\n"
- "host dev [<label>] - set or retrieve the current host device\n"
- "host commands use the \"hostfs\" device. The \"host\" device is used\n"
- "with standard IO commands such as fatls or ext2load"
- );
|