Problem is both primary and secondary channels of my PDC20265 use irq 10.
When we probe first interface, everything is fine, as irq 10 is disabled,
and so irq assertion is silently ignored (but it would die if I'll start
using USB which also wants irq 10...). But when secondary channel was
probed, irq 10 was asserted, and things went really wrong... So I made
disable_irq() unconditional: I see no reason why it should depend on
ack_intr. Any code which will cause IRQ assertion, and does not install
either IRQ handler, or which does not disable that IRQ, is buggy.
Another problem I noticed is that actual probe code in probe_hwif between
disable_irq() and enable_irq() could change hwif->irq, and so we could
enable irq we did not disable (it happened to me after I removed ack_intr
test: irq is 0 on entry when probing onboard VIA, but on exit it is 14...
so we enabled irq 14 source without previously disabling it, and it caused
bad things to happen).
This patch makes disabling IRQ during probe unconditional, and makes sure
that we enable same irq we disabled.
Of course that moving init_irq call before probe would be nicer, and
it would solve also pending edge-triggered IRQ, but unfortunately as
code is currently written, we do not know IRQ until after probe, and
at this point we already asserted IRQ, even on PCI devices which can
share IRQ with someone else.
After this patch, and after commenting out "ide_intr: unexpected interrupt"
printk in ide.c:ide_intr system works finally fine.
Thanks,
Petr Vandrovec
vandrove@vc.cvut.cz
P.S.: I set 'Cc' list to my best knowledge. If you feel that you
are missing (Andre & Alan, I believe that you both work on 2.4 only),
add yourself to the "IDE DRIVER [GENERAL]" entry in MAINTAINERS. There
is still Martin listed there.
diff -urdN linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux/drivers/ide/ide-probe.c 2002-09-15 20:31:55.000000000 +0200
+++ linux/drivers/ide/ide-probe.c 2002-09-15 22:55:41.000000000 +0200
@@ -592,6 +592,7 @@
{
unsigned int unit;
unsigned long flags;
+ unsigned int irqd;
if (hwif->noprobe)
return;
@@ -623,8 +624,14 @@
return;
}
- if (hwif->hw.ack_intr && hwif->irq)
+ /* We must always disable IRQ, as probe_for_drive will assert IRQ, but
+ we'll install our IRQ driver much later... */
+ if ((1 || hwif->hw.ack_intr) && hwif->irq) {
disable_irq(hwif->irq);
+ irqd = hwif->irq;
+ } else {
+ irqd = 0; /* Use 0... IDE does not support using irq=0 at all... */
+ }
local_irq_set(flags);
/*
@@ -659,8 +666,9 @@
}
local_irq_restore(flags);
- if (hwif->hw.ack_intr && hwif->irq)
- enable_irq(hwif->irq);
+ /* Use cached IRQ number. It might be (and is...) changed by probe code above */
+ if (irqd)
+ enable_irq(irqd);
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/