Subject: [PATCH] Fix BSR to allow mmap of small BSR on 64k kernel

From: Sonny Rao <[email-masked]>
Date: Thu, 6 Nov 2008 18:38:41 -0600

Fix the BSR driver to allow small BSR devices, which are limited to a
single 4k space, on a 64k page kernel.  Previously the driver would
reject the mmap since the size was smaller than PAGESIZE (or because
the size was greater than the size of the device).  Now, we check for
this case use remap_4k_pfn(). Also, take out code to set vm_flags,
as the remap_pfn functions will do this for us.

Signed-off-by: Sonny Rao <[email-masked]>

Index: common/drivers/char/bsr.c
===================================================================
--- common.orig/drivers/char/bsr.c	2008-11-06 16:43:58.000000000 -0600
+++ common/drivers/char/bsr.c	2008-11-06 18:30:41.000000000 -0600
@@ -27,6 +27,7 @@
 #include <linux/cdev.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <asm/pgtable.h>
 #include <asm/io.h>
 
 /*
@@ -115,15 +116,23 @@
 {
 	unsigned long size   = vma->vm_end - vma->vm_start;
 	struct bsr_dev *dev = filp->private_data;
+	int ret;
 
-	if (size > dev->bsr_len || (size & (PAGE_SIZE-1)))
-		return -EINVAL;
+	/* This is legal where we have a BSR on a 4k page but a 64k kernel */
+	if (size > dev->bsr_len)
+		size = dev->bsr_len;
 
-	vma->vm_flags |= (VM_IO | VM_DONTEXPAND);
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
-	if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT,
-			       size, vma->vm_page_prot))
+	if (dev->bsr_len < PAGE_SIZE)
+		ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12,
+				   vma->vm_page_prot);
+	else
+		ret = io_remap_pfn_range(vma, vma->vm_start,
+					 dev->bsr_addr >> PAGE_SHIFT,
+					 size, vma->vm_page_prot);
+
+	if (ret)
 		return -EAGAIN;
 
 	return 0;