| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -12,6 +12,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/spinlock_types.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/fs.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/proc_fs.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/cdev.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/sched.h> | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -19,13 +20,14 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/delay.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <linux/poll.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define DMA_ADDR_OFFSET 32 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define PRINT(A) printk(KERN_ALERT ">>>>> #A %x\n", A); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					MODULE_AUTHOR("h4ndh"); //hediyehloo based on Talaee works
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					MODULE_LICENSE("Dual BSD/GPL"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static struct pci_device_id pcie_ids[] = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {PCI_DEVICE(0x10ee, 0x7024)}, | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -33,43 +35,28 @@ static struct pci_device_id pcie_ids[] = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					MODULE_DEVICE_TABLE(pci, pcie_ids); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static irqreturn_t interrupt_handler(int irq, void *p); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static struct pci_dev *pcidev = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int chrdev_major = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int chrdev_minor = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int ioctl_alloc_dma = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int ioctl_refresh_link = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar0_addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar0_size = 64 * 1024; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void* bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar1_addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar1_size = 128 * 1024 * 1024; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void* bar1_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int irq; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct page** dma_pages = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					unsigned int dma_pages_count = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void* dma_addr = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					unsigned long mmap_buffersize = 4 * 1024; //4KB
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int pcie_init(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int chrdev_init(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open(struct inode *inode, struct file *flip); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap(struct file *filp, struct vm_area_struct *vma); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int usd_poll (struct file *filp, poll_table *wait); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void pcie_exit(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int pcie_probe (struct pci_dev *dev, const struct pci_device_id *id); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void pcie_remove(struct pci_dev *dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void pcie_exit(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int chrdev_init(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_0(struct inode *inode, struct file *flip); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_0(struct inode *inode, struct file *filp); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_0(struct file *filp, struct vm_area_struct *vma); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_1(struct inode *inode, struct file *flip); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_1(struct inode *inode, struct file *filp); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_1(struct file *filp, struct vm_area_struct *vma); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_2(struct inode *inode, struct file *flip); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_2(struct inode *inode, struct file *filp); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_2(struct file *filp, struct vm_area_struct *vma); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static dev_t chrdev; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -78,16 +65,19 @@ static struct class *class = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define DEV_NAME  "usd_reg" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define CLASS_NAME  "usdpci" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define NODE_0_NAME  "usd_reg0" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct file_operations chrdev_fops =  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    .owner = THIS_MODULE, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    .open = usd_open, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    .mmap = usd_mmap, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    .poll = usd_poll | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define TOTAL_BAR_NUM 2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct bar_t{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long bar_addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long bar_size; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  void* bar_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  struct file_operations chrdev_fops; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct bar_t bars[TOTAL_BAR_NUM]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static struct  pci_driver pci_driver = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -114,6 +104,27 @@ static int __init pcie_init(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return res; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //gone have 3 bar for now
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].chrdev_fops.owner = THIS_MODULE; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].chrdev_fops.open = usd_open_0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].chrdev_fops.mmap = usd_mmap_0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].chrdev_fops.release = usd_close_0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].bar_size = 4 * 1024; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].chrdev_fops.owner = THIS_MODULE; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].chrdev_fops.open = usd_open_1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].chrdev_fops.mmap = usd_mmap_1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].chrdev_fops.release = usd_close_1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].bar_size = 128 * 1024 * 1024; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //  bars[2].chrdev_fops = {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //   .owner = THIS_MODULE,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //   .open = usd_open_2,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //   .mmap = usd_mmap_2,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //   .release = usd_close_2
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // bars[2].bar_size = 4 * 1024;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("register driver success" ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						res = chrdev_init(); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -131,44 +142,113 @@ static int chrdev_init(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  PRINT_ALERT("chrdev_init"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int res = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  struct device *device = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  res = alloc_chrdev_region(&chrdev, 0, 1, DEV_NAME); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(res < 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  char name[16]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int i = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for( ;i < TOTAL_BAR_NUM; i++) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    sprintf(name, "%s_%d", DEV_NAME, i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    proc_create(name, 0, NULL, &bars[i].chrdev_fops); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  cdev_init(&cdev, &chrdev_fops); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  res = cdev_add(&cdev, chrdev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (res) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							unregister_chrdev_region(chrdev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return res; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_0(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class = class_create(THIS_MODULE, CLASS_NAME); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						device = device_create(class, NULL, chrdev, NULL, NODE_0_NAME); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_1(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open_2(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_open(struct inode *inode, struct file *flip) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_0(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_1(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_close_2(struct inode *inode, struct file *filp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_0(struct file *filp, struct vm_area_struct *vma) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  PRINT_ALERT("MMAP"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long vsize = vma->vm_end - vma->vm_start; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long physical = bars[0].bar_addr + off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned int intvsize = bars[0].bar_size - off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // these are required for io maps, but is it okay for the buffer as well?
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_flags |= VM_IO; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if ( vsize < intvsize )  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    intvsize = vsize; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  remap_pfn_range(vma, vma->vm_start, physical>>PAGE_SHIFT, intvsize, vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap(struct file *filp, struct vm_area_struct *vma) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_1(struct file *filp, struct vm_area_struct *vma) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  PRINT_ALERT("MMAP"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long vsize = vma->vm_end - vma->vm_start; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long physical = bars[1].bar_addr + off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned int intvsize = bars[1].bar_size - off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // these are required for io maps, but is it okay for the buffer as well?
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_flags |= VM_IO; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if ( vsize < intvsize )  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    intvsize = vsize; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  remap_pfn_range(vma, vma->vm_start, physical>>PAGE_SHIFT, intvsize, vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int usd_poll (struct file *filp, poll_table *wait)  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int usd_mmap_2(struct file *filp, struct vm_area_struct *vma) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  PRINT_ALERT("MMAP"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long vsize = vma->vm_end - vma->vm_start; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned long physical = bars[2].bar_addr + off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned int intvsize = bars[2].bar_size - off; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // these are required for io maps, but is it okay for the buffer as well?
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  vma->vm_flags |= VM_IO; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if ( vsize < intvsize )  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    intvsize = vsize; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  remap_pfn_range(vma, vma->vm_start, physical>>PAGE_SHIFT, intvsize, vma->vm_page_prot); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -184,6 +264,7 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						  goto probe_fail_enable; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  /***************BAR 0***********************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(!(pci_resource_flags(dev, 0) & IORESOURCE_MEM)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      printk(KERN_ERR "USDriver PCIe driver incorrect BAR configuration\n" ); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -191,7 +272,7 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      goto probe_fail; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar0_addr = pci_resource_start(dev, 0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].bar_addr = pci_resource_start(dev, 0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  rc = pci_request_region(dev, 0, "bar0"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(rc) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -199,8 +280,8 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    goto probe_fail; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar0_ptr = pci_iomap(dev, 0, bar0_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u32* bar0_data = (u32*)bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[0].bar_ptr = pci_iomap(dev, 0, bars[0].bar_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u32* bar0_data = (u32*)bars[0].bar_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(bar0_data == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -216,7 +297,7 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      goto probe_fail; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar1_addr = pci_resource_start(dev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].bar_addr = pci_resource_start(dev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  rc = pci_request_region(dev, 1, "bar1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(rc) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -224,8 +305,8 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    goto probe_fail; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar1_ptr = pci_iomap(dev, 1, bar1_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u32* bar1_data = (u32*)bar1_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bars[1].bar_ptr = pci_iomap(dev, 1, bars[1].bar_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u32* bar1_data = (u32*)bars[1].bar_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(bar1_data == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -257,21 +338,11 @@ static void pcie_remove(struct pci_dev *dev) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  PRINT_ALERT("remove driver"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						u8* bar0_data; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						bar0_data = (u8*)bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for ( i = 0; i < dma_pages_count; i++ ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							pci_unmap_single(pcidev, bar0_data[DMA_ADDR_OFFSET + 4*i], PAGE_SIZE, DMA_BIDIRECTIONAL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							__free_page(dma_pages[i]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (dma_pages != NULL) kfree(dma_pages); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("Freed DMA pages"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_clear_master(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("Cleared PCIe master"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_iounmap(dev, bar0_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pci_iounmap(dev, bar1_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_iounmap(dev, bars[0].bar_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pci_iounmap(dev, bars[1].bar_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("IOunmap"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_release_regions(dev); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -288,18 +359,14 @@ static void __exit pcie_exit(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("driver unregistering"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_unregister_driver(&pci_driver); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("unregister_chrdev_region"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unregister_chrdev_region(chrdev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("cdev_del"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						cdev_del(&cdev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("device_destroy"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						device_destroy(class, chrdev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("class_destroy"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class_destroy(class); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  char name[16]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int i = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for( ; i < TOTAL_BAR_NUM; i++) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    snprintf(name, 8, "%s%d", DEV_NAME, i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    remove_proc_entry(name, NULL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("driver unloaded"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |