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