⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spartan_drv.c

📁 好东西啊,PCI的IP核.大家快下吧.@可以用来参考.FPGA设计的
💻 C
📖 第 1 页 / 共 2 页
字号:
#define __KERNEL__#define MODULE#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/pci.h>#include <asm/uaccess.h>#include <spartan_kint.h> //IOCTL definitions // define vendor and device ID here - currently this definitions specify reference designs from insight electronic#define OC_PCI_VENDOR 0x1597#define OC_PCI_DEVICE 0x0300// if someone wants specific major number assigned to spartan board - specify it here // if 0 is used, kernel assigns it automaticaly#define REQUESTED_MAJOR 0// if compiling module for kernel 2.4 - leave this defined// for kernel 2.2 - comment this out#define KERNEL_VER_24#ifndef SEEK_SET	#define SEEK_SET 0	#define SEEK_CUR 1	#define SEEK_END 2#endif// io.h needed just for kernel 2.2#ifndef KERNEL_VER_24	#include <asm/io.h>#endif// memory mapped or IO mapped region definitions#define SPARTAN_MEM_MAPPED 0#define SPARTAN_IO_MAPPED 1// structure for holding board information// (6 base addresses, mapping, page etc.static struct our_dev{	int major ;	u32 bases[6] ;	u8 num_of_bases ;	u32 base_size[6] ;	u32 offset ;	u32 page_addr ;	u32 base_page_offset ;	int current_resource ;	int base_map[6] ; 	struct pci_dev *ppci_spartan_dev ; } pspartan_dev ;// function prototypesint spartan_open(struct inode *inode, struct file *filp); int spartan_release(struct inode *inode, struct file *filp);ssize_t spartan_read(struct file *filp, char *buf, size_t count, loff_t *offset ) ;ssize_t spartan_write(struct file *filp, const char *buf, size_t count, loff_t *offset) ;int	spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) ;loff_t  spartan_seek(struct file *filp, loff_t offset, int what) ;// file operations structure - different for kernels 2.2 and 2.4static struct file_operations *pspartan_fops ;static struct file_operations spartan_fops = {	#ifdef KERNEL_VER_24	NULL,	#endif        spartan_seek,        spartan_read,        spartan_write,        NULL,        NULL,        spartan_ioctl,        NULL,        spartan_open,        NULL,        spartan_release,} ;                     int open_mem_mapped(void) ;// seek file operation functionloff_t  spartan_seek(struct file *filp, loff_t offset, int origin){	loff_t requested_offset ;	int resource_num = pspartan_dev.current_resource ;	switch (origin)	{		case SEEK_CUR:requested_offset = pspartan_dev.offset + offset ; break ;		case SEEK_END:requested_offset = pspartan_dev.base_size[resource_num] + offset ; break ;		default:requested_offset  = offset ; break ;	}		if ((requested_offset < 0) || (requested_offset > pspartan_dev.base_size[resource_num]))		return -EFAULT ;	pspartan_dev.offset = requested_offset ;	return requested_offset ; 				 }// ioctl for device// currently just a few operations are supported here - defined in spartan_kint.h headerint     spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) {	int error = 0;	int size = _IOC_SIZE(cmd) ;	unsigned long base ;	unsigned long base_size ;	if (_IOC_TYPE(cmd) != SPARTAN_IOC_NUM) return -EINVAL ;	if (_IOC_NR(cmd) > SPARTAN_IOC_MAX_NUM) return -EINVAL ;	// Writes through pointers not allowed - writes only through argument 	if (_IOC_DIR(cmd) & _IOC_WRITE) return -EINVAL ;	else if (_IOC_DIR(cmd) & _IOC_READ)		error = verify_area(VERIFY_WRITE, (void *) arg, size) ;		if (error)		return error ;	switch (cmd){		case SPARTAN_IOC_CURRESGET:return (pspartan_dev.current_resource + 1) ;  // current resource - they start at 1		case SPARTAN_IOC_CURRESSET:// check if resource is in a range of implemented resources						if (arg < 0 )							return -EINVAL ;						// unmap previous resource if it was mapped                                                if (pspartan_dev.current_resource >= 0)                                                {                                                        iounmap((void *)pspartan_dev.page_addr) ;                                                }        						if (arg == 0)						{							// previous resource unmaped - that's all							pspartan_dev.current_resource = -1 ;							return 0 ;							}						if (pspartan_dev.num_of_bases < arg)							return -ENODEV ;						// IO mapped not supported yet						if (pspartan_dev.base_map[arg] == SPARTAN_IO_MAPPED)						{							// set current resource to none, since it was unmapped							pspartan_dev.current_resource = -1 ;							return -ENODEV ;						}						pspartan_dev.current_resource= (int)(arg-1) ;						// remap new resource						if ( (error = open_mem_mapped()) )						{							pspartan_dev.current_resource = -1 ;							return error ;						}						return 0 ;		case SPARTAN_IOC_CURBASE:						// check if any resource is currently activated						if (pspartan_dev.current_resource>=0)							base = pspartan_dev.bases[pspartan_dev.current_resource] ;						else							base = 0x00000000 ;												*(unsigned long *)arg = base ;						return 0 ;		case SPARTAN_IOC_CURBASEMAP:						// check if any resource is currently activated                                                if (pspartan_dev.current_resource>=0)                                                        base = pspartan_dev.page_addr ;                                                else                                                        base = 0x00000000 ;							*(unsigned long *)arg = base ;                                                return 0 ;        		case SPARTAN_IOC_CURBASESIZE:							// check if any resource is currently activated                                                if (pspartan_dev.current_resource>=0)                                                        base_size = pspartan_dev.base_size[pspartan_dev.current_resource] ;                                                else                                                        base_size = 0x00000000 ;												*(unsigned long *)arg = base_size ;                                                return 0 ;                                        		case SPARTAN_IOC_NUMOFRES:							return (pspartan_dev.num_of_bases) ;		default:			return -EINVAL ;	}}// helper function for memory remapingint open_mem_mapped(void){	int resource_num = pspartan_dev.current_resource ;	unsigned long num_of_pages = 0 ;	unsigned long base = pspartan_dev.bases[resource_num] ;	unsigned long size = pspartan_dev.base_size[resource_num] ;	if (!(num_of_pages = (unsigned long)(size/PAGE_SIZE))) ;		num_of_pages++ ;	pspartan_dev.base_page_offset = base & ~PAGE_MASK ;	if ((pspartan_dev.base_page_offset + size) < (num_of_pages*PAGE_SIZE)) 		num_of_pages++ ;		// remap memory mapped space	pspartan_dev.page_addr = (unsigned long)ioremap(base & PAGE_MASK, num_of_pages * PAGE_SIZE) ;		if (pspartan_dev.page_addr == 0x00000000)		return -ENOMEM ;		return 0 ;}// add io mapped resource handler hereint open_io_mapped( void ) {	return 0 ;}// open file operation functionint spartan_open(struct inode *inode, struct file *filp){	if (MOD_IN_USE)		return -EBUSY ;	pspartan_fops = &spartan_fops ;        filp->f_op = pspartan_fops ;	pspartan_dev.offset = 0 ;	pspartan_dev.current_resource = -1 ;	        MOD_INC_USE_COUNT ;        return 0 ;} // release - called by close on file descriptorint spartan_release(struct inode *inode, struct file *filp){	// unmap any remaped pages	if (pspartan_dev.current_resource >= 0)		iounmap((void *)pspartan_dev.page_addr) ;	pspartan_dev.current_resource = -1 ;        MOD_DEC_USE_COUNT ;	return 0 ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -