/*
 * Copyright (C) 2004,2005 IBM Corporation
 * Interface implementation for communication with the v/VM control program
 * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
 *
 *
 * z/VMs CP offers the possibility to issue commands via the diagnose code 8
 * this driver implements a character device that issues these commands and
 * returns the answer of CP.

 * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
 */

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <asm/cpcmd.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
#include "vmcp.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>");
MODULE_DESCRIPTION("z/VM CP interface");

static debug_info_t *vmcp_debug;

static int vmcp_open(struct inode *inode, struct file *file)
{
	struct vmcp_session *session;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	session = kmalloc(sizeof(*session), GFP_KERNEL);
	if (!session)
		return -ENOMEM;
	session->bufsize = PAGE_SIZE;
	session->response = NULL;
	session->resp_size = 0;
	init_MUTEX(&session->mutex);
	file->private_data = session;
	return nonseekable_open(inode, file);
}

static int vmcp_release(struct inode *inode, struct file *file)
{
	struct vmcp_session *session;

	session = (struct vmcp_session *)file->private_data;
	file->private_data = NULL;
	free_pages((unsigned long)session->response, get_order(session->bufsize));
	kfree(session);
	return 0;
}

static ssize_t
vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos)
{
	size_t tocopy;
	struct vmcp_session *session;

	session = (struct vmcp_session *)file->private_data;
	if (down_interruptible(&session->mutex))
		return -ERESTARTSYS;
	if (!session->response) {
		up(&session->mutex);
		return 0;
	}
	if (*ppos > session->resp_size) {
		up(&session->mutex);
		return 0;
	}
	tocopy = min(session->resp_size - (size_t) (*ppos), count);
	tocopy = min(tocopy,session->bufsize - (size_t) (*ppos));

	if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
		up(&session->mutex);
		return -EFAULT;
	}
	up(&session->mutex);
	*ppos += tocopy;
	return tocopy;
}

static ssize_t
vmcp_write(struct file *file, const char __user * buff, size_t count,
	   loff_t * ppos)
{
	char *cmd;
	struct vmcp_session *session;

	if (count > 240)
		return -EINVAL;
	cmd = kmalloc(count + 1, GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;
	if (copy_from_user(cmd, buff, count)) {
		kfree(cmd);
		return -EFAULT;
	}
	cmd[count] = '\0';
	session = (struct vmcp_session *)file->private_data;
	if (down_interruptible(&session->mutex)) {
		kfree(cmd);
		return -ERESTARTSYS;
	}
	if (!session->response)
		session->response = (char *)__get_free_pages(GFP_KERNEL
						| __GFP_REPEAT 	| GFP_DMA,
						get_order(session->bufsize));
	if (!session->response) {
		up(&session->mutex);
		kfree(cmd);
		return -ENOMEM;
	}
	debug_text_event(vmcp_debug, 1, cmd);
	session->resp_size = __cpcmd(cmd, session->response,
				     session->bufsize,
				     &session->resp_code);
	up(&session->mutex);
	kfree(cmd);
	*ppos = 0;		/* reset the file pointer after a command */
	return count;
}


/*
 * These ioctls are available, as the semantics of the diagnose 8 call
 * does not fit very well into a Linux call. Diagnose X'08' is described in
 * CP Programming Services SC24-6084-00
 *
 * VMCP_GETCODE: gives the CP return code back to user space
 * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8
 * expects adjacent pages in real storage and to make matters worse, we
 * dont know the size of the response. Therefore we default to PAGESIZE and
 * let userspace to change the response size, if userspace expects a bigger
 * response
 */
static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct vmcp_session *session;
	int temp;

	session = (struct vmcp_session *)file->private_data;
	if (down_interruptible(&session->mutex))
		return -ERESTARTSYS;
	switch (cmd) {
	case VMCP_GETCODE:
		temp = session->resp_code;
		up(&session->mutex);
		return put_user(temp, (int __user *)arg);
	case VMCP_SETBUF:
		free_pages((unsigned long)session->response,
				get_order(session->bufsize));
		session->response=NULL;
		temp = get_user(session->bufsize, (int __user *)arg);
		if (get_order(session->bufsize) > 8) {
			session->bufsize = PAGE_SIZE;
			temp = -EINVAL;
		}
		up(&session->mutex);
		return temp;
	case VMCP_GETSIZE:
		temp = session->resp_size;
		up(&session->mutex);
		return put_user(temp, (int __user *)arg);
	default:
		up(&session->mutex);
		return -ENOIOCTLCMD;
	}
}

static struct file_operations vmcp_fops = {
	.owner		= THIS_MODULE,
	.open		= &vmcp_open,
	.release	= &vmcp_release,
	.read		= &vmcp_read,
	.llseek		= &no_llseek,
	.write		= &vmcp_write,
	.unlocked_ioctl	= &vmcp_ioctl,
	.compat_ioctl	= &vmcp_ioctl
};

static struct miscdevice vmcp_dev = {
	.name	= "vmcp",
	.minor	= MISC_DYNAMIC_MINOR,
	.fops	= &vmcp_fops,
};

static int __init vmcp_init(void)
{
	int ret;

	if (!MACHINE_IS_VM) {
		printk(KERN_WARNING
		       "z/VM CP interface is only available under z/VM\n");
		return -ENODEV;
	}
	ret = misc_register(&vmcp_dev);
	if (!ret)
		printk(KERN_INFO "z/VM CP interface loaded\n");
	else
		printk(KERN_WARNING
		       "z/VM CP interface not loaded. Could not register misc device.\n");
	vmcp_debug = debug_register("vmcp", 1, 1, 240);
	debug_register_view(vmcp_debug, &debug_hex_ascii_view);
	return ret;
}

static void __exit vmcp_exit(void)
{
	WARN_ON(misc_deregister(&vmcp_dev) != 0);
	debug_unregister(vmcp_debug);
	printk(KERN_INFO "z/VM CP interface unloaded.\n");
}

module_init(vmcp_init);
module_exit(vmcp_exit);
