PCIe驱动开发(2)— 第一个简单驱动编写和测试

#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> #define HELLO_PCI_DEVICE_ID 0x11e8 #define HELLO_PCI_VENDOR_ID 0x1234 #define HELLO_PCI_REVISION_ID 0x10 static struct pci_device_id ids[] = { { PCI_DEVICE(HELLO_PCI_VENDOR_ID, HELLO_PCI_DEVICE_ID), }, { 0 , } }; static struct hello_pci_info_t { struct pci_dev *dev; void __iomem *address_bar0; } hello_pci_info; MODULE_DEVICE_TABLE(pci, ids); static irqreturn_t hello_pci_irq_handler(int irq, void *dev_info) { struct hello_pci_info_t *_pci_info = dev_info; uint32_t irq_status; // get irq_stutas irq_status = *((uint32_t *)(_pci_info->address_bar0 + 0x24)); printk("hello_pcie: get irq status: 0x%0x\n", irq_status); // clean irq *((uint32_t *)(_pci_info->address_bar0 + 0x64)) = irq_status; // get irq_stutas irq_status = *((uint32_t *)(_pci_info->address_bar0 + 0x24)); if(irq_status == 0x00){ printk("hello_pcie: receive irq and clean success. \n"); return IRQ_HANDLED; }else{ printk("hello_pcie: receive irq but clean failed !!! \n"); return IRQ_NONE; } } static int hello_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id) { int bar = 0; int ret; resource_size_t len; ret = pci_enable_device(dev); if(ret) { return ret; } len = pci_resource_len(dev, bar); hello_pci_info.address_bar0 = pci_iomap(dev, bar, len); hello_pci_info.dev = dev; // register interrupt ret = request_irq(dev->irq, hello_pci_irq_handler, IRQF_SHARED, "hello_pci", &hello_pci_info); if(ret) { printk("request IRQ failed.\n"); return ret; } // enable irq for finishing factorial computation *((uint32_t *)(hello_pci_info.address_bar0 + 0x20)) = 0x80; return 0; } static void hello_pcie_remove(struct pci_dev *dev) { // disable irq for finishing factorial computation *((uint32_t *)(hello_pci_info.address_bar0 + 0x20)) = 0x01; free_irq(dev->irq, &hello_pci_info); pci_iounmap(dev, hello_pci_info.address_bar0); pci_disable_device(dev); } static struct pci_driver hello_pci_driver = { .name = "hello_pcie", .id_table = ids, .probe = hello_pcie_probe, .remove = hello_pcie_remove, }; static int __init hello_pci_init(void) { return pci_register_driver(&hello_pci_driver); } static void __exit hello_pci_exit(void) { pci_unregister_driver(&hello_pci_driver); } MODULE_LICENSE("GPL"); module_init(hello_pci_init); module_exit(hello_pci_exit);
上一篇:springboot 、springcloud、springcloud Alibaba各版本对应情况