/*
 * Copyright (c) 2020, Mediatek Inc. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wpointer-bool-conversion"

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <endian.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include "ufs.h"
#include "ufs_hmr.h"
#include "ufs_cmds.h"

/*
 * HMR Quirks: 1 - enable, 0 - disable
 */

/*
 * Big-little-endian byte order: some params
 * may occur in order other than expected.
 * Change byte order for the following params.
 */
#define HMR_QUIRK_REFRESH_TOTCOUNT_BYTE_ORDER	1
#define HMR_QUIRK_REFRESH_PROGRESS_BYTE_ORDER	1

/*
 * There is the maximum number of HMR operations in the life
 * of the device. Having reached this number, the device will
 * return "General Failure" and set the bRefreshStatus attribute
 * to 0x05.
 */
#define HMR_REFRESH_MAX_TOTCOUNT	200

/*
 * Output progress every N iterations.
 */
#define HMR_PROGRESS_OUTPUT_ITER	1
#if HMR_PROGRESS_OUTPUT_ITER <= 0
#	error keep HMR_PROGRESS_OUTPUT_ITER > 0
#endif

/*
 * The HMR mode type description string size we
 * support to output. Can be enlarged if required.
 */
#define HMR_MODE_TYPE_MAX_SIZE	40

enum hmr_err_codes {
	EHMR_OK					= 0,	/* success */
	EHMR_REFRESH_PROGRESS	= 100,	/* wrong refresh progress */
	EHMR_REFRESH_STATUS,			/* wrong refresh status */
	EHMR_REFRESH_TOTCOUNT,			/* wrong refresh total count */
	EHMR_FREEMEM,					/* memory wasn't freed */
	EHMR_NOMEM,						/* not enough memory */
	EHMR_INVAL,						/* invalid argument */
	EHMR_NORETRY,					/* cannot be retried */
	EHMR_REFRESH_METHOD,			/* wrong refrresh method  */
	EHMR_REFRESH_UNIT,				/* wrong refrresh unit */
};

enum hmr_refresh_status {
	HMR_ST_IDLE = 0,
	HMR_ST_IN_PROGRESS,
	HMR_ST_ABORTED,
	HMR_ST_COMPLETED,
	HMR_ST_BUSY,
	HMR_ST_GENERAL,
};

enum hmr_stage_skip {
	HMR_SKIP_STATUS_CHECK	= 1 << 0,
	HMR_SKIP_METHOD_SET		= 1 << 1,
	HMR_SKIP_UNIT_SET		= 1 << 2,
};

#pragma pack(push, 1)
struct descriptor_health_layout {
	__u8  length;
	__u8  type;
	__u8  pre_eol_info;
	__u8  dev_life_time_est_a;
	__u8  dev_life_time_est_b;
	__u8  vendor_prop_info[0x20];
	__u32 refresh_total_count;
	__u32 refresh_progress;
};
#pragma pack(pop)

struct descriptor {
	enum desc_idn idn;
	const char *name;
	size_t size;
	void *layout;
};

extern int do_query_rq(int fd,
	struct ufs_bsg_request *bsg_req,	/* request  struct of the sg_io_v4 */
	struct ufs_bsg_reply *bsg_rsp,		/* response struct of the sg_io_v4 */
	__u8 query_req_func,				/* read / write */
	__u8 opcode,						/* opcode r/w of desc/attr/fl etc.*/
	__u8 idn,							/* (-t) util option */
	__u8 index,							/* (-i) util option */
	__u8 sel,							/* (-s) util option */
	__u16 req_buf_len,					/* request buffer size */
	__u16 res_buf_len,					/* response buffer size */
	__u8 *data_buf);					/* buffer with/for data */

extern struct desc_field_offset device_health_desc_conf_field_name[];
extern struct attr_fields ufs_attrs[];
extern struct flag_fields ufs_flags[];

static struct descriptor_health_layout desc_health_layout;

static struct descriptor desc_health = {
	QUERY_DESC_IDN_HEALTH,
	"Health",
	sizeof desc_health_layout,
	&desc_health_layout
};

static inline void hmr_delay_retry(int sec)
{
	if (sec > 0)
		sleep(sec);
}

static inline void hmr_output_message(const char *msg)
{
	/*
	 * |---------------------------------------------------------|
	 * | Message format template:                                |
	 * |---------------------------------------------------------|
	 * |<<-6->|   |<<-29->                                       |
	 * |HMR:  |   |variable string                               |
	 * |                                                         |
	 * |---------------------------------------------------------|
	 * |HMR:  |   |waiting idle status                           |
	 * |---------------------------------------------------------|
	 */
	printf("%-6s   %-29s\r",  "HMR:", msg);
	fflush(stdout);
}

static inline void hmr_output_progress(__u32 progress,
	__u64 iter, int sec, const char *msg)
{
	/*
	 * |---------------------------------------------------------|
	 * | Progress format template:                               |
	 * |---------------------------------------------------------|
	 * |<<-6->| |   <-9->>|  |<<-35->                            |
	 * |HMR:  | |  hex dig|  |variable string                    |
	 * |                                                         |
	 * |---------------------------------------------------------|
	 * | The case of up to 100% progress:                        |
	 * |---------------------------------------------------------|
	 * |<<-6->| |   <-9->>|  |<<-35->                            |
	 * |HMR:  | |     f20a|  |                                   |
	 * |      | |         |  |                                   |
	 * |---------------------------------------------------------|
	 * | The case of 100% progress:                              |
	 * |---------------------------------------------------------|
	 * |<<-6->| |  <-8->>|   |<<-20->                            |
	 * |HMR:  | |     100|%  |                                   |
	 * |---------------------------------------------------------|
	 */

	/*
	 * Completed - print 100%,
	 * otherwise print hex progress indicator every N iterations.
	 */
	if (!progress)
		printf("%-6s %8d%%  %-20s\r", "HMR:", 100, msg);
	else if (0 == (iter % HMR_PROGRESS_OUTPUT_ITER))
		printf("%-6s %9x  %-20s\r",  "HMR:", progress, msg);

	fflush(stdout);
	if (sec > 0)
		sleep(sec);
}

static inline void hmr_output_header(const char *unit_str, int method)
{
	int count;
	const char *method_str;
	char mode_str[HMR_MODE_TYPE_MAX_SIZE];

	method_str = method == HMR_METHOD_FORCE ? "force" : "selective";

	count = snprintf(mode_str, sizeof mode_str, "method:%s, unit:%s",
		method_str, unit_str);

	if (count >= HMR_MODE_TYPE_MAX_SIZE)
		; /* the output was truncated, enlarge HMR_MODE_TYPE_MAX_SIZE */

	/*
	 * |---------------------------------------------------------|
	 * | Header format template:                                 |
	 * |---------------------------------------------------------|
	 * |<<-6->| |   <-9->>|  |<<-35->                            |
	 * |HMR:  | |   status|  |mode type                          |
	 * |                                                         |
	 * |---------------------------------------------------------|
	 * | Examples:                                               |
	 * |---------------------------------------------------------|
	 * |HMR:  | |  started|  |method:selective, unit:minimum     |
	 * |      | |         |  |                                   |
	 * |---------------------------------------------------------|
	 * |HMR:  | |  started|  |method:force, unit:full            |
	 * |      | |         |  |                                   |
	 * |---------------------------------------------------------|
	 */
	printf("%-6s %9s  %-30s\n", "HMR:", "started", mode_str);
	fflush(stdout);
}

static inline void hmr_output_footer(int rc)
{
	/*
	 * |---------------------------------------------------------|
	 * | Footer format template:                                 |
	 * |---------------------------------------------------------|
	 * |<<-6->| |   <-9->>|  |<<-35->                            |
	 * |HMR:  | |   status|  |error msg / code                   |
	 * |                                                         |
	 * |---------------------------------------------------------|
	 * | Examples:                                               |
	 * |---------------------------------------------------------|
	 * |HMR:  | |completed|  | OK                                |
	 * |      | |         |  |                                   |
	 * |---------------------------------------------------------|
	 * |HMR:  | |  stopped|  |-115                               |
	 * |      | |         |  |                                   |
	 * |---------------------------------------------------------|
	 */

	/*
	 * Leading LF is due to CR-ending on progress print out.
	 * In case of error LF was already sent with the error msg.
	 */
	if (0 == rc)
		printf("\n%-6s %9s  %-30s\n", "HMR:", "completed", "OK");
	else
		printf("%-6s %9s  %-30d\n", "HMR:", "stopped", rc);

	fflush(stdout);
}

static inline void hmr_query_error(int rc,
	const char *job_type,		/* write/read/set/clear/etc. */
	const char *subject,		/* desc/attr/flag/etc. */
	int opcode,					/* opcode r/w of desc/attr/fl etc. */
	const char *field_name,		/* name of the operated field */
	int field_idn)				/* index of the field */
{
	print_error("hmr: query command: %s %s failed: "
		"opcode 0x%x, field-name %s, field-idn 0x%x, rc %d.\n",
		job_type, subject, opcode, field_name, field_idn);
}

static inline int hmr_attr_sanity(enum attr_idn idn)
{
	if (idn < 0 || idn >= QUERY_ATTR_IDN_MAX)
		return -EHMR_INVAL;

	return EHMR_OK;
}

static inline int hmr_flag_sanity(enum flag_idn idn)
{
	if (idn < 0 || idn >= QUERY_FLAG_IDN_MAX)
		return -EHMR_INVAL;

	return EHMR_OK;
}

static inline int hmr_desc_sanity(enum desc_idn idn)
{
	if (idn < 0 || idn >= QUERY_DESC_IDN_MAX)
		return -EHMR_INVAL;

	return EHMR_OK;
}

static int hmr_dev_open(const char* path, int *fd)
{
	int rc = 0;

	errno = 0;

	*fd = open(path, O_RDWR);
	if (*fd < 0) {
		rc = errno; /* save errno: errno can be changed by the print */
		print_error("hmr: %s: '%s'", strerror(rc), path);
	}

	return rc == 0 ? rc : -rc;
}

static int hmr_dev_close(const char* path, int fd)
{
	int rc;

	errno = 0;

	rc = close(fd);
	if (rc) {
		rc = errno;
		print_error("hmr: %s: '%s'", strerror(rc), path);
	}

	return rc == 0 ? rc : -rc;
}

static int hmr_attr_read(__u32 *result,
	int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply   *bsg_rsp,
	enum attr_idn idn)
{
	int rc;
	struct attr_fields *field;

	if (hmr_attr_sanity(idn) != EHMR_OK || !result)
		return -EHMR_INVAL;

	field = &ufs_attrs[idn];

	/* Query to read attribute */
	rc = do_query_rq(fd,
		bsg_req,
		bsg_rsp,
		UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
		UPIU_QUERY_OPCODE_READ_ATTR,
		idn,
		0,
		0,
		0,
		0,
		0);

	if (rc) {
		hmr_query_error(rc, "read", "attr", UPIU_QUERY_OPCODE_READ_ATTR,
			field->name, idn);
		goto out;
	}

	*result = be32toh(bsg_rsp->upiu_rsp.qr.value);

out:
	return rc;
}

static int hmr_attr_write(__u32 value,
	int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply   *bsg_rsp,
	enum attr_idn idn)
{
	int rc;
	struct attr_fields *field;

	if (hmr_attr_sanity(idn) != EHMR_OK)
		return -EHMR_INVAL;

	field = &ufs_attrs[idn];

	bsg_req->upiu_req.qr.value = htobe32(value);

	/* Query to write attribute */
	rc = do_query_rq(fd,
		bsg_req,
		bsg_rsp,
		UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
		UPIU_QUERY_OPCODE_WRITE_ATTR,
		idn,
		0,
		0,
		0,
		0,
		0);

	if (rc)
		hmr_query_error(rc, "write", "attr", UPIU_QUERY_OPCODE_WRITE_ATTR,
			field->name, idn);

	return rc;
}

static int hmr_flag_modify(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply   *bsg_rsp,
	enum query_opcode opcode,
	enum flag_idn idn)
{
	int rc;
	struct flag_fields *field;

	if (opcode != UPIU_QUERY_OPCODE_SET_FLAG &&
		opcode != UPIU_QUERY_OPCODE_CLEAR_FLAG &&
		opcode != UPIU_QUERY_OPCODE_TOGGLE_FLAG)
		return -EHMR_INVAL;

	if (hmr_flag_sanity(idn) != EHMR_OK)
		return -EHMR_INVAL;

	field = &ufs_flags[idn];

	/* Query to set/clear/toggle flag */
	rc = do_query_rq(fd,
		bsg_req,
		bsg_rsp,
		UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
		opcode,
		idn,
		0,
		0,
		0,
		0,
		0);

	if (rc)
		hmr_query_error(rc, "modify", "flag", opcode, field->name, idn);

	return rc;
}

static int hmr_desc_read(struct descriptor *result,
	int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply   *bsg_rsp,
	enum desc_idn idn)
{
	int rc;

	if (hmr_desc_sanity(idn) != EHMR_OK ||
		!result ||
		!result->layout ||
		result->size <= 0)
		return -EHMR_INVAL;

	/* Query to read descriptor */
	rc = do_query_rq(fd,
		bsg_req,
		bsg_rsp,
		UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
		UPIU_QUERY_OPCODE_READ_DESC,
		idn,
		0,
		0,
		0,
		result->size,
		result->layout);

	if (rc)
		hmr_query_error(rc, "read", "desc", UPIU_QUERY_OPCODE_READ_DESC,
			result->name, idn);

	return rc;
}

static int hmr_progress_read(__u32 *result,
	int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply   *bsg_rsp)
{
	int rc;
	struct descriptor *desc;
	struct descriptor_health_layout *layout;

	desc = &desc_health;

	/* Read descriptor Health */
	rc = hmr_desc_read(desc,
		fd,
		bsg_req,
		bsg_rsp,
		desc->idn);

	if (rc)
		goto out;

	layout = desc->layout;

	if (!HMR_QUIRK_REFRESH_PROGRESS_BYTE_ORDER)
		*result = be32toh(layout->refresh_progress);
	else
		*result = layout->refresh_progress;

	return rc;

out:
	print_error("hmr: read progress: failed.");
	return rc;
}

static int inline hmr_method_set(int fd, int method)
{
	int rc;
	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	/* Set attribute bRefreshMethod - force or selective */
	rc = hmr_attr_write(method,
		fd, &bsg_req, &bsg_rsp, QUERY_ATTR_IDN_REFRESH_METHOD);

	return rc;
}

static inline int hmr_unit_set(int fd, int unit)
{
	int rc;
	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	/* Set attribute bRefreshUnit - minimum or full */
	rc = hmr_attr_write(unit,
		fd, &bsg_req, &bsg_rsp, QUERY_ATTR_IDN_REFRESH_UNIT);

	return rc;
}

static inline int hmr_precondition_verify_status(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp)
{
	int rc;
	int cur = 0;
	int count = 10;
	__u32 result;

retry:
	/* Read refresh status */
	rc = hmr_attr_read(&result,
		fd,
		bsg_req,
		bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_STATUS);
	if (rc)
		goto out;

	if (result != HMR_ST_IDLE) {
		/* One time only */
		if (0 == cur)
			hmr_output_message("waiting idle status");

		/* Retry */
		if (++cur <= count) {
			hmr_delay_retry(1);
			goto retry;
		}

		/* Error */
		print_error("hmr: precondition: "
			"refresh status != 0x%x (0x%x)", HMR_ST_IDLE, result);
		rc = -EHMR_REFRESH_STATUS;
	}

out:
	return rc;
}

static inline int hmr_precondition_validate_totcount(__u32 *result,
	struct descriptor_health_layout *layout)
{
	int rc = EHMR_OK;
	__u32 refresh_totcount;

	if (!result || !layout)
		return -EHMR_INVAL;

	if (!HMR_QUIRK_REFRESH_TOTCOUNT_BYTE_ORDER)
		refresh_totcount = be32toh(layout->refresh_total_count);
	else
		refresh_totcount = layout->refresh_total_count;

	if (refresh_totcount >= HMR_REFRESH_MAX_TOTCOUNT) {
		print_error("hmr: precondition: "
			"refresh total count  >= max (0x%x >= 0x%x).",
			refresh_totcount, HMR_REFRESH_MAX_TOTCOUNT);
		rc = -EHMR_REFRESH_TOTCOUNT;
		goto out;
	}

	*result = refresh_totcount;

out:
	return rc;
}

static inline void hmr_output_wrong_run(int method, int unit)
{
	print_error("hmr: precondition: device's hmr-progress is not empty. "
		"Run is possible only with the method: %d, unit: %d",
		method, unit);
}

static int hmr_precondition_verify_run(int fd,
	int req_method, int req_unit, enum hmr_stage_skip *stage_passer)
{
	int rc;
	__u32 dev_method;
	__u32 dev_unit;
	__u32 dev_progress;

	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	if (!stage_passer)
		return -EHMR_INVAL;

	/*
	 * This code is intended to solve the case when the
	 * utility was run while HMR progress is not empty.
	 * It can happen, for example, when running the utility
	 * in one mode, then exit and run it again in some
	 * other mode, while the underline device's HMR status
	 * is still in progress.
	 *
	 * Let's make the policy simple:
	 * 1. Refresh progress is 0 -> OK.
	 * 2. Requested method equal device method
	 *			and
	 *    Requested unit equal device unit
	 *    1) Unit is minimum -> OK.
	 *	  2) Unit is full    -> OK, but have to skip the check for
	 *							refresh status to be "idle", since
	 *						    in this mode it is "in-progress"
	 *							until the HMR is completed.
	 * 3. Any other case is considered as violation.
	 */

	/* Read progress */
	rc = hmr_progress_read(&dev_progress, fd, &bsg_req, &bsg_rsp);
	if (rc)
		goto out;

	/* Clean run, may proceed with HMR */
	if (0 == dev_progress)
		goto out;

	/* Read method */
	rc = hmr_attr_read(&dev_method,
		fd,
		&bsg_req,
		&bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_METHOD);
	if (rc)
		goto out;

	/* Read unit */
	rc = hmr_attr_read(&dev_unit,
		fd,
		&bsg_req,
		&bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_UNIT);
	if (rc)
		goto out;

	/* Method is different, set error */
	if (req_method != dev_method) {
		hmr_output_wrong_run(dev_method, dev_unit);
		rc = -EHMR_REFRESH_UNIT;
		goto out;
	}

	/* Unit is different, set error */
	if (req_unit != dev_unit) {
		hmr_output_wrong_run(dev_method, dev_unit);
		rc = -EHMR_REFRESH_METHOD;
		goto out;
	}

	/*
	 * The progress is not empty, and method/unit are the same.
	 *
	 * 1. Unit type is full? - skip the refresh status check,
	 *    since it will never be completed/idle in this mode until ends.
	 * 2. Skip set method and unit, no need - the values are already set.
	 */
	if (dev_unit == HMR_UNIT_FULL)
		*stage_passer |= HMR_SKIP_STATUS_CHECK;

	 *stage_passer |= (HMR_SKIP_METHOD_SET | HMR_SKIP_UNIT_SET);

out:
	return rc;
}

static int hmr_precondition_verify(int fd,
	struct tool_options *opt, __u32 *totcount,
	enum hmr_stage_skip *stage_passer)
{
	int rc;
	struct descriptor *desc;
	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	if (!opt || !totcount || !stage_passer)
		return -EHMR_INVAL;

	/*
	 * 1. Verify the run perspective.
	 *
	 * In case of non-empty progress, make a decision
	 * if the run still can be proceeded.
	 */
	rc = hmr_precondition_verify_run(fd,
		opt->hmr_method, opt->hmr_unit, stage_passer);
	if (rc)
		goto err;

	/*
	 * 2. Verify refresh total count.
	 *
	 * Note: the Health descriptor was already read in
	 * hmr_precondition_verify_run(), so updated
	 * refresh total count is already available.
	 */
	desc = &desc_health;
	rc = hmr_precondition_validate_totcount(totcount, desc->layout);
	if (rc)
		goto err;

	/* Skip the refresh status check */
	if (*stage_passer & HMR_SKIP_STATUS_CHECK)
		goto success;

	/*
	 * 3. Verify refresh status.
	 *
	 * Read refresh status.
	 * In case the status is not Idle - retry.
	 *
	 * We are expecting here to get the Idle status (0x00),
	 * but in some cases the status may be different:
	 * aborted (0x02), completed (0x03), etc.
	 *
	 * Usually, the statuses of this kind are saved until
	 * the first reading of the attribute is occured, then
	 * the value o the attribute should be change to Idle (0x00),
	 * but let's be generous and give it a sufficient number of
	 * retries.
	 */
	 rc = hmr_precondition_verify_status(fd, &bsg_req, &bsg_rsp);
	 if (rc)
		goto err;

success:
	return rc;

err:
	print_error("hmr: precondition failed.");
	return rc;
}

static inline int hmr_postcondition_verify_progress(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp)
{
	int rc;
	__u32 result;

	/* Read Health descriptor, and get refresh progress field */
	rc = hmr_progress_read(&result, fd, bsg_req, bsg_rsp);
	if (rc)
		goto out;

	/* Progress should be 0 on HMR completion */
	if (result != 0) {
		print_error("hmr: postcondition: "
			"refresh progress != 0x0 (0x%x).", result);
		rc = -EHMR_REFRESH_PROGRESS;
		goto out;
	}

out:
	return rc;
}

static inline int hmr_postcondition_verify_status(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp)
{
	int rc;
	__u32 result;

	/* Read refresh status */
	rc = hmr_attr_read(&result,
		fd,
		bsg_req,
		bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_STATUS);

	if (rc)
		goto out;

	/* The accepted statuses are Completed and Idle */
	if (result != HMR_ST_COMPLETED && result != HMR_ST_IDLE) {
		print_error("hmr: postcondition: "
			"refresh status != (0x%x or 0x%x) (0x%x)",
			HMR_ST_COMPLETED, HMR_ST_IDLE, result);
		rc = -EHMR_REFRESH_STATUS;
		goto out;
	}

out:
	return rc;
}

static inline int hmr_postcondition_verify_totcount(__u32 prev_totcount,
		struct descriptor_health_layout *layout)
{
	int rc = EHMR_OK;
	__u32 result;

	if (!layout)
		return -EHMR_INVAL;

	if (!HMR_QUIRK_REFRESH_TOTCOUNT_BYTE_ORDER)
		result = be32toh(layout->refresh_total_count);
	else
		result = layout->refresh_total_count;

	if (result <= prev_totcount) {
		print_error("hmr: postcondition: "
			"refresh total count 0x%x <= 0x%x.",
			prev_totcount, result);
		rc = -EHMR_REFRESH_TOTCOUNT;
	}

	return rc;
}

static int hmr_postcondition_verify(int fd, __u32 totcount)
{
	int rc;
	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};
	struct descriptor *desc;

	desc = &desc_health;

	/*
	 * 1. Verify refresh progress.
	 *
	 * Progress equal to 0 indicates refresh was completed.
	 */
	rc = hmr_postcondition_verify_progress(fd, &bsg_req, &bsg_rsp);
	if (rc)
		goto err;

	/*
	 * 2. Check refresh status.
	 *
	 * The expected value is Completed (0x03) in first read,
	 * and Idle (0x00) in any following read (assuming no new
	 * HMR process begins).
	 * Perhaps, depending on the type of test, the first reading
	 * has already taken place. Therefore, we may consider both
	 * values to be valid.
	 */
	rc = hmr_postcondition_verify_status(fd, &bsg_req, &bsg_rsp);
	if (rc)
		goto err;

	/*
	 * 3. Verify refresh total count.
	 *
	 * Refresh total count expected to be increased
	 * upon completion.
	 *
	 * The health descriptor was already read in step 1
	 * doing hmr_progress_read(). Just use its layout.
	 */
	rc = hmr_postcondition_verify_totcount(totcount, desc->layout);
	if (rc)
		goto err;

	/* Success */
	return rc;

err:
	print_error("hmr: postcondition failed.");
	return rc;
}

static inline int hmr_refresh_initiate_retry(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp,
	int cur,
	int count)
{
	int rc;
	__u32 result;

	if (cur > count)
		return -EHMR_NORETRY;

	/*
	 * Read refresh status.
	 * Then retry only in case the status is Busy.
	 */
	rc = hmr_attr_read(&result,
		fd,
		bsg_req,
		bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_STATUS);

	if (rc)
		goto out;

	/* Other than Busy - canot be retried */
	if (result != HMR_ST_BUSY) {
		rc =  -EHMR_NORETRY;
		goto out;
	}

out:
	/* 0 - can be retried, otherwise cannot */
	return rc;
}

static int hmr_refresh_initiate(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp)
{
	int rc;
	int err;
	int cur = 0;
	int count = 10;

	/*
	 * Initiate refresh.
	 * For that, set flag fRefreshEnable to 1.
	 * In case device command queues are not empty,
	 * this query request may fail. In such a case
	 * the bRefreshStatus attribite shell be set to
	 * 0x04 - HMR_ST_BUSY. This case is handled by
	 * hmr_refresh_initiate_retry().
	 */
retry:
	rc = hmr_flag_modify(fd, bsg_req, bsg_rsp,
		UPIU_QUERY_OPCODE_SET_FLAG,
		QUERY_FLAG_IDN_REFRESH_ENABLE);

	/* Success */
	if (!rc)
		goto out;

	/* Check query can be retried */
	err = hmr_refresh_initiate_retry(fd, bsg_req, bsg_rsp, ++cur, count);
	if (!err) {
		hmr_delay_retry(1);
		goto retry;
	}

	print_error("hmr: initiate unit refresh: setting flag "
		"fRefreshEnable failed after %d retries (%d).", count, rc);

out:
	return rc;
}

static int hmr_unit_verify_completed(int fd,
	struct ufs_bsg_request *bsg_req,
	struct ufs_bsg_reply *bsg_rsp)
{
	__u32 result;
	int rc;
	int cur = 0;
	int count = 10;

	/*
	 * Read refresh status.
	 *
	 * The expected status is Completed, which changes to Idle
	 * after it was read once. Thus, if a given attribute reads
	 * some other process, then we are in a race state and there
	 * is a possibility that the attribute value will be reset
	 * to Idle by another process. Thus, we will consider both
	 * statuses - Completed and Idle as valid at this stage.
	 */
retry:
	rc = hmr_attr_read(&result,
		fd,
		bsg_req,
		bsg_rsp,
		QUERY_ATTR_IDN_REFRESH_STATUS);

	/* Error or (Completed / Idle) */
	if (rc ||
		result == HMR_ST_COMPLETED ||
		result == HMR_ST_IDLE)
		goto out;

	/* Retry */
	if (++cur <= count) {
		hmr_delay_retry(1);
		goto retry;
	}

	/*
	 * Cannot be completed, result holds
	 * other than HMR_ST_COMPLETED or HMR_ST_IDLE status.
	 */
	rc = -EHMR_REFRESH_STATUS;
	print_error("hmr: verify unit completed: getting status "
		"completed failed after %d retries (%d).", count, result);

out:
	return rc;
}

static int hmr_full_start(int fd, int method)
{
	int rc;
	__u32 result;
	__u64 iter = 0;

	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	hmr_output_header("full", method);

	/* Start full refresh */
	rc = hmr_refresh_initiate(fd, &bsg_req, &bsg_rsp);
	if (rc)
		goto out;

	/* Start progress loop */
	while (1) {
		/* Sample progress */
		rc = hmr_progress_read(&result, fd, &bsg_req, &bsg_rsp);
		if (rc)
			goto out;

		hmr_output_progress(result, iter++, 1, "");

		/* Progress is 0 - completed */
		if (0 == result)
			break;
	}

out:
	hmr_output_footer(rc);
	return rc;
}

static int hmr_unit_start(int fd, int method)
{
	int rc;
	__u32 result;
	__u64 iter = 0;

	struct ufs_bsg_request bsg_req = {0};
	struct ufs_bsg_reply   bsg_rsp = {0};

	hmr_output_header("minimum", method);

	/* Start HMR loop */
	while (1) {
		/* Start unit refresh */
		rc = hmr_refresh_initiate(fd, &bsg_req, &bsg_rsp);
		if (rc)
			goto out;

		/* Verify completed */
		rc = hmr_unit_verify_completed(fd, &bsg_req, &bsg_rsp);
		if (rc)
			goto out;

		/* Read progress */
		rc = hmr_progress_read(&result, fd, &bsg_req, &bsg_rsp);
		if (rc)
			goto out;

		hmr_output_progress(result, iter++, 0, "");

		/* Progress is 0 - completed */
		if (0 == result)
			break;
	}

out:
	hmr_output_footer(rc);
	return rc;
}

int do_hmr(struct tool_options *opt)
{
	int rc;
	int fd;
	int (*hmr_job)(int, int);
	__u32 refresh_totcount;
	enum hmr_stage_skip stage_passer = 0;

	if (!opt || !opt->path)
		return -EHMR_INVAL;

	/* Open dev in subject */
	rc = hmr_dev_open(opt->path, &fd);
	if (rc)
		goto out;

	/* Make verifications prior to HMR */
	rc = hmr_precondition_verify(fd, opt, &refresh_totcount, &stage_passer);
	if (rc)
		goto free;

	/* Set HMR method: force or selective */
	if (!(stage_passer & HMR_SKIP_METHOD_SET)) {
		rc = hmr_method_set(fd, opt->hmr_method);
		if (rc)
			goto free;
	}

	/* Set HMR unit: minimum or full */
	if (!(stage_passer & HMR_SKIP_UNIT_SET)) {
		rc = hmr_unit_set(fd, opt->hmr_unit);
		if (rc)
			goto free;
	}

	/* Do the HMR job */
	hmr_job = opt->hmr_unit == HMR_UNIT_MIN ?
		&hmr_unit_start : &hmr_full_start;

	rc = (*hmr_job)(fd, opt->hmr_method);
	if (rc)
		goto free;

	/* Verify variables upon completion */
	rc = hmr_postcondition_verify(fd, refresh_totcount);
	if (rc)
		goto free;

free:
	rc = hmr_dev_close(opt->path, fd);

out:
	return rc;
}

void hmr_help(char *tool_name)
{
	/* General use case description */
	printf("\n HMR command usage:\n");
	printf("\n\t%s hmr [-p] <path to device> ([-x] <method> [-y] <unit>)\n",
		tool_name);

	/* -p: mandatory, device path */
	printf("\n\t-p\t path - mandatory, ufs-bsg device path\n");

	/* -x: optional, HMR method */
	printf("\n\t-x\t method - optional, the default is %d\n",
		HMR_METHOD_SELECTIVE);
	printf("\t\t\t %-3d: %-25s\n",
		HMR_METHOD_FORCE, "force, refresh all blocks containing data");
	printf("\t\t\t %-3d: %-25s\n",
		HMR_METHOD_SELECTIVE, "selective, refresh marked blocks only");

	/* -y: optional, HMR unit */
	printf("\n\t-y\t unit - optional, the default is %d\n", HMR_UNIT_MIN);
	printf("\t\t\t %-3d: %-25s\n",
		HMR_UNIT_MIN, "minimum, perform HMR by minimum refresh units");
	printf("\t\t\t %-3d: %-25s\n",
		HMR_UNIT_FULL, "full, perform a full HMR cycle in one command");
}
