Hi,
I am working on a PPC440 board that supports
a PCI-IDE device, and I am experiencing an
interrupt handling problem.
The PCI-IDE controller uses External Interrupt 7 and
the controller interrupt line is wired to the
processor directly. When the IDE device is
being initialized, I can see that the interrupt
goes off. But the code is stuck in the
ISR and can not get out. Here are the screen
debug messages:
<Linux booting up>
ide1: CMD649 Bus-Master DMA disabled (BIOS)
disabling irq 50 defensively
ppc405_uic_disable - irq 50 word 1 bit 0x12
hda: SanDisk SDCFB-128, ATA DISK drive
ppc405_uic_enable - irq 50 word 1 bit 0x12
ppc405_uic_enable - irq 50 word 1 bit 0x12
ide0 at 0x2000-0x2007,0x3002 on irq 50
hda: 250880 sectors (128 MB) w/1KiB Cache,
CHS=980/8/32
Partition check:
hda:ppc405_pic_get_irq - irq 50 bit 0x2000
ppc405_uic_disable_and_ack - irq 50 word 1 bit 0x12
ppc405_pic_get_irq - irq 64 bit 0x0
ppc405_pic_get_irq - irq 64 bit 0x0
-------------
I am able to retrieve a stack trace when the
console is displaying the above messages. It is
shown as follows.
-----------
#8 0xc0004950 in do_IRQ (regs=0xc02b68a4) at
irq.c:585
#9 0xc00037cc in ret_from_fork () at entry.S:97
#10 0xc0004730 in ppc_irq_dispatch_handler
(regs=0xc02a522f, irq=3178)
at irq.c:477
#11 0xc0004938 in do_IRQ (regs=0xc01dbf30) at
irq.c:583
------------
Does anybody have an explaination on what is
going on? Thank you for your help.
Regards,
Terry
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
I am working on a PPC440 board that supports
a PCI-IDE device, and I am experiencing an
interrupt handling problem.
The PCI-IDE controller uses External Interrupt 7 and
the controller interrupt line is wired to the
processor directly. When the IDE device is
being initialized, I can see that the interrupt
goes off. But the code is stuck in the
ISR and can not get out. Here are the screen
debug messages:
<Linux booting up>
ide1: CMD649 Bus-Master DMA disabled (BIOS)
disabling irq 50 defensively
ppc405_uic_disable - irq 50 word 1 bit 0x12
hda: SanDisk SDCFB-128, ATA DISK drive
ppc405_uic_enable - irq 50 word 1 bit 0x12
ppc405_uic_enable - irq 50 word 1 bit 0x12
ide0 at 0x2000-0x2007,0x3002 on irq 50
hda: 250880 sectors (128 MB) w/1KiB Cache,
CHS=980/8/32
Partition check:
hda:ppc405_pic_get_irq - irq 50 bit 0x2000
ppc405_uic_disable_and_ack - irq 50 word 1 bit 0x12
ppc405_pic_get_irq - irq 64 bit 0x0
ppc405_pic_get_irq - irq 64 bit 0x0
-------------
Well, "irq 64" bothers me.
You shouldn't see this message. Real external interrupts are in the range 0-63
Please, check that you are using latest code from 2.4 devel tree
(in particular file arch/ppc/kernel/ppc4xx_pic.c)
BTW, how did you setup trigger and polarity settings for IRQ7 ?
Eugene.
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Hi, Eugene,
The IRQ7 is setup as level trigger and active low.
I think what happened is that when the ISR is
serving the first interrupt, which is external
interrupt 7 (number 50), it is interrupted again.
This time, ppc405_pic_get_irq() returns irq 64 because
the routine knows that all interrupts have been
disabled (I have looked at UIC_ER0 and UIC_ER1
and verified that is the case). So the question is,
if all interrupts are disabled, why the code is stuck
inside the ISR?
I am using the lastest 2.4.19 code.
Thank you for your help again.
Regards,
Terry L.
--- Eugene Surovegin <ebs@ebshome.net> wrote:
At 10:15 PM 5/13/2003, Xupei Liang wrote:
quoted
I am working on a PPC440 board that supports
a PCI-IDE device, and I am experiencing an
interrupt handling problem.
The PCI-IDE controller uses External Interrupt 7
and
quoted
the controller interrupt line is wired to the
processor directly. When the IDE device is
being initialized, I can see that the interrupt
goes off. But the code is stuck in the
ISR and can not get out. Here are the screen
debug messages:
<Linux booting up>
ide1: CMD649 Bus-Master DMA disabled (BIOS)
disabling irq 50 defensively
ppc405_uic_disable - irq 50 word 1 bit 0x12
hda: SanDisk SDCFB-128, ATA DISK drive
ppc405_uic_enable - irq 50 word 1 bit 0x12
ppc405_uic_enable - irq 50 word 1 bit 0x12
ide0 at 0x2000-0x2007,0x3002 on irq 50
hda: 250880 sectors (128 MB) w/1KiB Cache,
CHS=980/8/32
Partition check:
hda:ppc405_pic_get_irq - irq 50 bit 0x2000
ppc405_uic_disable_and_ack - irq 50 word 1 bit 0x12
ppc405_pic_get_irq - irq 64 bit 0x0
ppc405_pic_get_irq - irq 64 bit 0x0
-------------
Well, "irq 64" bothers me.
You shouldn't see this message. Real external
interrupts are in the range 0-63
Please, check that you are using latest code from
2.4 devel tree
(in particular file arch/ppc/kernel/ppc4xx_pic.c)
BTW, how did you setup trigger and polarity settings
for IRQ7 ?
Eugene.
Hi, Eugene,
The IRQ7 is setup as level trigger and active low.
<snip>
This time, ppc405_pic_get_irq() returns irq 64 because
the routine knows that all interrupts have been
disabled (I have looked at UIC_ER0 and UIC_ER1
and verified that is the case).
No, this is not correct, it should return -1.
Otherwise do_IRQ will spin forever (see arch/ppc/kernel/irq.c)
Here is the code in question:
int
ppc405_pic_get_irq(struct pt_regs *regs)
{
........
if (irq == (NR_UIC_IRQS * NR_UICS))
irq = -1;
#ifdef UIC_DEBUG
printk("ppc405_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
#endif
return (irq);
}
Check, that NR_UIC_IRQS == 32 (defined in include/arch-ppc/irq.h)
and NR_UICS == 2 (defined in /include/arch-ppc/ibm440.h) in your tree.
They weren't set correctly in some early versions of 440GP code.
Eugene
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Hi, Eugene,
Thank you for pointing out this. I have updated
ibm440.h and ppc4xx_pic.c as well. Now, in
ppc405_disable_and_ack(), besides acking the
interrupt, it will clear UIC0_UIC1NC bit in the
UIC0_SR register as well. That works for my
board.
Thanks.
Regards,
Terry L.
--- Eugene Surovegin <ebs@ebshome.net> wrote:
At 08:20 AM 5/14/2003, Xupei Liang wrote:
quoted
Hi, Eugene,
The IRQ7 is setup as level trigger and active low.
<snip>
quoted
This time, ppc405_pic_get_irq() returns irq 64
because
quoted
the routine knows that all interrupts have been
disabled (I have looked at UIC_ER0 and UIC_ER1
and verified that is the case).
No, this is not correct, it should return -1.
Otherwise do_IRQ will spin forever (see
arch/ppc/kernel/irq.c)
Here is the code in question:
int
ppc405_pic_get_irq(struct pt_regs *regs)
{
........
if (irq == (NR_UIC_IRQS * NR_UICS))
irq = -1;
#ifdef UIC_DEBUG
printk("ppc405_pic_get_irq - irq %d bit
0x%x\n", irq, bits);
#endif
return (irq);
}
Check, that NR_UIC_IRQS == 32 (defined in
include/arch-ppc/irq.h)
and NR_UICS == 2 (defined in
/include/arch-ppc/ibm440.h) in your tree.
They weren't set correctly in some early versions of
440GP code.
Eugene