📄 pmc9054.c
字号:
for(tt=0;tt<20;tt++) printk(KERN_ALERT "PCI REGSTER=0x%x \n",*(a+tt)); break; case DMA_CH1_SEND_CTRL: printk(KERN_ALERT "6.15 DMA start!1 \n"); // map the kernBuffer into dma address //bufFlag = 1;// for (page = virt_to_page(kernBuffer); page < virt_to_page(kernBuffer + BUF_SIZE); page++)// SetPageReserved(page); a=kmalloc(8*1024,__GFP_DMA);//4k mem. //debug DMA// b=kmalloc(64*1024,GFP_KERNEL);//8k mem. for(i=0;i<1024*4;i++) { if(i<1024*2) *((short *) a+i)=0; else *( (short * )a+i)=1024; }// for(i=0;i<1024*32;i++)// *((short*)a+i)=*((short*)b+i);/* for(i=0;i<=50;i++) printk(KERN_ALERT "a =0x%x \n",*( a+i)); for(i=512;i<=512+50;i++) printk(KERN_ALERT "a =0x%x \n",*( a+i));*/ // dmaSendAddr=(unsigned long )a; dmaSendAddr = pci_map_single(pdev, a,1024*4, PCI_DMA_TODEVICE); // dmactl|=APDCEN; // writel(dmactl,PCI_DMACTRL)//dmactl channel 1 enable printk(KERN_ALERT "dmasendaddr =0x%x \n", dmaSendAddr); printk(KERN_ALERT "a =0x%x \n", a); //writel(dmaRecvAddr,(unsigned long)PCI_ATPDMA0_AHBADDR ); // local bus to pci //Set pointer to the right array address before the first transfer //writel((unsigned long)ulFpgaRegister,(unsigned long)PCI_ATPDMA0_AHBADDR); // CH1 PCI address // CH0 local address offset *PCI_ATPDMA0_PCIADDR=(unsigned long )ulFpgaRegister; // Enable CH0 * PCI_ATPDMA0_AHBADDR=dmaSendAddr; *PCI_ATPDMA0_LENADDR =2048; printk(KERN_ALERT "ATPDMA0LEN value after size =0x%x \n", *PCI_ATPDMA0_LENADDR); // bregvalue |= 1 << 27; //writel(bregvalue,(unsigned long)PCI_ATPDMA0_LENADDR); //data swap // *PCI_ATPDMA0_LENADDR|=bregvalue; *PCI_ATPDMA0_LENADDR|= (1<<31);// Start DMA CH1 printk(KERN_ALERT "*PCI_ATPDMA0_LENADDR=0x%x \n",*PCI_ATPDMA0_LENADDR); break; case SET_DMA_SIZE: // writel(0,PCI_ATPDMA0_LENADDR); *PCI_ATPDMA0_LENADDR=0x80000; printk(KERN_ALERT "ATPDMA0LEN=0x%x\n",PCI_ATPDMA0_LENADDR); break; default: return -EINVAL; } return 0;}static int pci9054_mmap(struct file *filp, struct vm_area_struct *vma){ unsigned long page, pos; unsigned long start = (unsigned long)vma->vm_start; unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start); // if userspace tries to mmap beyond end of our buffer, fail if (size > BUF_SIZE) return -EINVAL; // start off at the start of the buffer pos = (unsigned long)kernBuffer; //vma->vm_flags |= VM_LOCKED; page = virt_to_phys((void *)pos); if (remap_page_range( start, page, size, PAGE_SHARED)) return -EAGAIN; return 0;}/* now poll... */static unsigned intpci9054_poll(struct file *filp, poll_table *wait){ unsigned int mask = 0; poll_wait(filp, &pci9054_wqs, wait); poll_wait(filp, &pci9054_wqr, wait); if (sendHappened == 1) { mask |= POLLIN | POLLRDNORM; sendHappened = 0; } if (recvHappened == 1) { mask |= POLLOUT | POLLWRNORM; recvHappened = 0; } return mask;}ssize_tpci9054_read(struct file *filp, char *buf, size_t len, loff_t *pos){ PDEBUG(" \n read...20080515..... "); int i=0; for( i=0;i<len/4;i++) { *((unsigned long *)buf+i)=readl((unsigned long)ulFpgaRegister+i); } // memcpy_fromio((unsigned long *)buf,(unsigned long )fpgaMem,len); // copy_to_user((unsigned long *)buf,(unsigned long *)kernbuf,len); PDEBUG( " over \n "); // wait_event_interruptible(pci9054_wqs, sendHappened == 1); return 0; }ssize_tpci9054_write(struct file *filp,const char *buf, size_t len, loff_t *pos){ PDEBUG( " \n write ...20080515..... "); unsigned long i=0;/* for( i=0;i<len;i++) { writel(*((unsigned long *)buf +i),(unsigned long)ulFpgaRegister+4*i); }*/ memcpy_toio((unsigned long)ulFpgaRegister,(unsigned char *)buf,len); //usable,but slow 8bits everytime printk(KERN_ALERT " over! \n "); return 0; }loff_t pci9054_llseek(struct file *filp,loff_t offset,int flag){ loff_t newpos; newpos=offset; filp->f_pos=newpos; return newpos;}/* device file operations interface */struct file_operations pci9054_fops = { owner: THIS_MODULE, poll: pci9054_poll, read: pci9054_read, write: pci9054_write, llseek: pci9054_llseek, ioctl: pci9054_ioctl, mmap: pci9054_mmap, open: pci9054_open, release: pci9054_release,};/*****************************************\|* Self-defined Functions *|\*****************************************/voidinitDevice(void){ unsigned long a; printk(KERN_ALERT "initdevice function\n"); ulPciRegister = pci_resource_start(pdev, 0); ulPciRegLen = pci_resource_len(pdev, 0); ulFpgaRegister = pci_resource_start(pdev, 2); ulFpgaRegLen = pci_resource_len(pdev, 2); //pci_read_config_byte(pdev, PCI_INTERRUPT_LINE,(void *)&pdev->irq); // pci_read_config_dword(pdev,0x0 ,&a); // printk(KERN_ALERT "pci configuration register = 0x%x\n",a); // a= readl(ulPciRegister); // printk(KERN_ALERT "local configuration register = 0x%x\n",a); if(request_region(ulFpgaRegister,ulFpgaRegLen,"pmc9054") ) printk(KERN_ALERT "FPGA request region sucess !!! \n"); else printk(KERN_ALERT "FPGA request region failed !!! \n"); if(request_region(ulPciRegister,ulPciRegLen,"pmc9054")) printk(KERN_ALERT " Pci request region sucess !!! \n"); else printk(KERN_ALERT " PCI request region failed !!! \n"); fpgaMem = ioremap(ulFpgaRegister,ulFpgaRegLen); pciMem = ioremap(ulPciRegister, ulPciRegLen); /*dma intenable PCIER&DCR*/ *PCI_INTEN|=(1<<3);//ATPDCEN *PCI_INTEN|=(1<<4);//PTACEN *PCI_DMACTRL|=(1<<7);//PTADCIE *PCI_DMACTRL|=(1<<0);//ATPDCIE }voidstartDevice(void){ struct page *page; printk(KERN_ALERT "start device function \n"); // Allocate memory order = get_order(BUF_SIZE); kernBuffer = (void *)__get_free_pages(__GFP_DMA, order); if (kernBuffer == NULL) { printk(KERN_ALERT "Buffer allocation failure\n"); return; } else printk(KERN_ALERT "BUFFER ALLOCATION SUCCESS"); // Lock these pages into memory for (page = virt_to_page(kernBuffer); page < virt_to_page(kernBuffer + BUF_SIZE); page++) SetPageReserved(page); } /*init and cleanup module*/int init_module(void){// unsigned char isr;// int err, status; int status=0; register_chrdev(121, "pmc9054", &pci9054_fops); status = pci_register_driver(&pci9054_driver); pdev = pci_find_device(VENDORID, DEVICEID, NULL); if (pdev == NULL) { PDEBUG("no device found12345! \n"); return -PCIBIOS_DEVICE_NOT_FOUND; } // init the device initDevice(); startDevice(); return 0; // return status;}void cleanup_module(void){ struct page *page;// free_irq(pdev->irq, (void *)pci9054_ids); for (page = virt_to_page(kernBuffer); page < virt_to_page(kernBuffer + BUF_SIZE); page++) ClearPageReserved(page); release_region(ulPciRegister,ulPciRegLen); release_region(ulFpgaRegister,ulFpgaRegLen); pci_unregister_driver(&pci9054_driver); unregister_chrdev(121, "pmc9054"); free_pages((unsigned long)kernBuffer, order); printk(KERN_ALERT "Goodbye, pci9054...\n");}MODULE_LICENSE("GPL");MODULE_AUTHOR("Chongfeng Wu");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -