/* file.c
 *
 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

/* This contains the implementation that allows a usermode program to
 * communicate with the visorchipset driver using a device/file interface.
 */

#include "globals.h"
#include "visorchannel.h"
#include <linux/mm.h>
#include <linux/fs.h>
#include "uisutils.h"
#include "file.h"

#define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c

static struct cdev Cdev;
static VISORCHANNEL **PControlVm_channel;
static dev_t MajorDev = -1; /**< indicates major num for device */
static BOOL Registered = FALSE;

static int visorchipset_open(struct inode *inode, struct file *file);
static int visorchipset_release(struct inode *inode, struct file *file);
static int visorchipset_mmap(struct file *file, struct vm_area_struct *vma);
#ifdef HAVE_UNLOCKED_IOCTL
long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#else
int visorchipset_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg);
#endif

static const struct file_operations visorchipset_fops = {
	.owner = THIS_MODULE,
	.open = visorchipset_open,
	.read = NULL,
	.write = NULL,
#ifdef HAVE_UNLOCKED_IOCTL
	.unlocked_ioctl = visorchipset_ioctl,
#else
	.ioctl = visorchipset_ioctl,
#endif
	.release = visorchipset_release,
	.mmap = visorchipset_mmap,
};

int
visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel)
{
	int rc = -1;

	PControlVm_channel = pControlVm_channel;
	MajorDev = majorDev;
	cdev_init(&Cdev, &visorchipset_fops);
	Cdev.owner = THIS_MODULE;
	if (MAJOR(MajorDev) == 0) {
		/* dynamic major device number registration required */
		if (alloc_chrdev_region(&MajorDev, 0, 1, MYDRVNAME) < 0) {
			ERRDRV("Unable to allocate+register char device %s",
			       MYDRVNAME);
			goto Away;
		}
		Registered = TRUE;
		INFODRV("New major number %d registered\n", MAJOR(MajorDev));
	} else {
		/* static major device number registration required */
		if (register_chrdev_region(MajorDev, 1, MYDRVNAME) < 0) {
			ERRDRV("Unable to register char device %s", MYDRVNAME);
			goto Away;
		}
		Registered = TRUE;
		INFODRV("Static major number %d registered\n", MAJOR(MajorDev));
	}
	if (cdev_add(&Cdev, MKDEV(MAJOR(MajorDev), 0), 1) < 0) {
		ERRDRV("failed to create char device: (status=%d)\n", rc);
		goto Away;
	}
	INFODRV("Registered char device for %s (major=%d)",
		MYDRVNAME, MAJOR(MajorDev));
	rc = 0;
Away:
	return rc;
}

void
visorchipset_file_cleanup(void)
{
	if (Cdev.ops != NULL)
		cdev_del(&Cdev);
	Cdev.ops = NULL;
	if (Registered) {
		if (MAJOR(MajorDev) >= 0) {
			unregister_chrdev_region(MajorDev, 1);
			MajorDev = MKDEV(0, 0);
		}
		Registered = FALSE;
	}
}

static int
visorchipset_open(struct inode *inode, struct file *file)
{
	unsigned minor_number = iminor(inode);
	int rc = -ENODEV;

	DEBUGDRV("%s", __func__);
	if (minor_number != 0)
		goto Away;
	file->private_data = NULL;
	rc = 0;
Away:
	if (rc < 0)
		ERRDRV("%s minor=%d failed", __func__, minor_number);
	return rc;
}

static int
visorchipset_release(struct inode *inode, struct file *file)
{
	DEBUGDRV("%s", __func__);
	return 0;
}

static int
visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
{
	ulong physAddr = 0;
	ulong offset = vma->vm_pgoff << PAGE_SHIFT;
	GUEST_PHYSICAL_ADDRESS addr = 0;

	/* sv_enable_dfp(); */
	DEBUGDRV("%s", __func__);
	if (offset & (PAGE_SIZE - 1)) {
		ERRDRV("%s virtual address NOT page-aligned!", __func__);
		return -ENXIO;	/* need aligned offsets */
	}
	switch (offset) {
	case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
		vma->vm_flags |= VM_IO;
		if (*PControlVm_channel == NULL) {
			ERRDRV("%s no controlvm channel yet", __func__);
			return -ENXIO;
		}
		visorchannel_read(*PControlVm_channel,
				  offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
					   gpControlChannel), &addr,
				  sizeof(addr));
		if (addr == 0) {
			ERRDRV("%s control channel address is 0", __func__);
			return -ENXIO;
		}
		physAddr = (ulong) (addr);
		DEBUGDRV("mapping physical address = 0x%lx", physAddr);
		if (remap_pfn_range(vma, vma->vm_start,
				    physAddr >> PAGE_SHIFT,
				    vma->vm_end - vma->vm_start,
				    /*pgprot_noncached */
				    (vma->vm_page_prot))) {
			ERRDRV("%s remap_pfn_range failed", __func__);
			return -EAGAIN;
		}
		break;
	default:
		return -ENOSYS;
	}
	DEBUGDRV("%s success!", __func__);
	return 0;
}

#ifdef HAVE_UNLOCKED_IOCTL
long
visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#else
int
visorchipset_ioctl(struct inode *inode, struct file *file,
		   unsigned int cmd, unsigned long arg)
#endif
{
	int rc = SUCCESS;
	s64 adjustment;
	s64 vrtc_offset;

	DBGINF("entered visorchipset_ioctl, cmd=%d", cmd);
	switch (cmd) {
	case VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET:
		/* get the physical rtc offset */
		vrtc_offset = issue_vmcall_query_guest_virtual_time_offset();
		if (copy_to_user
		    ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) {
			rc = -EFAULT;
			goto Away;
		}
		DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld",
		       cmd, vrtc_offset);
		break;
	case VMCALL_UPDATE_PHYSICAL_TIME:
		if (copy_from_user
		    (&adjustment, (void __user *)arg, sizeof(adjustment))) {
			rc = -EFAULT;
			goto Away;
		}
		DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd,
		       adjustment);
		rc = issue_vmcall_update_physical_time(adjustment);
		break;
	default:
		LOGERR("visorchipset_ioctl received invalid command");
		rc = -EFAULT;
		break;
	}
Away:
	DBGINF("exiting %d!", rc);
	return rc;
}
