手动初始化PCI设备:正确启用IRQ的缺失步骤是什么?
手动初始化PCI设备时正确启用IRQ的缺失步骤
当你通过pci_get_device()手动获取PCI设备句柄时,内核不会自动执行pci_register_driver()流程中包含的IRQ分配与配置步骤,导致dev->irq为0。你需要补充以下关键操作:
1. 确保设备处于可操作状态
在读取IRQ前,先将设备从低功耗状态唤醒并启用:
pci_set_power_state(dev, PCI_D0); pci_enable_device(dev);
2. 手动分配/读取正确的IRQ号
根据设备的中断类型,选择对应的操作:
传统PCI中断
调用内核函数分配IRQ(推荐),或直接读取PCI配置空间的中断线寄存器:
// 方式1:让内核自动分配IRQ dev->irq = pci_assign_irq(dev); // 方式2:直接读取PCI配置空间的中断线寄存器 u8 irq_line; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_line); dev->irq = irq_line;
MSI/MSIX中断(如果设备支持)
优先启用MSI/MSIX中断,这类中断可靠性更高,需手动调用对应函数:
// 启用MSI中断(单向量) if (pci_enable_msi(dev) == 0) { // dev->irq 已被设置为MSI中断号 } // 或启用MSIX中断(多向量,需提前准备msix_entries数组) struct msix_entry msix_entries[NUM_VECTORS]; // 填充msix_entries的entry字段等信息 if (pci_enable_msix(dev, msix_entries, NUM_VECTORS) == 0) { // 使用msix_entries[i].irq作为对应向量的中断号 }
3. 完成其他必要初始化步骤
在申请IRQ前,还需完成资源申请与DMA配置(如果需要):
// 申请设备的I/O/内存资源区域,避免资源冲突 pci_request_regions(dev, "your_driver_name"); // 设置设备为主DMA设备(仅当设备需要DMA功能时调用) pci_set_master(dev);
4. 申请中断
完成上述步骤后,dev->irq已被设置为有效中断号,即可正常调用:
request_irq(dev->irq, your_interrupt_handler, IRQF_SHARED, "your_driver_name", dev);
内容的提问来源于stack exchange,提问作者Maximilian
相关产品推荐
相关产品推荐

