Permalink
Browse files

+mmap

  • Loading branch information...
1 parent 24f2737 commit 5492ec7f2505bd1ff74af12100e16a2c864e7019 @makelinux committed Sep 16, 2012
Showing with 82 additions and 8 deletions.
  1. +14 −7 dio.c
  2. +1 −1 ldt-test
  3. +67 −0 ldt.c
View
@@ -37,38 +37,44 @@ static enum io_type {
static void *inbuf, * outbuf;
static void *mm;
-int buf_size = 8 * PAGE_SIZE;
+static int buf_size = 16 * 1024;
static int mmapoffset;
-static int mmapsize;
+static int mmapsize = 16 * 1024;
static char *dev_name;
static int ignore_eof;
int output(int dev, void *buf, int len)
{
+ int ret = 0;
if ( dev < 0 )
return 0;
switch (io_type) {
case mmap_io:
+ memcpy(mm,buf,len);
+ ret = len;
break;
case file_io:
default:
- len = write(dev, buf, len);
+ ret = write(dev, buf, len);
}
- return len;
+ return ret;
}
int input(int dev, void *buf, int len)
{
+ int ret;
if ( dev < 0 )
return 0;
switch (io_type) {
case mmap_io:
+ memcpy(buf,mm,len);
+ ret = len;
break;
case file_io:
default:
- len = read(dev, buf, len);
+ ret = read(dev, buf, len);
}
- return len;
+ return ret;
}
int pipe_start(int dev)
@@ -265,9 +271,10 @@ int main(int argc, char *argv[])
chkne(dev = open(dev_name, O_CREAT | O_RDWR,0666));
trvd(dev);
if (io_type == mmap_io) {
- mm = mmap(0, mmapsize, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, dev, mmapoffset);
+ mm = mmap(NULL, mmapsize, PROT_READ | PROT_WRITE, MAP_SHARED, dev, mmapoffset);
if (mm == MAP_FAILED) {
fprintf(stderr, "mmap() failed\n");
+ trvs(strerror(errno));
goto exit;
}
}
View
@@ -42,7 +42,7 @@ tracing_stop()
}
# sudo rmmod parport_pc parport ppdev lp
-sudo rmmod ldt ldt_plat_dev
+sudo rmmod ldt ldt_plat_dev 2> /dev/null
set -o errexit
make -s
sudo insmod ldt.ko irq=$irq
View
@@ -34,6 +34,10 @@
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
+static int bufsize = PFN_ALIGN(16 * 1024);
+static void * in_buf;
+static void * out_buf;
+
int irq = 0;
module_param(irq, int, 0);
@@ -157,6 +161,7 @@ static ssize_t ldt_read(struct file *file, char __user * buf, size_t count, loff
{
int ret;
unsigned int copied;
+_entry:
// TODO: implement blocking I/O
if (mutex_lock_interruptible(&read_lock))
return -EINTR;
@@ -171,6 +176,7 @@ static ssize_t ldt_write(struct file *file, const char __user * buf, size_t coun
{
int ret;
unsigned int copied;
+_entry:
if (mutex_lock_interruptible(&write_lock))
return -EINTR;
@@ -179,12 +185,53 @@ static ssize_t ldt_write(struct file *file, const char __user * buf, size_t coun
return ret ? ret : copied;
}
+void pages_set_reserved(struct page * page, int pages)
+{
+ for (; pages; pages--, page++)
+ SetPageReserved(page);
+}
+
+
+/* pages_flag - set or clear a flag for sequence of pages
+ *
+ * more generic soultion instead SetPageReserved, ClearPageReserved etc
+ */
+
+void pages_flag(struct page * page, int pages, int mask, int value)
+{
+ for (; pages; pages--, page++)
+ if (value)
+ __set_bit(mask, &page->flags);
+ else
+ __clear_bit(mask, &page->flags);
+
+}
+
+static int ldt_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ void * buf;
+_entry:
+ if (vma->vm_flags & VM_WRITE)
+ buf = in_buf;
+ else if (vma->vm_flags & VM_READ)
+ buf = out_buf;
+
+ //vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); // PAGE_SHARED
+ if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(in_buf) >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ trlm("remap_pfn_range failed");
+ return -EAGAIN;
+ }
+ return 0;
+}
+
struct file_operations ldt_fops = {
.owner = THIS_MODULE,
.open = ldt_open,
.release = ldt_release,
.read = ldt_read,
.write = ldt_write,
+ .mmap = ldt_mmap,
.poll = NULL,
};
@@ -205,7 +252,19 @@ static __devinit int ldt_probe(struct platform_device *pdev)
trvs_(KBUILD_MODNAME);
trvp_(pdev);
trvd_(irq);
+ trvd_(bufsize);
trln();
+ if (!( in_buf = alloc_pages_exact(bufsize, GFP_KERNEL | __GFP_ZERO) )) {
+ ret = - ENOMEM;
+ goto exit;
+ }
+ pages_flag(virt_to_page(in_buf), PFN_UP(bufsize), PG_reserved,1);
+ if (!( out_buf = alloc_pages_exact(bufsize, GFP_KERNEL | __GFP_ZERO) )) {
+ ret = - ENOMEM;
+ goto exit;
+ }
+ pages_flag(virt_to_page(out_buf), PFN_UP(bufsize), PG_reserved,1);
+ //ret = register_chrdev (0, KBUILD_MODNAME, &ldt_fops);
if (pdev) {
data = pdev->dev.platform_data;
r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -241,6 +300,14 @@ static int __devexit ldt_remove(struct platform_device *pdev)
if (irq) {
free_irq(irq, THIS_MODULE);
}
+ if (in_buf) {
+ pages_flag(virt_to_page(in_buf), PFN_UP(bufsize), PG_reserved,0);
+ free_pages_exact(in_buf, bufsize);
+ }
+ if (out_buf) {
+ pages_flag(virt_to_page(out_buf), PFN_UP(bufsize), PG_reserved,0);
+ free_pages_exact(out_buf, bufsize);
+ }
trvd(isr_counter);
trvd(ldt_work_counter);
return 0;

0 comments on commit 5492ec7

Please sign in to comment.