Annotation of Gnu-Mach/linux/src/drivers/net/auto_irq.c, revision 1.1

1.1     ! root        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 [email protected], 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 const char *version=
        !            32: "auto_irq.c:v1.11 Donald Becker ([email protected])";
        !            33: #endif
        !            34: 
        !            35: #include <linux/sched.h>
        !            36: #include <linux/delay.h>
        !            37: #include <asm/bitops.h>
        !            38: #include <asm/io.h>
        !            39: #include <asm/irq.h>
        !            40: #include <linux/netdevice.h>
        !            41: 
        !            42: struct device *irq2dev_map[NR_IRQS] = {0, 0, /* ... zeroed */};
        !            43: 
        !            44: unsigned long irqs_busy = 0x2147;              /* The set of fixed IRQs (keyboard, timer, etc) */
        !            45: unsigned long irqs_used = 0x0001;              /* The set of fixed IRQs sometimes enabled. */
        !            46: unsigned long irqs_reserved = 0x0000;          /* An advisory "reserved" table. */
        !            47: unsigned long irqs_shared = 0x0000;            /* IRQ lines "shared" among conforming cards.*/
        !            48: 
        !            49: static volatile unsigned long irq_bitmap;      /* The irqs we actually found. */
        !            50: static unsigned long irq_handled;              /* The irq lines we have a handler on. */
        !            51: static volatile int irq_number;                        /* The latest irq number we actually found. */
        !            52: 
        !            53: static void autoirq_probe(int irq, void *dev_id, struct pt_regs * regs)
        !            54: {
        !            55:        irq_number = irq;
        !            56:        set_bit(irq, (void *)&irq_bitmap);      /* irq_bitmap |= 1 << irq; */
        !            57:        /* This code used to disable the irq. However, the interrupt stub
        !            58:         * would then re-enable the interrupt with (potentially) disastrous
        !            59:         * consequences
        !            60:         */
        !            61:        free_irq(irq, dev_id);
        !            62:        return;
        !            63: }
        !            64: 
        !            65: int autoirq_setup(int waittime)
        !            66: {
        !            67:        int i;
        !            68:        unsigned long timeout = jiffies + waittime;
        !            69:        unsigned long boguscount = (waittime*loops_per_sec) / 100;
        !            70: 
        !            71:        irq_handled = 0;
        !            72:        irq_bitmap = 0;
        !            73: 
        !            74:        for (i = 0; i < 16; i++) {
        !            75:                if (test_bit(i, &irqs_busy) == 0
        !            76:                        && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe", NULL) == 0)
        !            77:                        set_bit(i, (void *)&irq_handled);       /* irq_handled |= 1 << i;*/
        !            78:        }
        !            79:        /* Update our USED lists. */
        !            80:        irqs_used |= ~irq_handled;
        !            81: 
        !            82:        /* Hang out at least <waittime> jiffies waiting for bogus IRQ hits. */
        !            83:        while (timeout > jiffies  &&  --boguscount > 0)
        !            84:                ;
        !            85: 
        !            86:        irq_handled &= ~irq_bitmap;
        !            87: 
        !            88:        irq_number = 0; /* We are interested in new interrupts from now on */
        !            89: 
        !            90:        return irq_handled;
        !            91: }
        !            92: 
        !            93: int autoirq_report(int waittime)
        !            94: {
        !            95:        int i;
        !            96:        unsigned long timeout = jiffies+waittime;
        !            97:        unsigned long boguscount = (waittime*loops_per_sec) / 100;
        !            98: 
        !            99:        /* Hang out at least <waittime> jiffies waiting for the IRQ. */
        !           100: 
        !           101:        while (timeout > jiffies  &&  --boguscount > 0)
        !           102:                if (irq_number)
        !           103:                        break;
        !           104: 
        !           105:        irq_handled &= ~irq_bitmap;     /* This eliminates the already reset handlers */
        !           106: 
        !           107:        /* Retract the irq handlers that we installed. */
        !           108:        for (i = 0; i < 16; i++) {
        !           109:                if (test_bit(i, (void *)&irq_handled))
        !           110:                        free_irq(i, NULL);
        !           111:        }
        !           112:        return irq_number;
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * Local variables:
        !           117:  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c auto_irq.c"
        !           118:  *  version-control: t
        !           119:  *  kept-new-versions: 5
        !           120:  *  c-indent-level: 4
        !           121:  *  tab-width: 4
        !           122:  * End:
        !           123:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.