Re: Level-Triggered Interrupt Advice Seeked.

Jason Wohlgemuth (wohlj7s0@numen.elon.edu)
Mon, 13 Jul 1998 10:26:08 -0400 (EDT)


Okay... I understand the majority of that. Maybe I was confusing
the issue by using the ACK term. I appreciate your help though!

Specifically, I need to end the interrupt after running the
handler. I understand stand that this is standard practice and it
was accomplished with the DOS drivers of this card by doing:

if (irq > 7)
outp(0xa0,0x20);
outp(0x20,0x20);

also in some other posts I have read regarding this same situation
in Linux have stated :

"So, if you ack a level triggered interrupt without prior clearing
of the interrupt condition will immediately raise another one. If
you disable that interrupt by setting int-destination to 0, it is
not really disabled, just the delivery is disabled."

Well, in either case... I need to do the End of Interrupt after my
handler sets some bits on the card. Right now this isn't
happening so I get floods of interrupts over and over. Alan Cox
sent me mail and said that this problem can be corrected by
setting some flags in the 2.1.xx kernels. Do you know what I have
to do in the request_irq() or which flag I have to set?

Thanks,
Jason

On Mon, 13 Jul 1998, Richard B. Johnson wrote:

> On Mon, 13 Jul 1998, Jason Wohlgemuth wrote:
>
> > I was directed to this mailing list for advice on a question I
> > initially posted on comp.linux.development.system.
> >
> > Basically, When an interrupt is set by a PCI card I am working
> > with some memory registers on the card must be manipulated before
> > the interrupt is ACK'd. From reading past posts and just looking
> > around I have found that Linux handles things in this order: MASK
> > irq, ACK irq, run handler, UNMASK irq.
>
> This is probably a semantics problem. Acking the interrupt is "resetting
> the in-service flag" so that a subsequent interrupt can be "stored".
> It makes no difference if you are looking at edges or are using levels.
>
> The APIC code is not very clear, and its documentation is very sparse.
> However, its logical operation is similar to the operation of the
> regular PC/AT controllers which are easy to understand. Therefore,
> I will use this controller as an example.
>
> Acking the interrupt means nothing to the device that caused the
> interrupt. It cannot possibly know that this operation occurred.
>
> The interrupt service routine for the device should do whatever is
> necessary to reset its interrupt output line (bit). It can do this in any
> necessary order, defined by the hardware the ISR services. When all
> the conditions that caused the interrupt request are satisfied, the
> interrupt output line will be reset. This wire is usually the OR of
> all the bits in some status register that could cause an interrupt.
>
> The interrupt "mask" for the controller is a GATE! It is logically
> connected to the input of the controller.
>
> Let's say your device raised its interrupt output bit which is routed
> to the controller. Since this bit is not masked, it is applied to
> the controller's input and, when priority conditions are satisfied,
> it raises the interrupt pin of the CPU.
>
> The CPU branches to the common routine, which handles the interrupt
> controller. This routine masks off the interrupt, i.e., turns OFF
> the input bit. It then resets the in-service flag so that another
> interrupt on this level COULD be stored. It won't be stored yet
> because the input line is disconnected by the masking operation.
> This is the so-called ACK. Your device can't possibly know about
> this operation nor be affected in any adverse way.
>
> The routine then calls your ISR software which handles the needs
> of the hardware. If you complete the requirements of the hardware,
> its interrupt request bit will go low. If something changes while
> your ISR is executing, i.e., new data are available, the hardware's
> interrupt request bit may not stay low. It makes no difference.
>
> Once your routine returns to the kernel's common routine, the
> input to the controller is reconnected by UN-masking that interrupt
> line. If the line is still high (a new interrupt has occurred), this
> event will now be latched, and once priority conditions are satisfied,
> the whole event occurs again. Because the input to the controller was
> disconnected, the in-service latch is reset, then the input is
> reconnected, these operations even produce a new "edge". You will
> never lose any interrupts.
>
> >
> > I need to run the interrupt handler before the interrupt is ACK'd.
>
> This cannot be true. Your interrupt handler doesn't care about the
> interrupt controller. It needs to satisfy the requirements of your
> hardware only. Your hardware cannot possibly "know" about the state
> of the interrupt controller.
>
> There are a lot of interrupt service routines within the kernel that
> are not good templates. Many do things that they really don't need to
> do, or shouldn't be doing, but they get away with it. A typical
> example is this:
>
> while((status = read_hardware_status()))
> {
> handler(status);
> }
>
> Such loops within ISRs remove the advantage of the prioritized
> interrupt controller and allow a single device to take unfair
> advantage of the whole machine.
>
> The other most common problem is that writers insist upon enabling
> interrupts within the interrupt service routines. There may be some
> very special circumstances where this is necessary, but the problem
> is that, regardless of how the routine is "protected" against
> reentry, etc., once you enable interrupts, the CPU WILL BE TAKEN AWAY!
> This means that a carefully coded routine that should execute in
> a new hundred microseconds, now takes many milliseconds to execute.
>
> Cheers,
> Dick Johnson
> ***** FILE SYSTEM MODIFIED *****
> Penguin : Linux version 2.1.108 on an i586 machine (66.15 BogoMips).
> Warning : It's hard to remain at the trailing edge of technology.
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.rutgers.edu
> Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html