In continuation of the previous text 第10章:中断处理-3: Autodetecting the IRQ Number, let's GO ahead.
Do-it-yourself probing
Probing can also be implemented in the driver itself without too much trouble. It is a rare driver that must implement its own probing, but seeing how it works gives some insight into the process. To that end, the short module performs do-it-yourself detection of the IRQ line if it is loaded with probe=2.
驱动也可以自行实现探测功能,过程并不复杂。虽然很少有驱动必须自行实现探测,但了解其工作原理有助于深入理解整个流程。为此,short 模块在以 probe=2 加载时,会执行自定义的 IRQ 线探测。
The mechanism is the same as the one described earlier: enable all unused interrupts, then wait and see what happens. We can, however, exploit our knowledge of the device. Often a device can be configured to use one IRQ number from a set of three or four; probing just those IRQs enables us to detect the right one, without having to test for all possible IRQs.
自定义探测的机制与前文描述的一致:启用所有未使用的中断,然后观察后续情况。不过,我们可以利用对设备的了解优化探测过程 —— 通常设备仅支持从 3 到 4 个候选值中选择一个 IRQ 号,只需探测这些候选 IRQ,无需测试所有可能的 IRQ,即可确定正确的中断号。
The short implementation assumes that 3, 5, 7, and 9 are the only possible IRQ values. These numbers are actually the values that some parallel devices allow you to select.
short 模块的实现假设 3、5、7、9 是仅有的可能 IRQ 值,这些数值实际上是部分并行设备允许用户选择的中断号。
The following code probes by testing all “possible” interrupts and looking at what happens. The trials array lists the IRQs to try and has 0 as the end marker; the tried array is used to keep track of which handlers have actually been registered by this driver.
以下代码通过测试所有 “可能的” 中断并观察结果来实现探测:trials 数组列出了待测试的 IRQ(以 0 作为结束标记);tried 数组用于记录该驱动实际注册了哪些中断处理程序。
int trials[ ] = {3, 5, 7, 9, 0};
int tried[ ] = {0, 0, 0, 0, 0};
int i, count = 0;
/*
* install the probing handler for all possible lines. Remember
* the result (0 for success, or -EBUSY) in order to only free
* what has been acquired
*/
for (i = 0; trials[i]; i++)
tried[i] = request_irq(trials[i], short_probing,
SA_INTERRUPT, "short probe", NULL);
do {
short_irq = 0; /* none got, yet */
outb_p(0x10,short_base+2); /* enable */
outb_p(0x00,short_base);
outb_p(0xFF,short_base); /* toggle the bit */
outb_p(0x00,short_base+2); /* disable */
udelay(5); /* give it some time */
/* the value has been set by the handler */
if (short_irq = = 0) { /* none of them? */
printk(KERN_INFO "short: no irq reported by probe\n");
}
/*
* If more than one line has been activated, the result is
* negative. We should service the interrupt (but the lpt port
* doesn't need it) and loop over again. Do it at most 5 times
*/
} while (short_irq <=0 && count++ < 5);
/* end of loop, uninstall the handler */
for (i = 0; trials[i]; i++)
if (tried[i] = = 0)
free_irq(trials[i], NULL);
if (short_irq < 0)
printk("short: probe failed %i times, giving up\n", count);
You might not know in advance what the “possible” IRQ values are. In that case, you need to probe all the free interrupts, instead of limiting yourself to a few trials[ ]. To probe for all interrupts, you have to probe from IRQ 0 to IRQ NR_IRQS-1, where NR_IRQS is defined in and is platform dependent.
有时你可能无法提前知道 “可能的” IRQ 值。这种情况下,需要探测所有空闲的中断,而非局限于 trials 数组中的少数几个。若要探测所有中断,需从 IRQ 0 测试到 IRQ NR_IRQS - 1——NR_IRQS 定义于 <linux/irq.h>,且因平台而异。
Now we are missing only the probing handler itself. The handler’s role is to update short_irq according to which interrupts are actually received. A 0 value in short_irq means “nothing yet,” while a negative value means “ambiguous.” These values were chosen to be consistent with probe_irq_off and to allow the same code to call either kind of probing within short.c.
目前还缺少探测处理程序本身。该处理程序的作用是根据实际接收到的中断更新 short_irq:short_irq 为 0 表示 “尚未探测到任何中断”,为负值表示 “探测结果模糊(多个中断触发)”。选择这些值是为了与 probe_irq_off 的返回值规则保持一致,以便 short.c 中可使用同一套代码调用两种探测方式。
irqreturn_t short_probing(int irq, void *dev_id, struct pt_regs *regs)
{
if (short_irq = = 0) short_irq = irq; /* found */
if (short_irq != irq) short_irq = -irq; /* ambiguous */
return IRQ_HANDLED;
}
The arguments to the handler are described later. Knowing that irq is the interrupt being handled should be sufficient to understand the function just shown.
该处理程序的参数将在后续介绍。目前只需知道 irq 是当前正在处理的中断号,即可理解上述函数的逻辑。

被折叠的 条评论
为什么被折叠?



