// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY UCLASS_BLK

#include <common.h>
#include <blk.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <part.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
#include <linux/err.h>

static const char *if_typename_str[IF_TYPE_COUNT] = {
	[IF_TYPE_IDE]		= "ide",
	[IF_TYPE_SCSI]		= "scsi",
	[IF_TYPE_ATAPI]		= "atapi",
	[IF_TYPE_USB]		= "usb",
	[IF_TYPE_DOC]		= "doc",
	[IF_TYPE_MMC]		= "mmc",
	[IF_TYPE_SD]		= "sd",
	[IF_TYPE_SATA]		= "sata",
	[IF_TYPE_HOST]		= "host",
	[IF_TYPE_NVME]		= "nvme",
	[IF_TYPE_EFI_MEDIA]	= "efi",
	[IF_TYPE_EFI_LOADER]	= "efiloader",
	[IF_TYPE_VIRTIO]	= "virtio",
	[IF_TYPE_PVBLOCK]	= "pvblock",
};

static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
	[IF_TYPE_IDE]		= UCLASS_IDE,
	[IF_TYPE_SCSI]		= UCLASS_SCSI,
	[IF_TYPE_ATAPI]		= UCLASS_INVALID,
	[IF_TYPE_USB]		= UCLASS_MASS_STORAGE,
	[IF_TYPE_DOC]		= UCLASS_INVALID,
	[IF_TYPE_MMC]		= UCLASS_MMC,
	[IF_TYPE_SD]		= UCLASS_INVALID,
	[IF_TYPE_SATA]		= UCLASS_AHCI,
	[IF_TYPE_HOST]		= UCLASS_ROOT,
	[IF_TYPE_NVME]		= UCLASS_NVME,
	[IF_TYPE_EFI_MEDIA]	= UCLASS_EFI_MEDIA,
	[IF_TYPE_EFI_LOADER]	= UCLASS_EFI_LOADER,
	[IF_TYPE_VIRTIO]	= UCLASS_VIRTIO,
	[IF_TYPE_PVBLOCK]	= UCLASS_PVBLOCK,
};

static enum if_type if_typename_to_iftype(const char *if_typename)
{
	int i;

	for (i = 0; i < IF_TYPE_COUNT; i++) {
		if (if_typename_str[i] &&
		    !strcmp(if_typename, if_typename_str[i]))
			return i;
	}

	return IF_TYPE_UNKNOWN;
}

static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
{
	return if_type_uclass_id[if_type];
}

const char *blk_get_if_type_name(enum if_type if_type)
{
	return if_typename_str[if_type];
}

struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
{
	struct blk_desc *desc;
	struct udevice *dev;
	int ret;

	ret = blk_get_device(if_type, devnum, &dev);
	if (ret)
		return NULL;
	desc = dev_get_uclass_plat(dev);

	return desc;
}

/*
 * This function is complicated with driver model. We look up the interface
 * name in a local table. This gives us an interface type which we can match
 * against the uclass of the block device's parent.
 */
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
{
	enum uclass_id uclass_id;
	enum if_type if_type;
	struct udevice *dev;
	struct uclass *uc;
	int ret;

	if_type = if_typename_to_iftype(if_typename);
	if (if_type == IF_TYPE_UNKNOWN) {
		debug("%s: Unknown interface type '%s'\n", __func__,
		      if_typename);
		return NULL;
	}
	uclass_id = if_type_to_uclass_id(if_type);
	if (uclass_id == UCLASS_INVALID) {
		debug("%s: Unknown uclass for interface type'\n",
		      if_typename_str[if_type]);
		return NULL;
	}

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return NULL;
	uclass_foreach_dev(dev, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
		if (desc->devnum != devnum)
			continue;

		/* Find out the parent device uclass */
		if (device_get_uclass_id(dev->parent) != uclass_id) {
			debug("%s: parent uclass %d, this dev %d\n", __func__,
			      device_get_uclass_id(dev->parent), uclass_id);
			continue;
		}

		if (device_probe(dev))
			return NULL;

		debug("%s: Device desc %p\n", __func__, desc);
		return desc;
	}
	debug("%s: No device found\n", __func__);

	return NULL;
}

/**
 * blk_get_by_device() - Get the block device descriptor for the given device
 * @dev:	Instance of a storage device
 *
 * Return: With block device descriptor on success , NULL if there is no such
 *	   block device.
 */
struct blk_desc *blk_get_by_device(struct udevice *dev)
{
	struct udevice *child_dev;

	device_foreach_child(child_dev, dev) {
		if (device_get_uclass_id(child_dev) != UCLASS_BLK)
			continue;

		return dev_get_uclass_plat(child_dev);
	}

	debug("%s: No block device found\n", __func__);

	return NULL;
}

/**
 * get_desc() - Get the block device descriptor for the given device number
 *
 * @if_type:	Interface type
 * @devnum:	Device number (0 = first)
 * @descp:	Returns block device descriptor on success
 * Return: 0 on success, -ENODEV if there is no such device and no device
 * with a higher device number, -ENOENT if there is no such device but there
 * is one with a higher number, or other -ve on other error.
 */
static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
{
	bool found_more = false;
	struct udevice *dev;
	struct uclass *uc;
	int ret;

	*descp = NULL;
	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev(dev, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
		if (desc->if_type == if_type) {
			if (desc->devnum == devnum) {
				ret = device_probe(dev);
				if (ret)
					return ret;

				*descp = desc;
				return 0;
			} else if (desc->devnum > devnum) {
				found_more = true;
			}
		}
	}

	return found_more ? -ENOENT : -ENODEV;
}

int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
{
	struct udevice *dev;
	int ret;

	ret = blk_get_device(if_type, devnum, &dev);
	if (ret)
		return ret;

	return blk_select_hwpart(dev, hwpart);
}

int blk_list_part(enum if_type if_type)
{
	struct blk_desc *desc;
	int devnum, ok;
	int ret;

	for (ok = 0, devnum = 0;; ++devnum) {
		ret = get_desc(if_type, devnum, &desc);
		if (ret == -ENODEV)
			break;
		else if (ret)
			continue;
		if (desc->part_type != PART_TYPE_UNKNOWN) {
			++ok;
			if (devnum)
				putc('\n');
			part_print(desc);
		}
	}
	if (!ok)
		return -ENODEV;

	return 0;
}

int blk_print_part_devnum(enum if_type if_type, int devnum)
{
	struct blk_desc *desc;
	int ret;

	ret = get_desc(if_type, devnum, &desc);
	if (ret)
		return ret;
	if (desc->type == DEV_TYPE_UNKNOWN)
		return -ENOENT;
	part_print(desc);

	return 0;
}

void blk_list_devices(enum if_type if_type)
{
	struct blk_desc *desc;
	int ret;
	int i;

	for (i = 0;; ++i) {
		ret = get_desc(if_type, i, &desc);
		if (ret == -ENODEV)
			break;
		else if (ret)
			continue;
		if (desc->type == DEV_TYPE_UNKNOWN)
			continue;  /* list only known devices */
		printf("Device %d: ", i);
		dev_print(desc);
	}
}

int blk_print_device_num(enum if_type if_type, int devnum)
{
	struct blk_desc *desc;
	int ret;

	ret = get_desc(if_type, devnum, &desc);
	if (ret)
		return ret;
	printf("\nIDE device %d: ", devnum);
	dev_print(desc);

	return 0;
}

int blk_show_device(enum if_type if_type, int devnum)
{
	struct blk_desc *desc;
	int ret;

	printf("\nDevice %d: ", devnum);
	ret = get_desc(if_type, devnum, &desc);
	if (ret == -ENODEV || ret == -ENOENT) {
		printf("unknown device\n");
		return -ENODEV;
	}
	if (ret)
		return ret;
	dev_print(desc);

	if (desc->type == DEV_TYPE_UNKNOWN)
		return -ENOENT;

	return 0;
}

ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
		      lbaint_t blkcnt, void *buffer)
{
	struct blk_desc *desc;
	ulong n;
	int ret;

	ret = get_desc(if_type, devnum, &desc);
	if (ret)
		return ret;
	n = blk_dread(desc, start, blkcnt, buffer);
	if (IS_ERR_VALUE(n))
		return n;

	return n;
}

ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
		       lbaint_t blkcnt, const void *buffer)
{
	struct blk_desc *desc;
	int ret;

	ret = get_desc(if_type, devnum, &desc);
	if (ret)
		return ret;
	return blk_dwrite(desc, start, blkcnt, buffer);
}

int blk_select_hwpart(struct udevice *dev, int hwpart)
{
	const struct blk_ops *ops = blk_get_ops(dev);

	if (!ops)
		return -ENOSYS;
	if (!ops->select_hwpart)
		return 0;

	return ops->select_hwpart(dev, hwpart);
}

int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
{
	return blk_select_hwpart(desc->bdev, hwpart);
}

int blk_first_device(int if_type, struct udevice **devp)
{
	struct blk_desc *desc;
	int ret;

	ret = uclass_find_first_device(UCLASS_BLK, devp);
	if (ret)
		return ret;
	if (!*devp)
		return -ENODEV;
	do {
		desc = dev_get_uclass_plat(*devp);
		if (desc->if_type == if_type)
			return 0;
		ret = uclass_find_next_device(devp);
		if (ret)
			return ret;
	} while (*devp);

	return -ENODEV;
}

int blk_next_device(struct udevice **devp)
{
	struct blk_desc *desc;
	int ret, if_type;

	desc = dev_get_uclass_plat(*devp);
	if_type = desc->if_type;
	do {
		ret = uclass_find_next_device(devp);
		if (ret)
			return ret;
		if (!*devp)
			return -ENODEV;
		desc = dev_get_uclass_plat(*devp);
		if (desc->if_type == if_type)
			return 0;
	} while (1);
}

int blk_find_device(int if_type, int devnum, struct udevice **devp)
{
	struct uclass *uc;
	struct udevice *dev;
	int ret;

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev(dev, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
		if (desc->if_type == if_type && desc->devnum == devnum) {
			*devp = dev;
			return 0;
		}
	}

	return -ENODEV;
}

int blk_get_device(int if_type, int devnum, struct udevice **devp)
{
	int ret;

	ret = blk_find_device(if_type, devnum, devp);
	if (ret)
		return ret;

	return device_probe(*devp);
}

unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
			lbaint_t blkcnt, void *buffer)
{
	struct udevice *dev = block_dev->bdev;
	const struct blk_ops *ops = blk_get_ops(dev);
	ulong blks_read;

	if (!ops->read)
		return -ENOSYS;

	if (blkcache_read(block_dev->if_type, block_dev->devnum,
			  start, blkcnt, block_dev->blksz, buffer))
		return blkcnt;
	blks_read = ops->read(dev, start, blkcnt, buffer);
	if (blks_read == blkcnt)
		blkcache_fill(block_dev->if_type, block_dev->devnum,
			      start, blkcnt, block_dev->blksz, buffer);

	return blks_read;
}

unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
			 lbaint_t blkcnt, const void *buffer)
{
	struct udevice *dev = block_dev->bdev;
	const struct blk_ops *ops = blk_get_ops(dev);

	if (!ops->write)
		return -ENOSYS;

	blkcache_invalidate(block_dev->if_type, block_dev->devnum);
	return ops->write(dev, start, blkcnt, buffer);
}

unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
			 lbaint_t blkcnt)
{
	struct udevice *dev = block_dev->bdev;
	const struct blk_ops *ops = blk_get_ops(dev);

	if (!ops->erase)
		return -ENOSYS;

	blkcache_invalidate(block_dev->if_type, block_dev->devnum);
	return ops->erase(dev, start, blkcnt);
}

int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
{
	struct udevice *dev;
	enum uclass_id id;
	int ret;

	device_find_first_child(parent, &dev);
	if (!dev) {
		debug("%s: No block device found for parent '%s'\n", __func__,
		      parent->name);
		return -ENODEV;
	}
	id = device_get_uclass_id(dev);
	if (id != UCLASS_BLK) {
		debug("%s: Incorrect uclass %s for block device '%s'\n",
		      __func__, uclass_get_name(id), dev->name);
		return -ENOTBLK;
	}
	ret = device_probe(dev);
	if (ret)
		return ret;
	*devp = dev;

	return 0;
}

const char *blk_get_devtype(struct udevice *dev)
{
	struct udevice *parent = dev_get_parent(dev);

	return uclass_get_name(device_get_uclass_id(parent));
};

int blk_find_max_devnum(enum if_type if_type)
{
	struct udevice *dev;
	int max_devnum = -ENODEV;
	struct uclass *uc;
	int ret;

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev(dev, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		if (desc->if_type == if_type && desc->devnum > max_devnum)
			max_devnum = desc->devnum;
	}

	return max_devnum;
}

int blk_next_free_devnum(enum if_type if_type)
{
	int ret;

	ret = blk_find_max_devnum(if_type);
	if (ret == -ENODEV)
		return 0;
	if (ret < 0)
		return ret;

	return ret + 1;
}

static int blk_flags_check(struct udevice *dev, enum blk_flag_t req_flags)
{
	const struct blk_desc *desc = dev_get_uclass_plat(dev);
	enum blk_flag_t flags;

	flags = desc->removable ? BLKF_REMOVABLE : BLKF_FIXED;

	return flags & req_flags ? 0 : 1;
}

int blk_find_first(enum blk_flag_t flags, struct udevice **devp)
{
	int ret;

	for (ret = uclass_find_first_device(UCLASS_BLK, devp);
	     *devp && !blk_flags_check(*devp, flags);
	     ret = uclass_find_next_device(devp))
		return 0;

	return -ENODEV;
}

int blk_find_next(enum blk_flag_t flags, struct udevice **devp)
{
	int ret;

	for (ret = uclass_find_next_device(devp);
	     *devp && !blk_flags_check(*devp, flags);
	     ret = uclass_find_next_device(devp))
		return 0;

	return -ENODEV;
}

int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp)
{
	int ret;

	for (ret = uclass_first_device_err(UCLASS_BLK, devp);
	     !ret;
	     ret = uclass_next_device_err(devp)) {
		if (!blk_flags_check(*devp, flags))
			return 0;
	}

	return -ENODEV;
}

int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp)
{
	int ret;

	for (ret = uclass_next_device_err(devp);
	     !ret;
	     ret = uclass_next_device_err(devp)) {
		if (!blk_flags_check(*devp, flags))
			return 0;
	}

	return -ENODEV;
}

int blk_count_devices(enum blk_flag_t flag)
{
	struct udevice *dev;
	int count = 0;

	blk_foreach_probe(flag, dev)
		count++;

	return count;
}

static int blk_claim_devnum(enum if_type if_type, int devnum)
{
	struct udevice *dev;
	struct uclass *uc;
	int ret;

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev(dev, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		if (desc->if_type == if_type && desc->devnum == devnum) {
			int next = blk_next_free_devnum(if_type);

			if (next < 0)
				return next;
			desc->devnum = next;
			return 0;
		}
	}

	return -ENOENT;
}

int blk_create_device(struct udevice *parent, const char *drv_name,
		      const char *name, int if_type, int devnum, int blksz,
		      lbaint_t lba, struct udevice **devp)
{
	struct blk_desc *desc;
	struct udevice *dev;
	int ret;

	if (devnum == -1) {
		devnum = blk_next_free_devnum(if_type);
	} else {
		ret = blk_claim_devnum(if_type, devnum);
		if (ret < 0 && ret != -ENOENT)
			return ret;
	}
	if (devnum < 0)
		return devnum;
	ret = device_bind_driver(parent, drv_name, name, &dev);
	if (ret)
		return ret;
	desc = dev_get_uclass_plat(dev);
	desc->if_type = if_type;
	desc->blksz = blksz;
	desc->log2blksz = LOG2(desc->blksz);
	desc->lba = lba;
	desc->part_type = PART_TYPE_UNKNOWN;
	desc->bdev = dev;
	desc->devnum = devnum;
	*devp = dev;

	return 0;
}

int blk_create_devicef(struct udevice *parent, const char *drv_name,
		       const char *name, int if_type, int devnum, int blksz,
		       lbaint_t lba, struct udevice **devp)
{
	char dev_name[30], *str;
	int ret;

	snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
	str = strdup(dev_name);
	if (!str)
		return -ENOMEM;

	ret = blk_create_device(parent, drv_name, str, if_type, devnum,
				blksz, lba, devp);
	if (ret) {
		free(str);
		return ret;
	}
	device_set_name_alloced(*devp);

	return 0;
}

int blk_probe_or_unbind(struct udevice *dev)
{
	int ret;

	ret = device_probe(dev);
	if (ret) {
		log_debug("probing %s failed\n", dev->name);
		device_unbind(dev);
	}

	return ret;
}

int blk_unbind_all(int if_type)
{
	struct uclass *uc;
	struct udevice *dev, *next;
	int ret;

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev_safe(dev, next, uc) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		if (desc->if_type == if_type) {
			ret = device_remove(dev, DM_REMOVE_NORMAL);
			if (ret)
				return ret;
			ret = device_unbind(dev);
			if (ret)
				return ret;
		}
	}

	return 0;
}

static int blk_post_probe(struct udevice *dev)
{
	if (CONFIG_IS_ENABLED(PARTITIONS) &&
	    IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) {
		struct blk_desc *desc = dev_get_uclass_plat(dev);

		part_init(desc);

		if (desc->part_type != PART_TYPE_UNKNOWN &&
		    part_create_block_devices(dev))
			debug("*** creating partitions failed\n");
	}

	return 0;
}

UCLASS_DRIVER(blk) = {
	.id		= UCLASS_BLK,
	.name		= "blk",
	.post_probe	= blk_post_probe,
	.per_device_plat_auto	= sizeof(struct blk_desc),
};
