You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法为PCI共享中断线注册中断的问题求助

问题分析与解决方案

注册共享IRQ返回-EINVAL(无效参数),常见原因及修复方式如下:

1. 确保dev_id是唯一且非空的有效指针

你定义了ptdk_dummy_device结构体,但如果代码里的dummy是未初始化的指针(仅声明未分配内存),会被内核判定为无效参数。

修复方式:

  • 静态分配全局唯一实例:
static ptdk_dummy_device dummy = { .i = 0 }; // 全局唯一标识
  • 或动态分配内存(模块退出时需释放):
static ptdk_dummy_device *dummy;

static int __init ptdk_init(void)
{
    dummy = kmalloc(sizeof(*dummy), GFP_KERNEL);
    if (!dummy) {
        return -ENOMEM;
    }
    // 后续request_threaded_irq调用
}

static void __exit ptdk_exit(void)
{
    free_irq(17, dummy);
    if (dummy) {
        kfree(dummy);
    }
}

关键:dev_id必须是这条IRQ线上的唯一标识,不能与b43或其他共享驱动的dev_id重复。

2. 匹配中断触发类型

共享IRQ要求所有注册驱动使用相同的触发类型(如电平触发、边沿触发)。b43驱动注册时可能指定了特定触发标志,你未指定的话,内核默认类型可能与b43不匹配,导致注册失败。

修复方式:
先通过cat /proc/irq/17/irq查看b43的触发类型,再在request_threaded_irq中添加对应标志。例如b43用高电平触发:

ptdk_could_not_register = request_threaded_irq(17, (irq_handler_t)ptdk_irq_handler,
                    (irq_handler_t)ptdk_threaded_irq_handler, 
                    IRQF_SHARED | IRQF_TRIGGER_LEVEL_HIGH, "ptdk", dummy);

3. 保证顶半部处理函数返回值合规

共享IRQ的顶半部处理函数必须返回以下值之一:

  • IRQ_HANDLED:确认是本设备产生的中断
  • IRQ_NONE:非本设备中断,转交其他共享驱动
  • IRQ_WAKE_THREAD:需唤醒线程处理时返回

示例合规函数:

static irqreturn_t ptdk_irq_handler(int irq, void *dev_id)
{
    // 检查是否为本设备中断(通过硬件寄存器判断)
    if (!is_my_device_interrupt()) {
        return IRQ_NONE;
    }
    clear_my_device_interrupt(); // 快速清中断标志
    return IRQ_WAKE_THREAD;
}

4. 确认IRQ确实支持共享

通过cat /proc/irq/17/flags查看输出,若包含shared则说明该IRQ线确实支持共享;若未包含,需排查硬件或中断控制器的限制。


内容的提问来源于stack exchange,提问作者as43z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:03:27