点击上方蓝字【囧囧妹】一起学习,一起成长!
一,启用pcie设备
在接触任何设备寄存器之前,驱动程序需要通过调用pci_enable_device()来启用PCI设备,该函数内部会做如下操作:
如果设备处于挂起状态,则唤醒设备,
分配设备的 I/O 和内存区域(如果 BIOS 没有),
分配一个 IRQ(如果 BIOS 没有)。
注意:
1,pci_enable_device()会失败!需要检查返回值。
2,OS BUG:在启用这些资源之前,系统不会检查资源分配,如果在调用 pci_request_resources() 之前调用pci_enable_device(),当两个设备分配到相同的范围时,设备驱动程序无法检测到该错误,这不是一个常见问题,但目前linux还不能很快解决该问题。
pci_set_master()将通过设置 PCI_COMMAND 寄存器中的总线主控位来启用 DMA。如果 BIOS 将其设置为虚假的,它还会修复延迟计时器值。pci_clear_master()将通过清除总线主机位来禁用 DMA。
如果 PCI 设备可以使用 PCI Memory-Write-Invalidate 事务,调用pci_set_mwi()这将为 Mem-Wr-Inval 启用 PCI_COMMAND 位,并确保正确设置高速缓存行大小寄存器,检查返回值,因为pci_set_mwi()并非所有架构或芯片组都可能支持 Memory-Write-Invalidate,虽然Mem-Wr-Inval很好用但如果不是必需的,最好调用pci_try_set_mwi()以让系统尽最大努力启用 Mem-Wr-Inval。
struct io_mapping *io_mapping_create_wc(unsigned long base, unsigned long size)
void *io_mapping_map_local_wc(struct io_mapping *mapping,unsigned long offset)void *io_mapping_map_atomic_wc(struct io_mapping *mapping,unsigned long offset)
'offset' 定义的映射区域内的偏移量。访问创建函数中指定区域之外的地址会产生未定义的结果。使用不是页面对齐的偏移量会产生未定义的结果。返回值指向 CPU 地址空间中的单个页面。
addr1 = io_mapping_map_local_wc(map1, offset1);addr2 = io_mapping_map_local_wc(map2, offset2);...io_mapping_unmap_local(addr2);io_mapping_unmap_local(addr1);
void io_mapping_unmap_local(void *vaddr)void io_mapping_unmap_atomic(void *vaddr)
void *
io_mapping_map_wc(struct
io_mapping *mapping,unsigned long offset)
void io_mapping_unmap(void *vaddr)
void io_mapping_free(struct io_mapping *mapping)
文章转载自囧囧妹,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




