La fonction
request_irq()
demande que la fonction indiquée (le gestionnaire) soit appellée à chaque fois
que le noyau reçoit une certaine interruption. Le gestionnaiore peut lui-même
enregistrer un gestionnaire bas, chargé de réaliser le gros du traitement de
manière asynchrone. Consultez
init_bh(9)
pour plus d'information sur les gestionnaires d'interruptions asynchrones.
Le paramètres
irq
est le numéro de l'interruption à gérer. Il doit ête inférieur à
NR_IRQS
(16 sur les sytèmes à base d'architecture Intel ix86 alias ia32) ; il peut y
avoir d'autres limitations sur cette valeur. Consultez
arch/*/kernel/irq.c (intr.c
pour les machines à base de Motorola 680x0 : m68k) pour plus d'informations.
gest
est un pointeur sur la fonction chargée de gérer les interruptions. Le
gestionnaire se verra passer les paramètres suivants lors de son exécution :
-
- int irq
-
Le numéro d'interruption. En testant la valeur de ce paramètre, il est possible
d'associer la gestion de plusieurs interruptions différentes à une même
fonction.
- void *dev_id
-
Le numéro de périphérique de ce gestionnaire (voir plus bas).
- struct pt_regs *regs
-
Les registres stockés sur la pile du processus qui a été interrompu.
Normalement, personne ne devrait avoir à s'en préoccuper ; cependant ils peuvent
être lus pour, par exemple, déterminer si le processus suspendu était en mode
utilisateur ou noyau.
drap_interrupt
est, comme l'indique son nom, un masque de drapeaux (chacun représenté par un
bit) relatifs à ce gestionnaire d'interruption. Les bits prédéfinis sont :
-
- SA_INTERRUPT
-
Ce bit indique que le gestionnaire d'interruptions est un gestionnaire rapide.
La sémantique de ce drapeau est défini plus loin.
- SA_SHIRQ
-
Ce bit indique que le gestionnaire supporte le partage de l'interruption avec
d'autres gestionnaires (voir aussi
*dev_id
plus loin).
- SA_SAMPLE_RANDOM
-
Ce bit indique que cette interruption peut être utilisée comme générateur
d'entropie pour
/dev/random
et
/dev/urandom
(voir
drivers/char/random.c).
[Ndt : voir aussi
random(4), urandom(4)]
- SA_PROBE
-
Ce bit indique que cette interruption est autodétectée et que le gestionnaire
installé est bidon. Cette valeur était prévue pour être utilisée en interne par
probe_irq_on()
(q.v.), mais n'est plus utilisée dans les noyaux 2.1.x. En fait, même dans les
noyaux 2.0.x, elle n'était déja plus utilisée dans l'architecture MIPS. Vous ne
devriez donc pas utiliser cette valeur à moins que vous ne sachiez ce que vous
faites.
- SA_STATIC_ALLOC
-
(Sparc/Sparc64 seulement). Ce bit demande à ce que la structure
struct irqaction
(voir plus loin) soit ajoutée à une tableau statiquement préalloué de quatre
gestionnaires plutôt que dans la table habituelle
irq_action[] .
Ceci est utilisé pour les interruptions qui doivent être utilisées tôt dans le
processus d'initialisation du système, avant que
kmalloc_init()
soit appelé.
Le paramètre
devname
est un nom court pour le périphérique et est affiché dans la liste /proc/interrupts.
Le paramètre
dev_id
est le numéro d'identification du périphérique. Ce paramètre est fréquemment
initialisé à NULL, mais ne devrait pas l'être dans le cas des interruptions
partagées. Cela n'a aucune importance en utilisation courante, mais quand
free_irq()
est appelée, le pilote correct est appelé. Comme son type est
void *,
il peut pointer sur n'importe quoi, comme une structure spécifique à un
périphérique, ou même un espace mémoire vide, mais soyez certain de passer le
même pointeur à
free_irq().
La fonction
free_irq()
libère un gestionnaire d'interruption. Elle prend en paramètres, le numéro
d'interruptions à désenregistrer et le numéro de périphérique à désenregistrer.
Vous devriez passer la même valeur que celle passée à
request_irq().
Vous ne devriez probablement jamais désenregistrer un autre gestionnaire à
moins de savoir ce que vous faites.
Opération
Sur la plupart des architectures,
request_irq()
alloue de la mémoire pour une structure de type
struct irqaction,
remplit ses champs, et l'ajoute à la table
irq_action[] .
enable_irq()
est ensuite appelée pour signaler au noyau de commencer à délivrer les
interruptions au gestionnaire nouvellement installé. Ce processus est très
différent sur les machines à base de m68k, où il dépend du sous-type de
machine (Amiga, Atari, etc.).
free_irq()
enlève simplement les entrées que
request_irq()
a ajoutées. NB : certains de ces noms changent sur certaines architectures (par
exemple,
struct irqaction
est appelée
struct irq_action
sur les Power PC). Si vous désirez approfondir vos connaissances sur le
fonctionnement interne de ces fonctions, vous devriez lire les sources, car une
partie de ces informations peut avoir changé lorsque vous lirez cette page
(dans ce cas, signalez-le moi afin que je mette à jour cette page).
Gestionnaire d'Interruption Rapides
Un gestionnaire d'inrruption « rapide » (dont le bit
SA_INTERRUPT
est positionné) a un comportement différent d'un gestionnaire « lent » :
-
Sur ix86 et MIPS, durant l'exécution du gestionnaire, les interruptions sont
désactivées (elles sont activées par défaut sur ces machines et désactivées sur
les autres).
Sur MIPS, le retour est plus rapide.
Sur Alpha, MIPS, Sparc et Sparc64, un gestionnaire lent et un gestionnaire
rapide ne peuvent pas partager la même interruption.
Sur toutes les architectures, exceptés les m68k et les ix86, un `+' est affiché
entre le compteur d'interruptions et le nom du périphérique dans
/proc/interrupts.
La distinction d'interruptions lente/rapide est lentement dépréciée. Par
exemple, sous 2.0.x sur ix86,
SA_INTERRUPT
activait un retour rapide comme il le fait encore sur le MIPS ; Cette
distinction a été supprimée dans le 2.1.x.
VALEUR RENVOYÉE
En cas de succès,
request_irq()
renvoie 0 si tout s'est déroulé normalement. Votre gestionnaire
d'interruptions commencera à recevoir des interruptions immédiatement. En cas
d'échec,
request_irq()
renvoie :
-
- -EINVAL
-
Le numéro d'interruption indiqué n'est pas valide ou est réservé, ou alors, un
pointeur NULL a été passé pour le paramètre
gest() .
- -ENOMEM
-
request_irq()
ne peut pas allouer suffisamment de mémoire pour quelque chose (probablement la
structure
struct irqaction).
- -EBUSY
-
L'interruption indiquée est déjà gérée, et ne peut être partagée entre
plusieurs gestionnaires. Cette erreur se produit lorque le gestionnaire en
cours d'enregistrement ou celui déja enregistré n'a pas le bit
SA_SHIRQ
activé dans son champ
drap_interrupt .
De plus, sur la plupart des architectures, tous les gestionnaires partageant la
même interruption doivent avoir la même « vitesse », c'est-à-dire être soit tous
soit aucun d'entre eux ont le bit
SA_INTERRUPT
positionné. Enfin, il est possible que votre architecture ne supporte pas le
partage de l'interruption que vous voulez utiliser.
- -ENXIO
-
Sur m68k, cette valeur de retour indique un mauvais numéro d'interruption.
free_irq()
ne renvoie aucune valeur.
DISPONIBILITÉ
Linux 2.1+. Les informations de cette page devraient fonctionner avec un noyau
2.0.x, mais de légères différences d'implémentation peuvent être rencontrées
(particulièrement dans le comportement de
SA_INTERRUPT
sur les machines à base d'ix86). Les versions plus anciennes que la 2.0.0
possèdent ces fonctions mais ne passent pas le paramètre
dev_id .
Si vous voulez voir votre code fonctionner sur des versions plus anciennes
et plus récentes que le 2.0, vous devriez protéger votre code avec des macros
du préprocesseur utilisant
LINUX_VERSION_CODE.
VOIR AUSSI
init_bh(9), probe_irq_on(9),
arch/*/kernel/irq.c, arch/*/kernel/entry.S,
include/linux/interrupt.h, include/asm*/signal.h.
AUTEUR
Neil Moore <amethyst@maxwell.ml.org>
TRADUCTION
Thierry Vignaud <tvignaud@mandrakesoft.com>, 2000
BOGUES
Ce n'est pas exactement un bug, mais
request_irq()
ne fontionne pas
tout à fait
sur m68k comme sur les autres architectures. Vous devriez lire
arch/m68k/kernel/ints.c, arch/m68k/atari/ataints.c,
arch/m68k/amiga/amiints.c, et arch/m68k/amiga/cia.c
si vous souhaitez écrire un pilote pour l'un de ces systèmes.
Index
- NOM
-
- SYNOPSIS
-
- DESCRIPTION
-
- Usage
-
- Opération
-
- Gestionnaire d'Interruption Rapides
-
- VALEUR RENVOYÉE
-
- DISPONIBILITÉ
-
- VOIR AUSSI
-
- AUTEUR
-
- TRADUCTION
-
- BOGUES
-
This document was created by
man2html,
using the manual pages.
Time: 21:33:13 GMT, July 10, 2005