3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
18 /* This contains the implementation that allows a usermode program to
19 * communicate with the visorchipset driver using a device/file interface.
23 #include "visorchannel.h"
29 #define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c
31 static struct cdev file_cdev;
32 static struct visorchannel **file_controlvm_channel;
35 visorchipset_file_cleanup(dev_t major_dev)
37 if (file_cdev.ops != NULL)
40 unregister_chrdev_region(major_dev, 1);
44 visorchipset_open(struct inode *inode, struct file *file)
46 unsigned minor_number = iminor(inode);
48 if (minor_number != 0)
50 file->private_data = NULL;
55 visorchipset_release(struct inode *inode, struct file *file)
61 visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
64 ulong offset = vma->vm_pgoff << PAGE_SHIFT;
65 GUEST_PHYSICAL_ADDRESS addr = 0;
67 /* sv_enable_dfp(); */
68 if (offset & (PAGE_SIZE - 1))
69 return -ENXIO; /* need aligned offsets */
72 case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
73 vma->vm_flags |= VM_IO;
74 if (*file_controlvm_channel == NULL) {
77 visorchannel_read(*file_controlvm_channel,
78 offsetof(struct spar_controlvm_channel_protocol,
84 physaddr = (ulong)addr;
85 if (remap_pfn_range(vma, vma->vm_start,
86 physaddr >> PAGE_SHIFT,
87 vma->vm_end - vma->vm_start,
89 (vma->vm_page_prot))) {
99 static long visorchipset_ioctl(struct file *file, unsigned int cmd,
106 case VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET:
107 /* get the physical rtc offset */
108 vrtc_offset = issue_vmcall_query_guest_virtual_time_offset();
110 ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) {
114 case VMCALL_UPDATE_PHYSICAL_TIME:
116 (&adjustment, (void __user *)arg, sizeof(adjustment))) {
119 return issue_vmcall_update_physical_time(adjustment);
125 static const struct file_operations visorchipset_fops = {
126 .owner = THIS_MODULE,
127 .open = visorchipset_open,
130 .unlocked_ioctl = visorchipset_ioctl,
131 .release = visorchipset_release,
132 .mmap = visorchipset_mmap,
136 visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
140 file_controlvm_channel = controlvm_channel;
141 cdev_init(&file_cdev, &visorchipset_fops);
142 file_cdev.owner = THIS_MODULE;
143 if (MAJOR(major_dev) == 0) {
144 rc = alloc_chrdev_region(&major_dev, 0, 1, MYDRVNAME);
145 /* dynamic major device number registration required */
149 /* static major device number registration required */
150 rc = register_chrdev_region(major_dev, 1, MYDRVNAME);
154 rc = cdev_add(&file_cdev, MKDEV(MAJOR(major_dev), 0), 1);
156 unregister_chrdev_region(major_dev, 1);