linux驱动怎么识别pcie,Linux驱动程序开发:PCI和PCIe驱动程序之间的区别?

这是我的代码。我的问题是,如果我想将此驱动程序用于PCIe设备,是否必须进行一些修改?

#include

#include

#include

#include

#include

#include

#undef debug

// ATTENTION copied from /uboot_for_mpc/arch/powerpc/include/asm/signal.h

// Maybe it don't work with that

//____________________________________________________________

#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */

#define SA_SHIRQ 0x04000000

//____________________________________________________________

#define pci_module_init pci_register_driver // function is obsoleted

// Hardware specific part

#define MY_VENDOR_ID 0x5333

#define MY_DEVICE_ID 0x8e40

#define MAJOR_NR 240

#define DRIVER_NAME "PCI-Driver"

static unsigned long ioport=0L, iolen=0L, memstart=0L, memlen=0L,flag0,flag1,flag2,temp=0L;

// private_data

struct _instance_data {

int counter; // just as a example (5-27)

// other instance specific data

};

// Interrupt Service Routine

static irqreturn_t pci_isr(int irq, void *dev_id, struct pt_regs *regs)

{

return IRQ_HANDLED;

}

// Check if this driver is for the new device

static int device_init(struct pci_dev *dev,

const struct pci_device_id *id)

{

int err=0; // temp variable

#ifdef debug

flag0=pci_resource_flags(dev, 0);

flag1=pci_resource_flags(dev, 1);

flag2=pci_resource_flags(dev, 2);

printk("DEBUG: FLAGS0 = %u\n",flag0);

printk("DEBUG: FLAGS1 = %u\n",flag1);

printk("DEBUG: FLAGS2 = %u\n",flag2);

/*

* The following sequence checks if the resource is in the

* IO/Storage/Interrupt/DMA address space

* and prints the result in the dmesg log

*/

if(pci_resource_flags(dev,0) & IORESOURCE_IO)

{

// Ressource is in the IO address space

printk("DEBUG: IORESOURCE_IO\n");

}

else if (pci_resource_flags(dev,0) & IORESOURCE_MEM)

{

// Resource is in the Storage address space

printk("DEBUG: IORESOURCE_MEM\n");

}

else if (pci_resource_flags(dev,0) & IORESOURCE_IRQ)

{

// Resource is in the IRQ address space

printk("DEBUG: IORESOURCE_IRQ\n");

}

else if (pci_resource_flags(dev,0) & IORESOURCE_DMA)

{

// Resource is in the DMA address space

printk("DEBUG: IORESOURCE_DMA\n");

}

else

{

printk("DEBUG: NOTHING\n");

}

#endif /* debug */

// allocate memory_region

memstart = pci_resource_start(dev, 0);

memlen = pci_resource_len(dev, 0);

if(request_mem_region(memstart, memlen, dev->dev.kobj.name)==NULL) {

printk(KERN_ERR "Memory address conflict for device \"%s\"\n",

dev->dev.kobj.name);

return -EIO;

}

// allocate a interrupt

if(request_irq(dev->irq,pci_isr,SA_INTERRUPT|SA_SHIRQ,

"pci_drv",dev)) {

printk(KERN_ERR "pci_drv: IRQ %d not free.\n", dev->irq);

}

else

{

err=pci_enable_device(dev);

if(err==0) // enable device successful

{

return 0;

}

else // enable device not successful

{

return err;

}

}

// cleanup_mem

release_mem_region(memstart, memlen);

return -EIO;

}

// Function for deinitialization of the device

static void device_deinit(struct pci_dev *pdev)

{

free_irq(pdev->irq, pdev);

if(memstart)

release_mem_region(memstart, memlen);

}

static struct file_operations pci_fops;

static struct pci_device_id pci_drv_tbl[] __devinitdata = {

{ MY_VENDOR_ID, // manufacturer identifier

MY_DEVICE_ID, // device identifier

PCI_ANY_ID, // subsystem manufacturer identifier

PCI_ANY_ID, // subsystem device identifier

0, // device class

0, // mask for device class

0 }, // driver specific data

{ 0, }

};

static int driver_open(struct inode *geraetedatei, struct file *instance)

{

struct _instance_data *iptr;

iptr = (struct _instance_data *)kmalloc(sizeof(struct _instance_data),

GFP_KERNEL);

if(iptr==0) {

printk("not enough kernel mem\n");

return -ENOMEM;

}

/* replace the following line with your instructions */

iptr->counter= strlen("Hello World\n")+1; // just as a example (5-27)

instance->private_data = (void *)iptr;

return 0;

}

static void driver_close(struct file *instance)

{

if(instance->private_data)

kfree(instance->private_data);

}

static struct pci_driver pci_drv = {

.name= "pci_drv",

.id_table= pci_drv_tbl,

.probe= device_init,

.remove= device_deinit,

};

static int __init pci_drv_init(void)

{ // register the driver by the OS

if(register_chrdev(MAJOR_NR, DRIVER_NAME, &pci_fops)==0) {

if(pci_module_init(&pci_drv) == 0) // register by the subsystem

return 0;

unregister_chrdev(MAJOR_NR,DRIVER_NAME); // unregister if no subsystem support

}

return -EIO;

}

static void __exit pci_drv_exit(void)

{

pci_unregister_driver(&pci_drv);

unregister_chrdev(MAJOR_NR,DRIVER_NAME);

}

module_init(pci_drv_init);

module_exit(pci_drv_exit);

MODULE_LICENSE("GPL");

2012-08-28

Peter

+0

在调用'pci_enable_device'之后调用'release_mem_region'是否合适?就目前而言,即使此通话失败,内存区仍将被分配。也许使用'check_mem_region'也可能是一种理智的行为? –

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值