From 786c393fbb00e6c8097a69ff79aefb03e277b0b6 Mon Sep 17 00:00:00 2001
From: "Wesley W. Terpstra" <w.terpstra@gsi.de>
Date: Tue, 17 Apr 2012 09:07:50 +0000
Subject: [PATCH] Much hacking to remove baggage from the old driver

---
 driver/Makefile                  |   5 +-
 driver/pci_char.c                | 507 -------------------------------
 driver/pci_char.mod.c            |   1 +
 driver/pci_char_load             |   8 +-
 driver/pcie_wb.c                 | 299 ++++++++++++++++++
 driver/{pci_char.h => pcie_wb.h} |   0
 6 files changed, 307 insertions(+), 513 deletions(-)
 delete mode 100644 driver/pci_char.c
 create mode 100644 driver/pcie_wb.c
 rename driver/{pci_char.h => pcie_wb.h} (100%)

diff --git a/driver/Makefile b/driver/Makefile
index a8273b1..d4f1308 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -15,9 +15,10 @@
 
 
 
-KERNELDIR ?= /common/usr/embedded/kernel/scu/linux-2.6.33.6/
+KERNELDIR ?= /usr/src/linux-3.2.14 #/common/usr/embedded/kernel/scu/linux-2.6.33.6/
 ifneq ($(KERNELRELEASE),)
-	obj-m	:= pci_char.o sleepy.o
+CFLAGS_pcie_wb.o = -msse2
+	obj-m	:= pcie_wb.o
 else
 	KERNELDIR ?= /lib/modules/$(shell uname -r)/build
 	PWD       := $(shell pwd)
diff --git a/driver/pci_char.c b/driver/pci_char.c
deleted file mode 100644
index cf5f728..0000000
--- a/driver/pci_char.c
+++ /dev/null
@@ -1,507 +0,0 @@
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/kdev_t.h>
-#include <linux/poll.h>
-#include <linux/interrupt.h>
-#include <linux/cdev.h>
-#include <linux/aer.h>
-
-#include <asm/io.h>		/*outb iowrite8 */
-#include <asm/spinlock.h>
-
-#include "pci_char.h"
-
-#define FALSE 0
-#define TRUE 1
-
-int use_mem = FALSE;			/* mem or io port */
-int use_msi = FALSE;			/* Message Signaled Interrupts enabled */
-
-static int  major_num  = 0;		/* major number for char device */
-static int  minor_num  = 0;		/* minor number for char device */
-static struct cdev *cdev_irq;
-static struct cdev *cdev_rd;
-
-struct pci_resource *pci_res0 = NULL;	/* ptrs to resource objects */
-struct pci_resource *pci_res1 = NULL;
-
-char name_str[] = "pci_char";
-char myirq = -1;						/* IRQ from PCI config reg */
-int instance_count = 0;					/* counting connected processes for housekeeping */
-
-static DECLARE_WAIT_QUEUE_HEAD(event_wq);
-static DEFINE_SPINLOCK(snapshot_lock);
-static DEFINE_SPINLOCK(period_lock);
-
-unsigned long short_buffer = 0;
-unsigned long volatile short_head;
-volatile unsigned long short_tail;
-
-
-static inline void short_incr_bp(volatile unsigned long *index, int delta)
-{
-	unsigned long new = *index + delta;
-	barrier();  /* Don't optimize these two together */
-	*index = (new >= (short_buffer + PAGE_SIZE)) ? short_buffer : new;
-}
-
-struct pci_resource {
-	int bar;						/* BAR number from 0 to 5 */
-	unsigned long start;			/* start addr of BAR */
-	unsigned long end;				/* end addr of BAR */
-	unsigned int size;
-	void *m_addr;					/* remapped addr */
-	int is_mem;
-};
-
-irq_handler_t my_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-
-	int ret;
-	int snapl_value;
-	int snaph_value;
-	int snap_value;
-	unsigned char *bptr = pci_res0->m_addr;
-	//int written;
-	
-	mb();
-	/* check if our device has triggered */
-	ret = ioread32(bptr + TMR_0_BASE);mb();
-	if (!(ret & 0x1))
-		return IRQ_NONE;
-
-
-	/* copy snapshot value from timer */
-	/* should be atomic */
-	spin_lock(&snapshot_lock);
-	/* trigger the latch of the counter value */
-	iowrite16(0x0, bptr + TMR_0_SNAPL);
-	rmb();	// has to be executed before reading
-	snapl_value = ioread16(bptr + TMR_0_SNAPL);rmb();
-	snaph_value = ioread16(bptr + TMR_0_SNAPH);rmb();
-	spin_unlock(&snapshot_lock);
-	snap_value = (int)(snaph_value << 16) | snapl_value;
-	//printk(KERN_ALERT "%s: snap_value = 0x%x\n", name_str, snap_value);
-	//snap_value = snap_value | (snaph_value << 32);
-	//written = sprintf((char *)short_head,"%08x\n", snap_value);
-	*(u32 *)short_head = snap_value;
-
-	short_incr_bp(&short_head, sizeof(u32));
-
-	/* wake up the reading process */
-	wake_up_interruptible(&event_wq);
-
-	/* clear the interrupting bit in the pio */
-	//iowrite32(0x0, bptr + PIO_BASE + EDGE_CAPTURE);
-	/* clear pending bit in edge capture register */
-	mb();
-	//iowrite32(0x0, bptr + TMR_EDGE_CAPTURE);
-	iowrite16(0x0, bptr + TMR_0_BASE);mb();
-
-
-
-	//printk(KERN_ALERT "%s: irq handler called\n", name_str);
-	return (irq_handler_t)IRQ_HANDLED;
-}
-
-
-int pci_skel_open (struct inode *inode, struct file *filp)
-{	
-	
-	int result;
-	unsigned char *bptr = pci_res0->m_addr;
-	int arg = IRQ_RATE;
-
-	instance_count++;
-
-	iowrite16(arg, bptr + TMR_0_PERIODL);
-	wmb();
-	iowrite16(arg >> 16, bptr + TMR_0_PERIODH);
-
-	/* we have a irq number and the first process is connecting */
-	if (myirq >= 0 && instance_count == 1) {
-		result = request_irq(	myirq,
- 					(irq_handler_t)my_irq_handler,
-					IRQF_SHARED,
-					name_str,
-					pci_res0 /* used as dev_id */
-					);
-		if (result) {
-			printk(KERN_ALERT "%s: can't get IRQ %d\n", name_str, myirq);
-			myirq = -1;
-		} else {
-			/* enable irq */
-			/* enable MSI in MSI Control Register of PCI Endpoint */
-			result = ioread32(bptr + PCIE_BASE + MSI);
-			iowrite32(result |= (1UL << 16), bptr + PCIE_BASE + MSI);
-			
-			/* enable AVL_IRQ in MSI Control Register of PCI Endpoint */
-			result = ioread32(bptr + PCIE_BASE + MSI);
-			iowrite32(result |= (1UL << 7), bptr + PCIE_BASE + MSI);
-
-			mb();
-
-			iowrite16(0x7, bptr + TMR_0_CTRL);
-
-			ioread32(bptr + PCIE_BASE); /* dummy read */
-			mb();
-
-		}
-	}
-					
-	return 0;
-}
-
-int pci_rd_open (struct inode *inode, struct file *filp)
-{
-	return 0;
-}
-
-int pci_irq_release (struct inode *inode, struct file *filp)
-{
-	unsigned char *bptr = pci_res0->m_addr;
-	int result;
-
-	instance_count--;
-
-	/* we have a irq number and the last connected process is to be released*/
-	if (myirq && instance_count == 0)
-	{
-		free_irq(myirq, pci_res0 /* dev_id */);
-
-		mb();
-		/* disable timer irq */
-		iowrite16(0x0, bptr + TMR_0_CTRL);
-		mb();
-
-		/* disable AVL_IRQ in MSI Control Register of PCI Endpoint */
-		result = ioread32(bptr + PCIE_BASE + MSI);
-		iowrite32(result |= (0UL << 7), bptr + PCIE_BASE + MSI);
-		/* disable MSI in MSI Control Register of PCI Endpoint */
-		result = ioread32(bptr + PCIE_BASE + MSI);
-		iowrite32(result |= (0UL << 16), bptr + PCIE_BASE + MSI);
-
-		ioread32(bptr + PCIE_BASE); /* dummy read */
-		mb();
-
-	}
-	return 0;
-}
-
-int pci_rd_release (struct inode *inode, struct file *filp)
-{
-
-	return 0;
-}
-
-ssize_t pci_blocking_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
-{
-	int count0;
-
-	
-	/* there is no data so we are going to wait. */
-	/* but only if there is no wakeup call pending */
-	wait_event_interruptible(event_wq, short_head != short_tail);
-
-	/* now we should have at least one event in the buffer */
-
-	/* count0 is the number of readable data bytes */
-	count0 = short_head - short_tail;
-	if (count0 < 0) /* wrapped */
-		count0 = short_buffer + PAGE_SIZE - short_tail;
-	//printk(KERN_ALERT "%s: read count0 = %d\n", name_str, count0);
-	if (count0 < count) count = count0;
-	if (copy_to_user(buf, (char *)short_tail, count))
-		return -EFAULT;
-	short_incr_bp (&short_tail, count);
-	return count;
-}
-
-ssize_t pci_nonblocking_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
-{
-	int snapl_value;
-	int snaph_value;
-	int snap_value;
-	unsigned char *bptr = pci_res0->m_addr;
-
-	/* copy snapshot value from timer */
-	/* should be atomic */
-	spin_lock(&snapshot_lock);
-	/* trigger the latch of the counter value */
-	iowrite16(0x0, bptr + TMR_0_SNAPL);
-	rmb();	// has to be executed before reading
-	snapl_value = ioread16(bptr + TMR_0_SNAPL);rmb();
-	snaph_value = ioread16(bptr + TMR_0_SNAPH);rmb();
-	spin_unlock(&snapshot_lock);
-	snap_value = (int)(snaph_value << 16) | snapl_value;
-
-	if (copy_to_user(buf, &snap_value, 4))
-			return -EFAULT;
-
-	return 4;
-}
-
-ssize_t pci_skel_write(struct file *filp, const char __user *buf, size_t count,
-		loff_t *f_pos)
-{
-  		return 0;
-}
-
-int pci_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,  unsigned long arg) {
-	
-	int retval = 0;
-	unsigned char *bptr = pci_res0->m_addr;
-	
-	if(_IOC_TYPE(cmd) != PCI_CHAR_MAGIC) return -ENOTTY;
-	if(_IOC_NR(cmd) > PCI_CHAR_MAXNR) return -ENOTTY;
-	
-	switch(cmd) {
-		/*case SET_PERIOD:
-			//printk(KERN_ALERT "%s: periodl 0x%x\n", name_str, arg);
-			 should be atomic
-			spin_lock(&period_lock);
-			iowrite16(arg, bptr + TMR_0_PERIODL);
-			wmb();
-			iowrite16(arg >> 16, bptr + TMR_0_PERIODH);
-			spin_unlock(&period_lock);
-			break;
-		case GET_PERIOD:
-			spin_lock(&period_lock);
-			retval = ioread16(bptr + TMR_0_PERIODL);
-			rmb();
-			retval = ioread16(bptr + TMR_0_PERIODH) << 16 | retval;
-			spin_unlock(&period_lock);
-			printk(KERN_ALERT "%s: period value is 0x%x\n", name_str, retval);
-			return retval;
-			break;*/
-			
-		default:
-			return -ENOTTY;
-	}
-	return retval;
-}
-
-
-unsigned int pci_skel_poll(struct file *filp, poll_table *wait)
-{
-	return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
-}
-
-struct file_operations pci_irq_fops = {
-	.owner	 = THIS_MODULE,
-	.read	 = pci_blocking_read,
-	.write	 = pci_skel_write,
-	.ioctl   = pci_ioctl,		
-	.poll	 = pci_skel_poll,
-	.open	 = pci_skel_open,
-	.release = pci_irq_release,
-};
-
-struct file_operations pci_rd_fops = {
-	.owner	 = THIS_MODULE,
-	.read	 = pci_nonblocking_read,
-	.poll	 = pci_skel_poll,
-	.open	 = pci_rd_open,
-	.release = pci_rd_release,
-};
-
-static struct pci_device_id ids[] = {
-	{ PCI_DEVICE(ALTERA_ID, DEVICE_ID), },
-	{ PCI_DEVICE(0x1002, 0x4750), },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, ids);
-
-static unsigned char skel_get_revision(struct pci_dev *dev)
-{
-	u8 revision;
-
-	pci_read_config_byte(dev, PCI_REVISION_ID, &revision);
-	return revision;
-}
-
-static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	/* Do probing type stuff here.  
-	 * Like calling request_region();
-	 * reading BARs
-	 * reading IRQ
-	 * register char dev
-	 */
-	int result;
-	int is_mem;
-	dev_t dev_irq = MKDEV(major_num, minor_num);
-	dev_t dev_rd = MKDEV(major_num, minor_num);
-
-	if (skel_get_revision(pdev) != 0x01) {
-		printk(KERN_ALERT "%s: revision ID wrong!\n", name_str);
-		return -ENODEV;
-	}
-
-	/* enable pcie error reporting */
-	result = pci_enable_pcie_error_reporting(pdev);
-	if (result) {
-		printk(KERN_ALERT "Could not enable pcie error reporting.\n");
-	}
-
-	/* enable message signaled interrupts */
-	result = pci_enable_msi(pdev);
-	/* could not use MSI? */
-	if (result) {
-	/* resort to legacy interrupts */
-		printk(KERN_ALERT "Could not enable MSI interrupting, staying with legacy.\n");
-	/* MSI enabled, remember for cleanup */
-	} else {
-		use_msi = TRUE;
-		printk(KERN_ALERT "Enabled MSI interrupting.\n");
-	}
-
-	pci_res0 = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);	/* mem for object */
-	if (!pci_res0) {
-		printk(KERN_ALERT "%s: could not alloc mem for pci_res0!\n", name_str);
-		goto err_pci_res0;
-	}
-
-	/*init of pci_res0 */
-	pci_res0->bar = 0;
-	pci_res0->start = pci_resource_start(pdev, 0);
-	pci_res0->end = pci_resource_end(pdev, 0);
-	pci_res0->size = pci_res0->end - pci_res0->start + 1;
-
-	is_mem = pci_resource_flags(pdev, 0);
-	is_mem = is_mem & IORESOURCE_MEM;
-	pci_res0->is_mem = is_mem;
-
-	printk(KERN_ALERT "%s: BAR0  0x%lx - 0x%lx\n", name_str, pci_res0->start, pci_res0->end);
-
-	if (!request_mem_region(pci_res0->start, pci_res0->size, name_str)) {
-			printk(KERN_ALERT "%s: request_mem_region failed\n", name_str);
-			goto err_mem_region;
-	}
-	
-	pci_res0->m_addr = ioremap_nocache(pci_res0->start, pci_res0->size);
-	printk(KERN_ALERT "%s: ioremap to %lx\n", name_str, (unsigned long)pci_res0->m_addr);
-
-	/* get irq number from pci */
-	myirq = pdev->irq;
-	printk(KERN_ALERT "%s: using IRQ number %d\n", name_str, myirq);
-
-	/* alloc DEV_COUNT device number */
-	result  = alloc_chrdev_region (&dev_irq, FIRSTMINOR, DEV_COUNT, name_str);
-	if(result < 0) {
-		printk(KERN_ALERT "%s: ERROR unable to get major number\n", name_str);
-		goto err_alloc_chrdev;
-	} else {
-		major_num = MAJOR(dev_irq);
-		printk(KERN_ALERT "%s: My major nummber is: %d\n", name_str, major_num);
-	};
-
-	// assign dev_rd the next minor number
-	dev_rd = MKDEV(major_num, MINOR(dev_irq) + 1);
-
-	// allocate cdev structures
-	cdev_irq = cdev_alloc();
-	cdev_rd = cdev_alloc();
-
-	if((cdev_irq == NULL) || (cdev_rd == NULL)){
-		printk("%s: ERROR allocate cdev structur failure\n", name_str);
-		goto err_cdev_alloc;
-	}
-
-	cdev_irq->owner  = THIS_MODULE;
-	cdev_irq->ops    = &pci_irq_fops;
-
-	cdev_rd->owner  = THIS_MODULE;
-	cdev_rd->ops    = &pci_rd_fops;
-
-	result = cdev_add(cdev_irq, dev_irq, 1);
-	if(result < 0){
-		printk("%s: cdev_add dev_irq failed\n", name_str);
-		goto err_alloc_chrdev;
-	} else
-		printk("%s: added cdev_irq\n", name_str);
-
-	result = cdev_add(cdev_rd, dev_rd, 1);
-	if(result < 0){
-		printk("%s: cdev_add dev_rd failed\\n", name_str);
-		goto err_cdev_add;
-	} else
-		printk("%s: added cdev_rd\n", name_str);
-
-
-	short_buffer = __get_free_pages(GFP_KERNEL,0);  //never fails
-	short_head = short_tail = short_buffer;
-
-	return pci_enable_device(pdev);
-
-	/* cleaning up */
-	err_cdev_add:
-		cdev_del(cdev_irq);
-	err_cdev_alloc:
-		unregister_chrdev_region (MKDEV(major_num, minor_num), DEV_COUNT);
-	err_alloc_chrdev:
-		iounmap(pci_res0->m_addr);
-		release_mem_region(pci_res0->start, pci_res0->size);
-	err_mem_region:
-		kfree(pci_res0);
-	err_pci_res0:
-		return -EIO;
-}
-
-static void remove(struct pci_dev *pdev)
-{
-	
-	/* clean up any allocated resources and stuff here.
-	 * like call release_mem_region();
-	 */
-
-	printk(KERN_ALERT "%s: releasing resources\n", name_str);
-	if (cdev_rd)
-		cdev_del(cdev_rd);
-	if (cdev_irq)
-		cdev_del(cdev_irq);
-	if (major_num) {
-		unregister_chrdev_region (MKDEV(major_num, minor_num), DEV_COUNT);
-		printk(KERN_ALERT "%s: released major number %i\n", name_str, major_num);
-	}
-	if (use_msi)
-		pci_disable_msi(pdev);
-
-	iounmap(pci_res0->m_addr);
-	release_mem_region(pci_res0->start, pci_res0->size);
-	printk(KERN_ALERT "%s: released io 0x%lx\n", name_str, pci_res0->start);
-	if (pci_res0 != NULL)
-		kfree(pci_res0);
-}
-
-static int err_handler(struct pci_dev *pdev) {
-	printk(KERN_ALERT "%s:  err handler called!\n", name_str);
-	return 0;
-}
-
-static struct pci_driver pci_driver = {
-	.name = name_str,
-	.id_table = ids,
-	.probe = probe,
-	.remove = remove,
-	.err_handler = err_handler,
-};
-
-static int __init pci_skel_init(void)
-{
-	return pci_register_driver(&pci_driver);
-}
-
-static void __exit pci_skel_exit(void)
-{	
-	pci_unregister_driver(&pci_driver);
-}
-
-MODULE_LICENSE("GPL");
-
-module_init(pci_skel_init);
-module_exit(pci_skel_exit);
diff --git a/driver/pci_char.mod.c b/driver/pci_char.mod.c
index 6e65825..377c689 100644
--- a/driver/pci_char.mod.c
+++ b/driver/pci_char.mod.c
@@ -20,3 +20,4 @@ __attribute__((section(".modinfo"))) =
 "depends=";
 
 MODULE_ALIAS("pci:v00001172d00000004sv*sd*bc*sc*i*");
+MODULE_ALIAS("pci:v00001002d00004750sv*sd*bc*sc*i*");
diff --git a/driver/pci_char_load b/driver/pci_char_load
index 75167ab..cc8887a 100755
--- a/driver/pci_char_load
+++ b/driver/pci_char_load
@@ -1,10 +1,11 @@
 #!/bin/sh
-module="pci_char"
-device="pci_char"
+module="pcie_wb"
+device="pcie_wb"
 mode="664"
 
 # invoke insmod with all arguments we got
 # and use a pathname, as newer modutils don't look in . by default
+rmmod $module
 /sbin/insmod ./$module.ko $* || exit 1
 
 #remove stale nodes
@@ -12,5 +13,4 @@ rm -f /dev/${device}[0-3]
 
 major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
 
-mknod /dev/${device}0 c $major 0
-mknod /dev/${device}1 c $major 1
+mknod /dev/${device} c $major 0
diff --git a/driver/pcie_wb.c b/driver/pcie_wb.c
new file mode 100644
index 0000000..2309ed9
--- /dev/null
+++ b/driver/pcie_wb.c
@@ -0,0 +1,299 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/kdev_t.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/aer.h>
+#include <linux/sched.h> 
+
+#include <asm/io.h>		/*outb iowrite8 */
+#include <asm/spinlock.h>
+
+#include "pcie_wb.h"
+
+#define FALSE 0
+#define TRUE 1
+
+typedef float __m128 __attribute__ ((__vector_size__ (16)));
+
+static int  major_num  = 0;		/* major number for char device */
+static int  minor_num  = 0;		/* minor number for char device */
+static struct cdev *cdev_char;
+
+struct pci_resource *pci_res0 = NULL;	/* ptrs to resource objects */
+struct pci_resource *pci_res1 = NULL;
+
+char name_str[] = "pcie_wb";
+char myirq = -1;						/* IRQ from PCI config reg */
+int instance_count = 0;					/* counting connected processes for housekeeping */
+
+static DECLARE_WAIT_QUEUE_HEAD(event_wq);
+static DEFINE_SPINLOCK(snapshot_lock);
+static DEFINE_SPINLOCK(period_lock);
+
+unsigned long short_buffer = 0;
+unsigned long volatile short_head;
+volatile unsigned long short_tail;
+
+
+static inline void short_incr_bp(volatile unsigned long *index, int delta)
+{
+	unsigned long new = *index + delta;
+	barrier();  /* Don't optimize these two together */
+	*index = (new >= (short_buffer + PAGE_SIZE)) ? short_buffer : new;
+}
+
+struct pci_resource {
+	int bar;						/* BAR number from 0 to 5 */
+	unsigned long start;			/* start addr of BAR */
+	unsigned long end;				/* end addr of BAR */
+	unsigned int size;
+	void *m_addr;					/* remapped addr */
+	int is_mem;
+};
+
+irq_handler_t my_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	return (irq_handler_t)IRQ_HANDLED;
+}
+
+
+int char_open (struct inode *inode, struct file *filp)
+{	
+	//iowrite16(arg >> 16, bptr + TMR_0_PERIODH);
+	//wmb();
+
+	return 0;
+}
+
+int char_release (struct inode *inode, struct file *filp)
+{
+
+	return 0;
+}
+
+ssize_t char_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	unsigned char *bptr = pci_res0->m_addr;
+	int value = 0x41424344;
+
+	/* copy snapshot value from timer */
+	/* should be atomic */
+	spin_lock(&snapshot_lock);
+	rmb();	// has to be executed before reading
+	spin_unlock(&snapshot_lock);
+
+	if (copy_to_user(buf, &value, 4))
+		return -EFAULT;
+
+	return 4;
+}
+
+ssize_t char_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	unsigned char *bptr = pci_res0->m_addr;
+	uint32_t value;
+	__m128 x;
+
+	if (copy_from_user(&value, buf, 4))
+		return -EFAULT;
+	
+	/* copy snapshot value from timer */
+	/* should be atomic */
+	spin_lock(&snapshot_lock);
+	iowrite32(value, bptr + 8);
+	iowrite32(value, bptr + 12);
+	iowrite16(value, bptr + 18);
+	iowrite8(value, bptr + 17);
+	ioread16(bptr + 16);
+//	iowrite32(value, bptr + 12);
+//	iowrite32(value, bptr + 16);
+//	iowrite16(value, bptr + 18);
+//	iowrite8(value, bptr + 25);
+	rmb();	// has to be executed before reading
+	spin_unlock(&snapshot_lock);
+
+	return 1;
+}
+
+unsigned int char_poll(struct file *filp, poll_table *wait)
+{
+	return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
+}
+
+struct file_operations char_fops = {
+	.owner	 = THIS_MODULE,
+	.read	 = char_read,
+	.write	 = char_write,
+	.poll	 = char_poll,
+	.open	 = char_open,
+	.release = char_release,
+};
+
+static struct pci_device_id ids[] = {
+	{ PCI_DEVICE(ALTERA_ID, DEVICE_ID), },
+	{ PCI_DEVICE(0x1002, 0x4750), },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, ids);
+
+static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	/* Do probing type stuff here.  
+	 * Like calling request_region();
+	 * reading BARs
+	 * reading IRQ
+	 * register char dev
+	 */
+	dev_t dev_char;
+	int result;
+	int is_mem;
+	u8 revision;
+
+	dev_char = MKDEV(major_num, minor_num);
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &revision);
+	if (revision != 0x01) {
+		printk(KERN_ALERT "%s: revision ID wrong!\n", name_str);
+		return -ENODEV;
+	}
+
+	/* enable pcie error reporting */
+/*
+	result = pci_enable_pcie_error_reporting(pdev);
+	if (result) {
+		printk(KERN_ALERT "Could not enable pcie error reporting.\n");
+		return -ENODEV;
+	}
+*/
+	/* enable message signaled interrupts */
+	if (pci_enable_msi(pdev) != 0) {
+		/* resort to legacy interrupts */
+		printk(KERN_ALERT "Could not enable MSI interrupting, staying with legacy.\n");
+		return -ENODEV;
+	}
+
+	pci_res0 = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);	/* mem for object */
+	if (!pci_res0) {
+		printk(KERN_ALERT "%s: could not alloc mem for pci_res0!\n", name_str);
+		goto err_pci_res0;
+	}
+
+	/*init of pci_res0 */
+	pci_res0->bar = 0;
+	pci_res0->start = pci_resource_start(pdev, 0);
+	pci_res0->end = pci_resource_end(pdev, 0);
+	pci_res0->size = pci_res0->end - pci_res0->start + 1;
+
+	is_mem = pci_resource_flags(pdev, 0);
+	is_mem = is_mem & IORESOURCE_MEM;
+	pci_res0->is_mem = is_mem;
+
+	printk(KERN_ALERT "%s: BAR0  0x%lx - 0x%lx\n", name_str, pci_res0->start, pci_res0->end);
+
+	if (!request_mem_region(pci_res0->start, pci_res0->size, name_str)) {
+		printk(KERN_ALERT "%s: request_mem_region failed\n", name_str);
+		goto err_mem_region;
+	}
+	
+	pci_res0->m_addr = ioremap_nocache(pci_res0->start, pci_res0->size);
+	printk(KERN_ALERT "%s: ioremap to %lx\n", name_str, (unsigned long)pci_res0->m_addr);
+
+	/* get irq number from pci */
+	myirq = pdev->irq;
+	printk(KERN_ALERT "%s: using IRQ number %d\n", name_str, myirq);
+
+	/* alloc DEV_COUNT device number */
+	result  = alloc_chrdev_region (&dev_char, FIRSTMINOR, DEV_COUNT, name_str);
+	if(result < 0) {
+		printk(KERN_ALERT "%s: ERROR unable to get major number\n", name_str);
+		goto err_alloc_chrdev;
+	} else {
+		major_num = MAJOR(dev_char);
+		printk(KERN_ALERT "%s: My major nummber is: %d\n", name_str, major_num);
+	};
+
+	// allocate cdev structures
+	cdev_char = cdev_alloc();
+
+	if(cdev_char == NULL) {
+		printk("%s: ERROR allocate cdev structur failure\n", name_str);
+		goto err_cdev_alloc;
+	}
+
+	cdev_char->owner  = THIS_MODULE;
+	cdev_char->ops    = &char_fops;
+
+	result = cdev_add(cdev_char, dev_char, 1);
+	if(result < 0){
+		printk("%s: cdev_add dev_char failed\n", name_str);
+		goto err_alloc_chrdev;
+	} else
+		printk("%s: added cdev_irq\n", name_str);
+
+	short_buffer = __get_free_pages(GFP_KERNEL,0);  //never fails
+	short_head = short_tail = short_buffer;
+
+	return pci_enable_device(pdev);
+
+	/* cleaning up */
+	err_cdev_alloc:
+		unregister_chrdev_region (MKDEV(major_num, minor_num), DEV_COUNT);
+	err_alloc_chrdev:
+		iounmap(pci_res0->m_addr);
+		release_mem_region(pci_res0->start, pci_res0->size);
+	err_mem_region:
+		kfree(pci_res0);
+	err_pci_res0:
+		return -EIO;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+	
+	/* clean up any allocated resources and stuff here.
+	 * like call release_mem_region();
+	 */
+
+	printk(KERN_ALERT "%s: releasing resources\n", name_str);
+	if (cdev_char)
+		cdev_del(cdev_char);
+	if (major_num) {
+		unregister_chrdev_region (MKDEV(major_num, minor_num), DEV_COUNT);
+		printk(KERN_ALERT "%s: released major number %i\n", name_str, major_num);
+	}
+	pci_disable_msi(pdev);
+
+	iounmap(pci_res0->m_addr);
+	release_mem_region(pci_res0->start, pci_res0->size);
+	printk(KERN_ALERT "%s: released io 0x%lx\n", name_str, pci_res0->start);
+	if (pci_res0 != NULL)
+		kfree(pci_res0);
+}
+
+static struct pci_driver pci_driver = {
+	.name = name_str,
+	.id_table = ids,
+	.probe = probe,
+	.remove = remove,
+};
+
+static int __init pcie_wb_init(void)
+{
+	return pci_register_driver(&pci_driver);
+}
+
+static void __exit pcie_wb_exit(void)
+{	
+	pci_unregister_driver(&pci_driver);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(pcie_wb_init);
+module_exit(pcie_wb_exit);
diff --git a/driver/pci_char.h b/driver/pcie_wb.h
similarity index 100%
rename from driver/pci_char.h
rename to driver/pcie_wb.h
-- 
GitLab