/*
 * Copyright 2015 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */


#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include "hcalls.h"
#include "trace.h"

#define CXL_HCALL_TIMEOUT 60000
#define CXL_HCALL_TIMEOUT_DOWNLOAD 120000

#define H_ATTACH_CA_PROCESS    0x344
#define H_CONTROL_CA_FUNCTION  0x348
#define H_DETACH_CA_PROCESS    0x34C
#define H_COLLECT_CA_INT_INFO  0x350
#define H_CONTROL_CA_FAULTS    0x354
#define H_DOWNLOAD_CA_FUNCTION 0x35C
#define H_DOWNLOAD_CA_FACILITY 0x364
#define H_CONTROL_CA_FACILITY  0x368

#define H_CONTROL_CA_FUNCTION_RESET                   1 /* perform a reset */
#define H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS         2 /* suspend a process from being executed */
#define H_CONTROL_CA_FUNCTION_RESUME_PROCESS          3 /* resume a process to be executed */
#define H_CONTROL_CA_FUNCTION_READ_ERR_STATE          4 /* read the error state */
#define H_CONTROL_CA_FUNCTION_GET_AFU_ERR             5 /* collect the AFU error buffer */
#define H_CONTROL_CA_FUNCTION_GET_CONFIG              6 /* collect configuration record */
#define H_CONTROL_CA_FUNCTION_GET_DOWNLOAD_STATE      7 /* query to return download status */
#define H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS       8 /* terminate the process before completion */
#define H_CONTROL_CA_FUNCTION_COLLECT_VPD             9 /* collect VPD */
#define H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT   11 /* read the function-wide error data based on an interrupt */
#define H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT   12 /* acknowledge function-wide error data based on an interrupt */
#define H_CONTROL_CA_FUNCTION_GET_ERROR_LOG          13 /* retrieve the Platform Log ID (PLID) of an error log */

#define H_CONTROL_CA_FAULTS_RESPOND_PSL         1
#define H_CONTROL_CA_FAULTS_RESPOND_AFU         2

#define H_CONTROL_CA_FACILITY_RESET             1 /* perform a reset */
#define H_CONTROL_CA_FACILITY_COLLECT_VPD       2 /* collect VPD */

#define H_DOWNLOAD_CA_FACILITY_DOWNLOAD         1 /* download adapter image */
#define H_DOWNLOAD_CA_FACILITY_VALIDATE         2 /* validate adapter image */


#define _CXL_LOOP_HCALL(call, rc, retbuf, fn, ...)			\
	{								\
		unsigned int delay, total_delay = 0;			\
		u64 token = 0;						\
									\
		memset(retbuf, 0, sizeof(retbuf));			\
		while (1) {						\
			rc = call(fn, retbuf, __VA_ARGS__, token);	\
			token = retbuf[0];				\
			if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))	\
				break;					\
									\
			if (rc == H_BUSY)				\
				delay = 10;				\
			else						\
				delay = get_longbusy_msecs(rc);		\
									\
			total_delay += delay;				\
			if (total_delay > CXL_HCALL_TIMEOUT) {		\
				WARN(1, "Warning: Giving up waiting for CXL hcall " \
					"%#x after %u msec\n", fn, total_delay); \
				rc = H_BUSY;				\
				break;					\
			}						\
			msleep(delay);					\
		}							\
	}
#define CXL_H_WAIT_UNTIL_DONE(...)  _CXL_LOOP_HCALL(plpar_hcall, __VA_ARGS__)
#define CXL_H9_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall9, __VA_ARGS__)

#define _PRINT_MSG(rc, format, ...)					\
	{								\
		if ((rc != H_SUCCESS) && (rc != H_CONTINUE))		\
			pr_err(format, __VA_ARGS__);			\
		else							\
			pr_devel(format, __VA_ARGS__);			\
	}								\


static char *afu_op_names[] = {
	"UNKNOWN_OP",		/* 0 undefined */
	"RESET",		/* 1 */
	"SUSPEND_PROCESS",	/* 2 */
	"RESUME_PROCESS",	/* 3 */
	"READ_ERR_STATE",	/* 4 */
	"GET_AFU_ERR",		/* 5 */
	"GET_CONFIG",		/* 6 */
	"GET_DOWNLOAD_STATE",	/* 7 */
	"TERMINATE_PROCESS",	/* 8 */
	"COLLECT_VPD",		/* 9 */
	"UNKNOWN_OP",		/* 10 undefined */
	"GET_FUNCTION_ERR_INT",	/* 11 */
	"ACK_FUNCTION_ERR_INT",	/* 12 */
	"GET_ERROR_LOG",	/* 13 */
};

static char *control_adapter_op_names[] = {
	"UNKNOWN_OP",		/* 0 undefined */
	"RESET",		/* 1 */
	"COLLECT_VPD",		/* 2 */
};

static char *download_op_names[] = {
	"UNKNOWN_OP",		/* 0 undefined */
	"DOWNLOAD",		/* 1 */
	"VALIDATE",		/* 2 */
};

static char *op_str(unsigned int op, char *name_array[], int array_len)
{
	if (op >= array_len)
		return "UNKNOWN_OP";
	return name_array[op];
}

#define OP_STR(op, name_array)      op_str(op, name_array, ARRAY_SIZE(name_array))

#define OP_STR_AFU(op)              OP_STR(op, afu_op_names)
#define OP_STR_CONTROL_ADAPTER(op)  OP_STR(op, control_adapter_op_names)
#define OP_STR_DOWNLOAD_ADAPTER(op) OP_STR(op, download_op_names)


long cxl_h_attach_process(u64 unit_address,
			struct cxl_process_element_hcall *element,
			u64 *process_token, u64 *mmio_addr, u64 *mmio_size)
{
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
	long rc;

	CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_ATTACH_CA_PROCESS, unit_address, virt_to_phys(element));
	_PRINT_MSG(rc, "cxl_h_attach_process(%#.16llx, %#.16lx): %li\n",
		unit_address, virt_to_phys(element), rc);
	trace_cxl_hcall_attach(unit_address, virt_to_phys(element), retbuf[0], retbuf[1], retbuf[2], rc);

	pr_devel("token: 0x%.8lx mmio_addr: 0x%lx mmio_size: 0x%lx\nProcess Element Structure:\n",
		retbuf[0], retbuf[1], retbuf[2]);
	cxl_dump_debug_buffer(element, sizeof(*element));

	switch (rc) {
	case H_SUCCESS:       /* The process info is attached to the coherent platform function */
		*process_token = retbuf[0];
		if (mmio_addr)
			*mmio_addr = retbuf[1];
		if (mmio_size)
			*mmio_size = retbuf[2];
		return 0;
	case H_PARAMETER:     /* An incorrect parameter was supplied. */
	case H_FUNCTION:      /* The function is not supported. */
		return -EINVAL;
	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
	case H_RESOURCE:      /* The coherent platform function does not have enough additional resource to attach the process */
	case H_HARDWARE:      /* A hardware event prevented the attach operation */
	case H_STATE:         /* The coherent platform function is not in a valid state */
	case H_BUSY:
		return -EBUSY;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_detach_process - Detach a process element from a coherent
 *                        platform function.
 */
long cxl_h_detach_process(u64 unit_address, u64 process_token)
{
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
	long rc;

	CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_DETACH_CA_PROCESS, unit_address, process_token);
	_PRINT_MSG(rc, "cxl_h_detach_process(%#.16llx, 0x%.8llx): %li\n", unit_address, process_token, rc);
	trace_cxl_hcall_detach(unit_address, process_token, rc);

	switch (rc) {
	case H_SUCCESS:       /* The process was detached from the coherent platform function */
		return 0;
	case H_PARAMETER:     /* An incorrect parameter was supplied. */
		return -EINVAL;
	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
	case H_RESOURCE:      /* The function has page table mappings for MMIO */
	case H_HARDWARE:      /* A hardware event prevented the detach operation */
	case H_STATE:         /* The coherent platform function is not in a valid state */
	case H_BUSY:
		return -EBUSY;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_control_function - This H_CONTROL_CA_FUNCTION hypervisor call allows
 *                          the partition to manipulate or query
 *                          certain coherent platform function behaviors.
 */
static long cxl_h_control_function(u64 unit_address, u64 op,
				   u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
{
	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
	long rc;

	CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FUNCTION, unit_address, op, p1, p2, p3, p4);
	_PRINT_MSG(rc, "cxl_h_control_function(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
		unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
	trace_cxl_hcall_control_function(unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);

	switch (rc) {
	case H_SUCCESS:       /* The operation is completed for the coherent platform function */
		if ((op == H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT ||
		     op == H_CONTROL_CA_FUNCTION_READ_ERR_STATE ||
		     op == H_CONTROL_CA_FUNCTION_COLLECT_VPD))
			*out = retbuf[0];
		return 0;
	case H_PARAMETER:     /* An incorrect parameter was supplied. */
	case H_FUNCTION:      /* The function is not supported. */
	case H_NOT_FOUND:     /* The operation supplied was not valid */
	case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
	case H_SG_LIST:       /* An block list entry was invalid */
		return -EINVAL;
	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
	case H_RESOURCE:      /* The function has page table mappings for MMIO */
	case H_HARDWARE:      /* A hardware event prevented the attach operation */
	case H_STATE:         /* The coherent platform function is not in a valid state */
	case H_BUSY:
		return -EBUSY;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_reset_afu - Perform a reset to the coherent platform function.
 */
long cxl_h_reset_afu(u64 unit_address)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_RESET,
				0, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_suspend_process - Suspend a process from being executed
 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
 *              process was attached.
 */
long cxl_h_suspend_process(u64 unit_address, u64 process_token)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS,
				process_token, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_resume_process - Resume a process to be executed
 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
 *              process was attached.
 */
long cxl_h_resume_process(u64 unit_address, u64 process_token)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_RESUME_PROCESS,
				process_token, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_read_error_state - Checks the error state of the coherent
 *                          platform function.
 * R4 contains the error state
 */
long cxl_h_read_error_state(u64 unit_address, u64 *state)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_READ_ERR_STATE,
				0, 0, 0, 0,
				state);
}

/**
 * cxl_h_get_afu_err - collect the AFU error buffer
 * Parameter1 = byte offset into error buffer to retrieve, valid values
 *              are between 0 and (ibm,error-buffer-size - 1)
 * Parameter2 = 4K aligned real address of error buffer, to be filled in
 * Parameter3 = length of error buffer, valid values are 4K or less
 */
long cxl_h_get_afu_err(u64 unit_address, u64 offset,
		u64 buf_address, u64 len)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_GET_AFU_ERR,
				offset, buf_address, len, 0,
				NULL);
}

/**
 * cxl_h_get_config - collect configuration record for the
 *                    coherent platform function
 * Parameter1 = # of configuration record to retrieve, valid values are
 *              between 0 and (ibm,#config-records - 1)
 * Parameter2 = byte offset into configuration record to retrieve,
 *              valid values are between 0 and (ibm,config-record-size - 1)
 * Parameter3 = 4K aligned real address of configuration record buffer,
 *              to be filled in
 * Parameter4 = length of configuration buffer, valid values are 4K or less
 */
long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
		u64 buf_address, u64 len)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_GET_CONFIG,
				cr_num, offset, buf_address, len,
				NULL);
}

/**
 * cxl_h_terminate_process - Terminate the process before completion
 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
 *              process was attached.
 */
long cxl_h_terminate_process(u64 unit_address, u64 process_token)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS,
				process_token, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
 * Parameter1 = # of VPD record to retrieve, valid values are between 0
 *              and (ibm,#config-records - 1).
 * Parameter2 = 4K naturally aligned real buffer containing block
 *              list entries
 * Parameter3 = number of block list entries in the block list, valid
 *              values are between 0 and 256
 */
long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
		       u64 num, u64 *out)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_COLLECT_VPD,
				record, list_address, num, 0,
				out);
}

/**
 * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
 */
long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT,
				0, 0, 0, 0, reg);
}

/**
 * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
 *                                based on an interrupt
 * Parameter1 = value to write to the function-wide error interrupt register
 */
long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT,
				value, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
 *                       an error log
 */
long cxl_h_get_error_log(u64 unit_address, u64 value)
{
	return cxl_h_control_function(unit_address,
				H_CONTROL_CA_FUNCTION_GET_ERROR_LOG,
				0, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_collect_int_info - Collect interrupt info about a coherent
 *                          platform function after an interrupt occurred.
 */
long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
			    struct cxl_irq_info *info)
{
	long rc;

	BUG_ON(sizeof(*info) != sizeof(unsigned long[PLPAR_HCALL9_BUFSIZE]));

	rc = plpar_hcall9(H_COLLECT_CA_INT_INFO, (unsigned long *) info,
			unit_address, process_token);
	_PRINT_MSG(rc, "cxl_h_collect_int_info(%#.16llx, 0x%llx): %li\n",
		unit_address, process_token, rc);
	trace_cxl_hcall_collect_int_info(unit_address, process_token, rc);

	switch (rc) {
	case H_SUCCESS:     /* The interrupt info is returned in return registers. */
		pr_devel("dsisr:%#llx, dar:%#llx, dsr:%#llx, pid:%u, tid:%u, afu_err:%#llx, errstat:%#llx\n",
			info->dsisr, info->dar, info->dsr, info->pid,
			info->tid, info->afu_err, info->errstat);
		return 0;
	case H_PARAMETER:   /* An incorrect parameter was supplied. */
		return -EINVAL;
	case H_AUTHORITY:   /* The partition does not have authority to perform this hcall. */
	case H_HARDWARE:    /* A hardware event prevented the collection of the interrupt info.*/
	case H_STATE:       /* The coherent platform function is not in a valid state to collect interrupt info. */
		return -EBUSY;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_control_faults - Control the operation of a coherent platform
 *                        function after a fault occurs.
 *
 * Parameters
 *    control-mask: value to control the faults
 *                  looks like PSL_TFC_An shifted >> 32
 *    reset-mask: mask to control reset of function faults
 *                Set reset_mask = 1 to reset PSL errors
 */
long cxl_h_control_faults(u64 unit_address, u64 process_token,
			  u64 control_mask, u64 reset_mask)
{
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
	long rc;

	memset(retbuf, 0, sizeof(retbuf));

	rc = plpar_hcall(H_CONTROL_CA_FAULTS, retbuf, unit_address,
			H_CONTROL_CA_FAULTS_RESPOND_PSL, process_token,
			control_mask, reset_mask);
	_PRINT_MSG(rc, "cxl_h_control_faults(%#.16llx, 0x%llx, %#llx, %#llx): %li (%#lx)\n",
		unit_address, process_token, control_mask, reset_mask,
		rc, retbuf[0]);
	trace_cxl_hcall_control_faults(unit_address, process_token,
				control_mask, reset_mask, retbuf[0], rc);

	switch (rc) {
	case H_SUCCESS:    /* Faults were successfully controlled for the function. */
		return 0;
	case H_PARAMETER:  /* An incorrect parameter was supplied. */
		return -EINVAL;
	case H_HARDWARE:   /* A hardware event prevented the control of faults. */
	case H_STATE:      /* The function was in an invalid state. */
	case H_AUTHORITY:  /* The partition does not have authority to perform this hcall; the coherent platform facilities may need to be licensed. */
		return -EBUSY;
	case H_FUNCTION:   /* The function is not supported */
	case H_NOT_FOUND:  /* The operation supplied was not valid */
		return -EINVAL;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_control_facility - This H_CONTROL_CA_FACILITY hypervisor call
 *                          allows the partition to manipulate or query
 *                          certain coherent platform facility behaviors.
 */
static long cxl_h_control_facility(u64 unit_address, u64 op,
				   u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
{
	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
	long rc;

	CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FACILITY, unit_address, op, p1, p2, p3, p4);
	_PRINT_MSG(rc, "cxl_h_control_facility(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
		unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
	trace_cxl_hcall_control_facility(unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);

	switch (rc) {
	case H_SUCCESS:       /* The operation is completed for the coherent platform facility */
		if (op == H_CONTROL_CA_FACILITY_COLLECT_VPD)
			*out = retbuf[0];
		return 0;
	case H_PARAMETER:     /* An incorrect parameter was supplied. */
	case H_FUNCTION:      /* The function is not supported. */
	case H_NOT_FOUND:     /* The operation supplied was not valid */
	case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
	case H_SG_LIST:       /* An block list entry was invalid */
		return -EINVAL;
	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
	case H_RESOURCE:      /* The function has page table mappings for MMIO */
	case H_HARDWARE:      /* A hardware event prevented the attach operation */
	case H_STATE:         /* The coherent platform facility is not in a valid state */
	case H_BUSY:
		return -EBUSY;
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
 */
long cxl_h_reset_adapter(u64 unit_address)
{
	return cxl_h_control_facility(unit_address,
				H_CONTROL_CA_FACILITY_RESET,
				0, 0, 0, 0,
				NULL);
}

/**
 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
 * Parameter1 = 4K naturally aligned real buffer containing block
 *              list entries
 * Parameter2 = number of block list entries in the block list, valid
 *              values are between 0 and 256
 */
long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
			       u64 num, u64 *out)
{
	return cxl_h_control_facility(unit_address,
				H_CONTROL_CA_FACILITY_COLLECT_VPD,
				list_address, num, 0, 0,
				out);
}

/**
 * cxl_h_download_facility - This H_DOWNLOAD_CA_FACILITY
 *                    hypervisor call provide platform support for
 *                    downloading a base adapter image to the coherent
 *                    platform facility, and for validating the entire
 *                    image after the download.
 * Parameters
 *    op: operation to perform to the coherent platform function
 *      Download: operation = 1, the base image in the coherent platform
 *                               facility is first erased, and then
 *                               programmed using the image supplied
 *                               in the scatter/gather list.
 *      Validate: operation = 2, the base image in the coherent platform
 *                               facility is compared with the image
 *                               supplied in the scatter/gather list.
 *    list_address: 4K naturally aligned real buffer containing
 *                  scatter/gather list entries.
 *    num: number of block list entries in the scatter/gather list.
 */
static long cxl_h_download_facility(u64 unit_address, u64 op,
				    u64 list_address, u64 num,
				    u64 *out)
{
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
	unsigned int delay, total_delay = 0;
	u64 token = 0;
	long rc;

	if (*out != 0)
		token = *out;

	memset(retbuf, 0, sizeof(retbuf));
	while (1) {
		rc = plpar_hcall(H_DOWNLOAD_CA_FACILITY, retbuf,
				 unit_address, op, list_address, num,
				 token);
		token = retbuf[0];
		if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))
			break;

		if (rc != H_BUSY) {
			delay = get_longbusy_msecs(rc);
			total_delay += delay;
			if (total_delay > CXL_HCALL_TIMEOUT_DOWNLOAD) {
				WARN(1, "Warning: Giving up waiting for CXL hcall "
					"%#x after %u msec\n",
					H_DOWNLOAD_CA_FACILITY, total_delay);
				rc = H_BUSY;
				break;
			}
			msleep(delay);
		}
	}
	_PRINT_MSG(rc, "cxl_h_download_facility(%#.16llx, %s(%#llx, %#llx), %#lx): %li\n",
		 unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
	trace_cxl_hcall_download_facility(unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);

	switch (rc) {
	case H_SUCCESS:       /* The operation is completed for the coherent platform facility */
		return 0;
	case H_PARAMETER:     /* An incorrect parameter was supplied */
	case H_FUNCTION:      /* The function is not supported. */
	case H_SG_LIST:       /* An block list entry was invalid */
	case H_BAD_DATA:      /* Image verification failed */
		return -EINVAL;
	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
	case H_RESOURCE:      /* The function has page table mappings for MMIO */
	case H_HARDWARE:      /* A hardware event prevented the attach operation */
	case H_STATE:         /* The coherent platform facility is not in a valid state */
	case H_BUSY:
		return -EBUSY;
	case H_CONTINUE:
		*out = retbuf[0];
		return 1;  /* More data is needed for the complete image */
	default:
		WARN(1, "Unexpected return code: %lx", rc);
		return -EINVAL;
	}
}

/**
 * cxl_h_download_adapter_image - Download the base image to the coherent
 *                                platform facility.
 */
long cxl_h_download_adapter_image(u64 unit_address,
				  u64 list_address, u64 num,
				  u64 *out)
{
	return cxl_h_download_facility(unit_address,
				       H_DOWNLOAD_CA_FACILITY_DOWNLOAD,
				       list_address, num, out);
}

/**
 * cxl_h_validate_adapter_image - Validate the base image in the coherent
 *                                platform facility.
 */
long cxl_h_validate_adapter_image(u64 unit_address,
				  u64 list_address, u64 num,
				  u64 *out)
{
	return cxl_h_download_facility(unit_address,
				       H_DOWNLOAD_CA_FACILITY_VALIDATE,
				       list_address, num, out);
}
