/*
 * 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_WRITE_EVENT_DATA;
	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);

