1 /* 2 * arch/um/drivers/mmapper_kern.c 3 * 4 * BRIEF MODULE DESCRIPTION 5 * 6 * Copyright (C) 2000 RidgeRun, Inc. 7 * Author: RidgeRun, Inc. 8 * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com 9 * 10 */ 11 12 #include <linux/types.h> 13 #include <linux/kdev_t.h> 14 #include <linux/time.h> 15 #include <linux/devfs_fs_kernel.h> 16 #include <linux/module.h> 17 #include <linux/mm.h> 18 #include <linux/slab.h> 19 #include <linux/init.h> 20 #include <linux/smp_lock.h> 21 #include <linux/miscdevice.h> 22 #include <asm/uaccess.h> 23 #include <asm/irq.h> 24 #include <asm/pgtable.h> 25 #include "mem_user.h" 26 #include "user_util.h" 27 28 /* These are set in mmapper_init, which is called at boot time */ 29 static unsigned long mmapper_size; 30 static unsigned long p_buf = 0; 31 static char *v_buf = NULL; 32 33 static ssize_t 34 mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) 35 { 36 if(*ppos > mmapper_size) 37 return -EINVAL; 38 39 if(count + *ppos > mmapper_size) 40 count = count + *ppos - mmapper_size; 41 42 if(count < 0) 43 return -EINVAL; 44 45 copy_to_user(buf,&v_buf[*ppos],count); 46 47 return count; 48 } 49 50 static ssize_t 51 mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 52 { 53 if(*ppos > mmapper_size) 54 return -EINVAL; 55 56 if(count + *ppos > mmapper_size) 57 count = count + *ppos - mmapper_size; 58 59 if(count < 0) 60 return -EINVAL; 61 62 copy_from_user(&v_buf[*ppos],buf,count); 63 64 return count; 65 } 66 67 static int 68 mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 69 unsigned long arg) 70 { 71 return(-ENOIOCTLCMD); 72 } 73 74 static int 75 mmapper_mmap(struct file *file, struct vm_area_struct * vma) 76 { 77 int ret = -EINVAL; 78 int size; 79 80 lock_kernel(); 81 if (vma->vm_pgoff != 0) 82 goto out; 83 84 size = vma->vm_end - vma->vm_start; 85 if(size > mmapper_size) return(-EFAULT); 86 87 /* XXX A comment above remap_pfn_range says it should only be 88 * called when the mm semaphore is held 89 */ 90 if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size, 91 vma->vm_page_prot)) 92 goto out; 93 ret = 0; 94 out: 95 unlock_kernel(); 96 return ret; 97 } 98 99 static int 100 mmapper_open(struct inode *inode, struct file *file) 101 { 102 return 0; 103 } 104 105 static int 106 mmapper_release(struct inode *inode, struct file *file) 107 { 108 return 0; 109 } 110 111 static struct file_operations mmapper_fops = { 112 .owner = THIS_MODULE, 113 .read = mmapper_read, 114 .write = mmapper_write, 115 .ioctl = mmapper_ioctl, 116 .mmap = mmapper_mmap, 117 .open = mmapper_open, 118 .release = mmapper_release, 119 }; 120 121 static struct miscdevice mmapper_dev = { 122 .minor = MISC_DYNAMIC_MINOR, 123 .name = "mmapper", 124 .fops = &mmapper_fops 125 }; 126 127 static int __init mmapper_init(void) 128 { 129 int err; 130 131 printk(KERN_INFO "Mapper v0.1\n"); 132 133 v_buf = (char *) find_iomem("mmapper", &mmapper_size); 134 if(mmapper_size == 0){ 135 printk(KERN_ERR "mmapper_init - find_iomem failed\n"); 136 goto out; 137 } 138 139 err = misc_register(&mmapper_dev); 140 if(err){ 141 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", 142 err); 143 goto out; 144 } 145 146 p_buf = __pa(v_buf); 147 out: 148 return 0; 149 } 150 151 static void mmapper_exit(void) 152 { 153 misc_deregister(&mmapper_dev); 154 } 155 156 module_init(mmapper_init); 157 module_exit(mmapper_exit); 158 159 MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); 160 MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); 161 /* 162 * --------------------------------------------------------------------------- 163 * Local variables: 164 * c-file-style: "linux" 165 * End: 166 */ 167