#include #include #include #include #include #include #include #define VENDOR_ID 0x14E4 #define DEVICE_ID 0x1600 #define SIZE 10000 struct file_operations fops ; static int major ; struct pci_dev *pci_dev = NULL ; dma_addr_t bus_addr ; static int my_open(struct inode *inode, struct file *file) { void *virt_addr = (void *)NULL ; struct page *page, *end_page ; printk("I am in my_open\n") ; virt_addr = pci_alloc_consistent(pci_dev, SIZE, &bus_addr) ; if (virt_addr == NULL) { printk("pci_alloc_consistent failed\n") ; return -ENOMEM ; } else { printk("pci_alloc_consistent successful, virt_addr = %ld\n", (unsigned long)virt_addr) ; } end_page = virt_to_page(virt_addr + SIZE - 1) ; for (page = virt_to_page(virt_addr) ; page <= end_page ; page++) { set_bit(PG_reserved, &page->flags) ; } file->private_data = virt_addr ; return 0 ; } static int my_close(struct inode *inode, struct file *file) { int *ptr, i ; struct page *page, *end_page ; void *virt_addr = file->private_data ; printk("I am in my_close\n") ; printk("virt_addr = %ld\n", (unsigned long)virt_addr) ; ptr = (int *)virt_addr ; printk("my_close : data read from kernel : \n") ; for(i = 0 ; i < 2048 ; i++) { printk("%d ", *(ptr + i)) ; } end_page = virt_to_page(virt_addr + SIZE - 1) ; for (page = virt_to_page(virt_addr) ; page <= end_page ; page++) { clear_bit(PG_reserved, &page->flags) ; } pci_free_consistent(pci_dev,SIZE,virt_addr,bus_addr) ; return 0 ; } static int my_mmap(struct file *file, struct vm_area_struct *vma) { void *data_ptr = (void *)file->private_data ; printk("I am in my_mmap\n") ; printk("data_ptr = %ld\n", (unsigned long) data_ptr) ; if (remap_page_range(vma, vma->vm_start, virt_to_phys(data_ptr), (vma->vm_end - vma->vm_start), vma->vm_page_prot)) { printk("remap_page_range failed\n") ; return -1 ; } return 0 ; } int init_module(void) { printk("I am in init_module\n") ; pci_dev = pci_get_device(VENDOR_ID, DEVICE_ID, pci_dev) ; if (pci_dev == (struct pci_dev *)NULL) { printk("pci_get_device failed\n") ; return -1 ; } printk("pci_dev found, pci_dev = %ld\n", (unsigned long)pci_dev) ; major = register_chrdev(0, "mydriver", &fops) ; if(major == -1) { printk("register_chrdev failed\n") ; return -1 ; } printk("module is registered with major no = %d\n", major) ; return 0 ; } void cleanup_module(void) { printk("I am in cleanup_module\n") ; unregister_chrdev(major, "mydriver") ; } struct file_operations fops = { .open = my_open, .release = my_close, .mmap = my_mmap, } ;