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 probe\n"); 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 up\n",count);
注意 udelay 的使用,在调用 probe_irq_off 之前. 依赖你的处理器的速度,你可能不 得不等待一小段时间来给中断时间来真正被递交.
探测可能是一个长时间的任务. 虽然对于 short 这不是真的,例如,探测一个帧抓取器,需要一个至少 20 ms 的延时( 对处理器是一个时代 ),并且其他的设备可能要更长. 因 此,最好只探测中断线一次,在模块初始化时,独立于你是否在设备打开时安装处理(如 同你应当做的),或者在初始化函数当中(这个不推荐).
有趣的是注意在一些平台上(PoweerPC,M68K,大部分 MIPS 实现,以及 2 个 SPARC 版 本)探测是不必要的,并且,因此,之前的函数只是空的占位者,有时称为"无用的 ISA 废话". 在其他平台上,探测只为 ISA 设备实现. 无论如何,大部分体系定义了函数( 即 便它们是空的 )来简化移植现存的设备驱动.
总结以上是内存溢出为你收集整理的linux 内核协助的探测全部内容,希望文章能够帮你解决linux 内核协助的探测所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)