patch-2.1.114 linux/arch/i386/kernel/io_apic.c
Next file: linux/arch/i386/kernel/irq.h
Previous file: linux/arch/i386/kernel/bios32.c
Back to the patch index
Back to the overall index
- Lines: 706
- Date:
Mon Aug 3 11:14:41 1998
- Orig file:
v2.1.113/linux/arch/i386/kernel/io_apic.c
- Orig date:
Tue Jul 28 14:21:07 1998
diff -u --recursive --new-file v2.1.113/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -7,49 +7,24 @@
* patches and reporting/debugging problems patiently!
*/
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/mc146818rtc.h>
-#include <asm/i82489.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
-#include <asm/pgtable.h>
-#include <asm/bitops.h>
-#include <asm/pgtable.h>
-#include <asm/smp.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include "irq.h"
/*
- * volatile is justified in this case, it might change
- * spontaneously, GCC should not cache it
+ * volatile is justified in this case, IO-APIC register contents
+ * might change spontaneously, GCC should not cache it
*/
#define IO_APIC_BASE ((volatile int *)fix_to_virt(FIX_IO_APIC_BASE))
-enum mp_irq_source_types {
- mp_INT = 0,
- mp_NMI = 1,
- mp_SMI = 2,
- mp_ExtINT = 3
-};
-
-enum ioapic_irq_destination_types {
- dest_Fixed = 0,
- dest_LowestPrio = 1,
- dest_ExtINT = 7
-};
-
/*
* The structure of the IO-APIC:
*/
+
struct IO_APIC_reg_00 {
__u32 __reserved_2 : 24,
ID : 4,
@@ -69,6 +44,17 @@
__reserved_1 : 4;
} __attribute__ ((packed));
+/*
+ * # of IRQ routing registers
+ */
+int nr_ioapic_registers = 0;
+
+enum ioapic_irq_destination_types {
+ dest_Fixed = 0,
+ dest_LowestPrio = 1,
+ dest_ExtINT = 7
+};
+
struct IO_APIC_route_entry {
__u32 vector : 8,
delivery_mode : 3, /* 000: FIXED
@@ -97,13 +83,17 @@
} __attribute__ ((packed));
-#define UNEXPECTED_IO_APIC() \
- { \
- printk(" WARNING: unexpected IO-APIC, please mail\n"); \
- printk(" to linux-smp@vger.rutgers.edu\n"); \
- }
+/*
+ * MP-BIOS irq configuration table structures:
+ */
+
+enum mp_irq_source_types {
+ mp_INT = 0,
+ mp_NMI = 1,
+ mp_SMI = 2,
+ mp_ExtINT = 3
+};
-int nr_ioapic_registers = 0; /* # of IRQ routing registers */
int mp_irq_entries = 0; /* # of MP IRQ source entries */
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
@@ -116,13 +106,13 @@
*/
static int irq_2_pin[NR_IRQS];
-unsigned int io_apic_read (unsigned int reg)
+static inline unsigned int io_apic_read(unsigned int reg)
{
*IO_APIC_BASE = reg;
return *(IO_APIC_BASE+4);
}
-void io_apic_write (unsigned int reg, unsigned int value)
+static inline void io_apic_write(unsigned int reg, unsigned int value)
{
*IO_APIC_BASE = reg;
*(IO_APIC_BASE+4) = value;
@@ -141,57 +131,57 @@
* We disable IO-APIC IRQs by setting their 'destination CPU mask' to
* zero. Trick, trick.
*/
-void disable_IO_APIC_irq(unsigned int irq)
+static inline void disable_IO_APIC_irq(unsigned int irq)
{
int pin = irq_2_pin[irq];
struct IO_APIC_route_entry entry;
if (pin != -1) {
- *(((int *)&entry)+1) = io_apic_read(0x11+pin*2);
+ *(((int *)&entry) + 1) = io_apic_read(0x11 + pin * 2);
entry.dest.logical.logical_dest = 0x0;
- io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(0x11 + 2 * pin, *(((int *)&entry) + 1));
io_apic_sync();
}
}
-void enable_IO_APIC_irq(unsigned int irq)
+static inline void enable_IO_APIC_irq(unsigned int irq)
{
int pin = irq_2_pin[irq];
struct IO_APIC_route_entry entry;
if (pin != -1) {
- *(((int *)&entry)+1) = io_apic_read(0x11+pin*2);
+ *(((int *)&entry) + 1) = io_apic_read(0x11 + pin * 2);
entry.dest.logical.logical_dest = 0xff;
- io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(0x11 + 2 * pin, *(((int *)&entry) + 1));
}
}
-void mask_IO_APIC_irq(unsigned int irq)
+static inline void mask_IO_APIC_irq(unsigned int irq)
{
int pin = irq_2_pin[irq];
struct IO_APIC_route_entry entry;
if (pin != -1) {
- *(((int *)&entry)+0) = io_apic_read(0x10+pin*2);
+ *(((int *)&entry) + 0) = io_apic_read(0x10 + pin * 2);
entry.mask = 1;
- io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(0x10 + 2 * pin, *(((int *)&entry) + 0));
io_apic_sync();
}
}
-void unmask_IO_APIC_irq(unsigned int irq)
+static inline void unmask_IO_APIC_irq(unsigned int irq)
{
int pin = irq_2_pin[irq];
struct IO_APIC_route_entry entry;
if (pin != -1) {
- *(((int *)&entry)+0) = io_apic_read(0x10+pin*2);
+ *(((int *)&entry) + 0) = io_apic_read(0x10 + pin * 2);
entry.mask = 0;
- io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(0x10 + 2 * pin, *(((int *)&entry) + 0));
}
}
-void clear_IO_APIC_pin (unsigned int pin)
+static void __init clear_IO_APIC_pin(unsigned int pin)
{
struct IO_APIC_route_entry entry;
@@ -200,8 +190,8 @@
*/
memset(&entry, 0, sizeof(entry));
entry.mask = 1;
- io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
- io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(0x10 + 2 * pin, *(((int *)&entry) + 0));
+ io_apic_write(0x11 + 2 * pin, *(((int *)&entry) + 1));
}
@@ -214,30 +204,30 @@
int pirq_entries [MAX_PIRQS];
int pirqs_enabled;
-__initfunc(void ioapic_pirq_setup(char *str, int *ints))
+void __init ioapic_pirq_setup(char *str, int *ints)
{
int i, max;
- for (i=0; i<MAX_PIRQS; i++)
- pirq_entries[i]=-1;
+ for (i = 0; i < MAX_PIRQS; i++)
+ pirq_entries[i] = -1;
if (!ints) {
- pirqs_enabled=0;
- printk("PIRQ redirection SETUP, trusting MP-BIOS.\n");
+ pirqs_enabled = 0;
+ printk("PIRQ redirection, trusting MP-BIOS.\n");
} else {
- pirqs_enabled=1;
- printk("PIRQ redirection SETUP, working around broken MP-BIOS.\n");
+ pirqs_enabled = 1;
+ printk("PIRQ redirection, working around broken MP-BIOS.\n");
max = MAX_PIRQS;
if (ints[0] < MAX_PIRQS)
max = ints[0];
- for (i=0; i < max; i++) {
+ for (i = 0; i < max; i++) {
printk("... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
/*
* PIRQs are mapped upside down, usually.
*/
- pirq_entries[MAX_PIRQS-i-1]=ints[i+1];
+ pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
}
}
}
@@ -245,11 +235,11 @@
/*
* Find the IRQ entry number of a certain pin.
*/
-__initfunc(static int find_irq_entry(int pin, int type))
+static int __init find_irq_entry(int pin, int type)
{
int i;
- for (i=0; i<mp_irq_entries; i++)
+ for (i = 0; i < mp_irq_entries; i++)
if ( (mp_irqs[i].mpc_irqtype == type) &&
(mp_irqs[i].mpc_dstirq == pin))
@@ -261,11 +251,11 @@
/*
* Find the pin to which IRQ0 (ISA) is connected
*/
-__initfunc(int find_timer_pin (int type))
+static int __init find_timer_pin(int type)
{
int i;
- for (i=0; i<mp_irq_entries; i++) {
+ for (i = 0; i < mp_irq_entries; i++) {
int lbus = mp_irqs[i].mpc_srcbus;
if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA) &&
@@ -281,11 +271,11 @@
* Find a specific PCI IRQ entry.
* Not an initfunc, possibly needed by modules
*/
-int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
{
int i;
- for (i=0; i<mp_irq_entries; i++) {
+ for (i = 0; i < mp_irq_entries; i++) {
int lbus = mp_irqs[i].mpc_srcbus;
if (IO_APIC_IRQ(mp_irqs[i].mpc_dstirq) &&
@@ -308,7 +298,7 @@
* to be accepted. Yes, ugh.
*/
-static int MPBIOS_polarity(int idx)
+static int __init MPBIOS_polarity(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int polarity;
@@ -367,8 +357,7 @@
return polarity;
}
-
-static int MPBIOS_trigger(int idx)
+static int __init MPBIOS_trigger(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int trigger;
@@ -427,7 +416,7 @@
return trigger;
}
-static int trigger_flag_broken (int idx)
+static int __init trigger_flag_broken(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int polarity = MPBIOS_polarity(idx);
@@ -442,7 +431,7 @@
return 0;
}
-static int irq_polarity (int idx)
+static inline int irq_polarity(int idx)
{
/*
* There are no known BIOS bugs wrt polarity. yet.
@@ -450,16 +439,16 @@
return MPBIOS_polarity(idx);
}
-static int irq_trigger (int idx)
+static inline int irq_trigger(int idx)
{
int trigger = MPBIOS_trigger(idx);
- if (trigger_flag_broken (idx))
+ if (trigger_flag_broken(idx))
trigger = 0;
return trigger;
}
-static int pin_2_irq (int idx, int pin)
+static int __init pin_2_irq(int idx, int pin)
{
int irq;
int bus = mp_irqs[idx].mpc_srcbus;
@@ -496,7 +485,7 @@
/*
* PCI IRQ command line redirection. Yes, limits are hardcoded.
*/
- if ((pin>=16) && (pin<=23)) {
+ if ((pin >= 16) && (pin <= 23)) {
if (pirq_entries[pin-16] != -1) {
if (!pirq_entries[pin-16]) {
printk("disabling PIRQ%d\n", pin-16);
@@ -510,14 +499,14 @@
return irq;
}
-int IO_APIC_irq_trigger (int irq)
+static inline int IO_APIC_irq_trigger(int irq)
{
int idx, pin;
- for (pin=0; pin<nr_ioapic_registers; pin++) {
+ for (pin = 0; pin < nr_ioapic_registers; pin++) {
idx = find_irq_entry(pin,mp_INT);
if ((idx != -1) && (irq == pin_2_irq(idx,pin)))
- return (irq_trigger(idx));
+ return irq_trigger(idx);
}
/*
* nonexistent IRQs are edge default
@@ -525,7 +514,7 @@
return 0;
}
-__initfunc(static int assign_irq_vector(int irq))
+static int __init assign_irq_vector(int irq)
{
static int current_vector = IRQ0_TRAP_VECTOR, offset = 0;
if (IO_APIC_VECTOR(irq) > 0)
@@ -541,14 +530,14 @@
return current_vector;
}
-__initfunc(void setup_IO_APIC_irqs (void))
+void __init setup_IO_APIC_irqs(void)
{
struct IO_APIC_route_entry entry;
- int pin, idx, bus, irq, first_notcon=1;
+ int pin, idx, bus, irq, first_notcon = 1;
printk("init IO_APIC IRQs\n");
- for (pin=0; pin<nr_ioapic_registers; pin++) {
+ for (pin = 0; pin < nr_ioapic_registers; pin++) {
/*
* add it to the IO-APIC irq-routing table:
@@ -564,7 +553,7 @@
if (idx == -1) {
if (first_notcon) {
printk(" IO-APIC pin %d", pin);
- first_notcon=0;
+ first_notcon = 0;
} else
printk(", %d", pin);
continue;
@@ -594,7 +583,7 @@
printk(" not connected.\n");
}
-__initfunc(void setup_IO_APIC_irq_ISA_default (unsigned int irq))
+void __init setup_IO_APIC_irq_ISA_default(unsigned int irq)
{
struct IO_APIC_route_entry entry;
@@ -610,8 +599,8 @@
entry.vector = assign_irq_vector(irq);
- entry.polarity=0;
- entry.trigger=0;
+ entry.polarity = 0;
+ entry.trigger = 0;
io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
@@ -620,7 +609,7 @@
/*
* Set up a certain pin as ExtINT delivered interrupt
*/
-__initfunc(void setup_ExtINT_pin (unsigned int pin))
+void __init setup_ExtINT_pin(unsigned int pin)
{
struct IO_APIC_route_entry entry;
@@ -636,14 +625,20 @@
entry.vector = 0; /* it's ignored */
- entry.polarity=0;
- entry.trigger=0;
+ entry.polarity = 0;
+ entry.trigger = 0;
io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
}
-void print_IO_APIC (void)
+void __init UNEXPECTED_IO_APIC(void)
+{
+ printk(" WARNING: unexpected IO-APIC, please mail\n");
+ printk(" to linux-smp@vger.rutgers.edu\n");
+}
+
+void __init print_IO_APIC(void)
{
int i;
struct IO_APIC_reg_00 reg_00;
@@ -695,7 +690,7 @@
printk(" NR Log Phy ");
printk("Mask Trig IRR Pol Stat Dest Deli Vect: \n");
- for (i=0; i<=reg_01.entries; i++) {
+ for (i = 0; i <= reg_01.entries; i++) {
struct IO_APIC_route_entry entry;
*(((int *)&entry)+0) = io_apic_read(0x10+i*2);
@@ -720,7 +715,7 @@
}
printk("IRQ to pin mappings:\n");
- for (i=0; i<NR_IRQS; i++)
+ for (i = 0; i < NR_IRQS; i++)
printk("%d->%d ", i, irq_2_pin[i]);
printk("\n");
@@ -729,15 +724,15 @@
return;
}
-__initfunc(static void init_sym_mode (void))
+static void __init init_sym_mode(void)
{
int i, pin;
- for (i=0; i<NR_IRQS; i++)
+ for (i = 0; i < NR_IRQS; i++)
irq_2_pin[i] = -1;
if (!pirqs_enabled)
- for (i=0; i<MAX_PIRQS; i++)
- pirq_entries[i]=-1;
+ for (i = 0; i < MAX_PIRQS; i++)
+ pirq_entries[i] =- 1;
printk("enabling symmetric IO mode... ");
@@ -759,18 +754,18 @@
/*
* Do not trust the IO-APIC being empty at bootup
*/
- for (pin=0; pin<nr_ioapic_registers; pin++)
- clear_IO_APIC_pin (pin);
+ for (pin = 0; pin < nr_ioapic_registers; pin++)
+ clear_IO_APIC_pin(pin);
}
/*
* Not an initfunc, needed by the reboot code
*/
-void init_pic_mode (void)
+void init_pic_mode(void)
{
printk("disabling symmetric IO mode... ");
- outb_p (0x70, 0x22);
- outb_p (0x00, 0x23);
+ outb_p(0x70, 0x22);
+ outb_p(0x00, 0x23);
printk("...done.\n");
}
@@ -782,7 +777,7 @@
char * product_id;
};
-struct ioapic_list_entry ioapic_whitelist [] = {
+struct ioapic_list_entry __initdata ioapic_whitelist [] = {
{ "INTEL " , "PR440FX " },
{ "INTEL " , "82440FX " },
@@ -790,22 +785,22 @@
{ 0 , 0 }
};
-struct ioapic_list_entry ioapic_blacklist [] = {
+struct ioapic_list_entry __initdata ioapic_blacklist [] = {
{ "OEM00000" , "PROD00000000" },
{ 0 , 0 }
};
-__initfunc(static int in_ioapic_list (struct ioapic_list_entry * table))
+static int __init in_ioapic_list(struct ioapic_list_entry * table)
{
- for (;table->oem_id; table++)
+ for ( ; table->oem_id ; table++)
if ((!strcmp(table->oem_id,ioapic_OEM_ID)) &&
(!strcmp(table->product_id,ioapic_Product_ID)))
return 1;
return 0;
}
-__initfunc(static int ioapic_whitelisted (void))
+static int __init ioapic_whitelisted(void)
{
/*
* Right now, whitelist everything to see whether the new parsing
@@ -818,12 +813,12 @@
#endif
}
-__initfunc(static int ioapic_blacklisted (void))
+static int __init ioapic_blacklisted(void)
{
return in_ioapic_list(ioapic_blacklist);
}
-__initfunc(static void setup_ioapic_id (void))
+static void __init setup_ioapic_id(void)
{
struct IO_APIC_reg_00 reg_00;
@@ -857,11 +852,11 @@
panic("could not set ID");
}
-__initfunc(static void construct_default_ISA_mptable (void))
+static void __init construct_default_ISA_mptable(void)
{
- int i, pos=0;
+ int i, pos = 0;
- for (i=0; i<16; i++) {
+ for (i = 0; i < 16; i++) {
if (!IO_APIC_IRQ(i))
continue;
@@ -903,14 +898,11 @@
* - if this function detects that timer IRQs are defunct, then we fall
* back to ISA timer IRQs
*/
-__initfunc(static int timer_irq_works (void))
+static int __init timer_irq_works(void)
{
- unsigned int t1=jiffies;
- unsigned long flags;
+ unsigned int t1 = jiffies;
- save_flags(flags);
sti();
-
udelay(10*10000);
if (jiffies-t1>1)
@@ -919,8 +911,6 @@
return 0;
}
-#ifdef __SMP__
-
/*
* In the SMP+IOAPIC case it might happen that there are an unspecified
* number of pending IRQ events unhandled. These cases are very rare,
@@ -928,7 +918,7 @@
* better to do it this way as thus we do not have to be aware of
* 'pending' interrupts in the IRQ path, except at this point.
*/
-static inline void self_IPI (unsigned int irq)
+static inline void self_IPI(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
@@ -1023,8 +1013,8 @@
irq_exit(cpu, irq);
}
-static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
- struct pt_regs * regs)
+static void do_level_ioapic_IRQ(unsigned int irq, int cpu,
+ struct pt_regs * regs)
{
irq_desc_t *desc = irq_desc + irq;
struct irqaction * action;
@@ -1095,7 +1085,7 @@
disable_level_ioapic_irq
};
-void init_IO_APIC_traps(void)
+static inline void init_IO_APIC_traps(void)
{
int i;
/*
@@ -1124,7 +1114,6 @@
}
}
}
-#endif
/*
* This code may look a bit paranoid, but it's supposed to cooperate with
@@ -1132,38 +1121,38 @@
* is so screwy. Thanks to Brian Perkins for testing/hacking this beast
* fanatically on his truly buggy board.
*/
-__initfunc(static void check_timer (void))
+static inline void check_timer(void)
{
int pin1, pin2;
- pin1 = find_timer_pin (mp_INT);
- pin2 = find_timer_pin (mp_ExtINT);
+ pin1 = find_timer_pin(mp_INT);
+ pin2 = find_timer_pin(mp_ExtINT);
- if (!timer_irq_works ()) {
+ if (!timer_irq_works()) {
if (pin1 != -1)
printk("..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
printk("...trying to set up timer as ExtINT... ");
if (pin2 != -1) {
printk(".. (found pin %d) ...", pin2);
- setup_ExtINT_pin (pin2);
+ setup_ExtINT_pin(pin2);
make_8259A_irq(0);
}
- if (!timer_irq_works ()) {
+ if (!timer_irq_works()) {
printk(" failed.\n");
printk("...trying to set up timer as BP IRQ...");
/*
* Just in case ...
*/
if (pin1 != -1)
- clear_IO_APIC_pin (pin1);
+ clear_IO_APIC_pin(pin1);
if (pin2 != -1)
- clear_IO_APIC_pin (pin2);
+ clear_IO_APIC_pin(pin2);
make_8259A_irq(0);
- if (!timer_irq_works ()) {
+ if (!timer_irq_works()) {
printk(" failed.\n");
panic("IO-APIC + timer doesn't work!");
}
@@ -1172,7 +1161,7 @@
}
}
-__initfunc(void setup_IO_APIC (void))
+void __init setup_IO_APIC(void)
{
init_sym_mode();
@@ -1216,7 +1205,7 @@
* Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
* mptable:
*/
- setup_IO_APIC_irqs ();
+ setup_IO_APIC_irqs();
init_IRQ_SMP();
check_timer();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov