Skip to content
This repository
Browse code

+mmap

  • Loading branch information...
commit 5492ec7f2505bd1ff74af12100e16a2c864e7019 1 parent 24f2737
Constantine authored September 17, 2012
21  dio.c
@@ -37,38 +37,44 @@ static enum io_type {
37 37
 
38 38
 static void *inbuf, * outbuf;
39 39
 static void *mm;
40  
-int buf_size = 8 * PAGE_SIZE;
  40
+static int buf_size = 16 * 1024;
41 41
 static int mmapoffset;
42  
-static int mmapsize;
  42
+static int mmapsize = 16 * 1024;
43 43
 static char *dev_name;
44 44
 static int ignore_eof;
45 45
 
46 46
 int output(int dev, void *buf, int len)
47 47
 {
  48
+	int ret = 0;
48 49
 	if ( dev < 0 )
49 50
 		return 0;
50 51
 	switch (io_type) {
51 52
 	case mmap_io:
  53
+		memcpy(mm,buf,len);
  54
+		ret = len;
52 55
 		break;
53 56
 	case file_io:
54 57
 	default:
55  
-		len = write(dev, buf, len);
  58
+		ret = write(dev, buf, len);
56 59
 	}
57  
-	return len;
  60
+	return ret;
58 61
 }
59 62
 
60 63
 int input(int dev, void *buf, int len)
61 64
 {
  65
+	int ret;
62 66
 	if ( dev < 0 )
63 67
 		return 0;
64 68
 	switch (io_type) {
65 69
 	case mmap_io:
  70
+		memcpy(buf,mm,len);
  71
+		ret = len;
66 72
 		break;
67 73
 	case file_io:
68 74
 	default:
69  
-		len = read(dev, buf, len);
  75
+		ret = read(dev, buf, len);
70 76
 	}
71  
-	return len;
  77
+	return ret;
72 78
 }
73 79
 
74 80
 int pipe_start(int dev)
@@ -265,9 +271,10 @@ int main(int argc, char *argv[])
265 271
 	chkne(dev = open(dev_name, O_CREAT | O_RDWR,0666));
266 272
 	trvd(dev);
267 273
 	if (io_type == mmap_io) {
268  
-		mm = mmap(0, mmapsize, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, dev, mmapoffset);
  274
+		mm = mmap(NULL, mmapsize, PROT_READ | PROT_WRITE, MAP_SHARED, dev, mmapoffset);
269 275
 		if (mm == MAP_FAILED) {
270 276
 			fprintf(stderr, "mmap() failed\n");
  277
+			trvs(strerror(errno));
271 278
 			goto exit;
272 279
 		}
273 280
 	}
2  ldt-test
@@ -42,7 +42,7 @@ tracing_stop()
42 42
 }
43 43
 
44 44
 # sudo rmmod parport_pc parport  ppdev lp
45  
-sudo rmmod ldt ldt_plat_dev
  45
+sudo rmmod ldt ldt_plat_dev 2> /dev/null
46 46
 set -o errexit
47 47
 make -s
48 48
 sudo insmod ldt.ko irq=$irq
67  ldt.c
@@ -34,6 +34,10 @@
34 34
 #include <linux/miscdevice.h>
35 35
 #include <linux/platform_device.h>
36 36
 
  37
+static int bufsize = PFN_ALIGN(16 * 1024);
  38
+static void * in_buf;
  39
+static void * out_buf;
  40
+
37 41
 int irq = 0;
38 42
 module_param(irq, int, 0);
39 43
 
@@ -157,6 +161,7 @@ static ssize_t ldt_read(struct file *file, char __user * buf, size_t count, loff
157 161
 {
158 162
 	int ret;
159 163
 	unsigned int copied;
  164
+_entry:
160 165
 	// TODO: implement blocking I/O
161 166
 	if (mutex_lock_interruptible(&read_lock))
162 167
 		return -EINTR;
@@ -171,6 +176,7 @@ static ssize_t ldt_write(struct file *file, const char __user * buf, size_t coun
171 176
 {
172 177
 	int ret;
173 178
 	unsigned int copied;
  179
+_entry:
174 180
 
175 181
 	if (mutex_lock_interruptible(&write_lock))
176 182
 		return -EINTR;
@@ -179,12 +185,53 @@ static ssize_t ldt_write(struct file *file, const char __user * buf, size_t coun
179 185
 	return ret ? ret : copied;
180 186
 }
181 187
 
  188
+void pages_set_reserved(struct page * page, int pages)
  189
+{
  190
+	for (; pages; pages--, page++)
  191
+		SetPageReserved(page);
  192
+}
  193
+
  194
+
  195
+/*	pages_flag - set or clear a flag for sequence of pages
  196
+ *   
  197
+ *	more generic soultion instead SetPageReserved, ClearPageReserved etc
  198
+ */
  199
+
  200
+void pages_flag(struct page * page, int pages, int mask, int value)
  201
+{
  202
+	for (; pages; pages--, page++)
  203
+		if (value)
  204
+			__set_bit(mask, &page->flags);
  205
+		else
  206
+			__clear_bit(mask, &page->flags); 
  207
+
  208
+}
  209
+
  210
+static int ldt_mmap(struct file *filp, struct vm_area_struct *vma)
  211
+{
  212
+       void * buf;
  213
+_entry:
  214
+       if (vma->vm_flags & VM_WRITE)
  215
+	       buf = in_buf;
  216
+       else if (vma->vm_flags & VM_READ)
  217
+	       buf = out_buf;
  218
+
  219
+       //vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);     // PAGE_SHARED
  220
+       if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(in_buf) >> PAGE_SHIFT,
  221
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  222
+	       trlm("remap_pfn_range failed");
  223
+	       return -EAGAIN;
  224
+       }
  225
+       return 0;
  226
+}
  227
+
182 228
 struct file_operations ldt_fops = {
183 229
 	.owner = THIS_MODULE,
184 230
 	.open = ldt_open,
185 231
 	.release = ldt_release,
186 232
 	.read = ldt_read,
187 233
 	.write = ldt_write,
  234
+	.mmap = ldt_mmap,
188 235
 	.poll = NULL,
189 236
 };
190 237
 
@@ -205,7 +252,19 @@ static __devinit int ldt_probe(struct platform_device *pdev)
205 252
 	trvs_(KBUILD_MODNAME);
206 253
 	trvp_(pdev);
207 254
 	trvd_(irq);
  255
+	trvd_(bufsize);
208 256
 	trln();
  257
+	if (!( in_buf = alloc_pages_exact(bufsize, GFP_KERNEL | __GFP_ZERO) )) { 
  258
+		ret = - ENOMEM;
  259
+		goto exit;
  260
+	}
  261
+	pages_flag(virt_to_page(in_buf), PFN_UP(bufsize), PG_reserved,1);
  262
+	if (!( out_buf = alloc_pages_exact(bufsize, GFP_KERNEL | __GFP_ZERO) )) { 
  263
+		ret = - ENOMEM;
  264
+		goto exit;
  265
+	}
  266
+	pages_flag(virt_to_page(out_buf), PFN_UP(bufsize), PG_reserved,1);
  267
+	//ret = register_chrdev (0, KBUILD_MODNAME, &ldt_fops);
209 268
 	if (pdev) {
210 269
 		data = pdev->dev.platform_data;
211 270
 		r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -241,6 +300,14 @@ static int __devexit ldt_remove(struct platform_device *pdev)
241 300
 	if (irq) {
242 301
 		free_irq(irq, THIS_MODULE);
243 302
 	}
  303
+	if (in_buf) {
  304
+		pages_flag(virt_to_page(in_buf), PFN_UP(bufsize), PG_reserved,0);
  305
+		free_pages_exact(in_buf, bufsize);
  306
+	}
  307
+	if (out_buf) {
  308
+		pages_flag(virt_to_page(out_buf), PFN_UP(bufsize), PG_reserved,0);
  309
+		free_pages_exact(out_buf, bufsize);
  310
+	}
244 311
 	trvd(isr_counter);
245 312
 	trvd(ldt_work_counter);
246 313
 	return 0;

0 notes on commit 5492ec7

Please sign in to comment.
Something went wrong with that request. Please try again.