// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#include <blk.h>
#include <command.h>
#include <env.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <part.h>
#include <ubifs_uboot.h>
#include <dm/uclass.h>

#undef	PART_DEBUG

#ifdef	PART_DEBUG
#define	PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif

/* Check all partition types */
#define PART_TYPE_ALL		-1

/**
 * part_driver_get_type() - Get a driver given its type
 *
 * @part_type: Partition type to find the driver for
 * Return: Driver for that type, or NULL if none
 */
static struct part_driver *part_driver_get_type(int part_type)
{
	struct part_driver *drv =
		ll_entry_start(struct part_driver, part_driver);
	const int n_ents = ll_entry_count(struct part_driver, part_driver);
	struct part_driver *entry;

	for (entry = drv; entry != drv + n_ents; entry++) {
		if (part_type == entry->part_type)
			return entry;
	}

	/* Not found */
	return NULL;
}

struct part_driver *part_driver_lookup_type(struct blk_desc *desc)
{
	struct part_driver *drv =
		ll_entry_start(struct part_driver, part_driver);
	const int n_ents = ll_entry_count(struct part_driver, part_driver);
	struct part_driver *entry;

	if (desc->part_type == PART_TYPE_UNKNOWN) {
		for (entry = drv; entry != drv + n_ents; entry++) {
			int ret;

			ret = entry->test(desc);
			if (!ret) {
				desc->part_type = entry->part_type;
				return entry;
			}
		}
	} else {
		return part_driver_get_type(desc->part_type);
	}

	/* Not found */
	return NULL;
}

static void disk_partition_clr(struct disk_partition *info)
{
	/* The common case is no UUID support */
	disk_partition_clr_uuid(info);
	disk_partition_clr_type_guid(info);
	info->name[0] = '\0';
	info->type[0] = '\0';
}

int part_driver_get_info(struct part_driver *drv, struct blk_desc *desc, int part,
			 struct disk_partition *info)
{
	if (!drv->get_info) {
		log_debug("## Driver %s does not have the get_info() method\n",
			  drv->name);
		return -ENOSYS;
	}

	disk_partition_clr(info);
	return drv->get_info(desc, part, info);
}

int part_get_type_by_name(const char *name)
{
	struct part_driver *drv =
		ll_entry_start(struct part_driver, part_driver);
	const int n_ents = ll_entry_count(struct part_driver, part_driver);
	struct part_driver *entry;

	for (entry = drv; entry != drv + n_ents; entry++) {
		if (!strcasecmp(name, entry->name))
			return entry->part_type;
	}

	/* Not found */
	return PART_TYPE_UNKNOWN;
}

/**
 * get_dev_hwpart() - Get the descriptor for a device with hardware partitions
 *
 * @ifname:	Interface name (e.g. "ide", "scsi")
 * @dev:	Device number (0 for first device on that interface, 1 for
 *		second, etc.
 * @hwpart: Hardware partition, or 0 if none (used for MMC)
 * Return: pointer to the block device, or NULL if not available, or an
 *	   error occurred.
 */
static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
	struct blk_desc *desc;
	int ret;

	if (!blk_enabled())
		return NULL;
	desc = blk_get_devnum_by_uclass_idname(ifname, dev);
	if (!desc) {
		debug("%s: No device for iface '%s', dev %d\n", __func__,
		      ifname, dev);
		return NULL;
	}
	ret = blk_dselect_hwpart(desc, hwpart);
	if (ret) {
		debug("%s: Failed to select h/w partition: err-%d\n", __func__,
		      ret);
		return NULL;
	}

	return desc;
}

struct blk_desc *blk_get_dev(const char *ifname, int dev)
{
	if (!blk_enabled())
		return NULL;

	return get_dev_hwpart(ifname, dev, 0);
}

/* ------------------------------------------------------------------------- */
/*
 * reports device info to the user
 */

#ifdef CONFIG_LBA48
typedef uint64_t lba512_t;
#else
typedef lbaint_t lba512_t;
#endif

/*
 * Overflowless variant of (block_count * mul_by / 2**right_shift)
 * when 2**right_shift > mul_by
 */
static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by,
			      int right_shift)
{
	lba512_t bc_quot, bc_rem;

	/* x * m / d == x / d * m + (x % d) * m / d */
	bc_quot = block_count >> right_shift;
	bc_rem  = block_count - (bc_quot << right_shift);
	return bc_quot * mul_by + ((bc_rem * mul_by) >> right_shift);
}

void dev_print(struct blk_desc *desc)
{
	lba512_t lba512; /* number of blocks if 512bytes block size */

	if (desc->type == DEV_TYPE_UNKNOWN) {
		puts ("not available\n");
		return;
	}

	switch (desc->uclass_id) {
	case UCLASS_SCSI:
		printf("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", desc->target,
		       desc->lun, desc->vendor, desc->product, desc->revision);
		break;
	case UCLASS_IDE:
	case UCLASS_AHCI:
		printf("Model: %s Firm: %s Ser#: %s\n", desc->vendor,
		       desc->revision, desc->product);
		break;
	case UCLASS_MMC:
	case UCLASS_USB:
	case UCLASS_NVME:
	case UCLASS_PVBLOCK:
	case UCLASS_HOST:
	case UCLASS_BLKMAP:
	case UCLASS_RKMTD:
		printf ("Vendor: %s Rev: %s Prod: %s\n",
			desc->vendor,
			desc->revision,
			desc->product);
		break;
	case UCLASS_VIRTIO:
		printf("%s VirtIO Block Device\n", desc->vendor);
		break;
	case UCLASS_EFI_MEDIA:
		printf("EFI media Block Device %d\n", desc->devnum);
		break;
	case UCLASS_INVALID:
		puts("device type unknown\n");
		return;
	default:
		printf("Unhandled device type: %i\n", desc->uclass_id);
		return;
	}
	puts ("            Type: ");
	if (desc->removable)
		puts ("Removable ");
	switch (desc->type & 0x1F) {
	case DEV_TYPE_HARDDISK:
		puts ("Hard Disk");
		break;
	case DEV_TYPE_CDROM:
		puts ("CD ROM");
		break;
	case DEV_TYPE_OPDISK:
		puts ("Optical Device");
		break;
	case DEV_TYPE_TAPE:
		puts ("Tape");
		break;
	default:
		printf("# %02X #", desc->type & 0x1F);
		break;
	}
	puts ("\n");
	if (desc->lba > 0L && desc->blksz > 0L) {
		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
		lbaint_t lba;

		lba = desc->lba;

		lba512 = lba * (desc->blksz / 512);
		/* round to 1 digit */
		/* 2048 = (1024 * 1024) / 512 MB */
		mb = lba512_muldiv(lba512, 10, 11);

		mb_quot	= mb / 10;
		mb_rem	= mb - (10 * mb_quot);

		gb = mb / 1024;
		gb_quot	= gb / 10;
		gb_rem	= gb - (10 * gb_quot);
#ifdef CONFIG_LBA48
		if (desc->lba48)
			printf ("            Supports 48-bit addressing\n");
#endif
#if defined(CONFIG_SYS_64BIT_LBA)
		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%llu x %lu)\n",
			mb_quot, mb_rem,
			gb_quot, gb_rem,
			lba,
			desc->blksz);
#else
		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)\n",
			mb_quot, mb_rem,
			gb_quot, gb_rem,
			(ulong)lba,
			desc->blksz);
#endif
	} else {
		puts ("            Capacity: not available\n");
	}
}

void part_init(struct blk_desc *desc)
{
	struct part_driver *drv =
		ll_entry_start(struct part_driver, part_driver);
	const int n_ents = ll_entry_count(struct part_driver, part_driver);
	struct part_driver *entry;

	blkcache_invalidate(desc->uclass_id, desc->devnum);

	if (desc->part_type != PART_TYPE_UNKNOWN) {
		for (entry = drv; entry != drv + n_ents; entry++) {
			if (entry->part_type == desc->part_type && !entry->test(desc))
				return;
		}
	}

	desc->part_type = PART_TYPE_UNKNOWN;
	for (entry = drv; entry != drv + n_ents; entry++) {
		int ret;

		ret = entry->test(desc);
		debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret);
		if (!ret) {
			desc->part_type = entry->part_type;
			break;
		}
	}
}

static void print_part_header(const char *type, struct blk_desc *desc)
{
#if CONFIG_IS_ENABLED(MAC_PARTITION) || \
	CONFIG_IS_ENABLED(DOS_PARTITION) || \
	CONFIG_IS_ENABLED(ISO_PARTITION) || \
	CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
	CONFIG_IS_ENABLED(EFI_PARTITION) || \
	CONFIG_IS_ENABLED(MTD_PARTITIONS)
	printf("\nPartition Map for %s device %d  --   Partition Type: %s\n\n",
	       uclass_get_name(desc->uclass_id), desc->devnum, type);
#endif /* any CONFIG_..._PARTITION */
}

void part_print(struct blk_desc *desc)
{
	struct part_driver *drv;

	drv = part_driver_lookup_type(desc);
	if (!drv) {
		printf("## Unknown partition table type %x\n",
		       desc->part_type);
		return;
	}

	PRINTF("## Testing for valid %s partition ##\n", drv->name);
	print_part_header(drv->name, desc);
	if (drv->print)
		drv->print(desc);
}

int part_get_info_by_type(struct blk_desc *desc, int part, int part_type,
			  struct disk_partition *info)
{
	struct part_driver *drv;
	int ret = -ENOENT;

	if (blk_enabled()) {
		if (part_type == PART_TYPE_UNKNOWN) {
			drv = part_driver_lookup_type(desc);
		} else {
			drv = part_driver_get_type(part_type);
		}

		if (!drv) {
			debug("## Unknown partition table type %x\n",
			      desc->part_type);
			return -EPROTONOSUPPORT;
		}

		ret = part_driver_get_info(drv, desc, part, info);
		if (ret && ret != -ENOSYS) {
			ret = -ENOENT;
		} else {
			PRINTF("## Valid %s partition found ##\n", drv->name);
		}
	}

	return ret;
}

int part_get_info(struct blk_desc *desc, int part,
		  struct disk_partition *info)
{
	return part_get_info_by_type(desc, part, PART_TYPE_UNKNOWN, info);
}

int part_get_info_whole_disk(struct blk_desc *desc,
			     struct disk_partition *info)
{
	info->start = 0;
	info->size = desc->lba;
	info->blksz = desc->blksz;
	info->bootable = 0;
	strcpy((char *)info->type, BOOT_PART_TYPE);
	strcpy((char *)info->name, "Whole Disk");
	disk_partition_clr_uuid(info);
	disk_partition_clr_type_guid(info);

	return 0;
}

int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
			  struct blk_desc **desc)
{
	char *ep;
	char *dup_str = NULL;
	const char *dev_str, *hwpart_str;
	int dev, hwpart;

	hwpart_str = strchr(dev_hwpart_str, '.');
	if (hwpart_str) {
		dup_str = strdup(dev_hwpart_str);
		dup_str[hwpart_str - dev_hwpart_str] = 0;
		dev_str = dup_str;
		hwpart_str++;
	} else {
		dev_str = dev_hwpart_str;
		hwpart = 0;
	}

	dev = hextoul(dev_str, &ep);
	if (*ep) {
		printf("** Bad device specification %s %s **\n",
		       ifname, dev_str);
		dev = -EINVAL;
		goto cleanup;
	}

	if (hwpart_str) {
		hwpart = hextoul(hwpart_str, &ep);
		if (*ep) {
			printf("** Bad HW partition specification %s %s **\n",
			    ifname, hwpart_str);
			dev = -EINVAL;
			goto cleanup;
		}
	}

	*desc = get_dev_hwpart(ifname, dev, hwpart);
	if (!(*desc) || ((*desc)->type == DEV_TYPE_UNKNOWN)) {
		debug("** Bad device %s %s **\n", ifname, dev_hwpart_str);
		dev = -ENODEV;
		goto cleanup;
	}

	if (blk_enabled()) {
		/*
		 * Updates the partition table for the specified hw partition.
		 * Always should be done, otherwise hw partition 0 will return
		 * stale data after displaying a non-zero hw partition.
		 */
		if ((*desc)->uclass_id == UCLASS_MMC)
			part_init(*desc);
	}

cleanup:
	free(dup_str);
	return dev;
}

#define PART_UNSPECIFIED -2
#define PART_AUTO -1
int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
			     struct blk_desc **desc,
			     struct disk_partition *info, int allow_whole_dev)
{
	int ret;
	const char *part_str;
	char *dup_str = NULL;
	const char *dev_str;
	int dev;
	char *ep;
	int p;
	int part;
	struct disk_partition tmpinfo;

	*desc = NULL;
	memset(info, 0, sizeof(*info));

#if IS_ENABLED(CONFIG_SANDBOX) || IS_ENABLED(CONFIG_SEMIHOSTING)
	/*
	 * Special-case a pseudo block device "hostfs", to allow access to the
	 * host's own filesystem.
	 */
	if (!strcmp(ifname, "hostfs")) {
		strcpy((char *)info->type, BOOT_PART_TYPE);
		strcpy((char *)info->name, "Host filesystem");

		return 0;
	}
#endif

#if IS_ENABLED(CONFIG_CMD_UBIFS) && !IS_ENABLED(CONFIG_XPL_BUILD)
	/*
	 * Special-case ubi, ubi goes through a mtd, rather than through
	 * a regular block device.
	 */
	if (!strcmp(ifname, "ubi")) {
		if (!ubifs_is_mounted()) {
			printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");
			return -EINVAL;
		}

		strcpy((char *)info->type, BOOT_PART_TYPE);
		strcpy((char *)info->name, "UBI");
		return 0;
	}
#endif

	/* If no dev_part_str, use bootdevice environment variable */
	if (CONFIG_IS_ENABLED(ENV_SUPPORT)) {
		if (!dev_part_str || !strlen(dev_part_str) ||
		    !strcmp(dev_part_str, "-"))
			dev_part_str = env_get("bootdevice");
	}

	/* If still no dev_part_str, it's an error */
	if (!dev_part_str) {
		printf("** No device specified **\n");
		ret = -ENODEV;
		goto cleanup;
	}

	/* Separate device and partition ID specification */
	part_str = strchr(dev_part_str, ':');
	if (part_str) {
		dup_str = strdup(dev_part_str);
		dup_str[part_str - dev_part_str] = 0;
		dev_str = dup_str;
		part_str++;
	} else {
		dev_str = dev_part_str;
	}

	/* Look up the device */
	dev = blk_get_device_by_str(ifname, dev_str, desc);
	if (dev < 0) {
		printf("** Bad device specification %s %s **\n",
		       ifname, dev_str);
		ret = dev;
		goto cleanup;
	}

	/* Convert partition ID string to number */
	if (!part_str || !*part_str) {
		part = PART_UNSPECIFIED;
	} else if (!strcmp(part_str, "auto")) {
		part = PART_AUTO;
	} else {
		/* Something specified -> use exactly that */
		part = (int)hextoul(part_str, &ep);
		/*
		 * Less than whole string converted,
		 * or request for whole device, but caller requires partition.
		 */
		if (*ep || (part == 0 && !allow_whole_dev)) {
			printf("** Bad partition specification %s %s **\n",
			    ifname, dev_part_str);
			ret = -ENOENT;
			goto cleanup;
		}
	}

	/*
	 * No partition table on device,
	 * or user requested partition 0 (entire device).
	 */
	if (((*desc)->part_type == PART_TYPE_UNKNOWN) || !part) {
		if (!(*desc)->lba) {
			printf("** Bad device size - %s %s **\n", ifname,
			       dev_str);
			ret = -EINVAL;
			goto cleanup;
		}

		/*
		 * If user specified a partition ID other than 0,
		 * or the calling command only accepts partitions,
		 * it's an error.
		 */
		if ((part > 0) || (!allow_whole_dev)) {
			printf("** No partition table - %s %s **\n", ifname,
			       dev_str);
			ret = -EPROTONOSUPPORT;
			goto cleanup;
		}

		(*desc)->log2blksz = LOG2((*desc)->blksz);

		part_get_info_whole_disk(*desc, info);

		ret = 0;
		goto cleanup;
	}

	/*
	 * Now there's known to be a partition table,
	 * not specifying a partition means to pick partition 1.
	 */
	if (part == PART_UNSPECIFIED)
		part = 1;

	/*
	 * If user didn't specify a partition number, or did specify something
	 * other than "auto", use that partition number directly.
	 */
	if (part != PART_AUTO) {
		ret = part_get_info(*desc, part, info);
		if (ret) {
			printf("** Invalid partition %d **\n", part);
			goto cleanup;
		}
	} else {
		/*
		 * Find the first bootable partition.
		 * If none are bootable, fall back to the first valid partition.
		 */
		part = 0;
		for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
			ret = part_get_info(*desc, p, info);
			if (ret)
				continue;

			/*
			 * First valid partition, or new better partition?
			 * If so, save partition ID.
			 */
			if (!part || info->bootable)
				part = p;

			/* Best possible partition? Stop searching. */
			if (info->bootable)
				break;

			/*
			 * We now need to search further for best possible.
			 * If we what we just queried was the best so far,
			 * save the info since we over-write it next loop.
			 */
			if (part == p)
				tmpinfo = *info;
		}
		/* If we found any acceptable partition */
		if (part) {
			/*
			 * If we searched all possible partition IDs,
			 * return the first valid partition we found.
			 */
			if (p == MAX_SEARCH_PARTITIONS + 1)
				*info = tmpinfo;
		} else {
			printf("** No valid partitions found **\n");
			goto cleanup;
		}
	}
	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
		printf("** Invalid partition type \"%.32s\""
			" (expect \"" BOOT_PART_TYPE "\")\n",
			info->type);
		ret  = -EINVAL;
		goto cleanup;
	}

	(*desc)->log2blksz = LOG2((*desc)->blksz);

	ret = part;
	goto cleanup;

cleanup:
	free(dup_str);
	return ret;
}

int part_get_info_by_name(struct blk_desc *desc, const char *name,
			  struct disk_partition *info)
{
	struct part_driver *part_drv;
	int ret;
	int i;

	part_drv = part_driver_lookup_type(desc);
	if (!part_drv)
		return -1;

	for (i = 1; i <= part_drv->max_entries; i++) {
		ret = part_driver_get_info(part_drv, desc, i, info);
		if (ret != 0) {
			/* -ENOSYS means no ->get_info method. */
			if (ret == -ENOSYS)
				return ret;
			/*
			 * Partition with this index can't be obtained, but
			 * further partitions might be, so keep checking.
			 */
			continue;
		}
		if (strcmp(name, (const char *)info->name) == 0) {
			/* matched */
			return i;
		}
	}

	return -ENOENT;
}

int part_get_info_by_uuid(struct blk_desc *desc, const char *uuid,
			  struct disk_partition *info)
{
	struct part_driver *part_drv;
	int ret;
	int i;

	if (!CONFIG_IS_ENABLED(PARTITION_UUIDS))
		return -ENOENT;

	part_drv = part_driver_lookup_type(desc);
	if (!part_drv)
		return -1;

	for (i = 1; i <= part_drv->max_entries; i++) {
		ret = part_driver_get_info(part_drv, desc, i, info);
		if (ret != 0) {
			/* -ENOSYS means no ->get_info method. */
			if (ret == -ENOSYS)
				return ret;
			/*
			 * Partition with this index can't be obtained, but
			 * further partitions might be, so keep checking.
			 */
			continue;
		}

		if (!strncasecmp(uuid, disk_partition_uuid(info), UUID_STR_LEN)) {
			/* matched */
			return i;
		}
	}

	return -ENOENT;
}

/**
 * Get partition info from device number and partition name.
 *
 * Parse a device number and partition name string in the form of
 * "devicenum.hwpartnum#partition_name", for example "0.1#misc". devicenum and
 * hwpartnum are both optional, defaulting to 0. If the partition is found,
 * sets desc and part_info accordingly with the information of the
 * partition with the given partition_name.
 *
 * @param[in] dev_iface Device interface
 * @param[in] dev_part_str Input string argument, like "0.1#misc"
 * @param[out] desc Place to store the device description pointer
 * @param[out] part_info Place to store the partition information
 * Return: 0 on success, or a negative on error
 */
static int part_get_info_by_dev_and_name(const char *dev_iface,
					 const char *dev_part_str,
					 struct blk_desc **desc,
					 struct disk_partition *part_info)
{
	char *dup_str = NULL;
	const char *dev_str, *part_str;
	int ret;

	/* Separate device and partition name specification */
	if (dev_part_str)
		part_str = strchr(dev_part_str, '#');
	else
		part_str = NULL;

	if (part_str) {
		dup_str = strdup(dev_part_str);
		dup_str[part_str - dev_part_str] = 0;
		dev_str = dup_str;
		part_str++;
	} else {
		return -EINVAL;
	}

	ret = blk_get_device_by_str(dev_iface, dev_str, desc);
	if (ret < 0)
		goto cleanup;

	ret = part_get_info_by_name(*desc, part_str, part_info);
	if (ret < 0)
		printf("Could not find \"%s\" partition\n", part_str);

cleanup:
	free(dup_str);
	return ret;
}

int part_get_info_by_dev_and_name_or_num(const char *dev_iface,
					 const char *dev_part_str,
					 struct blk_desc **desc,
					 struct disk_partition *part_info,
					 int allow_whole_dev)
{
	int ret;

	/* Split the part_name if passed as "$dev_num#part_name". */
	ret = part_get_info_by_dev_and_name(dev_iface, dev_part_str, desc,
					    part_info);
	if (ret >= 0)
		return ret;
	/*
	 * Couldn't lookup by name, try looking up the partition description
	 * directly.
	 */
	ret = blk_get_device_part_str(dev_iface, dev_part_str, desc, part_info,
				      allow_whole_dev);
	if (ret < 0)
		printf("Couldn't find partition %s %s\n",
		       dev_iface, dev_part_str);
	return ret;
}

void part_set_generic_name(const struct blk_desc *desc, int part_num,
			   char *name)
{
	char *devtype;

	switch (desc->uclass_id) {
	case UCLASS_IDE:
	case UCLASS_AHCI:
		devtype = "hd";
		break;
	case UCLASS_SCSI:
		devtype = "sd";
		break;
	case UCLASS_USB:
		devtype = "usbd";
		break;
	case UCLASS_MMC:
		devtype = "mmcsd";
		break;
	default:
		devtype = "xx";
		break;
	}

	sprintf(name, "%s%c%d", devtype, 'a' + desc->devnum, part_num);
}

int part_get_bootable(struct blk_desc *desc)
{
	struct disk_partition info;
	int p;

	for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
		int ret;

		ret = part_get_info(desc, p, &info);
		if (!ret && info.bootable)
			return p;
	}

	return 0;
}
