Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > f47c9556fae08a4ba497aec95548acd0 > files > 72

lkmpg-1.1.0-6mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<!--Converted with LaTeX2HTML 98.1 release (February 19th, 1998)
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>Interrupt Handlers</TITLE>
<META NAME="description" CONTENT="Interrupt Handlers">
<META NAME="keywords" CONTENT="mpg">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<LINK REL="STYLESHEET" HREF="mpg.css">
<LINK REL="next" HREF="node26.html">
<LINK REL="previous" HREF="node23.html">
<LINK REL="up" HREF="mpg.html">
<LINK REL="next" HREF="node25.html">
</HEAD>
<BODY >
<!--Navigation Panel-->
<A NAME="tex2html671"
 HREF="node25.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
 SRC="next_motif.gif"></A> 
<A NAME="tex2html667"
 HREF="mpg.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
 SRC="up_motif.gif"></A> 
<A NAME="tex2html661"
 HREF="node23.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
 SRC="previous_motif.gif"></A> 
<A NAME="tex2html669"
 HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
 SRC="contents_motif.gif"></A> 
<A NAME="tex2html670"
 HREF="node34.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
 SRC="index_motif.gif"></A> 
<BR>
<B> Next:</B> <A NAME="tex2html672"
 HREF="node25.html">Keyboards on the Intel</A>
<B> Up:</B> <A NAME="tex2html668"
 HREF="mpg.html">Linux Kernel Module Programming</A>
<B> Previous:</B> <A NAME="tex2html662"
 HREF="node23.html">Scheduling Tasks</A>
<BR>
<BR>
<!--End of Navigation Panel-->

<H1><A NAME="SECTION001300000000000000000">&#160;</A><A NAME="int-handler">&#160;</A><A NAME="665">&#160;</A><A NAME="666">&#160;</A>
<BR>
Interrupt Handlers
</H1>

<P>
Except for the last chapter, everything we did in the kernel so far we've
done as a response to a process asking for it, either by dealing with a 
special file, sending an <TT>ioctl</TT>, or issuing a system call. But the job
of the kernel isn't just to respond to process requests. Another job, which
is every bit as important, is to speak to the hardware connected to the
machine.

<P>
There are two types of interaction between the CPU and the rest of the 
computer's hardware. The first type is when the CPU gives orders to the 
hardware, the other is when the hardware needs to tell the CPU something.
The second, called interrupts, is much harder to implement because it has
to be dealt with when convenient for the hardware, not the CPU. Hardware
devices typically have a very small amount of ram, and if you don't read
their information when available, it is lost.

<P>
Under Linux, hardware interrupts are called IRQs (short for <B>I</B>nterrupt 
<B>R</B>e<B>q</B>uests)<A NAME="tex2html243"
 HREF="footnode.html#foot671"><SUP>11.1</SUP></A>. There are two types of IRQs, 
short and long. A short IRQ is one which is expected to take a <B>very</B>
short period of time, during which the rest of the machine will be blocked
and no other interrupts will be handled. A long IRQ is one which can take
longer, and during which other interrupts may occur (but not interrupts 
from the same device). If at all possible, it's better to declare an interrupt
handler to be long.

<P>
When the CPU receives an interrupt, it stops whatever it's doing (unless
it's processing a more important interrupt, in which case it will deal with
this one only when the more important one is done), saves certain parameters
on the stack and calls the interrupt handler. This means that certain things
are not allowed in the interrupt handler itself, because the system is in 
an unknown state. The solution to this problem is for the interrupt
handler to do what needs to be done immediately, usually read something from
the hardware or send something to the hardware, and then schedule the 
handling of the new information at a later time (this is called the `bottom 
half') and return. The kernel is then guaranteed to call the bottom half as
soon as possible -- and when it does, everything allowed in kernel modules
will be allowed.
<A NAME="673">&#160;</A>

<P>
The way to implement this is to call <TT>request_irq</TT> to get your 
interrupt handler called when the relevant IRQ is received (there are 16 of
them on Intel platforms). This function receives the IRQ number, the name
of the function, flags, a name for <TT>/proc/interrupts</TT> and a parameter
to pass to the interrupt handler. The flags can include <TT>SA_SHIRQ</TT> to
indicate you're willing to share the IRQ with other interrupt handlers 
(usually because a number of hardware devices sit on the same IRQ) and 
<TT>SA_INTERRUPT</TT> to indicate this is a fast interrupt. This function
will only succeed if there isn't already a handler on this IRQ, or if 
you're both willing to share.
<A NAME="678">&#160;</A>
<A NAME="679">&#160;</A>
<A NAME="680">&#160;</A>
<A NAME="681">&#160;</A>

<P>
Then, from within the interrupt handler, we communicate with the hardware
and then use <TT>queue_task_irq</TT> with <TT>tq_immediate</TT> and 
<TT>mark_bh(BH_IMMEDIATE)</TT> to
schedule the bottom half. The reason we can't use the standard 
<TT>queue_task</TT> in version 2.0 is that the interrupt might happen right 
in the middle
of somebody else's <TT>queue_task</TT><A NAME="tex2html249"
 HREF="footnode.html#foot856"><SUP>11.2</SUP></A>.
We need <TT>mark_bh</TT> because earlier versions of
Linux only had an array of 32 bottom halves, and now one of them 
(<TT>BH_IMMEDIATE</TT>) is used for the linked list of bottom halves for 
drivers which didn't get a bottom half entry assigned to them.
<A NAME="692">&#160;</A>
<A NAME="693">&#160;</A>
<A NAME="694">&#160;</A>
<A NAME="695">&#160;</A>
<A NAME="696">&#160;</A>

<P>
<BR><HR>
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS">&#160;</A>
<UL>
<LI><A NAME="tex2html673"
 HREF="node25.html">Keyboards on the Intel Architecture</A>
</UL>
<!--End of Table of Child-Links-->
<HR>
<!--Navigation Panel-->
<A NAME="tex2html671"
 HREF="node25.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
 SRC="next_motif.gif"></A> 
<A NAME="tex2html667"
 HREF="mpg.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
 SRC="up_motif.gif"></A> 
<A NAME="tex2html661"
 HREF="node23.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
 SRC="previous_motif.gif"></A> 
<A NAME="tex2html669"
 HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
 SRC="contents_motif.gif"></A> 
<A NAME="tex2html670"
 HREF="node34.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
 SRC="index_motif.gif"></A> 
<BR>
<B> Next:</B> <A NAME="tex2html672"
 HREF="node25.html">Keyboards on the Intel</A>
<B> Up:</B> <A NAME="tex2html668"
 HREF="mpg.html">Linux Kernel Module Programming</A>
<B> Previous:</B> <A NAME="tex2html662"
 HREF="node23.html">Scheduling Tasks</A>
<!--End of Navigation Panel-->
<ADDRESS>
<I></I>
<BR><I>1999-05-19</I>
</ADDRESS>
</BODY>
</HTML>