[go: nahoru, domu]

18f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/*
28f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *    SCLP Event Type (ET) 7 - Diagnostic Test FTP Services, useable on LPAR
38f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *
48f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *    Copyright IBM Corp. 2013
58f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *    Author(s): Ralf Hoppe (rhoppe@de.ibm.com)
68f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *
78f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
88f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
98f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#define KMSG_COMPONENT "hmcdrv"
108f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
118f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
128f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/kernel.h>
138f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/mm.h>
148f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/slab.h>
158f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/io.h>
168f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/wait.h>
178f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/string.h>
188f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <linux/jiffies.h>
198f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <asm/sysinfo.h>
208f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include <asm/ebcdic.h>
218f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
228f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include "sclp.h"
238f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include "sclp_diag.h"
248f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#include "sclp_ftp.h"
258f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
268f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic DECLARE_COMPLETION(sclp_ftp_rx_complete);
278f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic u8 sclp_ftp_ldflg;
288f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic u64 sclp_ftp_fsize;
298f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic u64 sclp_ftp_length;
308f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
318f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
328f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_txcb() - Diagnostic Test FTP services SCLP command callback
338f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
348f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic void sclp_ftp_txcb(struct sclp_req *req, void *data)
358f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
368f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	struct completion *completion = data;
378f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
388f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
398f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("SCLP (ET7) TX-IRQ, SCCB @ 0x%p: %*phN\n",
408f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 req->sccb, 24, req->sccb);
418f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
428f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	complete(completion);
438f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
448f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
458f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
468f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_rxcb() - Diagnostic Test FTP services receiver event callback
478f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
488f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic void sclp_ftp_rxcb(struct evbuf_header *evbuf)
498f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
508f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	struct sclp_diag_evbuf *diag = (struct sclp_diag_evbuf *) evbuf;
518f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
528f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/*
538f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * Check for Diagnostic Test FTP Service
548f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 */
558f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (evbuf->type != EVTYP_DIAG_TEST ||
568f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	    diag->route != SCLP_DIAG_FTP_ROUTE ||
578f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	    diag->mdd.ftp.pcx != SCLP_DIAG_FTP_XPCX ||
588f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	    evbuf->length < SCLP_DIAG_FTP_EVBUF_LEN)
598f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		return;
608f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
618f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
628f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("SCLP (ET7) RX-IRQ, Event @ 0x%p: %*phN\n",
638f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 evbuf, 24, evbuf);
648f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
658f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
668f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/*
678f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * Because the event buffer is located in a page which is owned
688f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * by the SCLP core, all data of interest must be copied. The
698f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * error indication is in 'sclp_ftp_ldflg'
708f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 */
718f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sclp_ftp_ldflg = diag->mdd.ftp.ldflg;
728f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sclp_ftp_fsize = diag->mdd.ftp.fsize;
738f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sclp_ftp_length = diag->mdd.ftp.length;
748f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
758f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	complete(&sclp_ftp_rx_complete);
768f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
778f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
788f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
798f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_et7() - start a Diagnostic Test FTP Service SCLP request
808f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * @ftp: pointer to FTP descriptor
818f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *
828f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * Return: 0 on success, else a (negative) error code
838f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
848f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic int sclp_ftp_et7(const struct hmcdrv_ftp_cmdspec *ftp)
858f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
868f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	struct completion completion;
878f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	struct sclp_diag_sccb *sccb;
888f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	struct sclp_req *req;
898f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	size_t len;
908f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	int rc;
918f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
928f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req = kzalloc(sizeof(*req), GFP_KERNEL);
938f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
948f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (!req || !sccb) {
958f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		rc = -ENOMEM;
968f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		goto out_free;
978f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	}
988f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
998f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->hdr.length = SCLP_DIAG_FTP_EVBUF_LEN +
1008f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		sizeof(struct sccb_header);
1018f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.hdr.type = EVTYP_DIAG_TEST;
1028f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.hdr.length = SCLP_DIAG_FTP_EVBUF_LEN;
1038f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.hdr.flags = 0; /* clear processed-buffer */
1048f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.route = SCLP_DIAG_FTP_ROUTE;
1058f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.pcx = SCLP_DIAG_FTP_XPCX;
1068f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.srcflg = 0;
1078f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.pgsize = 0;
1088f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.asce = _ASCE_REAL_SPACE;
1098f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.ldflg = SCLP_DIAG_FTP_LDFAIL;
1108f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.fsize = 0;
1118f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.cmd = ftp->id;
1128f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.offset = ftp->ofs;
1138f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.length = ftp->len;
1148f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sccb->evbuf.mdd.ftp.bufaddr = virt_to_phys(ftp->buf);
1158f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1168f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	len = strlcpy(sccb->evbuf.mdd.ftp.fident, ftp->fname,
1178f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		      HMCDRV_FTP_FIDENT_MAX);
1188f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (len >= HMCDRV_FTP_FIDENT_MAX) {
1198f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		rc = -EINVAL;
1208f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		goto out_free;
1218f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	}
1228f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1238f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req->command = SCLP_CMDW_WRITE_EVENT_DATA;
1248f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req->sccb = sccb;
1258f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req->status = SCLP_REQ_FILLED;
1268f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req->callback = sclp_ftp_txcb;
1278f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	req->callback_data = &completion;
1288f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1298f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	init_completion(&completion);
1308f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1318f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	rc = sclp_add_request(req);
1328f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (rc)
1338f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		goto out_free;
1348f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1358f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/* Wait for end of ftp sclp command. */
1368f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	wait_for_completion(&completion);
1378f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1388f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
1398f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("status of SCLP (ET7) request is 0x%04x (0x%02x)\n",
1408f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 sccb->hdr.response_code, sccb->evbuf.hdr.flags);
1418f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
1428f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1438f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/*
1448f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * Check if sclp accepted the request. The data transfer runs
1458f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * asynchronously and the completion is indicated with an
1468f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * sclp ET7 event.
1478f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 */
1488f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (req->status != SCLP_REQ_DONE ||
1498f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	    (sccb->evbuf.hdr.flags & 0x80) == 0 || /* processed-buffer */
1508f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	    (sccb->hdr.response_code & 0xffU) != 0x20U) {
1518f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		rc = -EIO;
1528f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	}
1538f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1548f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppeout_free:
1558f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	free_page((unsigned long) sccb);
1568f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	kfree(req);
1578f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	return rc;
1588f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
1598f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1608f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
1618f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_cmd() - executes a HMC related SCLP Diagnose (ET7) FTP command
1628f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * @ftp: pointer to FTP command specification
1638f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * @fsize: return of file size (or NULL if undesirable)
1648f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *
1658f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * Attention: Notice that this function is not reentrant - so the caller
1668f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * must ensure locking.
1678f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe *
1688f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * Return: number of bytes read/written or a (negative) error code
1698f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
1708f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppessize_t sclp_ftp_cmd(const struct hmcdrv_ftp_cmdspec *ftp, size_t *fsize)
1718f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
1728f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	ssize_t len;
1738f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
1748f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	unsigned long start_jiffies;
1758f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1768f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("starting SCLP (ET7), cmd %d for '%s' at %lld with %zd bytes\n",
1778f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 ftp->id, ftp->fname, (long long) ftp->ofs, ftp->len);
1788f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	start_jiffies = jiffies;
1798f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
1808f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1818f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	init_completion(&sclp_ftp_rx_complete);
1828f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1838f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/* Start ftp sclp command. */
1848f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	len = sclp_ftp_et7(ftp);
1858f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (len)
1868f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		goto out_unlock;
1878f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1888f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	/*
1898f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * There is no way to cancel the sclp ET7 request, the code
1908f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 * needs to wait unconditionally until the transfer is complete.
1918f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	 */
1928f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	wait_for_completion(&sclp_ftp_rx_complete);
1938f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
1948f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
1958f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("completed SCLP (ET7) request after %lu ms (all)\n",
1968f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 (jiffies - start_jiffies) * 1000 / HZ);
1978f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	pr_debug("return code of SCLP (ET7) FTP Service is 0x%02x, with %lld/%lld bytes\n",
1988f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		 sclp_ftp_ldflg, sclp_ftp_length, sclp_ftp_fsize);
1998f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
2008f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2018f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	switch (sclp_ftp_ldflg) {
2028f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	case SCLP_DIAG_FTP_OK:
2038f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		len = sclp_ftp_length;
2048f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		if (fsize)
2058f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe			*fsize = sclp_ftp_fsize;
2068f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		break;
2078f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	case SCLP_DIAG_FTP_LDNPERM:
2088f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		len = -EPERM;
2098f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		break;
2108f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	case SCLP_DIAG_FTP_LDRUNS:
2118f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		len = -EBUSY;
2128f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		break;
2138f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	case SCLP_DIAG_FTP_LDFAIL:
2148f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		len = -ENOENT;
2158f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		break;
2168f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	default:
2178f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		len = -EIO;
2188f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		break;
2198f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	}
2208f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2218f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppeout_unlock:
2228f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	return len;
2238f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
2248f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2258f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/*
2268f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * ET7 event listener
2278f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
2288f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppestatic struct sclp_register sclp_ftp_event = {
2298f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	.send_mask = EVTYP_DIAG_TEST_MASK,    /* want tx events */
2308f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	.receive_mask = EVTYP_DIAG_TEST_MASK, /* want rx events */
2318f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	.receiver_fn = sclp_ftp_rxcb,	      /* async callback (rx) */
2328f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	.state_change_fn = NULL,
2338f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	.pm_event_fn = NULL,
2348f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe};
2358f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2368f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
2378f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_startup() - startup of FTP services, when running on LPAR
2388f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
2398f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppeint sclp_ftp_startup(void)
2408f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
2418f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
2428f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	unsigned long info;
2438f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif
2448f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	int rc;
2458f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2468f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	rc = sclp_register(&sclp_ftp_event);
2478f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (rc)
2488f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		return rc;
2498f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2508f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#ifdef DEBUG
2518f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	info = get_zeroed_page(GFP_KERNEL);
2528f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2538f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	if (info != 0) {
2548f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
2558f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2568f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		if (!stsi(info222, 2, 2, 2)) { /* get SYSIB 2.2.2 */
2578f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe			info222->name[sizeof(info222->name) - 1] = '\0';
2588f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe			EBCASC_500(info222->name, sizeof(info222->name) - 1);
2598f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe			pr_debug("SCLP (ET7) FTP Service working on LPAR %u (%s)\n",
2608f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe				 info222->lpar_number, info222->name);
2618f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		}
2628f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2638f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe		free_page(info);
2648f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	}
2658f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe#endif	/* DEBUG */
2668f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	return 0;
2678f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
2688f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe
2698f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe/**
2708f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe * sclp_ftp_shutdown() - shutdown of FTP services, when running on LPAR
2718f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe */
2728f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppevoid sclp_ftp_shutdown(void)
2738f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe{
2748f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe	sclp_unregister(&sclp_ftp_event);
2758f933b1043e1e51f4776fc1ffe86752c7785fd4eRalf Hoppe}
276