// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for sandbox host interface, used to access files on the host which
 * contain partitions and filesystem
 *
 * Copyright 2022 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY UCLASS_HOST

#include <blk.h>
#include <bootdev.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <os.h>
#include <sandbox_host.h>
#include <dm/device-internal.h>

static int host_sb_attach_file(struct udevice *dev, const char *filename)
{
	struct host_sb_plat *plat = dev_get_plat(dev);
	struct blk_desc *desc;
	struct udevice *blk;
	int ret, fd;
	off_t size;
	char *fname;

	if (!filename)
		return -EINVAL;

	if (plat->fd)
		return log_msg_ret("fd", -EEXIST);

	/* Sanity check that host_sb_bind() has been used */
	ret = blk_find_from_parent(dev, &blk);
	if (ret)
		return ret;

	fd = os_open(filename, OS_O_RDWR);
	if (fd == -1) {
		printf("Failed to access host backing file '%s', trying read-only\n",
		       filename);
		fd = os_open(filename, OS_O_RDONLY);
		if (fd == -1) {
			printf("- still failed\n");
			return log_msg_ret("open", -ENOENT);
		}
	}

	fname = strdup(filename);
	if (!fname) {
		ret = -ENOMEM;
		goto err_fname;
	}

	size = os_filesize(fd);
	desc = dev_get_uclass_plat(blk);
	if (size % desc->blksz) {
		printf("The size of host backing file '%s' is not multiple of "
		       "the device block size\n", filename);
		ret = -EINVAL;
		goto err_fname;
	}
	desc->lba = size / desc->blksz;

	/* write this in last, when nothing can go wrong */
	plat = dev_get_plat(dev);
	plat->fd = fd;
	plat->filename = fname;

	return 0;

err_fname:
	os_close(fd);

	return ret;
}

static int host_sb_detach_file(struct udevice *dev)
{
	struct host_sb_plat *plat = dev_get_plat(dev);
	int ret;

	if (!plat->fd)
		return log_msg_ret("fd", -ENOENT);

	ret = device_remove(dev, DM_REMOVE_NORMAL);
	if (ret)
		return log_msg_ret("rem", ret);

	/* Unbind all children */
	ret = device_chld_unbind(dev, NULL);
	if (ret)
		return log_msg_ret("unb", ret);

	os_close(plat->fd);
	plat->fd = 0;
	free(plat->filename);
	free(plat->label);

	return 0;
}

static int host_sb_bind(struct udevice *dev)
{
	struct udevice *blk, *bdev;
	struct blk_desc *desc;
	int ret;

	ret = blk_create_devicef(dev, "sandbox_host_blk", "blk", UCLASS_HOST,
				 dev_seq(dev), DEFAULT_BLKSZ, 0, &blk);
	if (ret)
		return log_msg_ret("blk", ret);

	desc = dev_get_uclass_plat(blk);
	snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
	snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
	snprintf(desc->revision, BLK_REV_SIZE, "1.0");

	if (CONFIG_IS_ENABLED(BOOTSTD)) {
		ret = bootdev_bind(dev, "host_bootdev", "bootdev", &bdev);
		if (ret)
			return log_msg_ret("bd", ret);
	}

	return 0;
}

static struct host_ops host_sb_ops = {
	.attach_file	= host_sb_attach_file,
	.detach_file	= host_sb_detach_file,
};

static const struct udevice_id host_ids[] = {
	{ .compatible = "sandbox,host" },
	{ }
};

U_BOOT_DRIVER(host_sb_drv) = {
	.name		= "host_sb_drv",
	.id		= UCLASS_HOST,
	.of_match	= host_ids,
	.ops		= &host_sb_ops,
	.bind		= host_sb_bind,
	.plat_auto	= sizeof(struct host_sb_plat),
};
