linux 内核协助的探测
Linux 内核提供了一个低级设施来探测中断号. 它只为非共享中断,但是大部分能够在共 享中断状态工作的硬件提供了更好的方法来尽量发现配置的中断号.这个设施包括 2 个函 数,在<linux/interrupt.h> 中声明( 也描述了探测机制 ). ? unsigned long probe_irq_on(void); ? 这个函数返回一个未安排的中断的位掩码. 驱动必须保留返回的位掩码,并且在后 面传递给 probe_irq_off. 在这个调用之后,驱动应当安排它的设备产生至少一次 中断. ? int probe_irq_off(unsigned long); ? 在设备已请求一个中断后,驱动调用这个函数,作为参数传递之前由 probe_irq_on 返回的位掩码. probe_irq_off 返回在"probe_on"之后发出的中断 号. 如果没有中断发生,返回 0 (因此,IRQ 0 不能探测,但是没有用户设备能够 在任何支持的体系上使用它). 如果多于一个中断发生( 模糊的探测 ),probe_irq_off 返回一个负值. ? 程序员应当小心使能设备上的中断,在调用 probe_irq_on 之后以及在调用 probe_irq_off 后禁止它们. 另外,你必须记住服务你的设备中挂起的中断,在 probe_irq_off 之后. ? short 模块演示了如何使用这样的探测. 如果你加载模块使用 probe=1,下列代码被执行 来探测你的中断线,如果并口连接器的管脚 9 和 10 连接在一起: ? int count = 0; do { unsigned long mask; mask = probe_irq_on(); outb_p(0x10,short_base+2); /* enable reporting */ outb_p(0x00,short_base); /* clear the bit */ outb_p(0xFF,short_base); /* set the bit: interrupt! */ outb_p(0x00,short_base+2); /* disable reporting */ udelay(5); /* give it some time */ short_irq = probe_irq_off(mask); ? if (short_irq == 0) { /* none of them? */ printk(KERN_INFO "short: no irq reported by proben"); short_irq = -1; } ? /* *? if more than one line has been activated,the result is *? negative. We should service the interrupt (no need for lpt port) *? and loop over again. Loop at most five times,then give up */ } while (short_irq < 0 && count++ < 5); if (short_irq < 0) printk("short: probe failed %i times,giving upn",count); ? 注意 udelay 的使用,在调用 probe_irq_off 之前. 依赖你的处理器的速度,你可能不 得不等待一小段时间来给中断时间来真正被递交. ? 探测可能是一个长时间的任务. 虽然对于 short 这不是真的,例如,探测一个帧抓取器,需要一个至少 20 ms 的延时( 对处理器是一个时代 ),并且其他的设备可能要更长. 因 此,最好只探测中断线一次,在模块初始化时,独立于你是否在设备打开时安装处理(如 同你应当做的),或者在初始化函数当中(这个不推荐). ? 有趣的是注意在一些平台上(PoweerPC,M68K,大部分 MIPS 实现,以及 2 个 SPARC 版 本)探测是不必要的,并且,因此,之前的函数只是空的占位者,有时称为"无用的 ISA 废话". 在其他平台上,探测只为 ISA 设备实现. 无论如何,大部分体系定义了函数( 即 便它们是空的 )来简化移植现存的设备驱动. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |