]> err.no Git - linux-2.6/blobdiff - drivers/char/mem.c
drm/radeon: fix texture uploads with large 3d textures (bug 13980)
[linux-2.6] / drivers / char / mem.c
index 56b2fb4fbc9390ccee722630db2cc96e7a635331..934ffafedaea207131f7d193bed9e75c929f4db9 100644 (file)
@@ -300,6 +300,35 @@ static inline int private_mapping_ok(struct vm_area_struct *vma)
 }
 #endif
 
+void __attribute__((weak))
+map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
+{
+       /* nothing. architectures can override. */
+}
+
+void __attribute__((weak))
+unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
+{
+       /* nothing. architectures can override. */
+}
+
+static void mmap_mem_open(struct vm_area_struct *vma)
+{
+       map_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
+                       vma->vm_page_prot);
+}
+
+static void mmap_mem_close(struct vm_area_struct *vma)
+{
+       unmap_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
+                       vma->vm_page_prot);
+}
+
+static struct vm_operations_struct mmap_mem_ops = {
+       .open  = mmap_mem_open,
+       .close = mmap_mem_close
+};
+
 static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
@@ -321,16 +350,21 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
                                                 size,
                                                 vma->vm_page_prot);
 
+       vma->vm_ops = &mmap_mem_ops;
+
        /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
        if (remap_pfn_range(vma,
                            vma->vm_start,
                            vma->vm_pgoff,
                            size,
-                           vma->vm_page_prot))
+                           vma->vm_page_prot)) {
+               unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot);
                return -EAGAIN;
+       }
        return 0;
 }
 
+#ifdef CONFIG_DEVKMEM
 static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
 {
        unsigned long pfn;
@@ -351,6 +385,7 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
        vma->vm_pgoff = pfn;
        return mmap_mem(file, vma);
 }
+#endif
 
 #ifdef CONFIG_CRASH_DUMP
 /*
@@ -389,6 +424,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf,
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
 
+#ifdef CONFIG_DEVKMEM
 /*
  * This function reads the *virtual* memory as seen by the kernel.
  */
@@ -593,6 +629,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
        *ppos = p;
        return virtr + wrote;
 }
+#endif
 
 #ifdef CONFIG_DEVPORT
 static ssize_t read_port(struct file * file, char __user * buf,
@@ -770,6 +807,7 @@ static const struct file_operations mem_fops = {
        .get_unmapped_area = get_unmapped_area_mem,
 };
 
+#ifdef CONFIG_DEVKMEM
 static const struct file_operations kmem_fops = {
        .llseek         = memory_lseek,
        .read           = read_kmem,
@@ -778,6 +816,7 @@ static const struct file_operations kmem_fops = {
        .open           = open_kmem,
        .get_unmapped_area = get_unmapped_area_mem,
 };
+#endif
 
 static const struct file_operations null_fops = {
        .llseek         = null_lseek,
@@ -856,11 +895,13 @@ static int memory_open(struct inode * inode, struct file * filp)
                        filp->f_mapping->backing_dev_info =
                                &directly_mappable_cdev_bdi;
                        break;
+#ifdef CONFIG_DEVKMEM
                case 2:
                        filp->f_op = &kmem_fops;
                        filp->f_mapping->backing_dev_info =
                                &directly_mappable_cdev_bdi;
                        break;
+#endif
                case 3:
                        filp->f_op = &null_fops;
                        break;
@@ -909,7 +950,9 @@ static const struct {
        const struct file_operations    *fops;
 } devlist[] = { /* list of minor devices */
        {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
+#ifdef CONFIG_DEVKMEM
        {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
+#endif
        {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
 #ifdef CONFIG_DEVPORT
        {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},