Annotation of Gnu-Mach/i386/i386at/gpl/linux/linux_autoirq.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Linux auto-irq support.
                      3:  * Copyright (C) 1995 Shantanu Goel.
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify
                      6:  * it under the terms of the GNU General Public License as published by
                      7:  * the Free Software Foundation; either version 2, or (at your option)
                      8:  * any later version.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful,
                     11:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13:  * GNU General Public License for more details.
                     14:  *
                     15:  * You should have received a copy of the GNU General Public License
                     16:  * along with this program; if not, write to the Free Software
                     17:  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     18:  */
                     19: 
                     20: /*
                     21:  *  Written 1994 by Donald Becker.
                     22:  *
                     23:  *  The author may be reached as [email protected], or C/O
                     24:  *  Center of Excellence in Space Data and Information Sciences
                     25:  *    Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
                     26:  *
                     27:  *  This code is a general-purpose IRQ line detector for devices with
                     28:  *  jumpered IRQ lines.  If you can make the device raise an IRQ (and
                     29:  *  that IRQ line isn't already being used), these routines will tell
                     30:  *  you what IRQ line it's using -- perfect for those oh-so-cool boot-time
                     31:  *  device probes!
                     32:  *
                     33:  *  To use this, first call autoirq_setup(timeout). TIMEOUT is how many
                     34:  *  'jiffies' (1/100 sec.) to detect other devices that have active IRQ lines,
                     35:  *  and can usually be zero at boot.  'autoirq_setup()' returns the bit
                     36:  *  vector of nominally-available IRQ lines (lines may be physically in-use,
                     37:  *  but not yet registered to a device).
                     38:  *  Next, set up your device to trigger an interrupt.
                     39:  *  Finally call autoirq_report(TIMEOUT) to find out which IRQ line was
                     40:  *  most recently active.  The TIMEOUT should usually be zero, but may
                     41:  *  be set to the number of jiffies to wait for a slow device to raise an IRQ.
                     42:  *
                     43:  *  The idea of using the setup timeout to filter out bogus IRQs came from
                     44:  *  the serial driver.
                     45:  */
                     46: 
                     47: #include <i386/pic.h>
                     48: #include <i386/ipl.h>
                     49: 
                     50: #include <linux/sched.h>
                     51: #include <linux/ptrace.h>
                     52: 
                     53: #include <asm/bitops.h>
                     54: #include <asm/system.h>
                     55: 
                     56: /*
                     57:  * IRQ to network device map.
                     58:  */
                     59: void *irq2dev_map[16];
                     60: 
                     61: /*
                     62:  * Set of fixed IRQs
                     63:  * (fpu, rtc, com1, PIC slave cascade, keyboard, timer).
                     64:  */
                     65: int irqs_busy = 0x2147;
                     66: 
                     67: static volatile int irq_number;        /* latest irq found */
                     68: static volatile int irq_bitmap;        /* bitmap of IRQs found */
                     69: static int irq_handled;                /* irq lines we have a handler on */
                     70: 
                     71: extern unsigned long loops_per_sec;
                     72: 
                     73: /*
                     74:  * Interrupt handler when probing an IRQ.
                     75:  */
                     76: static void
                     77: autoirq_probe(irq)
                     78:        int irq;
                     79: {
                     80:        /*
                     81:         * Mark this IRQ as the last one
                     82:         * that interrupted and disable it.
                     83:         */
                     84:        irq_number = irq;
                     85:        set_bit(irq, (void *)&irq_bitmap);
                     86:        disable_irq(irq);
                     87: }
                     88: 
                     89: /*
                     90:  * Set up for auto-irq.
                     91:  */
                     92: int
                     93: autoirq_setup(waittime)
                     94:        int waittime;
                     95: {
                     96:        int i, mask;
                     97:        int timeout = jiffies + waittime;
                     98:        int boguscount = (waittime * loops_per_sec) / 100;
                     99: 
                    100:        /*
                    101:         * Allocate all possible IRQs.
                    102:         */
                    103:        irq_handled = 0;
                    104:        for (i = 0; i < 16; i++) {
                    105:                if (test_bit(i, (void *)&irqs_busy) == 0
                    106:                    && request_irq(i, autoirq_probe, 0, 0) == 0)
                    107:                        set_bit(i, (void *)&irq_handled);
                    108:        }
                    109: 
                    110:        irq_number = 0;
                    111:        irq_bitmap = 0;
                    112: 
                    113:        /*
                    114:         * Hang out at least <waittime>
                    115:         * jiffies waiting for bogus IRQ hits.
                    116:         */
                    117:        while (timeout > jiffies && --boguscount > 0)
                    118:                ;
                    119: 
                    120:        /*
                    121:         * Free IRQs that caused bogus hits.
                    122:         */
                    123:        for (i = 0, mask = 0x01; i < 16; i++, mask <<= 1) {
                    124:                if (irq_bitmap & irq_handled & mask) {
                    125:                        irq_handled &= ~mask;
                    126:                        free_irq(i);
                    127:                }
                    128:        }
                    129: 
                    130:        return (irq_handled);
                    131: }
                    132: 
                    133: /*
                    134:  * Return the last IRQ that caused an interrupt.
                    135:  */
                    136: int
                    137: autoirq_report(waittime)
                    138:        int waittime;
                    139: {
                    140:        int i;
                    141:        int timeout = jiffies + waittime;
                    142:        int boguscount = (waittime * loops_per_sec) / 100;
                    143: 
                    144:        /*
                    145:         * Hang out at least <waittime>
                    146:         * jiffies waiting for the IRQ.
                    147:         */
                    148:        while (timeout > jiffies && --boguscount > 0)
                    149:                if (irq_number)
                    150:                        break;
                    151: 
                    152:        /*
                    153:         * Retract the IRQ handlers that we handled.
                    154:         */
                    155:        for (i = 0; i < 16; i++) {
                    156:                if (test_bit(i, (void *)&irq_handled))
                    157:                        free_irq(i);
                    158:        }
                    159: 
                    160:        return (irq_number);
                    161: }

unix.superglobalmegacorp.com

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