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

📄 driver.c

📁 Windows设备驱动程序设计 (*.ppt) intoduce about how to develop the windows driver
💻 C
字号:
#include <linux/unistd.h>#include <linux/module.h>#if defined(CONFIG_SMP)#define __SMP__#endif#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 "testpcidevice"#define IOSIZE  64#define PCI_MAJOR  0#define VENDOR 0x10e8#define DEVICE 0x4750int PCI_major = PCI_MAJOR;int succ = 1;struct DMA_data {	dma_addr_t PciAddr;	unsigned int Count;	void *Handle;        };struct PCI_device {	const char *Name;	unsigned long BaseAddr;	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 *);static int PCI_init(void){	int res;	struct pci_dev *mydev;	u32 pci_addr,flag,memaddr;	u8 irq;        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");		kfree(Device);		return(-ENODEV);	}	pci_read_config_dword(mydev,PCI_BASE_ADDRESS_0,&pci_addr);	pci_read_config_byte(mydev,PCI_INTERRUPT_LINE,&irq);        flag = pci_addr;	if(flag&0x0001) pci_addr &= (~0x0003);//This port is I/O	  else pci_addr &= (~0x000f);	printk("<1> The device has been finded.Addr=%x  Irq=%d\n",pci_addr,irq);		Device->Name = PCINAME;	Device->BaseAddr =pci_addr;	Device->IoSize = IOSIZE;	Device->IrqNum = irq;        Device->PciMajor = PCI_major;        Device->MyDev = mydev;	               /* res = check_region(Device->BaseAddr,Device->IoSize);	if(res < 0){                printk("<1> Check I/O port failed.\n");   	 return res;	}*/        if(request_region(Device->BaseAddr,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");	return 0;}MCSRwrite(unsigned long flag,unsigned long addr){	unsigned long init;	init = inl(addr);	init = init | flag;	outl(init,addr);}/**********************Function interrupt****************************/void PCI_interrupt(int irq,void *dev_id,struct pt_regs *regs){	struct PCI_device *dev = dev_id;	u32 flag,MCSR;	if(dev->Name == PCINAME) 	{	   printk("<1> The IRQ roution start execute\n");	   flag = inl(dev->BaseAddr + 0x38);	   	   printk("<1> The INT flag is %x\n",flag);	   MCSR = inl(dev->BaseAddr + 0x3c);	   printk("<1> The MCSR register is : %x\n",MCSR);	   MCSR = inl(dev->BaseAddr + 0x3c);	   printk("<1> The MCSR register is : %x\n",MCSR);	   	   if(flag & 0x00080000)	   {		   printk("<1> The DMA transfer has completed.\n");		   flag |=0x00080000;		   outl(flag,dev->BaseAddr + 0x38);	           pci_unmap_single(dev->MyDev,dev->DmaData.PciAddr,				   dev->DmaData.Count,PCI_DMA_TODEVICE);		   kfree(dev->DmaData.Handle);	   		   MCSR = inl(dev->BaseAddr + 0x3c);	           printk("<1> The MCSR register is : %x\n",MCSR);	   }	   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){	int i;	u8 data;	char offset;	copy_from_user(&offset,buf,1);	printk("The buf value is : %x\n",offset);	for(i=0;i<count;i++)	{        	data = inb(Device->BaseAddr + offset + i);		copy_to_user(buf,&data,1);		buf++;	}	printk("<1> PCI_read has execution\n");}/***************************PCI write************************************/ssize_t PCI_write(struct file *filp,char *buf,size_t count,loff_t *offp){	unsigned long Size = count;	unsigned long Start = 0x00004000;	dma_addr_t Busaddr;	u32 *buffer,MCSR;		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(Device->MyDev,buffer,			count,PCI_DMA_TODEVICE);//        outl(Int,Device->BaseAddr + 0x38);//INTCSR//	MCSRwrite(Fifo,Device->BaseAddr + 0x3c);//MCSR	outl(Busaddr,Device->BaseAddr + 0x2c);//MRAR	outl(Size,Device->BaseAddr + 0x30);//MRTC	MCSRwrite(Start,Device->BaseAddr + 0x3c);		MCSR = inb(Device->BaseAddr + 0x3c);	printk("<1> start MCSR is %x\n",MCSR);		Device->DmaData.PciAddr = Busaddr;	Device->DmaData.Count = count;	Device->DmaData.Handle = buffer;	printk("<1> The vir address is :%x\nThe phy address is :%x\n",buffer,Busaddr);		return count;}int  PCI_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){	unsigned long Int = 0x00008000;	unsigned long Fifo = 0x00003000;	unsigned long Ffre = 0x02000000;	struct PCI_device *dev = filp->private_data;	unsigned long fifo;	switch(cmd){              case 1: {                              outl(Int,dev->BaseAddr + 0x38);//INTCSR			      MCSRwrite(Ffre,dev->BaseAddr + 0x3c);                              MCSRwrite(Fifo,dev->BaseAddr + 0x3c);//MCSR				      fifo = inl(dev->BaseAddr + 0x3c);			      printk("<1> The FIFO has been reseted,value=%x\n",fifo);			      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");		succ = 0;	}           else printk("<1> MYPCI initializition success.\n");        return 0;}/****************************Module release********************************/void cleanup_module(void){        unregister_chrdev(PCI_major,PCINAME);        release_region(Device->BaseAddr,Device->IoSize);        free_irq(Device->IrqNum,Device);          if(succ) kfree(Device);	printk("<1> MYPCI release success.\n");}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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