// SPDX-License-Identifier: GPL-2.0
/*
 *    DIAGNOSE X'2C4' instruction based HMC FTP services, useable on z/VM
 *
 *    Copyright IBM Corp. 2013
 *    Author(s): Ralf Hoppe (rhoppe@de.ibm.com)
 *
 */

#define KMSG_COMPONENT "hmcdrv"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/wait.h>
#include <linux/string.h>
#include <asm/asm-extable.h>
#include <asm/ctl_reg.h>
#include <asm/diag.h>

#include "hmcdrv_ftp.h"
#include "diag_ftp.h"

/* DIAGNOSE X'2C4' return codes in Ry */
#define DIAG_FTP_RET_OK	0 /* HMC FTP started successfully */
#define DIAG_FTP_RET_EBUSY	4 /* HMC FTP service currently busy */
#define DIAG_FTP_RET_EIO	8 /* HMC FTP service I/O error */
/* and an artificial extension */
#define DIAG_FTP_RET_EPERM	2 /* HMC FTP service privilege error */

/* FTP service status codes (after INTR at guest real location 133) */
#define DIAG_FTP_STAT_OK	0U /* request completed successfully */
#define DIAG_FTP_STAT_PGCC	4U /* program check condition */
#define DIAG_FTP_STAT_PGIOE	8U /* paging I/O error */
#define DIAG_FTP_STAT_TIMEOUT	12U /* timeout */
#define DIAG_FTP_STAT_EBASE	16U /* base of error codes from SCLP */
#define DIAG_FTP_STAT_LDFAIL	(DIAG_FTP_STAT_EBASE + 1U) /* failed */
#define DIAG_FTP_STAT_LDNPERM	(DIAG_FTP_STAT_EBASE + 2U) /* not allowed */
#define DIAG_FTP_STAT_LDRUNS	(DIAG_FTP_STAT_EBASE + 3U) /* runs */
#define DIAG_FTP_STAT_LDNRUNS	(DIAG_FTP_STAT_EBASE + 4U) /* not runs */

/**
 * struct diag_ftp_ldfpl - load file FTP parameter list (LDFPL)
 * @bufaddr: real buffer address (at 4k boundary)
 * @buflen: length of buffer
 * @offset: dir/file offset
 * @intparm: interruption parameter (unused)
 * @transferred: bytes transferred
 * @fsize: file size, filled on GET
 * @failaddr: failing address
 * @spare: padding
 * @fident: file name - ASCII
 */
struct diag_ftp_ldfpl {
	u64 bufaddr;
	u64 buflen;
	u64 offset;
	u64 intparm;
	u64 transferred;
	u64 fsize;
	u64 failaddr;
	u64 spare;
	u8 fident[HMCDRV_FTP_FIDENT_MAX];
} __packed;

static DECLARE_COMPLETION(diag_ftp_rx_complete);
static int diag_ftp_subcode;

/**
 * diag_ftp_handler() - FTP services IRQ handler
 * @extirq: external interrupt (sub-) code
 * @param32: 32-bit interruption parameter from &struct diag_ftp_ldfpl
 * @param64: unused (for 64-bit interrupt parameters)
 */
static void diag_ftp_handler(struct ext_code extirq,
			     unsigned int param32,
			     unsigned long param64)
{
	if ((extirq.subcode >> 8) != 8)
		return; /* not a FTP services sub-code */

	inc_irq_stat(IRQEXT_FTP);
	diag_ftp_subcode = extirq.subcode & 0xffU;
	complete(&diag_ftp_rx_complete);
}

/**
 * diag_ftp_2c4() - DIAGNOSE X'2C4' service call
 * @fpl: pointer to prepared LDFPL
 * @cmd: FTP command to be executed
 *
 * Performs a DIAGNOSE X'2C4' call with (input/output) FTP parameter list
 * @fpl and FTP function code @cmd. In case of an error the function does
 * nothing and returns an (negative) error code.
 *
 * Notes:
 * 1. This function only initiates a transfer, so the caller must wait
 *    for completion (asynchronous execution).
 * 2. The FTP parameter list @fpl must be aligned to a double-word boundary.
 * 3. fpl->bufaddr must be a real address, 4k aligned
 */
static int diag_ftp_2c4(struct diag_ftp_ldfpl *fpl,
			enum hmcdrv_ftp_cmdid cmd)
{
	int rc;

	diag_stat_inc(DIAG_STAT_X2C4);
	asm volatile(
		"	diag	%[addr],%[cmd],0x2c4\n"
		"0:	j	2f\n"
		"1:	la	%[rc],%[err]\n"
		"2:\n"
		EX_TABLE(0b, 1b)
		: [rc] "=d" (rc), "+m" (*fpl)
		: [cmd] "0" (cmd), [addr] "d" (virt_to_phys(fpl)),
		  [err] "i" (DIAG_FTP_RET_EPERM)
		: "cc");

	switch (rc) {
	case DIAG_FTP_RET_OK:
		return 0;
	case DIAG_FTP_RET_EBUSY:
		return -EBUSY;
	case DIAG_FTP_RET_EPERM:
		return -EPERM;
	case DIAG_FTP_RET_EIO:
	default:
		return -EIO;
	}
}

/**
 * diag_ftp_cmd() - executes a DIAG X'2C4' FTP command, targeting a HMC
 * @ftp: pointer to FTP command specification
 * @fsize: return of file size (or NULL if undesirable)
 *
 * Attention: Notice that this function is not reentrant - so the caller
 * must ensure locking.
 *
 * Return: number of bytes read/written or a (negative) error code
 */
ssize_t diag_ftp_cmd(const struct hmcdrv_ftp_cmdspec *ftp, size_t *fsize)
{
	struct diag_ftp_ldfpl *ldfpl;
	ssize_t len;
#ifdef DEBUG
	unsigned long start_jiffies;

	pr_debug("starting DIAG X'2C4' on '%s', requesting %zd bytes\n",
		 ftp->fname, ftp->len);
	start_jiffies = jiffies;
#endif
	init_completion(&diag_ftp_rx_complete);

	ldfpl = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!ldfpl) {
		len = -ENOMEM;
		goto out;
	}

	len = strlcpy(ldfpl->fident, ftp->fname, sizeof(ldfpl->fident));
	if (len >= HMCDRV_FTP_FIDENT_MAX) {
		len = -EINVAL;
		goto out_free;
	}

	ldfpl->transferred = 0;
	ldfpl->fsize = 0;
	ldfpl->offset = ftp->ofs;
	ldfpl->buflen = ftp->len;
	ldfpl->bufaddr = virt_to_phys(ftp->buf);

	len = diag_ftp_2c4(ldfpl, ftp->id);
	if (len)
		goto out_free;

	/*
	 * There is no way to cancel the running diag X'2C4', the code
	 * needs to wait unconditionally until the transfer is complete.
	 */
	wait_for_completion(&diag_ftp_rx_complete);

#ifdef DEBUG
	pr_debug("completed DIAG X'2C4' after %lu ms\n",
		 (jiffies - start_jiffies) * 1000 / HZ);
	pr_debug("status of DIAG X'2C4' is %u, with %lld/%lld bytes\n",
		 diag_ftp_subcode, ldfpl->transferred, ldfpl->fsize);
#endif

	switch (diag_ftp_subcode) {
	case DIAG_FTP_STAT_OK: /* success */
		len = ldfpl->transferred;
		if (fsize)
			*fsize = ldfpl->fsize;
		break;
	case DIAG_FTP_STAT_LDNPERM:
		len = -EPERM;
		break;
	case DIAG_FTP_STAT_LDRUNS:
		len = -EBUSY;
		break;
	case DIAG_FTP_STAT_LDFAIL:
		len = -ENOENT; /* no such file or media */
		break;
	default:
		len = -EIO;
		break;
	}

out_free:
	free_page((unsigned long) ldfpl);
out:
	return len;
}

/**
 * diag_ftp_startup() - startup of FTP services, when running on z/VM
 *
 * Return: 0 on success, else an (negative) error code
 */
int diag_ftp_startup(void)
{
	int rc;

	rc = register_external_irq(EXT_IRQ_CP_SERVICE, diag_ftp_handler);
	if (rc)
		return rc;

	irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
	return 0;
}

/**
 * diag_ftp_shutdown() - shutdown of FTP services, when running on z/VM
 */
void diag_ftp_shutdown(void)
{
	irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
	unregister_external_irq(EXT_IRQ_CP_SERVICE, diag_ftp_handler);
}
