opl_reg_mmap.c
浏览该文件的文档。00001 00015 #include <linux/init.h> 00016 #include <linux/kernel.h> 00017 #include <linux/module.h> 00018 #include <linux/sched.h> 00019 #include <linux/wait.h> 00020 #include <asm/uaccess.h> 00021 #include <asm/io.h> 00022 #include <linux/slab.h> 00023 00024 #include <opl_hw_ops.h> 00025 #include <opl_reg_mmap.h> 00026 00030 /*--------------------------Macro definition------------------------- */ 00031 #define OPL_REG_MAJOR 110 00032 #define OPL_REG_DEVICE "opl_reg" 00033 00034 00040 /*--------------------------type definition------------------------- */ 00041 00047 /*-----------------global varible/function declaration--------------- */ 00048 00060 /*--------------local function declaration------------- */ 00061 static int opl_reg_open(struct inode *inode, struct file *filp); 00062 static ssize_t opl_reg_read(struct file *filp, char *buffer, size_t length, loff_t *offset); 00063 static ssize_t opl_reg_write(struct file *filp, const char *buffer, size_t length, loff_t *offset); 00064 static int opl_reg_mmap(struct file * file, struct vm_area_struct * vma); 00065 static int opl_reg_release(struct inode *inode, struct file *filp); 00066 00072 /*--------------local varible declaration and definition------------- */ 00073 static u32 opl_reg_open_count = 0; 00074 static u32 opl_reg_is_open = 0; 00075 struct file_operations opl_reg_fops = { 00076 .read = opl_reg_read, 00077 .write = opl_reg_write, 00078 .mmap = opl_reg_mmap, 00079 .open = opl_reg_open, 00080 .release = opl_reg_release, 00081 }; 00082 00088 /*------------local function declaration and definition-------------- */ 00089 00102 static ssize_t opl_reg_read(struct file *filp, char *buffer, size_t length, loff_t *offset) 00103 { 00104 return 0; 00105 } 00106 00107 static ssize_t opl_reg_write(struct file *filp, const char *buffer, size_t length, loff_t *offset) 00108 { 00109 return 0; 00110 } 00111 00124 static int opl_reg_mmap(struct file * file, struct vm_area_struct * vma) 00125 { 00126 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 00127 /* 00128 * Accessing memory above the top the kernel knows about or 00129 * through a file pointer that was marked O_SYNC will be 00130 * done non-cached. 00131 */ 00132 offset += 0x1f000000; 00133 if ((offset>__pa(high_memory)) || (file->f_flags & O_SYNC)) { 00134 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 00135 } 00136 00137 /* Don't try to swap out physical pages.. */ 00138 vma->vm_flags |= VM_RESERVED; 00139 00140 /* Don't dump addresses that are not real memory to a core file.*/ 00141 if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) 00142 vma->vm_flags |= VM_IO; 00143 if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, 00144 vma->vm_page_prot)){ 00145 return -EAGAIN; 00146 } 00147 return 0; 00148 } 00149 00150 static int opl_reg_open(struct inode *inode, struct file *filp) 00151 { 00152 if (test_and_set_bit(0, &opl_reg_is_open)) 00153 printk(KERN_DEBUG "the /dev/opl_reg is already opened\n"); 00154 opl_reg_open_count ++; 00155 MOD_INC_USE_COUNT; 00156 return 0; 00157 } 00158 00159 static int opl_reg_release(struct inode *inode, struct file *filp) 00160 { 00161 opl_reg_open_count ++; 00162 if(!opl_reg_open_count) 00163 clear_bit(0, &opl_reg_is_open); 00164 MOD_DEC_USE_COUNT; 00165 return 0; 00166 } 00176 static int __init opl_reg_init(void) 00177 { 00178 int ret; 00179 ret = register_chrdev(OPL_REG_MAJOR,OPL_REG_DEVICE,&opl_reg_fops); 00180 if(ret<0){ 00181 /* TBD add debug message */ 00182 } 00183 return ret; 00184 } 00193 static void __exit opl_reg_exit(void) 00194 { 00195 int ret; 00196 ret = unregister_chrdev(OPL_REG_MAJOR,OPL_REG_DEVICE); 00197 if(ret < 0){ 00198 /*TBD:add debug message */ 00199 } 00200 return; 00201 } 00202 00203 module_init(opl_reg_init); 00204 module_exit(opl_reg_exit); 00205 MODULE_LICENSE("GPL2"); 00206 MODULE_AUTHOR("stephanxu <[email protected]>"); 00207 MODULE_DESCRIPTION("dedicated the module for mmap the opulan switch chip register.");
Generated at Mon Jul 30 16:43:48 2007 for IPMUX1IPMUX2IPMUX3 by 1.3.9.1