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

📄 driver.c

📁 信息安全类
💻 C
字号:
#include <linux/unistd.h>#include <linux/module.h>#if defined(CONFIG_SMP)#define __SMP__#endif#include <linux/wait.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/types.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/fcntl.h>#define PCINAME "09449device"#define IOSIZE  0xff#define MEMSIZE 0x3fff#define PCI_MAJOR  0#define VENDOR 0x10b5#define DEVICE 0x9054int PCI_major = PCI_MAJOR;//DECLARE_WAIT_QUEUE_HEAD(wq);//int wake = 0;//struct DMA_data{//	dma_addr_t PciAddr;//	int Count;//	void *Handle;//};struct PCI_device {	const char *Name;	unsigned long MemVirAddr;	unsigned long MemPhyAddr;	unsigned int MemSize;	unsigned long IoAddr;	unsigned int IoSize;    unsigned int IrqNum;	unsigned int PciMajor;	struct pci_dev *MyDev;//    struct DMA_data DmaData;} *Device;//void PCI_interrupt(int ,void *,struct pt_regs *);//Regwrite(unsigned long flag,unsigned long addr)//{//	unsigned long init;//	init = readl(addr);//	init = init | flag;//	writel(init,addr);//}static int PCI_init(void){	int res;	struct pci_dev *mydev;	u32 mem_addr,io_addr,flag;	u32 mem, io;	u8 irq, pin;	Device = kmalloc(sizeof(struct PCI_device),GFP_KERNEL);	if(Device == NULL) 	{		printk(" KERN_ALERT allocate device memory failed.\n"); 		return(-ENOMEM);	}	memset(Device,0,sizeof(struct PCI_device));		mydev = pci_find_device(VENDOR,DEVICE,NULL);	if(mydev == NULL)	{		printk("<1> Find the device failed.\n");		return(-ENODEV);	}//	pci_read_config_dword(mydev,PCI_BASE_ADDRESS_0,&mem);//	pci_read_config_dword(mydev,PCI_BASE_ADDRESS_1,&io_addr);//	pci_read_config_byte(mydev,PCI_INTERRUPT_LINE,&irq);//	pci_read_config_byte(mydev,PCI_INTERRUPT_PIN,&pin);	pci_read_config_dword(mydev,PCI_BASE_ADDRESS_2,&mem_addr);	pci_read_config_dword(mydev,PCI_BASE_ADDRESS_1,&io_addr);    flag = mem_addr;	if(flag&0x0001) mem_addr &= (~0x00000003);//This port is I/O	  else mem_addr &= (~0x0000000f);    flag = io_addr;	if(flag&0x0001) io_addr &= (~0x00000003);//This port is I/O	  else io_addr &= (~0x0000000f);	printk("<1> The device has been finded.\nMenAddr=0x%x IoAddr=0x%x Irq=0x%d Pin=0x%x mem=0x%x io=0x%x\n",mem_addr,io_addr,irq,pin,mem,io);	//	mem &= (~0x0000000f);	mem = ioremap(0xec014000,0xff);//	writel(0xffffffff, mem);	printk("The range is %x\n",readl(mem));		Device->Name = PCINAME;	Device->MemPhyAddr =mem_addr;	Device->IoAddr =io_addr;		Device->MemSize = MEMSIZE;	Device->IoSize = IOSIZE;	Device->IrqNum = irq;	Device->PciMajor = PCI_major;	Device->MyDev = mydev;	        	if(check_mem_region(Device->MemPhyAddr,Device->MemSize))	{		printk("<1> Requested MEM already in use.\n");		return -EBUSY;	}	request_mem_region(Device->MemPhyAddr,Device->MemSize,Device->Name);	printk("<1> Request MEM success.\n");		if(request_region(Device->IoAddr,Device->IoSize,Device->Name) != NULL)		printk("<1> Request I/O port success.\n");	else	{		printk("<1> Request I/O port failed.\n");		return(-1);	}	//	res = request_irq(Device->IrqNum,PCI_interrupt,SA_SHIRQ|SA_INTERRUPT,Device->Name,Device);//	if(res < 0)//	{//		printk("<1> Request IRP feiled.\n");//		return res;//	}//	printk("<1> Request IRO success.\n");		Device->MemVirAddr = (long)ioremap(Device->MemPhyAddr,Device->MemSize);	printk("<1> The vir addr is %x\n",Device->MemVirAddr);	//	writel(0xffff0000,Device->MemVirAddr);//	printk("The range is 0x%x\n",readl(Device->MemVirAddr));//	printk("The range is 0x%x\n",readl(Device->MemVirAddr+4));//	printk("The range is 0x%x\n",readl(Device->MemVirAddr+8));//	printk("The range is 0x%x\n",readl(Device->MemVirAddr+12));//	printk("The range is 0x%x\n",readl(Device->MemVirAddr+0x2000));	int i;	for(i=0;i<64;i++)	{		printk("%d: 0x%x ",i,readl(Device->MemVirAddr+i*4));	}	return 0;}/**********************Function interrupt****************************///void PCI_interrupt(int irq,void *dev_id,struct pt_regs *regs)//{//        struct PCI_device *dev = dev_id;//	u32 rw,flag;//	if(dev->Name == PCINAME) //	{////	   printk("<1> The IRQ roution start execute\n");//	   flag = readl(dev->MemVirAddr + 0x04e4);////	   printk("<1> The INT flag is %x\n",flag);//	   if(flag & 0x00000020)//	   {//		   flag |=0x00000020;//		   Regwrite(flag,dev->MemVirAddr + 0x04e4);//                   rw = readl(dev->MemVirAddr + 0x04bc);//                   if(rw &= 1)//		   {//			   wake_up_interruptible(&wq);//			   wake = 1;//			   printk("<1> The DMA read has been completed.\n");//	                   pci_unmap_single(dev->MyDev,dev->DmaData.PciAddr,//				   dev->DmaData.Count,PCI_DMA_TODEVICE);//		   }//                   else//		   {//			  printk("<1> The DMA write has completed.\n");//	                  pci_unmap_single(dev->MyDev,dev->DmaData.PciAddr,//				   dev->DmaData.Count,PCI_DMA_TODEVICE);//		          kfree(dev->DmaData.Handle);//		   }//	   //	   }////	   else printk("<1> The DMA complete flag is not set.\n");//	}//}/*****************************PCI open**********************************/int PCI_open(struct inode *inode,struct file *filp){       filp->private_data =  Device;        MOD_INC_USE_COUNT;        return 0;}                             /*****************************Functin PCI_release**************************/int PCI_release(struct inode *inode,struct file *filp){//        struct PCI_device *dev = filp->private_data;	MOD_DEC_USE_COUNT;        return 0;}/*************************PCI read***************************************/ssize_t PCI_read(struct file *filp,char *buf,size_t count,loff_t *offp){//	unsigned long Locaddr = 0x4000;//	unsigned long Start = 0x00000001;//	unsigned long Int = 0x00200000;//	struct PCI_device *dev =filp->private_data;//	dma_addr_t Busaddr;//	u32 *buffer;//	//	buffer = kmalloc(sizeof(u32) * (count/4),GFP_KERNEL);//	if(buffer == NULL)//	{//		printk("<1> Allocate Mem in Read function failed.\n");//		return(-ENOMEM);//	}//	memset(buffer,0,sizeof(u32)*(count/4));//	Busaddr = pci_map_single(dev->MyDev,buffer,//			count,PCI_DMA_TODEVICE);//        Regwrite(Int,dev->MemVirAddr + 0x04e4);//INT//	writel(Busaddr,dev->MemVirAddr + 0x04b4);//HOST//	writel(Locaddr,dev->MemVirAddr + 0x04b0);//LOCAL//	writel(count,dev->MemVirAddr + 0x04b8);//SIZE//	writel(Start,dev->MemVirAddr + 0x04bc);//START//	//	dev->DmaData.PciAddr = Busaddr;//	dev->DmaData.Count = count;//	dev->DmaData.Handle = buffer;//	//	wait_event_interruptible(wq,wake);//	printk("<1> The read routine has waked up\n");//	copy_to_user(buf,buffer,count);//	kfree(dev->DmaData.Handle);//	wake = 0;	struct PCI_device *dev =filp->private_data;	u8 *buffer;	u8 *pt;	unsigned long baseaddr;	int i;	buffer = kmalloc(count,GFP_KERNEL);	if(buffer == NULL)	{		printk("<1> Allocate Mem in Read function failed.\n");		return(-ENOMEM);	}	memset(buffer,0,count);	baseaddr = dev->MemVirAddr;	pt = buffer;	for(i=0; i<count; i++, pt++)	{		*pt = (u8)(readl(baseaddr+(i/4)) & 0xff);//		*pt = readb(baseaddr+i);		printk("%d: 0x%x  ", i, *pt); 	}	printk("\n");	copy_to_user(buf,buffer,count);	return count;}/***************************PCI write************************************/ssize_t PCI_write(struct file *filp,char *buf,size_t count,loff_t *offp){//	unsigned long Locaddr = 0x4000;//	unsigned long Start = 0x00000000;//	unsigned long Int = 0x00200000;//	struct PCI_device *dev =filp->private_data;//	dma_addr_t Busaddr;//	u32 *buffer;//	//	buffer = kmalloc(sizeof(u32) * (count/4),GFP_KERNEL);//	if(buffer == NULL)//	{//		printk("<1> Allocate Mem in Write function failed.\n");//		return(-ENOMEM);//	}//	memset(buffer,0,sizeof(u32)*(count/4));//	copy_from_user(buffer,buf,count);//	Busaddr = pci_map_single(dev->MyDev,buffer,//			count,PCI_DMA_TODEVICE);//        Regwrite(Int,dev->MemVirAddr + 0x04e4);//INT//	writel(Busaddr,dev->MemVirAddr + 0x04b4);//HOST//	writel(Locaddr,dev->MemVirAddr + 0x04b0);//LOCAL//	writel(count,dev->MemVirAddr + 0x04b8);//SIZE//	writel(Start,dev->MemVirAddr + 0x04bc);//START//	//	dev->DmaData.PciAddr = Busaddr;//	dev->DmaData.Count = count;//	dev->DmaData.Handle = buffer;	struct PCI_device *dev =filp->private_data;	u8 *buffer;	u32 *pt;	unsigned long baseaddr;	int i;	buffer = kmalloc(count,GFP_KERNEL);	if(buffer == NULL)	{		printk("<1> Allocate Mem in Read function failed.\n");		return(-ENOMEM);	}	memset(buffer,0,count);	copy_from_user(buffer,buf,count);	baseaddr = dev->MemVirAddr;	pt = (u32*)buffer;	for(i=0; i<count; i+=4, pt++)	{		printk("%d: 0x%x  ", i, *pt);		writel(*pt, baseaddr+i);	}	printk("\n");	return count;}//////////////////////////////IOCTL FUNCTION////////////////////////////////////int  PCI_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){//	unsigned long Int;//	struct PCI_device *dev = filp->private_data;//	unsigned long fifo;//	switch(cmd){//              case 1: {//                              Int = readl(dev->MemVirAddr + 0x04e4);//			      printk("<1> The INT value is :%x\n",Int);//			      break;//		      }//              case 2: {//                              writel(0x00000001,dev->MemVirAddr + 0x04e0);//                              writel(0x00000000,dev->MemVirAddr + 0x04e0);//			      printk("<1> The system has been reseted.\n");//			      break;//		      }//	      default: printk("<1> The argument wrong!\n");//	}	      }/**************************File operations define************************/struct file_operations PCI_fops = {//    NULL,//    NULL,    read :  PCI_read,    //readwrite:  PCI_write,    //write//    NULL,     //    NULL,    //EMM_poll,ioctl:  PCI_ioctl,    //ioctl//    NULL,     open  :    PCI_open,    //open  //  NULL,release:   PCI_release,    //release/*    NULL,    NULL,	    NULL,    NULL,    NULL,    NULL,    NULL,*/};/****************************Module initialize******************************/int init_module(void){	int res;	EXPORT_NO_SYMBOLS;	res = register_chrdev(PCI_major,PCINAME,&PCI_fops);	if(res < 0) {		printk("<1> PCI device register failed.\n");		return res;	}	if(PCI_major == 0) 		PCI_major = res;	if(PCI_init() < 0) 		printk("<1> PCI device initializition failed.\n");	else printk("<1> MYPCI initializition success.\n");  	return 0;}/****************************Module release********************************/void cleanup_module(void){	unregister_chrdev(PCI_major,PCINAME);	release_mem_region(Device->MemPhyAddr,Device->MemSize);	release_region(Device->IoAddr,Device->IoSize);// 	free_irq(Device->IrqNum,Device);  	iounmap((void*)Device->MemVirAddr);	printk("<1> MYPCI release success.\n");}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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