以下是一个典型的中断处理程序声明:
- static irqreturn_t intr_handler(intirq, void *dev_id, struct pt_regs *regs)
第一个参数irq就是这个处理程序要响应的中断的中断线号。
第二个参数dev_id是一个通用指针,它与在中断处理程序注册时传递给request_irq()的参数dev_id必须一致。如果该值有唯一确定性(建议采用这样的值,以便支持共享),那么它就相当于一个cookie,可以用来区分共享同一中断处理程序的多个设备。
最后一个参数regs是一个指向结构的指针,该结构包含处理中断之前处理器的寄存器和状态。
中断处理程序可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED。当中断处理程序检测到一个中断,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回IRQ_NONE;当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HANDLED。利用这些特殊的值,内核可以知道设备发出的是否一种虚假的(为请求)中断。
重入和中断处理程序
Linux中的中断处理程序是无需重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一中断线上接收另一个新的中断。通常情况下,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断线总是被禁止的。由此可以看出,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。
6.4.1 共享的中断处理程序
共享的处理程序与非共享的处理程序在注册和运行方式上比较相似,但差异主要有以下三处:
- request_irq()的参数flags必须设置SA_SHIRQ标志。
- 对每个注册的中断处理程序来说,dev_id参数必须唯一。不能给共享的处理程序传递NULL值。
- 中断处理程序必须能够区分它的设备是否真的产生了中断。
所有共享中断线的驱动程序都必须满足以上要求。指定SA_SHIRQ标志以调用request_irq()时,只有在以下两种情况下才可能成功:中断线当前未被注册,或者在该线上的所有已注册处理程序都制定了SA_SHIRQ.