我需要在Linux 3.12驱动程序中“启用”PCIe内存区域吗?

我有我的PCIe驱动程序(松散地基于这篇文章 )的probe()函数调用的代码:

编辑: 基于Andreas Bombe的回应,我改变了代码使用pci_iomap() ,但我仍然体验系统挂起

 static my_pci_dev pci_dev; /* local structure */ static int pci_setup_region(struct pci_dev *dev) { int bar = 0; pci_dev.physical.addr = pci_resource_start(dev, bar); pci_dev.physical.size = pci_resource_len(dev, bar); pci_dev.virtual.addr = pci_iomap(dev, bar, pci_dev.physical.size); if (NULL == pci_dev.virtual.addr) { return -ENOMEM; } else { pci_dev.virtual.size = pci_dev.physical.size; } printk(KERN_ALERT "Virtual address: %p", pci_dev.virtual.addr); if (request_mem_region(pci_dev.physical.addr, pci_dev.physical.size, DEVICE_NAME) == NULL) { pci_release_resources(); return -EBUSY; } else { pci_dev.physical.allocated = 1; } /* Test it out! */ printk(KERN_ALERT "Trying to read data.\n"); printk(KERN_ALERT "Copied chip-id data:%08x", ioread8(pci_dev.virtual.addr)); return 0; } 

但内核挂在ioread8()的调用。

难道我做错了什么? 还是我需要看硬件?

这里是对系统的干净启动lspci -vcat /proc/iomem

 root@socfpga:~# lspci -v 00:00.0 PCI bridge: Altera Corporation Device e000 (rev 01) (prog-if 00 [Normal decode]) Flags: fast devsel Bus: primary=00, secondary=01, subordinate=01, sec-latency=0 I/O behind bridge: 00000000-00000fff Memory behind bridge: c0000000-c00fffff Prefetchable memory behind bridge: 00000000-000fffff Capabilities: [50] MSI: Enable- Count=1/4 Maskable- 64bit+ Capabilities: [78] Power Management version 3 Capabilities: [80] Express Root Port (Slot-), MSI 00 Capabilities: [100] Virtual Channel Capabilities: [200] Vendor Specific Information: ID=1172 Rev=0 Len=044 <?> 01:00.0 Multimedia audio controller: Altera Corporation Device e002 (rev 01) Subsystem: Altera Corporation Device e002 Flags: fast devsel, IRQ 75 Memory at c0000000 (32-bit, non-prefetchable) [disabled] [size=128K] Capabilities: [50] MSI: Enable- Count=1/4 Maskable- 64bit+ Capabilities: [78] Power Management version 3 Capabilities: [80] Express Endpoint, MSI 00 Capabilities: [100] Virtual Channel Capabilities: [200] Vendor Specific Information: ID=1172 Rev=0 Len=044 <?> Kernel modules: test-pci 

内存出现[disabled]我必须启用它吗?

 root@socfpga:~# cat /proc/iomem 00000000-3fffffff : System RAM 00008000-006fa7d3 : Kernel code 00754000-007d8c23 : Kernel data c0000000-cfffffff : ALTERA PCIE RP MEM c0000000-c00fffff : PCI Bus 0000:01 c0000000-c001ffff : 0000:01:00.0 d0000000-dfffffff : ALTERA PCIE RP PREF MEM ff200000-ff20000f : csr ff200010-ff20008f : vector_slave ff210000-ff21003f : ff210000.chipidbridge0 ff280000-ff283fff : Cra ff702000-ff703fff : /soc/ethernet@ff702000 ff704000-ff704fff : /soc/dwmmc0@ff704000 ff705000-ff705fff : ff705000.spi ffa00000-ffa00fff : ff705000.spi ffb40000-ffb4fffe : /soc/usb@ffb40000 ffc00000-ffc00fff : c_can_platform ffc02000-ffc0201f : serial ffc04000-ffc04fff : /soc/i2c@ffc04000 ffd02000-ffd02fff : /soc/wd@ffd02000 ffe01000-ffe01fff : /soc/amba/pdma@ffe01000 fff00000-fff00fff : fff00000.spi ffff0000-ffffffff : /soc/sram@ffff0000 root@socfpga:~# 

你一定要启用它。 这些是基本步骤:

 pci_enable_device(dev); pci_request_regions(dev, "driver/device name"); bar0 = pci_iomap(dev, 0, 0); x = ioread(bar0 + offset); /* there you are */ 

所有的pci_*调用都需要检查错误。 如果设备需要执行DMA,则还需要调用pci_set_masterpci_set_dma_mask

详细阐述一下,绕过PCI内核代码直接映射BAR可能已经很久以前了。 我不确定现在的代码是否合法,但肯定是不可取的。