root/drivers/net/auto_irq.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. autoirq_probe
  2. autoirq_setup
  3. autoirq_report

   1 /* auto_irq.c: Auto-configure IRQ lines for linux. */
   2 /*
   3     Written 1994 by Donald Becker.
   4 
   5     The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
   6     Center of Excellence in Space Data and Information Sciences
   7       Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
   8 
   9     This code is a general-purpose IRQ line detector for devices with
  10     jumpered IRQ lines.  If you can make the device raise an IRQ (and
  11     that IRQ line isn't already being used), these routines will tell
  12     you what IRQ line it's using -- perfect for those oh-so-cool boot-time
  13     device probes!
  14 
  15     To use this, first call autoirq_setup(timeout). TIMEOUT is how many
  16     'jiffies' (1/100 sec.) to detect other devices that have active IRQ lines,
  17     and can usually be zero at boot.  'autoirq_setup()' returns the bit
  18     vector of nominally-available IRQ lines (lines may be physically in-use,
  19     but not yet registered to a device).
  20     Next, set up your device to trigger an interrupt.
  21     Finally call autoirq_report(TIMEOUT) to find out which IRQ line was
  22     most recently active.  The TIMEOUT should usually be zero, but may
  23     be set to the number of jiffies to wait for a slow device to raise an IRQ.
  24 
  25     The idea of using the setup timeout to filter out bogus IRQs came from
  26     the serial driver.
  27 */
  28 
  29 
  30 #ifdef version
  31 static char *version=
  32 "auto_irq.c:v1.11 Donald Becker (becker@cesdis.gsfc.nasa.gov)";
  33 #endif
  34 
  35 /*#include <linux/config.h>*/
  36 /*#include <linux/kernel.h>*/
  37 #include <linux/sched.h>
  38 #include <linux/delay.h>
  39 #include <asm/bitops.h>
  40 #include <asm/io.h>
  41 #include <asm/irq.h>
  42 #include <linux/netdevice.h>
  43 /*#include <asm/system.h>*/
  44 
  45 struct device *irq2dev_map[16] = {0, 0, /* ... zeroed */};
  46 
  47 int irqs_busy = 0x2147;         /* The set of fixed IRQs (keyboard, timer, etc) */
  48 int irqs_used = 0x0001;         /* The set of fixed IRQs sometimes enabled. */
  49 int irqs_reserved = 0x0000;     /* An advisory "reserved" table. */
  50 int irqs_shared = 0x0000;       /* IRQ lines "shared" among conforming cards.*/
  51 
  52 static volatile int irq_number; /* The latest irq number we actually found. */
  53 static volatile int irq_bitmap; /* The irqs we actually found. */
  54 static int irq_handled;         /* The irq lines we have a handler on. */
  55 
  56 static void autoirq_probe(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58         irq_number = irq;
  59         set_bit(irq, (void *)&irq_bitmap);      /* irq_bitmap |= 1 << irq; */
  60         disable_irq(irq);
  61         return;
  62 }
  63 
  64 int autoirq_setup(int waittime)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66         int i, mask;
  67         int timeout = jiffies + waittime;
  68         int boguscount = (waittime*loops_per_sec) / 100;
  69 
  70         irq_handled = 0;
  71         for (i = 0; i < 16; i++) {
  72                 if (test_bit(i, &irqs_busy) == 0
  73                         && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe") == 0)
  74                         set_bit(i, (void *)&irq_handled);       /* irq_handled |= 1 << i;*/
  75         }
  76         /* Update our USED lists. */
  77         irqs_used |= ~irq_handled;
  78         irq_number = 0;
  79         irq_bitmap = 0;
  80 
  81         /* Hang out at least <waittime> jiffies waiting for bogus IRQ hits. */
  82         while (timeout > jiffies  &&  --boguscount > 0)
  83                 ;
  84 
  85         for (i = 0, mask = 0x01; i < 16; i++, mask <<= 1) {
  86                 if (irq_bitmap & irq_handled & mask) {
  87                         irq_handled &= ~mask;
  88 #ifdef notdef
  89                         printk(" Spurious interrupt on IRQ %d\n", i);
  90 #endif
  91                         free_irq(i);
  92                 }
  93         }
  94         return irq_handled;
  95 }
  96 
  97 int autoirq_report(int waittime)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         int i;
 100         int timeout = jiffies+waittime;
 101         int boguscount = (waittime*loops_per_sec) / 100;
 102 
 103         /* Hang out at least <waittime> jiffies waiting for the IRQ. */
 104 
 105         while (timeout > jiffies  &&  --boguscount > 0)
 106                 if (irq_number)
 107                         break;
 108 
 109         /* Retract the irq handlers that we installed. */
 110         for (i = 0; i < 16; i++) {
 111                 if (test_bit(i, (void *)&irq_handled))
 112                         free_irq(i);
 113         }
 114         return irq_number;
 115 }
 116 
 117 /*
 118  * Local variables:
 119  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c auto_irq.c"
 120  *  version-control: t
 121  *  kept-new-versions: 5
 122  *  c-indent-level: 4
 123  *  tab-width: 4
 124  * End:
 125  */

/* [previous][next][first][last][top][bottom][index][help] */