/*
 * Author: Martin Peschke <mpeschke@de.ibm.com>
 * Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation
 *
 * SCLP Control-Program Identification.
 */

#include <linux/version.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <asm/ebcdic.h>
#include <asm/semaphore.h>

#include "sclp.h"
#include "sclp_rw.h"

#define CPI_LENGTH_SYSTEM_TYPE	8
#define CPI_LENGTH_SYSTEM_NAME	8
#define CPI_LENGTH_SYSPLEX_NAME	8

struct cpi_evbuf {
	struct evbuf_header header;
	u8	id_format;
	u8	reserved0;
	u8	system_type[CPI_LENGTH_SYSTEM_TYPE];
	u64	reserved1;
	u8	system_name[CPI_LENGTH_SYSTEM_NAME];
	u64	reserved2;
	u64	system_level;
	u64	reserved3;
	u8	sysplex_name[CPI_LENGTH_SYSPLEX_NAME];
	u8	reserved4[16];
} __attribute__((packed));

struct cpi_sccb {
	struct sccb_header header;
	struct cpi_evbuf cpi_evbuf;
} __attribute__((packed));

/* Event type structure for write message and write priority message */
static struct sclp_register sclp_cpi_event =
{
	.send_mask = EvTyp_CtlProgIdent_Mask
};

MODULE_LICENSE("GPL");

MODULE_AUTHOR(
	"Martin Peschke, IBM Deutschland Entwicklung GmbH "
	"<mpeschke@de.ibm.com>");

MODULE_DESCRIPTION(
	"identify this operating system instance to the S/390 "
	"or zSeries hardware");

static char *system_name = NULL;
module_param(system_name, charp, 0);
MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters");

static char *sysplex_name = NULL;
#ifdef ALLOW_SYSPLEX_NAME
module_param(sysplex_name, charp, 0);
MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters");
#endif

/* use default value for this field (as well as for system level) */
static char *system_type = "LINUX";

static int
cpi_check_parms(void)
{
	/* reject if no system type specified */
	if (!system_type) {
		printk("cpi: bug: no system type specified\n");
		return -EINVAL;
	}

	/* reject if system type larger than 8 characters */
	if (strlen(system_type) > CPI_LENGTH_SYSTEM_NAME) {
		printk("cpi: bug: system type has length of %li characters - "
		       "only %i characters supported\n",
		       strlen(system_type), CPI_LENGTH_SYSTEM_TYPE);
		return -EINVAL;
	}

	/* reject if no system name specified */
	if (!system_name) {
		printk("cpi: no system name specified\n");
		return -EINVAL;
	}

	/* reject if system name larger than 8 characters */
	if (strlen(system_name) > CPI_LENGTH_SYSTEM_NAME) {
		printk("cpi: system name has length of %li characters - "
		       "only %i characters supported\n",
		       strlen(system_name), CPI_LENGTH_SYSTEM_NAME);
		return -EINVAL;
	}

	/* reject if specified sysplex name larger than 8 characters */
	if (sysplex_name && strlen(sysplex_name) > CPI_LENGTH_SYSPLEX_NAME) {
		printk("cpi: sysplex name has length of %li characters"
		       " - only %i characters supported\n",
		       strlen(sysplex_name), CPI_LENGTH_SYSPLEX_NAME);
		return -EINVAL;
	}
	return 0;
}

static void
cpi_callback(struct sclp_req *req, void *data)
{
	struct semaphore *sem;

	sem = (struct semaphore *) data;
	up(sem);
}

static struct sclp_req *
cpi_prepare_req(void)
{
	struct sclp_req *req;
	struct cpi_sccb *sccb;
	struct cpi_evbuf *evb;

	req = kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
	if (req == NULL)
		return ERR_PTR(-ENOMEM);
	sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL | GFP_DMA);
	if (sccb == NULL) {
		kfree(req);
		return ERR_PTR(-ENOMEM);
	}
	memset(sccb, 0, sizeof(struct cpi_sccb));

	/* setup SCCB for Control-Program Identification */
	sccb->header.length = sizeof(struct cpi_sccb);
	sccb->cpi_evbuf.header.length = sizeof(struct cpi_evbuf);
	sccb->cpi_evbuf.header.type = 0x0B;
	evb = &sccb->cpi_evbuf;

	/* set system type */
	memset(evb->system_type, ' ', CPI_LENGTH_SYSTEM_TYPE);
	memcpy(evb->system_type, system_type, strlen(system_type));
	sclp_ascebc_str(evb->system_type, CPI_LENGTH_SYSTEM_TYPE);
	EBC_TOUPPER(evb->system_type, CPI_LENGTH_SYSTEM_TYPE);

	/* set system name */
	memset(evb->system_name, ' ', CPI_LENGTH_SYSTEM_NAME);
	memcpy(evb->system_name, system_name, strlen(system_name));
	sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
	EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME);

	/* set sytem level */
	evb->system_level = LINUX_VERSION_CODE;

	/* set sysplex name */
	if (sysplex_name) {
		memset(evb->sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME);
		memcpy(evb->sysplex_name, sysplex_name, strlen(sysplex_name));
		sclp_ascebc_str(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
		EBC_TOUPPER(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
	}

	/* prepare request data structure presented to SCLP driver */
	req->command = SCLP_CMDW_WRITEDATA;
	req->sccb = sccb;
	req->status = SCLP_REQ_FILLED;
	req->callback = cpi_callback;
	return req;
}

static void
cpi_free_req(struct sclp_req *req)
{
	free_page((unsigned long) req->sccb);
	kfree(req);
}

static int __init
cpi_module_init(void)
{
	struct semaphore sem;
	struct sclp_req *req;
	int rc;

	rc = cpi_check_parms();
	if (rc)
		return rc;

	rc = sclp_register(&sclp_cpi_event);
	if (rc) {
		/* could not register sclp event. Die. */
		printk(KERN_WARNING "cpi: could not register to hardware "
		       "console.\n");
		return -EINVAL;
	}
	if (!(sclp_cpi_event.sclp_send_mask & EvTyp_CtlProgIdent_Mask)) {
		printk(KERN_WARNING "cpi: no control program identification "
		       "support\n");
		sclp_unregister(&sclp_cpi_event);
		return -EOPNOTSUPP;
	}

	req = cpi_prepare_req();
	if (IS_ERR(req)) {
		printk(KERN_WARNING "cpi: couldn't allocate request\n");
		sclp_unregister(&sclp_cpi_event);
		return PTR_ERR(req);
	}

	/* Prepare semaphore */
	sema_init(&sem, 0);
	req->callback_data = &sem;
	/* Add request to sclp queue */
	rc = sclp_add_request(req);
	if (rc) {
		printk(KERN_WARNING "cpi: could not start request\n");
		cpi_free_req(req);
		sclp_unregister(&sclp_cpi_event);
		return rc;
	}
	/* make "insmod" sleep until callback arrives */
	down(&sem);

	rc = ((struct cpi_sccb *) req->sccb)->header.response_code;
	if (rc != 0x0020) {
		printk(KERN_WARNING "cpi: failed with response code 0x%x\n",
		       rc);
		rc = -ECOMM;
	} else
		rc = 0;

	cpi_free_req(req);
	sclp_unregister(&sclp_cpi_event);

	return rc;
}


static void __exit cpi_module_exit(void)
{
}


/* declare driver module init/cleanup functions */
module_init(cpi_module_init);
module_exit(cpi_module_exit);

