zion - request_irq
Nom
request_irq, free_irq - déclare un gestionnaire d'interruptions
Résumé
#include <asm/irq.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> .HP int request_irq(unsigned int irq , void (* gest )(int, void *, struct pt_regs *), unsigned long drap_interrupt , const char * devname , void * dev_id );
void free_irq(unsigned int irq , void * dev_id );
Description
Usage
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
void * dev_id
struct pt_regs * regs
|
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
SA_SHIRQ
SA_SAMPLE_RANDOM
SA_PROBE
SA_STATIC_ALLOC
|
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
-ENOMEM request_irq()
-EBUSY
-ENXIO
|
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
Bugs
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.
Poster un commentaire