/*
 * cmd_gpt.c -- GPT (GUID Partition Table) handling command
 *
 * Copyright (C) 2015
 * Lukasz Majewski <l.majewski@majess.pl>
 *
 * Copyright (C) 2012 Samsung Electronics
 * author: Lukasz Majewski <l.majewski@samsung.com>
 * author: Piotr Wilczek <p.wilczek@samsung.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <malloc.h>
#include <command.h>
#include <part_efi.h>
#include <exports.h>
#include <linux/ctype.h>
#include <div64.h>
#include <memalign.h>
#include <linux/compat.h>
#include <linux/sizes.h>
#include <stdlib.h>

static LIST_HEAD(disk_partitions);

/**
 * extract_env(): Expand env name from string format '&{env_name}'
 *                and return pointer to the env (if the env is set)
 *
 * @param str - pointer to string
 * @param env - pointer to pointer to extracted env
 *
 * @return - zero on successful expand and env is set
 */
static int extract_env(const char *str, char **env)
{
	int ret = -1;
	char *e, *s;
#ifdef CONFIG_RANDOM_UUID
	char uuid_str[UUID_STR_LEN + 1];
#endif

	if (!str || strlen(str) < 4)
		return -1;

	if (!((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')))
		return -1;

	s = strdup(str);
	if (s == NULL)
		return -1;

	memset(s + strlen(s) - 1, '\0', 1);
	memmove(s, s + 2, strlen(s) - 1);

	e = env_get(s);
	if (e == NULL) {
#ifdef CONFIG_RANDOM_UUID
		debug("%s unset. ", str);
		gen_rand_uuid_str(uuid_str, UUID_STR_FORMAT_GUID);
		env_set(s, uuid_str);

		e = env_get(s);
		if (e) {
			debug("Set to random.\n");
			ret = 0;
		} else {
			debug("Can't get random UUID.\n");
		}
#else
		debug("%s unset.\n", str);
#endif
	} else {
		debug("%s get from environment.\n", str);
		ret = 0;
	}

	*env = e;
	free(s);

	return ret;
}

/**
 * extract_val(): Extract value from a key=value pair list (comma separated).
 *                Only value for the given key is returend.
 *                Function allocates memory for the value, remember to free!
 *
 * @param str - pointer to string with key=values pairs
 * @param key - pointer to the key to search for
 *
 * @return - pointer to allocated string with the value
 */
static char *extract_val(const char *str, const char *key)
{
	char *v, *k;
	char *s, *strcopy;
	char *new = NULL;

	strcopy = strdup(str);
	if (strcopy == NULL)
		return NULL;

	s = strcopy;
	while (s) {
		v = strsep(&s, ",");
		if (!v)
			break;
		k = strsep(&v, "=");
		if (!k)
			break;
		if  (strcmp(k, key) == 0) {
			new = strdup(v);
			break;
		}
	}

	free(strcopy);

	return new;
}

/**
 * found_key(): Found key without value in parameter list (comma separated).
 *
 * @param str - pointer to string with key
 * @param key - pointer to the key to search for
 *
 * @return - true on found key
 */
static bool found_key(const char *str, const char *key)
{
	char *k;
	char *s, *strcopy;
	bool result = false;

	strcopy = strdup(str);
	if (!strcopy)
		return NULL;

	s = strcopy;
	while (s) {
		k = strsep(&s, ",");
		if (!k)
			break;
		if  (strcmp(k, key) == 0) {
			result = true;
			break;
		}
	}

	free(strcopy);

	return result;
}

static int calc_parts_list_len(int numparts)
{
	int partlistlen = UUID_STR_LEN + 1 + strlen("uuid_disk=");
	/* for the comma */
	partlistlen++;

	/* per-partition additions; numparts starts at 1, so this should be correct */
	partlistlen += numparts * (strlen("name=,") + PART_NAME_LEN + 1);
	/* see part.h for definition of struct disk_partition */
	partlistlen += numparts * (strlen("start=MiB,") + sizeof(lbaint_t) + 1);
	partlistlen += numparts * (strlen("size=MiB,") + sizeof(lbaint_t) + 1);
	partlistlen += numparts * (strlen("uuid=;") + UUID_STR_LEN + 1);
	/* for the terminating null */
	partlistlen++;
	debug("Length of partitions_list is %d for %d partitions\n", partlistlen,
	      numparts);
	return partlistlen;
}

#ifdef CONFIG_CMD_GPT_RENAME
static void del_gpt_info(void)
{
	struct list_head *pos = &disk_partitions;
	struct disk_part *curr;
	while (!list_empty(pos)) {
		curr = list_entry(pos->next, struct disk_part, list);
		list_del(pos->next);
		free(curr);
	}
}

static struct disk_part *allocate_disk_part(disk_partition_t *info, int partnum)
{
	struct disk_part *newpart;
	newpart = calloc(1, sizeof(struct disk_part));
	if (!newpart)
		return ERR_PTR(-ENOMEM);

	newpart->gpt_part_info.start = info->start;
	newpart->gpt_part_info.size = info->size;
	newpart->gpt_part_info.blksz = info->blksz;
	strncpy((char *)newpart->gpt_part_info.name, (const char *)info->name,
		PART_NAME_LEN);
	newpart->gpt_part_info.name[PART_NAME_LEN - 1] = '\0';
	strncpy((char *)newpart->gpt_part_info.type, (const char *)info->type,
		PART_TYPE_LEN);
	newpart->gpt_part_info.type[PART_TYPE_LEN - 1] = '\0';
	newpart->gpt_part_info.bootable = info->bootable;
#ifdef CONFIG_PARTITION_UUIDS
	strncpy(newpart->gpt_part_info.uuid, (const char *)info->uuid,
		UUID_STR_LEN);
	/* UUID_STR_LEN is correct, as uuid[]'s length is UUID_STR_LEN+1 chars */
	newpart->gpt_part_info.uuid[UUID_STR_LEN] = '\0';
#endif
	newpart->partnum = partnum;

	return newpart;
}

static void prettyprint_part_size(char *sizestr, lbaint_t partsize,
				  lbaint_t blksize)
{
	unsigned long long partbytes, partmegabytes;

	partbytes = partsize * blksize;
	partmegabytes = lldiv(partbytes, SZ_1M);
	snprintf(sizestr, 16, "%lluMiB", partmegabytes);
}

static void print_gpt_info(void)
{
	struct list_head *pos;
	struct disk_part *curr;
	char partstartstr[16];
	char partsizestr[16];

	list_for_each(pos, &disk_partitions) {
		curr = list_entry(pos, struct disk_part, list);
		prettyprint_part_size(partstartstr, curr->gpt_part_info.start,
				      curr->gpt_part_info.blksz);
		prettyprint_part_size(partsizestr, curr->gpt_part_info.size,
				      curr->gpt_part_info.blksz);

		printf("Partition %d:\n", curr->partnum);
		printf("Start %s, size %s\n", partstartstr, partsizestr);
		printf("Block size %lu, name %s\n", curr->gpt_part_info.blksz,
		       curr->gpt_part_info.name);
		printf("Type %s, bootable %d\n", curr->gpt_part_info.type,
		       curr->gpt_part_info.bootable);
#ifdef CONFIG_PARTITION_UUIDS
		printf("UUID %s\n", curr->gpt_part_info.uuid);
#endif
		printf("\n");
	}
}

/*
 * create the string that upstream 'gpt write' command will accept as an
 * argument
 *
 * From doc/README.gpt, Format of partitions layout:
 *    "uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
 *	name=kernel,size=60MiB,uuid=...;"
 * The fields 'name' and 'size' are mandatory for every partition.
 * The field 'start' is optional. The fields 'uuid' and 'uuid_disk'
 * are optional if CONFIG_RANDOM_UUID is enabled.
 */
static int create_gpt_partitions_list(int numparts, const char *guid,
				      char *partitions_list)
{
	struct list_head *pos;
	struct disk_part *curr;
	char partstr[PART_NAME_LEN + 1];

	if (!partitions_list)
		return -EINVAL;

	strcpy(partitions_list, "uuid_disk=");
	strncat(partitions_list, guid, UUID_STR_LEN + 1);
	strcat(partitions_list, ";");

	list_for_each(pos, &disk_partitions) {
		curr = list_entry(pos, struct disk_part, list);
		strcat(partitions_list, "name=");
		strncat(partitions_list, (const char *)curr->gpt_part_info.name,
			PART_NAME_LEN + 1);
		strcat(partitions_list, ",start=");
		prettyprint_part_size(partstr, (unsigned long)curr->gpt_part_info.start,
				      (unsigned long) curr->gpt_part_info.blksz);
		/* one extra byte for NULL */
		strncat(partitions_list, partstr, PART_NAME_LEN + 1);
		strcat(partitions_list, ",size=");
		prettyprint_part_size(partstr, curr->gpt_part_info.size,
				      curr->gpt_part_info.blksz);
		strncat(partitions_list, partstr, PART_NAME_LEN + 1);

		strcat(partitions_list, ",uuid=");
		strncat(partitions_list, curr->gpt_part_info.uuid,
			UUID_STR_LEN + 1);
		strcat(partitions_list, ";");
	}
	return 0;
}

/*
 * read partition info into disk_partitions list where
 * it can be printed or modified
 */
static int get_gpt_info(struct blk_desc *dev_desc)
{
	/* start partition numbering at 1, as U-Boot does */
	int valid_parts = 0, p, ret;
	disk_partition_t info;
	struct disk_part *new_disk_part;

	/*
	 * Always re-read partition info from device, in case
	 * it has changed
	 */
	INIT_LIST_HEAD(&disk_partitions);

	for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
		ret = part_get_info(dev_desc, p, &info);
		if (ret)
			continue;

		/* Add 1 here because counter is zero-based but p1 is
		   the first partition */
		new_disk_part = allocate_disk_part(&info, valid_parts+1);
		if (IS_ERR(new_disk_part))
			goto out;

		list_add_tail(&new_disk_part->list, &disk_partitions);
		valid_parts++;
	}
	if (valid_parts == 0) {
		printf("** No valid partitions found **\n");
		goto out;
	}
	return valid_parts;
 out:
	if (valid_parts >= 1)
		del_gpt_info();
	return -ENODEV;
}

/* a wrapper to test get_gpt_info */
static int do_get_gpt_info(struct blk_desc *dev_desc)
{
	int ret;

	ret = get_gpt_info(dev_desc);
	if (ret > 0) {
		print_gpt_info();
		del_gpt_info();
		return 0;
	}
	return ret;
}
#endif

/**
 * set_gpt_info(): Fill partition information from string
 *		function allocates memory, remember to free!
 *
 * @param dev_desc - pointer block device descriptor
 * @param str_part - pointer to string with partition information
 * @param str_disk_guid - pointer to pointer to allocated string with disk guid
 * @param partitions - pointer to pointer to allocated partitions array
 * @param parts_count - number of partitions
 *
 * @return - zero on success, otherwise error
 *
 */
static int set_gpt_info(struct blk_desc *dev_desc,
			const char *str_part,
			char **str_disk_guid,
			disk_partition_t **partitions,
			u8 *parts_count)
{
	char *tok, *str, *s;
	int i;
	char *val, *p;
	int p_count;
	disk_partition_t *parts;
	int errno = 0;
	uint64_t size_ll, start_ll;
	lbaint_t offset = 0;
	int max_str_part = calc_parts_list_len(MAX_SEARCH_PARTITIONS);

	debug("%s:  lba num: 0x%x %d\n", __func__,
	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);

	if (str_part == NULL)
		return -1;

	str = strdup(str_part);
	if (str == NULL)
		return -ENOMEM;

	/* extract disk guid */
	s = str;
	val = extract_val(str, "uuid_disk");
	if (!val) {
#ifdef CONFIG_RANDOM_UUID
		*str_disk_guid = malloc(UUID_STR_LEN + 1);
		if (*str_disk_guid == NULL)
			return -ENOMEM;
		gen_rand_uuid_str(*str_disk_guid, UUID_STR_FORMAT_STD);
#else
		free(str);
		return -2;
#endif
	} else {
		val = strsep(&val, ";");
		if (extract_env(val, &p))
			p = val;
		*str_disk_guid = strdup(p);
		free(val);
		/* Move s to first partition */
		strsep(&s, ";");
	}
	if (s == NULL) {
		printf("Error: is the partitions string NULL-terminated?\n");
		return -EINVAL;
	}
	if (strnlen(s, max_str_part) == 0)
		return -3;

	i = strnlen(s, max_str_part) - 1;
	if (s[i] == ';')
		s[i] = '\0';

	/* calculate expected number of partitions */
	p_count = 1;
	p = s;
	while (*p) {
		if (*p++ == ';')
			p_count++;
	}

	/* allocate memory for partitions */
	parts = calloc(sizeof(disk_partition_t), p_count);
	if (parts == NULL)
		return -ENOMEM;

	/* retrieve partitions data from string */
	for (i = 0; i < p_count; i++) {
		tok = strsep(&s, ";");

		if (tok == NULL)
			break;

		/* uuid */
		val = extract_val(tok, "uuid");
		if (!val) {
			/* 'uuid' is optional if random uuid's are enabled */
#ifdef CONFIG_RANDOM_UUID
			gen_rand_uuid_str(parts[i].uuid, UUID_STR_FORMAT_STD);
#else
			errno = -4;
			goto err;
#endif
		} else {
			if (extract_env(val, &p))
				p = val;
			if (strnlen(p, max_str_part) >= sizeof(parts[i].uuid)) {
				printf("Wrong uuid format for partition %d\n", i);
				errno = -4;
				goto err;
			}
			strncpy((char *)parts[i].uuid, p, max_str_part);
			free(val);
		}
#ifdef CONFIG_PARTITION_TYPE_GUID
		/* guid */
		val = extract_val(tok, "type");
		if (val) {
			/* 'type' is optional */
			if (extract_env(val, &p))
				p = val;
			if (strnlen(p, max_str_part) >= sizeof(parts[i].type_guid)) {
				printf("Wrong type guid format for partition %d\n",
				       i);
				errno = -4;
				goto err;
			}
			strncpy((char *)parts[i].type_guid, p, max_str_part);
			free(val);
		}
#endif
		/* name */
		val = extract_val(tok, "name");
		if (!val) { /* name is mandatory */
			errno = -4;
			goto err;
		}
		if (extract_env(val, &p))
			p = val;
		if (strnlen(p, max_str_part) >= sizeof(parts[i].name)) {
			errno = -4;
			goto err;
		}
		strncpy((char *)parts[i].name, p, max_str_part);
		free(val);

		/* size */
		val = extract_val(tok, "size");
		if (!val) { /* 'size' is mandatory */
			errno = -4;
			goto err;
		}
		if (extract_env(val, &p))
			p = val;
		if ((strcmp(p, "-") == 0)) {
			/* Let part efi module to auto extend the size */
			parts[i].size = 0;
		} else {
			size_ll = ustrtoull(p, &p, 0);
			parts[i].size = lldiv(size_ll, dev_desc->blksz);
		}

		free(val);

		/* start address */
		val = extract_val(tok, "start");
		if (val) { /* start address is optional */
			if (extract_env(val, &p))
				p = val;
			start_ll = ustrtoull(p, &p, 0);
			parts[i].start = lldiv(start_ll, dev_desc->blksz);
			free(val);
		}

		offset += parts[i].size + parts[i].start;

		/* bootable */
		if (found_key(tok, "bootable"))
			parts[i].bootable = 1;
	}

	*parts_count = p_count;
	*partitions = parts;
	free(str);

	return 0;
err:
	free(str);
	free(*str_disk_guid);
	free(parts);

	return errno;
}

static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
{
	int ret;
	char *str_disk_guid;
	u8 part_count = 0;
	disk_partition_t *partitions = NULL;

	/* fill partitions */
	ret = set_gpt_info(blk_dev_desc, str_part,
			&str_disk_guid, &partitions, &part_count);
	if (ret) {
		if (ret == -1)
			printf("No partition list provided\n");
		if (ret == -2)
			printf("Missing disk guid\n");
		if ((ret == -3) || (ret == -4))
			printf("Partition list incomplete\n");
		return -1;
	}

	/* save partitions layout to disk */
	ret = gpt_restore(blk_dev_desc, str_disk_guid, partitions, part_count);
	free(str_disk_guid);
	free(partitions);

	return ret;
}

static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1,
				     blk_dev_desc->blksz);
	disk_partition_t *partitions = NULL;
	gpt_entry *gpt_pte = NULL;
	char *str_disk_guid;
	u8 part_count = 0;
	int ret = 0;

	/* fill partitions */
	ret = set_gpt_info(blk_dev_desc, str_part,
			&str_disk_guid, &partitions, &part_count);
	if (ret) {
		if (ret == -1) {
			printf("No partition list provided - only basic check\n");
			ret = gpt_verify_headers(blk_dev_desc, gpt_head,
						 &gpt_pte);
			goto out;
		}
		if (ret == -2)
			printf("Missing disk guid\n");
		if ((ret == -3) || (ret == -4))
			printf("Partition list incomplete\n");
		return -1;
	}

	/* Check partition layout with provided pattern */
	ret = gpt_verify_partitions(blk_dev_desc, partitions, part_count,
				    gpt_head, &gpt_pte);
	free(str_disk_guid);
	free(partitions);
 out:
	free(gpt_pte);
	return ret;
}

static int do_disk_guid(struct blk_desc *dev_desc, char * const namestr)
{
	int ret;
	char disk_guid[UUID_STR_LEN + 1];

	ret = get_disk_guid(dev_desc, disk_guid);
	if (ret < 0)
		return CMD_RET_FAILURE;

	if (namestr)
		env_set(namestr, disk_guid);
	else
		printf("%s\n", disk_guid);

	return ret;
}

#ifdef CONFIG_CMD_GPT_RENAME
/*
 * There are 3 malloc() calls in set_gpt_info() and there is no info about which
 * failed.
 */
static void set_gpt_cleanup(char **str_disk_guid,
			    disk_partition_t **partitions)
{
#ifdef CONFIG_RANDOM_UUID
	if (str_disk_guid)
		free(str_disk_guid);
#endif
	if (partitions)
		free(partitions);
}

static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm,
			       char *name1, char *name2)
{
	struct list_head *pos;
	struct disk_part *curr;
	disk_partition_t *new_partitions = NULL;
	char disk_guid[UUID_STR_LEN + 1];
	char *partitions_list, *str_disk_guid;
	u8 part_count = 0;
	int partlistlen, ret, numparts = 0, partnum, i = 1, ctr1 = 0, ctr2 = 0;

	if ((subcomm == NULL) || (name1 == NULL) || (name2 == NULL) ||
	    (strcmp(subcomm, "swap") && (strcmp(subcomm, "rename"))))
		return -EINVAL;

	ret = get_disk_guid(dev_desc, disk_guid);
	if (ret < 0)
		return ret;
	/*
	 * Allocates disk_partitions, requiring matching call to del_gpt_info()
	 * if successful.
	 */
	numparts = get_gpt_info(dev_desc);
	if (numparts <=  0)
		return numparts ? numparts : -ENODEV;

	partlistlen = calc_parts_list_len(numparts);
	partitions_list = malloc(partlistlen);
	if (!partitions_list) {
		del_gpt_info();
		return -ENOMEM;
	}
	memset(partitions_list, '\0', partlistlen);

	ret = create_gpt_partitions_list(numparts, disk_guid, partitions_list);
	if (ret < 0) {
		free(partitions_list);
		return ret;
	}
	/*
	 * Uncomment the following line to print a string that 'gpt write'
	 * or 'gpt verify' will accept as input.
	 */
	debug("OLD partitions_list is %s with %u chars\n", partitions_list,
	      (unsigned)strlen(partitions_list));

	/* set_gpt_info allocates new_partitions and str_disk_guid */
	ret = set_gpt_info(dev_desc, partitions_list, &str_disk_guid,
			   &new_partitions, &part_count);
	if (ret < 0) {
		del_gpt_info();
		free(partitions_list);
		if (ret == -ENOMEM)
			set_gpt_cleanup(&str_disk_guid, &new_partitions);
		else
			goto out;
	}

	if (!strcmp(subcomm, "swap")) {
		if ((strlen(name1) > PART_NAME_LEN) || (strlen(name2) > PART_NAME_LEN)) {
			printf("Names longer than %d characters are truncated.\n", PART_NAME_LEN);
			ret = -EINVAL;
			goto out;
		}
		list_for_each(pos, &disk_partitions) {
			curr = list_entry(pos, struct disk_part, list);
			if (!strcmp((char *)curr->gpt_part_info.name, name1)) {
				strcpy((char *)curr->gpt_part_info.name, name2);
				ctr1++;
			} else if (!strcmp((char *)curr->gpt_part_info.name, name2)) {
				strcpy((char *)curr->gpt_part_info.name, name1);
				ctr2++;
			}
		}
		if ((ctr1 + ctr2 < 2) || (ctr1 != ctr2)) {
			printf("Cannot swap partition names except in pairs.\n");
			ret = -EINVAL;
			goto out;
		}
	} else { /* rename */
		if (strlen(name2) > PART_NAME_LEN) {
			printf("Names longer than %d characters are truncated.\n", PART_NAME_LEN);
			ret = -EINVAL;
			goto out;
		}
		partnum = (int)simple_strtol(name1, NULL, 10);
		if ((partnum < 0) || (partnum > numparts)) {
			printf("Illegal partition number %s\n", name1);
			ret = -EINVAL;
			goto out;
		}
		ret = part_get_info(dev_desc, partnum, new_partitions);
		if (ret < 0)
			goto out;

		/* U-Boot partition numbering starts at 1 */
		list_for_each(pos, &disk_partitions) {
			curr = list_entry(pos, struct disk_part, list);
			if (i == partnum) {
				strcpy((char *)curr->gpt_part_info.name, name2);
				break;
			}
			i++;
		}
	}

	ret = create_gpt_partitions_list(numparts, disk_guid, partitions_list);
	if (ret < 0)
		goto out;
	debug("NEW partitions_list is %s with %u chars\n", partitions_list,
	      (unsigned)strlen(partitions_list));

	ret = set_gpt_info(dev_desc, partitions_list, &str_disk_guid,
			   &new_partitions, &part_count);
	/*
	 * Even though valid pointers are here passed into set_gpt_info(),
	 * it mallocs again, and there's no way to tell which failed.
	 */
	if (ret < 0) {
		del_gpt_info();
		free(partitions_list);
		if (ret == -ENOMEM)
			set_gpt_cleanup(&str_disk_guid, &new_partitions);
		else
			goto out;
	}

	debug("Writing new partition table\n");
	ret = gpt_restore(dev_desc, disk_guid, new_partitions, numparts);
	if (ret < 0) {
		printf("Writing new partition table failed\n");
		goto out;
	}

	debug("Reading back new partition table\n");
	/*
	 * Empty the existing disk_partitions list, as otherwise the memory in
	 * the original list is unreachable.
	 */
	del_gpt_info();
	numparts = get_gpt_info(dev_desc);
	if (numparts <=  0) {
		ret = numparts ? numparts : -ENODEV;
		goto out;
	}
	printf("new partition table with %d partitions is:\n", numparts);
	print_gpt_info();
	del_gpt_info();
 out:
	free(new_partitions);
	free(str_disk_guid);
	free(partitions_list);
	return ret;
}
#endif

/**
 * do_gpt(): Perform GPT operations
 *
 * @param cmdtp - command name
 * @param flag
 * @param argc
 * @param argv
 *
 * @return zero on success; otherwise error
 */
static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret = CMD_RET_SUCCESS;
	int dev = 0;
	char *ep;
	struct blk_desc *blk_dev_desc = NULL;

#ifndef CONFIG_CMD_GPT_RENAME
	if (argc < 4 || argc > 5)
#else
	if (argc < 4 || argc > 6)
#endif
		return CMD_RET_USAGE;

	dev = (int)simple_strtoul(argv[3], &ep, 10);
	if (!ep || ep[0] != '\0') {
		printf("'%s' is not a number\n", argv[3]);
		return CMD_RET_USAGE;
	}
	blk_dev_desc = blk_get_dev(argv[2], dev);
	if (!blk_dev_desc) {
		printf("%s: %s dev %d NOT available\n",
		       __func__, argv[2], dev);
		return CMD_RET_FAILURE;
	}

	if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
		printf("Writing GPT: ");
		ret = gpt_default(blk_dev_desc, argv[4]);
	} else if ((strcmp(argv[1], "verify") == 0)) {
		ret = gpt_verify(blk_dev_desc, argv[4]);
		printf("Verify GPT: ");
	} else if (strcmp(argv[1], "guid") == 0) {
		ret = do_disk_guid(blk_dev_desc, argv[4]);
#ifdef CONFIG_CMD_GPT_RENAME
	} else if (strcmp(argv[1], "read") == 0) {
		ret = do_get_gpt_info(blk_dev_desc);
	} else if ((strcmp(argv[1], "swap") == 0) ||
		   (strcmp(argv[1], "rename") == 0)) {
		ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]);
#endif
	} else {
		return CMD_RET_USAGE;
	}

	if (ret) {
		printf("error!\n");
		return CMD_RET_FAILURE;
	}

	printf("success!\n");
	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
	"GUID Partition Table",
	"<command> <interface> <dev> <partitions_list>\n"
	" - GUID partition table restoration and validity check\n"
	" Restore or verify GPT information on a device connected\n"
	" to interface\n"
	" Example usage:\n"
	" gpt write mmc 0 $partitions\n"
	" gpt verify mmc 0 $partitions\n"
	" read <interface> <dev>\n"
	"    - read GPT into a data structure for manipulation\n"
	" guid <interface> <dev>\n"
	"    - print disk GUID\n"
	" guid <interface> <dev> <varname>\n"
	"    - set environment variable to disk GUID\n"
	" Example usage:\n"
	" gpt guid mmc 0\n"
	" gpt guid mmc 0 varname\n"
#ifdef CONFIG_CMD_GPT_RENAME
	"gpt partition renaming commands:\n"
	"gpt swap <interface> <dev> <name1> <name2>\n"
	"    - change all partitions named name1 to name2\n"
	"      and vice-versa\n"
	"gpt rename <interface> <dev> <part> <name>\n"
	"    - rename the specified partition\n"
	" Example usage:\n"
	" gpt swap mmc 0 foo bar\n"
	" gpt rename mmc 0 3 foo\n"
#endif
);
