Re: PCI interrupt lost
From: Dimitris Lampridis
Date: Wed Dec 15 2004 - 06:12:25 EST
On Mon, 2004-12-13 at 12:08 -0500, linux-os wrote:
> Also, PCI interrupts __must__ be level. It's in the PCI specification.
> If this IRQ level is raised, the kernel will call the registered
> interrupts. It has no choice and if it didn't work nobody would
> be able to boot. The only possibility is that somebody else is
> using the interrupt and hasn't allocated it shared, or your
> code has bug(s).
>
OK, so level triggered, active low it is.
The interrupt line is not shared by anyone else (right now. in the past
it did but only with other pci devices) as I can see
in /proc/interrupts, but also request_irq() is returning with success.
So no problem there. Therefore, I must agree with you, my code has
bug(s).
> Also, returning IRQ_NONE will force your ISR to be called repeatedly
> until the kernel is forced to shut off the ISR. It should return
> IRQ_DONE. You need to allocate the interrupt specified in the
> "dev" structure and not attempt to out-think anything. You should
> never even care what the raw configuration settings are. If your
> code looks at that stuff, it's broken.
>
Why returning IRQ_NONE is wrong? if it is not my interrupt but for
another driver for a device sharing the interrupt line, I should leave
it to him to return IRQ_HANDLED. No?
> struct pci_dev *pdev;
> pdev = PCI_FIND_DEVICE(PCI_ID, PCI_DEV, pdev);
>
> // use ioremap_nocache() for BARS.
>
> request_irq(pdev->irq, my_isr, SA_INTERRUPT|SA_SHIRQ, "device",
> pointer_to_your_stuff);
> pci_set_drvdata(pdev, NULL); // Not necessary
> pci_set_power_state(pdev, 0); // Now mandatory
> pci_set_master(pdev); // PLX is a master
> pci_set_dma_mask(pdev, 0xffffffffULL); // Future needs on ix86
> pci_set_mwi(pdev); // If you want
> pci_enable_device(pdev); // Remember to do this
>
>
> This __will__ initialize the PLX chip, but you still have to
> set/unmask its interrupt registers to get an interrupt.
>
> Both the PLX chip and the kernel code will properly handle an
> interrupt. We use these extensively here, so it's just some
> bug(s) in your code.
>
The only thing that didn't already exist in my code was
pci_set_power_state(pdev, 0), but it did not make any difference. the
problem persists. Do you think that there is a problem if I request the
irq line after calling pci_enable_device()? I cannot think of anything
else. Everything that you mentioned is already in my code, and yet I can
see no interrupt. Maybe it has something to do with my HW / BIOS?
Thanks a lot,
Dimitris Lampridis <labis@xxxxxxxxxx>
Attachment:
signature.asc
Description: This is a digitally signed message part