Re: ISR for shared IRQ is called again and again

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2009/2/25 Michael Blizek <michi1@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>:
> On 17:44 Wed 25 Feb     , Denis Borisevich wrote:
>> Hi!
>> I've done some tests and here is what I figured out: the interrupts
>> assigned to the device controlled by the ahci driver keep going even
>> without my driver loaded and even with all my boards removed from
>> system physically. So it seems that everything ok.
>> But I have another question concerning interrupts:
>> Let's take the situation I described in my first and second posts - I
>> have a system with the PCI board which I develop driver for. This
>> board shares interrupt with the device controlled by ahci driver. The
>> question is why every interrupt I got on this line is interpreted by
>> my driver as the interrupt which belongs to it?
>
> If an interrupt is shared, the kernel does not know which device a raised
> interrupt belongs to. For this reason, it is delivered to every driver which
> has an interrupt handler for this interrupt.
>
>> Here is the code I use:
>>
>> === CODE BELOW ===
>>
>> to register ISR:
>> struct my_dev *board;
>> request_irq(board->irq, my_interrupt_handler, IRQF_SHARED, "my_module", board);
>>
>> ISR:
>> static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
>> {
>>     struct my_dev *board;
>>     int i, retval = IRQ_NONE;
>>
>>     // find out which board got an interrupt
>>     for (i = 0; i < MAX_BOARDS; i++)
>>         if (dev_id == &my_boards[i]) {
>>         board = dev_id;
>>         break;
>>     }
>>
>>     // Check if interrupt was issued by another device (in case of shared
>>     // interrupt line).
>>     if (i == MAX_BOARDS)
>>         goto handled;
>>     if (board == NULL)
>>         goto handled;
>>
>>     // if we are here then it's our interrupt
>>     retval = IRQ_HANDLED;
>>
>>     /* here goes some checks on the device registers
>>        to know if there is interrupts pending in it.
>>        these checks are sure to be right. If there's no
>>        interrupt, then debug message "no interrupt" is
>>        printed.
>>     */
>>      .......
>>     /* here goes the interrupt handling, if the previous check
>>        was successful
>>     */
>>     .......
>>
>>     handled:
>>        return retval;
>> }
>>
>> === CODE ABOVE ===
>>
>> So, what do I have now. When no program touches my device (it is
>> idling) and the ahci driver is loaded I have this "no interrupt"
>> message in dmesg output 20-30 times per second. When some application
>> uses my device I have the proper printouts (the kind of interrupt and
>> so on) and bunch of these "no interrupt". When I install my board into
>> another PCI slot (and get another interrupt line) I never see these
>> "no interrupt" messages, but only the ones concerning to the actual
>> interrupt handling in my driver. Which indicates that driver works as
>> intended. The questions is why the dev_id parameter of
>> my_interrupt_handler() holds the data which belongs to one of the
>> boards controlled by my driver (which is the reason why the check in
>> the very beginning of ISR routine is passed)?
>
> The dev_id is the what you passed it request_irq. You do not need the loop,
> because you will not be called if dev_id is not your device. The 2
> if...goto handled should never happen. What you need to do in the interrupt
> handler is to ask the device if it has raised the interrupt and do the
> interrupt handling if necessary. Something like this:
>
> static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
> {
>        struct my_dev *board = dev_id;
>
>        int interrupts_pending = do_some_check;
>
>        if (interrupts_pending == 0) {
>                /* probably another device which is sharing the interrupt has
>                 * raised thi irq
>                 */
>                return IRQ_NONE;
>        }
>
>        /* here goes the interrupt handling */
>
>        return IRQ_HANDLED;
> }
>
>        -Michi
>
> --
> programing a layer 3+4 network protocol for mesh networks
> see http://michaelblizek.twilightparadox.com
>
>

I see. Thanks for your help. Have you any idea why the ahci driver
behaves this way?

--
Denis

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux