赞
踩
pci_host_bridge
:pci_bus
:pci_ops
:pci_slot
:pci_dev
:pci_driver
:pci_driver_i
:/* PCI设备驱动编程,必须包括两个核心重要的头文件 */ #include <linux/module.h> #include <linux/pci.h> /* 用户自定义结构体类型,作用于中断服务函数里面 */ struct pci_Card { resource_size_t io; long range, flags; void __iomem *ioaddr; int irq; }; static struct pci_device_id ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x100f) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0) }, {0,} }; MODULE_DEVICE_TABLE(pci, ids); void skel_get_configs(struct pci_dev *dev) { uint8_t revisionId; uint16_t vendorId, deviceId; uint32_t classId; pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId); printk("vendorID = %x", vendorId); pci_read_config_word(dev, PCI_DEVICE_ID, &deviceId); printk("deviceID = %x", deviceId); pci_read_config_byte(dev, PCI_REVISION_ID, &revisionId); printk("revisionID = %x",revisionId); pci_read_config_dword(dev, PCI_CLASS_REVISION, &classId); printk("classID = %x",classId); } static irqreturn_t pci_Mcard_interrupt(int irq, void *dev_id) { struct pci_Card *pci_Mcard = (struct pci_Card *)dev_id; printk("irq = %d, pci_Mcard_irq = %d\n", irq, pci_Mcard->irq); return IRQ_HANDLED; } static int probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval = 0; struct pci_Card *pci_Mcard; printk("probe func\n"); /* 设备使能 */ if(pci_enable_device(dev)) { printk (KERN_ERR "IO Error.\n"); return -EIO; } pci_Mcard = kmalloc(sizeof(struct pci_Card),GFP_KERNEL); if(!pci_Mcard) { printk("In %s,kmalloc err!",__func__); return -ENOMEM; } /* 设备中断号 */ pci_Mcard->irq = dev->irq; if(pci_Mcard->irq < 0) { printk("IRQ is %d, it's invalid!\n",pci_Mcard->irq); goto out_pci_Mcard; } /*获取io内存相关信息*/ pci_Mcard->io = pci_resource_start(dev, 0); pci_Mcard->range = pci_resource_end(dev, 0) - pci_Mcard->io + 1; pci_Mcard->flags = pci_resource_flags(dev,0); printk("start %llx %lx %lx\n",pci_Mcard->io, pci_Mcard->range, pci_Mcard->flags); printk("PCI base addr 0 is io%s.\n",(pci_Mcard->flags & IORESOURCE_MEM)? "mem":"port"); /*防止地址访问冲突,所以这里先申请*/ retval = pci_request_regions(dev,"pci_module"); if(retval) { printk("PCI request regions err!\n"); goto out_pci_Mcard; } /*再进行映射*/ pci_Mcard->ioaddr = pci_ioremap_bar(dev, 0); if(!pci_Mcard->ioaddr) { printk("ioremap err!\n"); retval = -ENOMEM; goto out_regions; } /*申请中断IRQ并设定中断服务子函数*/ retval = request_irq(pci_Mcard->irq, pci_Mcard_interrupt, IRQF_SHARED, "pci_module", pci_Mcard); if(retval) { printk (KERN_ERR "Can't get assigned IRQ %d.\n",pci_Mcard->irq); goto out_iounmap; } pci_set_drvdata(dev, pci_Mcard); skel_get_configs(dev); return 0; out_iounmap: iounmap(pci_Mcard->ioaddr); out_regions: pci_release_regions(dev); out_pci_Mcard: kfree(pci_Mcard); return retval; } /* 移除PCI设备 */ static void remove(struct pci_dev *dev) { struct pci_Card *pci_Mcard = pci_get_drvdata(dev); free_irq (pci_Mcard->irq, pci_Mcard); iounmap(pci_Mcard->ioaddr); pci_release_regions(dev); kfree(pci_Mcard); pci_disable_device(dev); printk("remove pci device ok\n"); } /* 结构体成员变量填充 */ static struct pci_driver pci_driver = { .name = "pci_module", .id_table = ids, .probe = probe, .remove = remove, }; /* 模块入口函数 */ static int __init pci_module_init(void) { printk("PCI module entry function\n"); return pci_register_driver(&pci_driver); } /* 模块退出函数 */ static void __exit pci_module_exit(void) { printk("PCI module exit function.\n"); // PCI驱动被卸载时,需要调用pci_unregister_driver pci_unregister_driver(&pci_driver); } MODULE_LICENSE("GPL"); module_init(pci_module_init); module_exit(pci_module_exit);
推荐课程:https://xxetb.xetslk.com/s/3oyV5o
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。