// 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 <sandboxblockdev.h>
#include <dm/device_compat.h>
#include <linux/errno.h>

static int host_curr_device = -1;

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[])
{
	if (argc < 2 || argc > 3)
		return CMD_RET_USAGE;
	char *ep;
	char *dev_str = argv[1];
	char *file = argc >= 3 ? argv[2] : NULL;
	int dev = simple_strtoul(dev_str, &ep, 16);
	if (*ep) {
		printf("** Bad device specification %s **\n", dev_str);
		return CMD_RET_USAGE;
	}
	return !!host_dev_bind(dev, file);
}

static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	if (argc < 1 || argc > 2)
		return CMD_RET_USAGE;
	int min_dev = 0;
	int max_dev = CONFIG_HOST_MAX_DEVICES - 1;
	if (argc >= 2) {
		char *ep;
		char *dev_str = argv[1];
		int dev = simple_strtoul(dev_str, &ep, 16);
		if (*ep) {
			printf("** Bad device specification %s **\n", dev_str);
			return CMD_RET_USAGE;
		}
		min_dev = dev;
		max_dev = dev;
	}
	int dev;
	printf("%3s %12s %s\n", "dev", "blocks", "path");
	for (dev = min_dev; dev <= max_dev; dev++) {
		struct blk_desc *blk_dev;
		int ret;

		printf("%3d ", dev);
		ret = host_get_dev_err(dev, &blk_dev);
		if (ret) {
			if (ret == -ENOENT)
				puts("Not bound to a backing file\n");
			else if (ret == -ENODEV)
				puts("Invalid host device number\n");

			continue;
		}
		struct host_block_dev *host_dev;

#ifdef CONFIG_BLK
		host_dev = dev_get_platdata(blk_dev->bdev);
#else
		host_dev = blk_dev->priv;
#endif
		printf("%12lu %s\n", (unsigned long)blk_dev->lba,
		       host_dev->filename);
	}
	return 0;
}

static int do_host_dev(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	int dev;
	char *ep;
	struct blk_desc *blk_dev;
	int ret;

	if (argc < 1 || argc > 3)
		return CMD_RET_USAGE;

	if (argc == 1) {
		if (host_curr_device < 0) {
			printf("No current host device\n");
			return 1;
		}
		printf("Current host device %d\n", host_curr_device);
		return 0;
	}

	dev = simple_strtoul(argv[1], &ep, 16);
	if (*ep) {
		printf("** Bad device specification %s **\n", argv[2]);
		return CMD_RET_USAGE;
	}

	ret = host_get_dev_err(dev, &blk_dev);
	if (ret) {
		if (ret == -ENOENT)
			puts("Not bound to a backing file\n");
		else if (ret == -ENODEV)
			puts("Invalid host device number\n");

		return 1;
	}

	host_curr_device = 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, 3, 0, do_host_bind, "", ""),
	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 <dev> [<filename>] - bind \"host\" device to file\n"
	"host info [<dev>]            - show device binding & info\n"
	"host dev [<dev>] - 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"
);
