PC 体系结构为了方便把一些中断固定下来,所以驱动程序在初始化的时候只需要简单地请求它的中断。软盘设备驱动程序就是这样:它总是请求中断 6 。但是也可能一个设备驱动程序不知道设备会使用什么中断。对于 PCI 设备驱动程序这不是问题,因为它们总是知道它们的中断编号。不幸的是对于 ISA 设备没有什么简单的办法找到它们的中断号码, Linux 允许设备驱动程序探查它们的中断来解决这个问题。
首先,设备驱动程序让设备产生中断,然后系统中所有没有分配的中断都允许了。这意味着设备等待处理的中断现在会通过可编程中断控制器传递。 Linux 读取中断状态寄存器然后把它的内容返回到设备驱动程序。非 0 的结果表示在探查中发生了一或多个中断。驱动程序现在关闭探查,并禁止所有位分配的中断。如果 ISA 设备驱动程序成功地找到了它的 IRQ 号,它就可以想平常一样地请求控制它。
参见 arch/*/kernel/irq.c irq_probe_*()
PCI 系统比 ISA 系统更加动态。 ISA 设备的中断通常用硬件设备上的跳线来设置,对于设备驱动程序是固定的。反过来, PCI 设备的中断是在系统启动的时候由 PCI BIOS 或者 PCI 子系统在 PCI 初始化的时候分配的。每一个 PCI 设备可以使用 4 个中断管脚其中之一: A 、 B 、 C 或 D 。这时设备制造的时候确定的,大多数设备缺省用中断管脚 A 。每一个 PCI 槽位的 PCI 中断线( interrupte line ) A 、 B 、 C 和 D 都转到中断控制器。所以槽位 4 的管脚 A 可能转到了中断控制器的第 6 管脚,槽位 4 的管脚 B 可能转到了中断控制器的管脚 7 ,依此类推。
PCI 中断如何被转发(路由 route )完全是和系统相关的,必须有一些理解这种 PCI 中断路由拓扑的设置代码。在 Intel PC 上,这是启动的时候的系统 BIOS 代码完成的。但是对于没有 BIOS 的系统(例如 Alpha AXP 系统), Linux 进行这种设置。 PCI 设置代码把中断控制器的管脚编号写到每一个设备的 PCI 配置头中。它使用它知道的 PCI 中断路有拓扑和设备的 PCI 槽位以及它正在使用的 PCI 中断管脚来决定中断管脚(或者说 IRQ )编号。设备使用的中断管脚就确定下来并放到 PCI 配置头的一个域。它把这个信息写到中断线( interrupte line )域(这是为此目的保留的)。当设备驱动程序运行的时候,它读取这个信息,并使用它向 Linux 核心请求对中断的控制。
参见 arch/alpha/kernel/bios32.c
系统中可能使用许多 PCI 中断资源。例如,当使用 PCI-PCI 桥的时候。中断来源的数目可能超过系统的可编程中断控制器的管脚数目。这种情况下, PCI 设备可以共享中断:中断控制器上的一个管脚接收来自多于一个 PCI 设备的中断。 Linux 让第一个请求一个中断的源宣称( declare )它是否可以共享,这样来支持中断共享。共享中断结果是 irq_action 向量表中的一个条目可以指向几个 irqaction 的数据结构。当发生了一个共享的中断的时候, Linux 会调用这个源的所有的中断处理程序。所有可以共享中断的设备驱动程序(都应该是 PCI 设备驱动程序)必须预备在没有中断服务的时候被调用。
7.3 Interrupt Handling (中断处理)