| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -44,8 +44,13 @@ static unsigned int ioctl_alloc_dma = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int ioctl_refresh_link = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar0_addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long bar0_size = 4*1024; //TODO ask about size. 4KB
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -72,6 +77,8 @@ static struct cdev cdev; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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 =  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -143,8 +150,8 @@ static int chrdev_init(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return res; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class = class_create(THIS_MODULE, "usdpci"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						device = device_create(class, NULL, 0, NULL, "usd_regs0"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class = class_create(THIS_MODULE, CLASS_NAME); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						device = device_create(class, NULL, 0, NULL, NODE_0_NAME); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -170,7 +177,7 @@ static unsigned int usd_poll (struct file *filp, poll_table *wait) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *id) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar0_ptr = pci_iomap(dev, 0, 64 * 1024);//4KB
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar0_ptr = pci_iomap(dev, 0, bar0_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u8* bar0_data = (u8*)bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int rc = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -181,18 +188,18 @@ static int __init pcie_probe (struct pci_dev *dev, const struct pci_device_id *i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    goto probe_fail_release_region; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pci_set_master(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bar1_ptr = pci_iomap(dev, 1, bar1_size); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  u8* bar1_data = (u8*)bar1_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if(bar1_data == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PRINT_ALERT("driver failed to map BAR 1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    rc = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    goto probe_fail_release_region; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // int i = 0;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // for( i = 0; i < 1; i++)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // int r32 = ioread32(&bar0_data[i*4]);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // printk(KERN_ALERT "Read: %x (%d)\n", r32, i);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pci_set_master(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  iowrite32(0x45670000, &bar0_data[0x8018]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int r32 = ioread32(&bar0_data[0x8018]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  printk(KERN_ALERT "Read: %x\n", r32); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  probe_fail_release_region: | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -216,102 +223,48 @@ static void pcie_remove(struct pci_dev *dev) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							__free_page(dma_pages[i]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (dma_pages != NULL) kfree(dma_pages); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "Freed DMA pages\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("Freed DMA pages"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_clear_master(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "Cleared PCIe master\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("Cleared PCIe master"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_iounmap(dev, bar0_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "IOunmap\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pci_iounmap(dev, bar1_ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("IOunmap"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_release_regions(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "pci_release_regions\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("pci_release_regions"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_disable_device(dev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "pci_disable_device\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("pci_disable_device"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void __exit pcie_exit(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						u8* bar0_data; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						bar0_data = (u8*)bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe driver unloading\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("driver unloading"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe driver unregistering\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("driver unregistering"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						pci_unregister_driver(&pci_driver); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe unregister_chrdev_region\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("unregister_chrdev_region"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unregister_chrdev_region(chrdev, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe cdev_del\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("cdev_del"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						cdev_del(&cdev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe device_destroy\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("device_destroy"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						device_destroy(class, chrdev); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe class_destroy\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("class_destroy"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class_destroy(class); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						printk(KERN_ALERT "USDriver PCIe driver unloaded\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						PRINT_ALERT("driver unloaded"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					module_init(pcie_init); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					module_exit(pcie_exit); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int create_dma_buffer(unsigned int bufcount) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int bufidx = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unsigned int gfp_mask = GFP_KERNEL | __GFP_DMA; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    dma_addr_t bus_addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    u8* bar0_data; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bar0_data = (u8*)bar0_ptr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printk(KERN_ALERT "USDriver DMA buffer alloc request: %d pages\n", bufcount); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if( dma_pages != NULL) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        printk(KERN_ALERT "USDriver DMA buffer already exist! Strange!\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    dma_pages = kmalloc(4*1024*1024 * bufcount, GFP_KERNEL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if(dma_pages == NULL) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        printk(KERN_ERR "USDriver DMA dma_pages alloc failed! \n" ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for(bufidx = 0; bufidx <  bufcount; bufidx++) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        void __iomem *maddr = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        struct page *pages = alloc_pages(gfp_mask, 10); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if(pages == NULL) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            printk(KERN_ERR "USDriver DMA buffer alloc failed! \n" ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        maddr = page_address(pages); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        dma_pages[bufidx] = pages; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        bus_addr = pci_map_single(pcidev, maddr,  1024 * PAGE_SIZE, DMA_BIDIRECTIONAL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							printk(KERN_ALERT ">>>>>[%d]    0x%x\n", bufidx, bus_addr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        iowrite32(bus_addr, &bar0_data[DMA_ADDR_OFFSET + (4 * bufidx)]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        wmb(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if(pci_dma_mapping_error(pcidev, bus_addr)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    dma_pages_count = bufcount; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printk(KERN_ALERT "USDriver DMA buffer alloc successful\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*************************************************************************************************/ | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |