// SPDX-License-Identifier: GPL-2.0
/*
 *    SCLP Event Type (ET) 7 - Diagnostic Test FTP Services, useable on LPAR
 *
 *    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/slab.h>
#include <linux/io.h>
#include <linux/wait.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <asm/sysinfo.h>
#include <asm/ebcdic.h>

#include "sclp.h"
#include "sclp_diag.h"
#include "sclp_ftp.h"

static DECLARE_COMPLETION(sclp_ftp_rx_complete);
static u8 sclp_ftp_ldflg;
static u64 sclp_ftp_fsize;
static u64 sclp_ftp_length;

/**
 * sclp_ftp_txcb() - Diagnostic Test FTP services SCLP command callback
 * @req: sclp request
 * @data: pointer to struct completion
 */
static void sclp_ftp_txcb(struct sclp_req *req, void *data)
{
	struct completion *completion = data;

#ifdef DEBUG
	pr_debug("SCLP (ET7) TX-IRQ, SCCB @ 0x%p: %*phN\n",
		 req->sccb, 24, req->sccb);
#endif
	complete(completion);
}

/**
 * sclp_ftp_rxcb() - Diagnostic Test FTP services receiver event callback
 * @evbuf: pointer to Diagnostic Test (ET7) event buffer
 */
static void sclp_ftp_rxcb(struct evbuf_header *evbuf)
{
	struct sclp_diag_evbuf *diag = (struct sclp_diag_evbuf *) evbuf;

	/*
	 * Check for Diagnostic Test FTP Service
	 */
	if (evbuf->type != EVTYP_DIAG_TEST ||
	    diag->route != SCLP_DIAG_FTP_ROUTE ||
	    diag->mdd.ftp.pcx != SCLP_DIAG_FTP_XPCX ||
	    evbuf->length < SCLP_DIAG_FTP_EVBUF_LEN)
		return;

#ifdef DEBUG
	pr_debug("SCLP (ET7) RX-IRQ, Event @ 0x%p: %*phN\n",
		 evbuf, 24, evbuf);
#endif

	/*
	 * Because the event buffer is located in a page which is owned
	 * by the SCLP core, all data of interest must be copied. The
	 * error indication is in 'sclp_ftp_ldflg'
	 */
	sclp_ftp_ldflg = diag->mdd.ftp.ldflg;
	sclp_ftp_fsize = diag->mdd.ftp.fsize;
	sclp_ftp_length = diag->mdd.ftp.length;

	complete(&sclp_ftp_rx_complete);
}

/**
 * sclp_ftp_et7() - start a Diagnostic Test FTP Service SCLP request
 * @ftp: pointer to FTP descriptor
 *
 * Return: 0 on success, else a (negative) error code
 */
static int sclp_ftp_et7(const struct hmcdrv_ftp_cmdspec *ftp)
{
	struct completion completion;
	struct sclp_diag_sccb *sccb;
	struct sclp_req *req;
	ssize_t len;
	int rc;

	req = kzalloc(sizeof(*req), GFP_KERNEL);
	sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!req || !sccb) {
		rc = -ENOMEM;
		goto out_free;
	}

	sccb->hdr.length = SCLP_DIAG_FTP_EVBUF_LEN +
		sizeof(struct sccb_header);
	sccb->evbuf.hdr.type = EVTYP_DIAG_TEST;
	sccb->evbuf.hdr.length = SCLP_DIAG_FTP_EVBUF_LEN;
	sccb->evbuf.hdr.flags = 0; /* clear processed-buffer */
	sccb->evbuf.route = SCLP_DIAG_FTP_ROUTE;
	sccb->evbuf.mdd.ftp.pcx = SCLP_DIAG_FTP_XPCX;
	sccb->evbuf.mdd.ftp.srcflg = 0;
	sccb->evbuf.mdd.ftp.pgsize = 0;
	sccb->evbuf.mdd.ftp.asce = _ASCE_REAL_SPACE;
	sccb->evbuf.mdd.ftp.ldflg = SCLP_DIAG_FTP_LDFAIL;
	sccb->evbuf.mdd.ftp.fsize = 0;
	sccb->evbuf.mdd.ftp.cmd = ftp->id;
	sccb->evbuf.mdd.ftp.offset = ftp->ofs;
	sccb->evbuf.mdd.ftp.length = ftp->len;
	sccb->evbuf.mdd.ftp.bufaddr = virt_to_phys(ftp->buf);

	len = strscpy(sccb->evbuf.mdd.ftp.fident, ftp->fname,
		      HMCDRV_FTP_FIDENT_MAX);
	if (len < 0) {
		rc = -EINVAL;
		goto out_free;
	}

	req->command = SCLP_CMDW_WRITE_EVENT_DATA;
	req->sccb = sccb;
	req->status = SCLP_REQ_FILLED;
	req->callback = sclp_ftp_txcb;
	req->callback_data = &completion;

	init_completion(&completion);

	rc = sclp_add_request(req);
	if (rc)
		goto out_free;

	/* Wait for end of ftp sclp command. */
	wait_for_completion(&completion);

#ifdef DEBUG
	pr_debug("status of SCLP (ET7) request is 0x%04x (0x%02x)\n",
		 sccb->hdr.response_code, sccb->evbuf.hdr.flags);
#endif

	/*
	 * Check if sclp accepted the request. The data transfer runs
	 * asynchronously and the completion is indicated with an
	 * sclp ET7 event.
	 */
	if (req->status != SCLP_REQ_DONE ||
	    (sccb->evbuf.hdr.flags & 0x80) == 0 || /* processed-buffer */
	    (sccb->hdr.response_code & 0xffU) != 0x20U) {
		rc = -EIO;
	}

out_free:
	free_page((unsigned long) sccb);
	kfree(req);
	return rc;
}

/**
 * sclp_ftp_cmd() - executes a HMC related SCLP Diagnose (ET7) FTP command
 * @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 sclp_ftp_cmd(const struct hmcdrv_ftp_cmdspec *ftp, size_t *fsize)
{
	ssize_t len;
#ifdef DEBUG
	unsigned long start_jiffies;

	pr_debug("starting SCLP (ET7), cmd %d for '%s' at %lld with %zd bytes\n",
		 ftp->id, ftp->fname, (long long) ftp->ofs, ftp->len);
	start_jiffies = jiffies;
#endif

	init_completion(&sclp_ftp_rx_complete);

	/* Start ftp sclp command. */
	len = sclp_ftp_et7(ftp);
	if (len)
		goto out_unlock;

	/*
	 * There is no way to cancel the sclp ET7 request, the code
	 * needs to wait unconditionally until the transfer is complete.
	 */
	wait_for_completion(&sclp_ftp_rx_complete);

#ifdef DEBUG
	pr_debug("completed SCLP (ET7) request after %lu ms (all)\n",
		 (jiffies - start_jiffies) * 1000 / HZ);
	pr_debug("return code of SCLP (ET7) FTP Service is 0x%02x, with %lld/%lld bytes\n",
		 sclp_ftp_ldflg, sclp_ftp_length, sclp_ftp_fsize);
#endif

	switch (sclp_ftp_ldflg) {
	case SCLP_DIAG_FTP_OK:
		len = sclp_ftp_length;
		if (fsize)
			*fsize = sclp_ftp_fsize;
		break;
	case SCLP_DIAG_FTP_LDNPERM:
		len = -EPERM;
		break;
	case SCLP_DIAG_FTP_LDRUNS:
		len = -EBUSY;
		break;
	case SCLP_DIAG_FTP_LDFAIL:
		len = -ENOENT;
		break;
	default:
		len = -EIO;
		break;
	}

out_unlock:
	return len;
}

/*
 * ET7 event listener
 */
static struct sclp_register sclp_ftp_event = {
	.send_mask = EVTYP_DIAG_TEST_MASK,    /* want tx events */
	.receive_mask = EVTYP_DIAG_TEST_MASK, /* want rx events */
	.receiver_fn = sclp_ftp_rxcb,	      /* async callback (rx) */
	.state_change_fn = NULL,
};

/**
 * sclp_ftp_startup() - startup of FTP services, when running on LPAR
 */
int sclp_ftp_startup(void)
{
#ifdef DEBUG
	unsigned long info;
#endif
	int rc;

	rc = sclp_register(&sclp_ftp_event);
	if (rc)
		return rc;

#ifdef DEBUG
	info = get_zeroed_page(GFP_KERNEL);

	if (info != 0) {
		struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;

		if (!stsi(info222, 2, 2, 2)) { /* get SYSIB 2.2.2 */
			info222->name[sizeof(info222->name) - 1] = '\0';
			EBCASC_500(info222->name, sizeof(info222->name) - 1);
			pr_debug("SCLP (ET7) FTP Service working on LPAR %u (%s)\n",
				 info222->lpar_number, info222->name);
		}

		free_page(info);
	}
#endif	/* DEBUG */
	return 0;
}

/**
 * sclp_ftp_shutdown() - shutdown of FTP services, when running on LPAR
 */
void sclp_ftp_shutdown(void)
{
	sclp_unregister(&sclp_ftp_event);
}
