53 static int eccdev_open(struct inode *, struct file *); |
53 static int eccdev_open(struct inode *, struct file *); |
54 static int eccdev_release(struct inode *, struct file *); |
54 static int eccdev_release(struct inode *, struct file *); |
55 static long eccdev_ioctl(struct file *, unsigned int, unsigned long); |
55 static long eccdev_ioctl(struct file *, unsigned int, unsigned long); |
56 static int eccdev_mmap(struct file *, struct vm_area_struct *); |
56 static int eccdev_mmap(struct file *, struct vm_area_struct *); |
57 |
57 |
|
58 /** This is the kernel version from which the .fault member of the |
|
59 * vm_operations_struct is usable. |
|
60 */ |
|
61 #define PAGE_FAULT_VERSION KERNEL_VERSION(2, 6, 23) |
|
62 |
|
63 #if LINUX_VERSION_CODE >= PAGE_FAULT_VERSION |
|
64 static int eccdev_vma_fault(struct vm_area_struct *, struct vm_fault *); |
|
65 #else |
58 static struct page *eccdev_vma_nopage( |
66 static struct page *eccdev_vma_nopage( |
59 struct vm_area_struct *, unsigned long, int *); |
67 struct vm_area_struct *, unsigned long, int *); |
|
68 #endif |
60 |
69 |
61 /*****************************************************************************/ |
70 /*****************************************************************************/ |
62 |
71 |
63 /** File operation callbacks for the EtherCAT character device. |
72 /** File operation callbacks for the EtherCAT character device. |
64 */ |
73 */ |
71 }; |
80 }; |
72 |
81 |
73 /** Callbacks for a virtual memory area retrieved with ecdevc_mmap(). |
82 /** Callbacks for a virtual memory area retrieved with ecdevc_mmap(). |
74 */ |
83 */ |
75 struct vm_operations_struct eccdev_vm_ops = { |
84 struct vm_operations_struct eccdev_vm_ops = { |
|
85 #if LINUX_VERSION_CODE >= PAGE_FAULT_VERSION |
|
86 .fault = eccdev_vma_fault |
|
87 #else |
76 .nopage = eccdev_vma_nopage |
88 .nopage = eccdev_vma_nopage |
|
89 #endif |
77 }; |
90 }; |
78 |
91 |
79 /*****************************************************************************/ |
92 /*****************************************************************************/ |
80 |
93 |
81 /** Private data structure for file handles. |
94 /** Private data structure for file handles. |
2585 return 0; |
2598 return 0; |
2586 } |
2599 } |
2587 |
2600 |
2588 /*****************************************************************************/ |
2601 /*****************************************************************************/ |
2589 |
2602 |
|
2603 #if LINUX_VERSION_CODE >= PAGE_FAULT_VERSION |
|
2604 |
2590 /** Page fault callback for a virtual memory area. |
2605 /** Page fault callback for a virtual memory area. |
|
2606 * |
|
2607 * Called at the first access on a virtual-memory area retrieved with |
|
2608 * ecdev_mmap(). |
|
2609 */ |
|
2610 static int eccdev_vma_fault( |
|
2611 struct vm_area_struct *vma, /**< Virtual memory area. */ |
|
2612 struct vm_fault *vmf /**< Fault data. */ |
|
2613 ) |
|
2614 { |
|
2615 struct page *page; |
|
2616 ec_cdev_priv_t *priv = (ec_cdev_priv_t *) vma->vm_private_data; |
|
2617 |
|
2618 if (vmf->pgoff >= priv->process_data_size) |
|
2619 return VM_FAULT_SIGBUS; |
|
2620 |
|
2621 page = vmalloc_to_page(priv->process_data + vmf->pgoff); |
|
2622 |
|
2623 if (priv->cdev->master->debug_level) |
|
2624 EC_DBG("Vma fault, address = %p, offset = %lu, page = %p\n", |
|
2625 vmf->virtual_address, vmf->pgoff, page); |
|
2626 |
|
2627 get_page(page); |
|
2628 vmf->page = page; |
|
2629 vmf->flags = 0; |
|
2630 return 0; |
|
2631 } |
|
2632 |
|
2633 #else |
|
2634 |
|
2635 /** Nopage callback for a virtual memory area. |
2591 * |
2636 * |
2592 * Called at the first access on a virtual-memory area retrieved with |
2637 * Called at the first access on a virtual-memory area retrieved with |
2593 * ecdev_mmap(). |
2638 * ecdev_mmap(). |
2594 */ |
2639 */ |
2595 struct page *eccdev_vma_nopage( |
2640 struct page *eccdev_vma_nopage( |