diff options
author | bde <bde@FreeBSD.org> | 1998-05-31 10:53:55 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-05-31 10:53:55 +0000 |
commit | ec6c6de5c612defe38320b5ec39ff98ed7c8ac7c (patch) | |
tree | 1e669cd7096649a4ebb83bcdc51c83f18faebd57 /sys | |
parent | ca4b05419a6136ad127441809357f724776e3303 (diff) | |
download | FreeBSD-src-ec6c6de5c612defe38320b5ec39ff98ed7c8ac7c.zip FreeBSD-src-ec6c6de5c612defe38320b5ec39ff98ed7c8ac7c.tar.gz |
Converted the ICU-level interrupt tests (3, 5 and 8) in sioprobe() into
a test of the irq number, and made failure of this test non-fatal.
Removed related unused complications for the APIC_IO case. Removed the
no-test3 flag.
Deverbosified the failure messages for the other tests. Removed the
per-port verbose flag - just use the general verbose flag.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/isa/intr_machdep.c | 57 | ||||
-rw-r--r-- | sys/amd64/isa/intr_machdep.h | 7 | ||||
-rw-r--r-- | sys/amd64/isa/nmi.c | 57 | ||||
-rw-r--r-- | sys/dev/sio/sio.c | 49 | ||||
-rw-r--r-- | sys/i386/isa/intr_machdep.c | 57 | ||||
-rw-r--r-- | sys/i386/isa/intr_machdep.h | 7 | ||||
-rw-r--r-- | sys/i386/isa/nmi.c | 57 | ||||
-rw-r--r-- | sys/i386/isa/sio.c | 49 | ||||
-rw-r--r-- | sys/isa/sio.c | 49 |
9 files changed, 125 insertions, 264 deletions
diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index 12e9e8e..7e5363f 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.9 1998/03/03 22:56:29 tegge Exp $ + * $Id: intr_machdep.c,v 1.10 1998/05/17 21:15:18 tegge Exp $ */ #include "opt_auto_eoi.h" @@ -268,57 +268,20 @@ isa_strayintr(d) } /* - * Return nonzero if a (masked) irq is pending for a given device. + * Return a bitmap of the current interrupt requests. This is 8259-specific + * and is only suitable for use at probe time. */ -#if defined(APIC_IO) - -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ -#ifdef FAST_HI -/* XXX not quite right for >1 IO APIC yet */ - if (dvp->id_ri_flags & RI_FAST) - /* read APIC IRR containing the FAST INTerrupts */ - return ((lapic.irr3 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; - else -#endif /* FAST_HI */ - /* read APIC IRR containing the SLOW INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; -} - -/* - * an 8259 specific routine, - * for use by boot probes in certain device drivers. - */ -int -icu_irq_pending(dvp) - struct isa_device *dvp; +intrmask_t +isa_irq_pending() { - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); -} - -#else /* APIC_IO */ + u_char irr1; + u_char irr2; -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); + irr1 = inb(IO_ICU1); + irr2 = inb(IO_ICU2); + return ((irr2 << 8) | irr1); } -#endif /* APIC_IO */ - int update_intr_masks(void) { diff --git a/sys/amd64/isa/intr_machdep.h b/sys/amd64/isa/intr_machdep.h index 97122e6..dc8f900 100644 --- a/sys/amd64/isa/intr_machdep.h +++ b/sys/amd64/isa/intr_machdep.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: intr_machdep.h,v 1.10 1998/03/03 20:55:24 tegge Exp $ + * $Id: intr_machdep.h,v 1.11 1998/03/03 22:56:30 tegge Exp $ */ #ifndef _I386_ISA_INTR_MACHDEP_H_ @@ -190,10 +190,7 @@ inthand_t struct isa_device; void isa_defaultirq __P((void)); -int isa_irq_pending __P((struct isa_device *dvp)); -#if defined(SMP) || defined(APIC_IO) -int icu_irq_pending __P((struct isa_device *dvp)); -#endif +intrmask_t isa_irq_pending __P((void)); int isa_nmi __P((int cd)); void update_intrname __P((int intr, int device_id)); int icu_setup __P((int intr, inthand2_t *func, void *arg, diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index 12e9e8e..7e5363f 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.9 1998/03/03 22:56:29 tegge Exp $ + * $Id: intr_machdep.c,v 1.10 1998/05/17 21:15:18 tegge Exp $ */ #include "opt_auto_eoi.h" @@ -268,57 +268,20 @@ isa_strayintr(d) } /* - * Return nonzero if a (masked) irq is pending for a given device. + * Return a bitmap of the current interrupt requests. This is 8259-specific + * and is only suitable for use at probe time. */ -#if defined(APIC_IO) - -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ -#ifdef FAST_HI -/* XXX not quite right for >1 IO APIC yet */ - if (dvp->id_ri_flags & RI_FAST) - /* read APIC IRR containing the FAST INTerrupts */ - return ((lapic.irr3 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; - else -#endif /* FAST_HI */ - /* read APIC IRR containing the SLOW INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; -} - -/* - * an 8259 specific routine, - * for use by boot probes in certain device drivers. - */ -int -icu_irq_pending(dvp) - struct isa_device *dvp; +intrmask_t +isa_irq_pending() { - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); -} - -#else /* APIC_IO */ + u_char irr1; + u_char irr2; -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); + irr1 = inb(IO_ICU1); + irr2 = inb(IO_ICU2); + return ((irr2 << 8) | irr1); } -#endif /* APIC_IO */ - int update_intr_masks(void) { diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index aa8641a..c122213 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.201 1998/05/13 07:26:55 phk Exp $ + * $Id: sio.c,v 1.202 1998/05/20 06:46:58 phk Exp $ */ #include "opt_comconsole.h" @@ -104,16 +104,6 @@ #define enable_intr() COM_ENABLE_INTR() #endif /* SMP */ -#ifdef APIC_IO -/* - * INTs are masked in the (global) IO APIC, - * but the IRR register is in each LOCAL APIC, - * so we would have to unmask the INT to be able to "see INT pending". - * So instead we just look in the 8259 ICU. - */ -#define isa_irq_pending icu_irq_pending -#endif /* APIC_IO */ - #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ #define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE) #define RS_IBUFSIZE 256 @@ -140,8 +130,6 @@ #define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40) #define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08) #define COM_NOFIFO(dev) ((dev)->id_flags & 0x02) -#define COM_VERBOSE(dev) ((dev)->id_flags & 0x80) -#define COM_NOTST3(dev) ((dev)->id_flags & 0x10000) #define COM_ST16650A(dev) ((dev)->id_flags & 0x20000) #define COM_C_NOPROBE (0x40000) #define COM_NOPROBE(dev) ((dev)->id_flags & COM_C_NOPROBE) @@ -587,6 +575,8 @@ sioprobe(dev) int fn; struct isa_device *idev; Port_t iobase; + intrmask_t irqmap[4]; + intrmask_t irqs; u_char mcr_image; int result; struct isa_device *xdev; @@ -678,6 +668,8 @@ sioprobe(dev) /* EXTRA DELAY? */ outb(iobase + com_mcr, mcr_image); outb(iobase + com_ier, 0); + DELAY(1000); /* XXX */ + irqmap[0] = isa_irq_pending(); /* * Attempt to set loopback mode so that we can send a null byte @@ -759,12 +751,10 @@ sioprobe(dev) failures[1] = inb(iobase + com_ier) - IER_ETXRDY; failures[2] = inb(iobase + com_mcr) - mcr_image; DELAY(10000); /* Some internal modems need this time */ - if (idev->id_irq != 0 && !COM_NOTST3(idev)) - failures[3] = isa_irq_pending(idev) ? 0 : 1; + irqmap[1] = isa_irq_pending(); failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY; DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[5] = isa_irq_pending(idev) ? 1 : 0; + irqmap[2] = isa_irq_pending(); failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; /* @@ -780,20 +770,35 @@ sioprobe(dev) outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */ failures[7] = inb(iobase + com_ier); DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[8] = isa_irq_pending(idev) ? 1 : 0; + irqmap[3] = isa_irq_pending(); failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; enable_intr(); + /* XXX the magic mask is to discard transient (clock) irqs. */ + irqs = irqmap[1] & ~irqmap[0] & ~0x0105; + if (irqs != idev->id_irq) + printf( + "sio%d: probed irq %d does not match configured irq %d\n", + ffs(irqs) - 1, ffs(idev->id_irq) - 1); + if (bootverbose) + printf("sio%d: irq maps: %04x %04x %04x %04x\n", + dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]); + result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) if (failures[fn]) { outb(iobase + com_mcr, 0); result = 0; - if (COM_VERBOSE(dev)) - printf("sio%d: probe test %d failed\n", - dev->id_unit, fn); + if (bootverbose) { + printf("sio%d: probe failed test(s):", + dev->id_unit); + for (fn = 0; fn < sizeof failures; ++fn) + if (failures[fn]) + printf(" %d", fn); + printf("\n"); + } + break; } return (result); } diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index 12e9e8e..7e5363f 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.9 1998/03/03 22:56:29 tegge Exp $ + * $Id: intr_machdep.c,v 1.10 1998/05/17 21:15:18 tegge Exp $ */ #include "opt_auto_eoi.h" @@ -268,57 +268,20 @@ isa_strayintr(d) } /* - * Return nonzero if a (masked) irq is pending for a given device. + * Return a bitmap of the current interrupt requests. This is 8259-specific + * and is only suitable for use at probe time. */ -#if defined(APIC_IO) - -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ -#ifdef FAST_HI -/* XXX not quite right for >1 IO APIC yet */ - if (dvp->id_ri_flags & RI_FAST) - /* read APIC IRR containing the FAST INTerrupts */ - return ((lapic.irr3 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; - else -#endif /* FAST_HI */ - /* read APIC IRR containing the SLOW INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; -} - -/* - * an 8259 specific routine, - * for use by boot probes in certain device drivers. - */ -int -icu_irq_pending(dvp) - struct isa_device *dvp; +intrmask_t +isa_irq_pending() { - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); -} - -#else /* APIC_IO */ + u_char irr1; + u_char irr2; -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); + irr1 = inb(IO_ICU1); + irr2 = inb(IO_ICU2); + return ((irr2 << 8) | irr1); } -#endif /* APIC_IO */ - int update_intr_masks(void) { diff --git a/sys/i386/isa/intr_machdep.h b/sys/i386/isa/intr_machdep.h index 97122e6..dc8f900 100644 --- a/sys/i386/isa/intr_machdep.h +++ b/sys/i386/isa/intr_machdep.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: intr_machdep.h,v 1.10 1998/03/03 20:55:24 tegge Exp $ + * $Id: intr_machdep.h,v 1.11 1998/03/03 22:56:30 tegge Exp $ */ #ifndef _I386_ISA_INTR_MACHDEP_H_ @@ -190,10 +190,7 @@ inthand_t struct isa_device; void isa_defaultirq __P((void)); -int isa_irq_pending __P((struct isa_device *dvp)); -#if defined(SMP) || defined(APIC_IO) -int icu_irq_pending __P((struct isa_device *dvp)); -#endif +intrmask_t isa_irq_pending __P((void)); int isa_nmi __P((int cd)); void update_intrname __P((int intr, int device_id)); int icu_setup __P((int intr, inthand2_t *func, void *arg, diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index 12e9e8e..7e5363f 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.9 1998/03/03 22:56:29 tegge Exp $ + * $Id: intr_machdep.c,v 1.10 1998/05/17 21:15:18 tegge Exp $ */ #include "opt_auto_eoi.h" @@ -268,57 +268,20 @@ isa_strayintr(d) } /* - * Return nonzero if a (masked) irq is pending for a given device. + * Return a bitmap of the current interrupt requests. This is 8259-specific + * and is only suitable for use at probe time. */ -#if defined(APIC_IO) - -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ -#ifdef FAST_HI -/* XXX not quite right for >1 IO APIC yet */ - if (dvp->id_ri_flags & RI_FAST) - /* read APIC IRR containing the FAST INTerrupts */ - return ((lapic.irr3 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; - else -#endif /* FAST_HI */ - /* read APIC IRR containing the SLOW INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; -} - -/* - * an 8259 specific routine, - * for use by boot probes in certain device drivers. - */ -int -icu_irq_pending(dvp) - struct isa_device *dvp; +intrmask_t +isa_irq_pending() { - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); -} - -#else /* APIC_IO */ + u_char irr1; + u_char irr2; -int -isa_irq_pending(dvp) - struct isa_device *dvp; -{ - unsigned id_irq; - id_irq = dvp->id_irq; - if (id_irq & 0xff) - return (inb(IO_ICU1) & id_irq); - return (inb(IO_ICU2) & (id_irq >> 8)); + irr1 = inb(IO_ICU1); + irr2 = inb(IO_ICU2); + return ((irr2 << 8) | irr1); } -#endif /* APIC_IO */ - int update_intr_masks(void) { diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c index aa8641a..c122213 100644 --- a/sys/i386/isa/sio.c +++ b/sys/i386/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.201 1998/05/13 07:26:55 phk Exp $ + * $Id: sio.c,v 1.202 1998/05/20 06:46:58 phk Exp $ */ #include "opt_comconsole.h" @@ -104,16 +104,6 @@ #define enable_intr() COM_ENABLE_INTR() #endif /* SMP */ -#ifdef APIC_IO -/* - * INTs are masked in the (global) IO APIC, - * but the IRR register is in each LOCAL APIC, - * so we would have to unmask the INT to be able to "see INT pending". - * So instead we just look in the 8259 ICU. - */ -#define isa_irq_pending icu_irq_pending -#endif /* APIC_IO */ - #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ #define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE) #define RS_IBUFSIZE 256 @@ -140,8 +130,6 @@ #define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40) #define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08) #define COM_NOFIFO(dev) ((dev)->id_flags & 0x02) -#define COM_VERBOSE(dev) ((dev)->id_flags & 0x80) -#define COM_NOTST3(dev) ((dev)->id_flags & 0x10000) #define COM_ST16650A(dev) ((dev)->id_flags & 0x20000) #define COM_C_NOPROBE (0x40000) #define COM_NOPROBE(dev) ((dev)->id_flags & COM_C_NOPROBE) @@ -587,6 +575,8 @@ sioprobe(dev) int fn; struct isa_device *idev; Port_t iobase; + intrmask_t irqmap[4]; + intrmask_t irqs; u_char mcr_image; int result; struct isa_device *xdev; @@ -678,6 +668,8 @@ sioprobe(dev) /* EXTRA DELAY? */ outb(iobase + com_mcr, mcr_image); outb(iobase + com_ier, 0); + DELAY(1000); /* XXX */ + irqmap[0] = isa_irq_pending(); /* * Attempt to set loopback mode so that we can send a null byte @@ -759,12 +751,10 @@ sioprobe(dev) failures[1] = inb(iobase + com_ier) - IER_ETXRDY; failures[2] = inb(iobase + com_mcr) - mcr_image; DELAY(10000); /* Some internal modems need this time */ - if (idev->id_irq != 0 && !COM_NOTST3(idev)) - failures[3] = isa_irq_pending(idev) ? 0 : 1; + irqmap[1] = isa_irq_pending(); failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY; DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[5] = isa_irq_pending(idev) ? 1 : 0; + irqmap[2] = isa_irq_pending(); failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; /* @@ -780,20 +770,35 @@ sioprobe(dev) outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */ failures[7] = inb(iobase + com_ier); DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[8] = isa_irq_pending(idev) ? 1 : 0; + irqmap[3] = isa_irq_pending(); failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; enable_intr(); + /* XXX the magic mask is to discard transient (clock) irqs. */ + irqs = irqmap[1] & ~irqmap[0] & ~0x0105; + if (irqs != idev->id_irq) + printf( + "sio%d: probed irq %d does not match configured irq %d\n", + ffs(irqs) - 1, ffs(idev->id_irq) - 1); + if (bootverbose) + printf("sio%d: irq maps: %04x %04x %04x %04x\n", + dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]); + result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) if (failures[fn]) { outb(iobase + com_mcr, 0); result = 0; - if (COM_VERBOSE(dev)) - printf("sio%d: probe test %d failed\n", - dev->id_unit, fn); + if (bootverbose) { + printf("sio%d: probe failed test(s):", + dev->id_unit); + for (fn = 0; fn < sizeof failures; ++fn) + if (failures[fn]) + printf(" %d", fn); + printf("\n"); + } + break; } return (result); } diff --git a/sys/isa/sio.c b/sys/isa/sio.c index aa8641a..c122213 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.201 1998/05/13 07:26:55 phk Exp $ + * $Id: sio.c,v 1.202 1998/05/20 06:46:58 phk Exp $ */ #include "opt_comconsole.h" @@ -104,16 +104,6 @@ #define enable_intr() COM_ENABLE_INTR() #endif /* SMP */ -#ifdef APIC_IO -/* - * INTs are masked in the (global) IO APIC, - * but the IRR register is in each LOCAL APIC, - * so we would have to unmask the INT to be able to "see INT pending". - * So instead we just look in the 8259 ICU. - */ -#define isa_irq_pending icu_irq_pending -#endif /* APIC_IO */ - #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ #define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE) #define RS_IBUFSIZE 256 @@ -140,8 +130,6 @@ #define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40) #define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08) #define COM_NOFIFO(dev) ((dev)->id_flags & 0x02) -#define COM_VERBOSE(dev) ((dev)->id_flags & 0x80) -#define COM_NOTST3(dev) ((dev)->id_flags & 0x10000) #define COM_ST16650A(dev) ((dev)->id_flags & 0x20000) #define COM_C_NOPROBE (0x40000) #define COM_NOPROBE(dev) ((dev)->id_flags & COM_C_NOPROBE) @@ -587,6 +575,8 @@ sioprobe(dev) int fn; struct isa_device *idev; Port_t iobase; + intrmask_t irqmap[4]; + intrmask_t irqs; u_char mcr_image; int result; struct isa_device *xdev; @@ -678,6 +668,8 @@ sioprobe(dev) /* EXTRA DELAY? */ outb(iobase + com_mcr, mcr_image); outb(iobase + com_ier, 0); + DELAY(1000); /* XXX */ + irqmap[0] = isa_irq_pending(); /* * Attempt to set loopback mode so that we can send a null byte @@ -759,12 +751,10 @@ sioprobe(dev) failures[1] = inb(iobase + com_ier) - IER_ETXRDY; failures[2] = inb(iobase + com_mcr) - mcr_image; DELAY(10000); /* Some internal modems need this time */ - if (idev->id_irq != 0 && !COM_NOTST3(idev)) - failures[3] = isa_irq_pending(idev) ? 0 : 1; + irqmap[1] = isa_irq_pending(); failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY; DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[5] = isa_irq_pending(idev) ? 1 : 0; + irqmap[2] = isa_irq_pending(); failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; /* @@ -780,20 +770,35 @@ sioprobe(dev) outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */ failures[7] = inb(iobase + com_ier); DELAY(1000); /* XXX */ - if (idev->id_irq != 0) - failures[8] = isa_irq_pending(idev) ? 1 : 0; + irqmap[3] = isa_irq_pending(); failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; enable_intr(); + /* XXX the magic mask is to discard transient (clock) irqs. */ + irqs = irqmap[1] & ~irqmap[0] & ~0x0105; + if (irqs != idev->id_irq) + printf( + "sio%d: probed irq %d does not match configured irq %d\n", + ffs(irqs) - 1, ffs(idev->id_irq) - 1); + if (bootverbose) + printf("sio%d: irq maps: %04x %04x %04x %04x\n", + dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]); + result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) if (failures[fn]) { outb(iobase + com_mcr, 0); result = 0; - if (COM_VERBOSE(dev)) - printf("sio%d: probe test %d failed\n", - dev->id_unit, fn); + if (bootverbose) { + printf("sio%d: probe failed test(s):", + dev->id_unit); + for (fn = 0; fn < sizeof failures; ++fn) + if (failures[fn]) + printf(" %d", fn); + printf("\n"); + } + break; } return (result); } |