Major cleanup of the interrupt registration subsystem.
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 13 Oct 2005 00:02:48 +0000 (00:02 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 13 Oct 2005 00:02:48 +0000 (00:02 +0000)
* Collapse the separate registrations in the kernel interrupt thread and
  i386 layers into a single machine-independant kernel interrupt thread layer
  in kern/kern_intr.c.  Get rid of the i386 layer's 'MUX' code entirely.

* Have the interrupt vector assembly code (icu_vector.s and apic_vector.s)
  call a machine-independant function in the kernel interrupt thread
  layer to figure out how to process an interrupt.

* Move a lot of assembly into the new C interrupt processing function.

* Add support for INTR_MPSAFE.  If a device driver registers an interrupt
  as being MPSAFE, the Big Giant Lock will not be obtained or required.

* Temporarily just schedule the ithread if a FAST interrupt cannot be executed
  due to its serializer being locked.

* Add LWKT serialization support for a non-blocking 'try' function.

* Get rid of ointhand2_t and adjust all old ISA code to use inthand2_t.

* Supply a frame pointer as a pointer rather then embedding it on th stack.

* Allow FAST and SLOW interrupts to be mixed on the same IRQ, though this
  will not necessarily result in optimal operation.

* Remove direct APIC/ICU vector calls from the apic/icu vector assembly code.
  Everything goes through the new routine in kern/kern_intr.c now.

* Add a new flag, INTR_NOPOLL.  Interrupts registered with the flag will
  not be polled by the upcoming emergency general interrupt polling
  sysctl (e.g. ATA cannot be safely polled due to the way ATA register
  access interferes with ATA DMA).

* Remove most of the distinction in the i386 assembly layers between FAST
  and SLOW interrupts (part 1/2).

* Revamp the interrupt name array returned to userland to list multiple
  drivers associated with the same IRQ.

48 files changed:
sys/bus/cam/cam_xpt.c
sys/bus/isa/i386/isa_device.h
sys/cpu/i386/include/atomic.h
sys/dev/disk/ata/ata-all.c
sys/dev/disk/mcd/mcd.c
sys/dev/disk/wt/wt.c
sys/dev/misc/labpc/labpc.c
sys/dev/misc/spigot/spigot.c
sys/dev/misc/tw/tw.c
sys/dev/netif/cx/if_cx.c
sys/dev/netif/el/if_el.c
sys/dev/netif/ie/if_ie.c
sys/dev/netif/le/if_le.c
sys/dev/serial/cy/cy.c
sys/dev/serial/rc/rc.c
sys/dev/serial/sio/sio.c
sys/dev/serial/stl/stallion.c
sys/i386/apic/apic_vector.s
sys/i386/i386/nexus.c
sys/i386/i386/vm_machdep.c
sys/i386/icu/icu_vector.s
sys/i386/include/atomic.h
sys/i386/isa/apic_vector.s
sys/i386/isa/asc.c
sys/i386/isa/clock.c
sys/i386/isa/icu_vector.s
sys/i386/isa/intr_machdep.c
sys/i386/isa/intr_machdep.h
sys/i386/isa/vector.s
sys/kern/kern_intr.c
sys/kern/lwkt_serialize.c
sys/kern/subr_taskqueue.c
sys/opencrypto/crypto.c
sys/platform/pc32/apic/apic_vector.s
sys/platform/pc32/i386/nexus.c
sys/platform/pc32/i386/vm_machdep.c
sys/platform/pc32/icu/icu_vector.s
sys/platform/pc32/isa/apic_vector.s
sys/platform/pc32/isa/asc.c
sys/platform/pc32/isa/clock.c
sys/platform/pc32/isa/icu_vector.s
sys/platform/pc32/isa/intr_machdep.c
sys/platform/pc32/isa/intr_machdep.h
sys/platform/pc32/isa/vector.s
sys/sys/bus.h
sys/sys/interrupt.h
sys/sys/serialize.h
sys/sys/thread.h

index 9384fce..c256972 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_xpt.c,v 1.80.2.18 2002/12/09 17:31:55 gibbs Exp $
- * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.26 2005/07/17 03:49:50 dillon Exp $
+ * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.27 2005/10/13 00:02:25 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1368,8 +1368,8 @@ xpt_init(dummy)
        }
 
        /* Install our software interrupt handlers */
-       register_swi(SWI_CAMNET, swi_camnet, NULL, "swi_camnet");
-       register_swi(SWI_CAMBIO, swi_cambio, NULL, "swi_cambio");
+       register_swi(SWI_CAMNET, swi_camnet, NULL, "swi_camnet", NULL);
+       register_swi(SWI_CAMBIO, swi_cambio, NULL, "swi_cambio", NULL);
 }
 
 static cam_status
@@ -3340,8 +3340,8 @@ xpt_polled_action(union ccb *start_ccb)
           && (--timeout > 0)) {
                DELAY(1000);
                (*(sim->sim_poll))(sim);
-               swi_camnet(NULL);
-               swi_cambio(NULL);               
+               swi_camnet(NULL, NULL);
+               swi_cambio(NULL, NULL);         
        }
        
        dev->ccbq.devq_openings++;
@@ -3351,8 +3351,8 @@ xpt_polled_action(union ccb *start_ccb)
                xpt_action(start_ccb);
                while(--timeout > 0) {
                        (*(sim->sim_poll))(sim);
-                       swi_camnet(NULL);
-                       swi_cambio(NULL);
+                       swi_camnet(NULL, NULL);
+                       swi_cambio(NULL, NULL);
                        if ((start_ccb->ccb_h.status  & CAM_STATUS_MASK)
                            != CAM_REQ_INPROG)
                                break;
@@ -6170,13 +6170,13 @@ xptpoll(struct cam_sim *sim)
  */
 
 static void
-swi_camnet(void *arg)
+swi_camnet(void *arg, void *frame)
 {
        camisr(&cam_netq);
 }
 
 static void
-swi_cambio(void *arg)
+swi_cambio(void *arg, void *frame)
 {
        camisr(&cam_bioq);
 }
index bc6f856..f731738 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     from: @(#)isa_device.h  7.1 (Berkeley) 5/9/91
  * $FreeBSD: src/sys/i386/isa/isa_device.h,v 1.68 2000/01/29 18:01:10 peter Exp $
- * $DragonFly: src/sys/bus/isa/i386/isa_device.h,v 1.6 2003/11/22 19:48:32 asmodai Exp $
+ * $DragonFly: src/sys/bus/isa/i386/isa_device.h,v 1.7 2005/10/13 00:02:28 dillon Exp $
  */
 
 #ifndef _I386_ISA_ISA_DEVICE_H_
@@ -63,12 +63,7 @@ struct isa_device {
        int     id_drq;         /* DMA request */
        caddr_t id_maddr;       /* physical i/o memory address on bus (if any)*/
        int     id_msize;       /* size of i/o memory */
-       union {
-               inthand2_t *id_i;
-               ointhand2_t *id_oi;
-       } id_iu;                /* interrupt interface routine */
-#define        id_intr         id_iu.id_i
-#define        id_ointr        id_iu.id_oi
+       inthand2_t *id_intr;
        int     id_unit;        /* unit number */
        int     id_flags;       /* flags */
        int     id_enabled;     /* is device enabled */
index c7a8cfa..87f3dce 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.14 2005/08/28 15:27:05 hsu Exp $
+ * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.15 2005/10/13 00:02:46 dillon Exp $
  */
 #ifndef _MACHINE_ATOMIC_H_
 #define _MACHINE_ATOMIC_H_
@@ -182,6 +182,13 @@ atomic_poll_release_int(volatile u_int *p)
  *                             acquired state.  Returns 0 if it not
  *                             acquired, non-zero if it is.
  *
+ * atomic_intr_cond_try(P)
+ *                             Increment the request counter and attempt to
+ *                             set bit 31 to acquire the interlock.  If
+ *                             we are unable to set bit 31 the request
+ *                             counter is decremented and we return -1,
+ *                             otherwise we return 0.
+ *
  * atomic_intr_cond_enter(P, func, arg)
  *                             Increment the request counter and attempt to
  *                             set bit 31 to acquire the interlock.  If
@@ -228,6 +235,7 @@ int atomic_intr_handler_disable(atomic_intr_t *p);
 void atomic_intr_handler_enable(atomic_intr_t *p);
 int atomic_intr_handler_is_enabled(atomic_intr_t *p);
 int atomic_intr_cond_test(atomic_intr_t *p);
+int atomic_intr_cond_try(atomic_intr_t *p);
 void atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg);
 void atomic_intr_cond_exit(atomic_intr_t *p, void (*func)(void *), void *arg);
 
@@ -285,6 +293,29 @@ atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg)
                         : "ax", "cx", "dx");
 }
 
+/*
+ * Attempt to enter the interrupt condition variable.  Returns zero on
+ * success, 1 on failure.
+ */
+static __inline
+int
+atomic_intr_cond_try(atomic_intr_t *p)
+{
+       int ret;
+
+       __asm __volatile(MPLOCKED "incl %0; " \
+                        "1: ;" \
+                        "subl %%eax,%%eax; " \
+                        MPLOCKED "btsl $31,%0; jnc 2f; " \
+                        MPLOCKED "decl %0; " \
+                        "movl $1,%%eax;" \
+                        "2: ;" \
+                        : "+m" (*p), "=a"(ret) \
+                        : : "cx", "dx");
+       return (ret);
+}
+
+
 static __inline
 int
 atomic_intr_cond_test(atomic_intr_t *p)
index 590e32d..4526b36 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ata/ata-all.c,v 1.50.2.45 2003/03/12 14:47:12 sos Exp $
- * $DragonFly: src/sys/dev/disk/ata/ata-all.c,v 1.27 2005/10/12 17:35:50 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/ata/ata-all.c,v 1.28 2005/10/13 00:02:29 dillon Exp $
  */
 
 #include "opt_ata.h"
@@ -200,7 +200,13 @@ ata_attach(device_t dev)
        ata_printf(ch, -1, "unable to allocate interrupt\n");
        return ENXIO;
     }
-    if ((error = bus_setup_intr(dev, ch->r_irq, 0,
+
+    /*
+     * Traditional ata registers are sensitive to when they can be accessed
+     * in the face of e.g. ongoing DMA.  Do not allow the interrupt to be
+     * polled.
+     */
+    if ((error = bus_setup_intr(dev, ch->r_irq, INTR_NOPOLL,
                                ata_intr, ch, &ch->ih, NULL))) {
        ata_printf(ch, -1, "unable to setup interrupt\n");
        return error;
index b399295..8c32ee3 100644 (file)
@@ -41,7 +41,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/mcd.c,v 1.115 2000/01/29 16:17:34 peter Exp $
- * $DragonFly: src/sys/dev/disk/mcd/Attic/mcd.c,v 1.12 2005/06/06 22:51:54 corecode Exp $
+ * $DragonFly: src/sys/dev/disk/mcd/Attic/mcd.c,v 1.13 2005/10/13 00:02:30 dillon Exp $
  */
 static const char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
 
@@ -170,7 +170,7 @@ static      int     mcd_send(int unit, int cmd,int nretrys);
 static void    hsg2msf(int hsg, bcd_t *msf);
 static  int     msf2hsg(bcd_t *msf, int relative);
 static int     mcd_volinfo(int unit);
-static ointhand2_t     mcdintr;
+static inthand2_t      mcdintr;
 static int     mcd_waitrdy(int port,int dly);
 static timeout_t mcd_timeout;
 static         void    mcd_doread(int state, struct mcd_mbx *mbxin);
@@ -248,7 +248,7 @@ int mcd_attach(struct isa_device *dev)
        int     unit = dev->id_unit;
        struct mcd_data *cd = mcd_data + unit;
 
-       dev->id_ointr = mcdintr;
+       dev->id_intr = mcdintr;
        cd->iobase = dev->id_iobase;
        cd->flags |= MCDINIT;
        callout_init(&cd->callout);
@@ -963,8 +963,7 @@ mcd_volinfo(int unit)
 }
 
 static void
-mcdintr(unit)
-       int unit;
+mcdintr(void *dummy)
 {
        MCD_TRACE("stray interrupt\n");
 }
index 8344492..ca3d466 100644 (file)
@@ -21,7 +21,7 @@
  *
  * Version 1.3, Thu Nov 11 12:09:13 MSK 1993
  * $FreeBSD: src/sys/i386/isa/wt.c,v 1.57.2.1 2000/08/08 19:49:53 peter Exp $
- * $DragonFly: src/sys/dev/disk/wt/wt.c,v 1.10 2005/06/16 15:53:38 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/wt/wt.c,v 1.11 2005/10/13 00:02:31 dillon Exp $
  *
  */
 
@@ -170,7 +170,7 @@ static void wtclock (wtinfo_t *t);
 static int wtreset (wtinfo_t *t);
 static int wtsense (wtinfo_t *t, int verb, int ignor);
 static int wtstatus (wtinfo_t *t);
-static ointhand2_t wtintr;
+static inthand2_t wtintr;
 static void wtrewind (wtinfo_t *t);
 static int wtreadfm (wtinfo_t *t);
 static int wtwritefm (wtinfo_t *t);
@@ -257,7 +257,7 @@ wtattach (struct isa_device *id)
 {
        wtinfo_t *t = wttab + id->id_unit;
 
-       id->id_ointr = wtintr;
+       id->id_intr = wtintr;
        if (t->type == ARCHIVE) {
                printf ("wt%d: type <Archive>\n", t->unit);
                outb (t->RDMAPORT, 0);          /* reset dma */
@@ -584,8 +584,9 @@ xit:    biodone (bp);
  * Interrupt routine.
  */
 static void
-wtintr (int u)
+wtintr (void *arg)
 {
+       int u = (int)arg;
        wtinfo_t *t = wttab + u;
        unsigned char s;
 
index 4e5ef6d..635d192 100644 (file)
@@ -39,7 +39,7 @@
  * dufault@hda.com
  *
  * $FreeBSD: src/sys/i386/isa/labpc.c,v 1.35 1999/09/25 18:24:08 phk Exp $
- * $DragonFly: src/sys/dev/misc/labpc/labpc.c,v 1.12 2005/06/16 16:04:28 joerg Exp $
+ * $DragonFly: src/sys/dev/misc/labpc/labpc.c,v 1.13 2005/10/13 00:02:32 dillon Exp $
  *
  */
 
@@ -308,7 +308,7 @@ static struct cdevsw labpc_cdevsw = {
        /* psize */     nopsize
 };
 
-static ointhand2_t labpcintr;
+static inthand2_t labpcintr;
 static void start(struct ctlr *ctlr);
 
 static void
@@ -480,7 +480,7 @@ labpcattach(struct isa_device *dev)
 {
        struct ctlr *ctlr = labpcs[dev->id_unit];
 
-       dev->id_ointr = labpcintr;
+       dev->id_intr = labpcintr;
        callout_init(&ctlr->ch);
        ctlr->sample_us = (1000000.0 / (double)LABPC_DEFAULT_HERTZ) + .50;
        reset(ctlr);
@@ -696,8 +696,10 @@ static void ad_intr(struct ctlr *ctlr)
        }
 }
 
-static void labpcintr(int unit)
+static void
+labpcintr(void *arg)
 {
+       int unit = (int)arg;
        struct ctlr *ctlr = labpcs[unit];
        (*ctlr->intr)(ctlr);
 }
index 5bdfa88..0cbce06 100644 (file)
@@ -43,7 +43,7 @@
  * Version 1.7, December 1995.
  *
  * $FreeBSD: src/sys/i386/isa/spigot.c,v 1.44 2000/01/29 16:17:36 peter Exp $
- * $DragonFly: src/sys/dev/misc/spigot/spigot.c,v 1.9 2004/05/19 22:52:44 dillon Exp $
+ * $DragonFly: src/sys/dev/misc/spigot/spigot.c,v 1.10 2005/10/13 00:02:33 dillon Exp $
  *
  */
 
@@ -115,7 +115,7 @@ static struct cdevsw spigot_cdevsw = {
        /* psize */     nopsize
 };
 
-static ointhand2_t     spigintr;
+static inthand2_t      spigintr;
 
 static int
 spigot_probe(struct isa_device *devp)
@@ -144,7 +144,7 @@ spigot_attach(struct isa_device *devp)
        int     unit;
        struct  spigot_softc    *ss= &spigot_softc[unit = devp->id_unit];
 
-       devp->id_ointr = spigintr;
+       devp->id_intr = spigintr;
        ss->maddr = kvtop(devp->id_maddr);
        ss->irq = devp->id_irq;
        cdevsw_add(&spigot_cdevsw, -1, unit);
@@ -257,8 +257,9 @@ struct      spigot_info     *info;
  * Just call a user level interrupt routine.
  */
 static void
-spigintr(int unit)
+spigintr(void *arg)
 {
+       int unit = (int)arg;
 struct spigot_softc    *ss = (struct spigot_softc *)&spigot_softc[unit];
 
        if(ss->p && ss->signal_num)
index 3ffc9ee..dc5da34 100644 (file)
@@ -29,7 +29,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/tw.c,v 1.38 2000/01/29 16:00:32 peter Exp $
- * $DragonFly: src/sys/dev/misc/tw/tw.c,v 1.12 2005/06/11 00:27:09 dillon Exp $
+ * $DragonFly: src/sys/dev/misc/tw/tw.c,v 1.13 2005/10/13 00:02:35 dillon Exp $
  *
  */
 
@@ -280,7 +280,7 @@ static void twdelayn(int n);
 static void twsetuptimes(int *a);
 static int wait_for_zero(struct tw_sc *sc);
 static int twputpkt(struct tw_sc *sc, u_char *p);
-static ointhand2_t twintr;
+static inthand2_t twintr;
 static int twgetbytes(struct tw_sc *sc, u_char *p, int cnt);
 static timeout_t twabortrcv;
 static int twsend(struct tw_sc *sc, int h, int k, int cnt);
@@ -398,7 +398,7 @@ static int twattach(idp)
   struct tw_sc *sc;
   int  unit;
 
-  idp->id_ointr = twintr;
+  idp->id_intr = twintr;
   sc = &tw_sc[unit = idp->id_unit];
   sc->sc_port = idp->id_iobase;
   sc->sc_state = 0;
@@ -918,9 +918,9 @@ tw_is_within(int value, int expected, int tolerance)
  * reconstruct the transmission without having to poll.
  */
 
-static void twintr(unit)
-int unit;
+static void twintr(void *arg)
 {
+  int unit = (int)arg;
   struct tw_sc *sc = &tw_sc[unit];
   int port;
   int newphase;
index 4df41b2..db4b86d 100644 (file)
@@ -17,7 +17,7 @@
  * Version 1.9, Wed Oct  4 18:58:15 MSK 1995
  *
  * $FreeBSD: src/sys/i386/isa/if_cx.c,v 1.32 1999/11/18 08:36:42 peter Exp $
- * $DragonFly: src/sys/dev/netif/cx/if_cx.c,v 1.16 2005/06/13 21:53:24 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/cx/if_cx.c,v 1.17 2005/10/13 00:02:36 dillon Exp $
  *
  */
 #undef DEBUG
@@ -61,7 +61,7 @@ static int cxattach (struct isa_device *id);
 static void cxput (cx_chan_t *c, char b);
 static void cxsend (cx_chan_t *c);
 static void cxrinth (cx_chan_t *c);
-static ointhand2_t cxintr;
+static inthand2_t cxintr;
 static int cxtinth (cx_chan_t *c);
 
 #ifdef DEBUG
@@ -234,7 +234,7 @@ cxattach (struct isa_device *id)
        int i;
        struct sppp *sp;
 
-       id->id_ointr = cxintr;
+       id->id_intr = cxintr;
 
        /* Initialize the board structure. */
        cx_init (b, unit, iobase, ffs(irq)-1, drq);
@@ -698,8 +698,9 @@ cxtinth (cx_chan_t *c)
 }
 
 static void
-cxintr (int bnum)
+cxintr (void *arg)
 {
+       int bnum = (int)arg;
        cx_board_t *b = cxboard + bnum;
        while (! (inw (BSR(b->port)) & BSR_NOINTR)) {
                /* Acknowledge the interrupt to enter the interrupt context. */
index 7fc04c6..b4ad94a 100644 (file)
@@ -7,7 +7,7 @@
  * Questions, comments, bug reports and fixes to kimmel@cs.umass.edu.
  *
  * $FreeBSD: src/sys/i386/isa/if_el.c,v 1.47.2.2 2000/07/17 21:24:30 archie Exp $
- * $DragonFly: src/sys/dev/netif/el/if_el.c,v 1.16 2005/06/14 14:35:05 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/el/if_el.c,v 1.17 2005/10/13 00:02:37 dillon Exp $
  */
 /* Except of course for the portions of code lifted from other FreeBSD
  * drivers (mainly elread, elget and el_ioctl)
@@ -75,7 +75,7 @@ static void el_watchdog(struct ifnet *);
 
 static void el_stop(void *);
 static int el_xmit(struct el_softc *,int);
-static ointhand2_t elintr;
+static inthand2_t elintr;
 static __inline void elread(struct el_softc *,caddr_t,int);
 static struct mbuf *elget(caddr_t,int,struct ifnet *);
 static __inline void el_hardreset(void *);
@@ -176,7 +176,7 @@ el_attach(struct isa_device *idev)
        dprintf(("Attaching el%d...\n",idev->id_unit));
 
        /* Get things pointing to the right places. */
-       idev->id_ointr = elintr;
+       idev->id_intr = elintr;
        sc = &el_softc[idev->id_unit];
        ifp = &sc->arpcom.ac_if;
        base = sc->el_base;
@@ -420,8 +420,9 @@ elread(struct el_softc *sc,caddr_t buf,int len)
 
 /* controller interrupt */
 static void
-elintr(int unit)
+elintr(void *arg)
 {
+       int unit = (int)arg;
        struct el_softc *sc;
        int base;
        int stat, rxstat, len, done;
index 8a2d569..7a2a337 100644 (file)
@@ -48,7 +48,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ie/if_ie.c,v 1.72.2.4 2003/03/27 21:01:49 mdodd Exp $
- * $DragonFly: src/sys/dev/netif/ie/if_ie.c,v 1.20 2005/06/20 15:10:41 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/ie/if_ie.c,v 1.21 2005/10/13 00:02:38 dillon Exp $
  */
 
 /*
@@ -164,7 +164,7 @@ struct ie_softc;
 
 static int     ieprobe(struct isa_device * dvp);
 static int     ieattach(struct isa_device * dvp);
-static ointhand2_t     ieintr;
+static inthand2_t      ieintr;
 static int     sl_probe(struct isa_device * dvp);
 static int     el_probe(struct isa_device * dvp);
 static int     ni_probe(struct isa_device * dvp);
@@ -781,7 +781,7 @@ ieattach(struct isa_device *dvp)
        struct ifnet *ifp = &ie->arpcom.ac_if;
        size_t  allocsize;
 
-       dvp->id_ointr = ieintr;
+       dvp->id_intr = ieintr;
 
        /*
         * based on the amount of memory we have, allocate our tx and rx
@@ -837,8 +837,9 @@ ieattach(struct isa_device *dvp)
  * What to do upon receipt of an interrupt.
  */
 static void
-ieintr(int unit)
+ieintr(void *arg)
 {
+       int unit = (int)arg;
        struct ie_softc *ie = &ie_softc[unit];
        u_short status;
 
index 782a7b7..511dbbb 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/if_le.c,v 1.56.2.4 2002/06/05 23:24:10 paul Exp $
- * $DragonFly: src/sys/dev/netif/le/if_le.c,v 1.27 2005/09/21 21:03:10 hsu Exp $
+ * $DragonFly: src/sys/dev/netif/le/if_le.c,v 1.28 2005/10/13 00:02:39 dillon Exp $
  */
 
 /*
@@ -214,7 +214,7 @@ struct le_softc {
 
 static int le_probe(struct isa_device *dvp);
 static int le_attach(struct isa_device *dvp);
-static ointhand2_t le_intr;
+static inthand2_t le_intr;
 static int le_ioctl(struct ifnet *ifp, u_long command, caddr_t data,
                    struct ucred *cr);
 static void le_input(struct le_softc *sc, caddr_t seg1, size_t total_len,
@@ -286,7 +286,7 @@ le_attach(struct isa_device *dvp)
     struct le_softc *sc = &le_softc[dvp->id_unit];
     struct ifnet *ifp = &sc->le_if;
 
-    dvp->id_ointr = le_intr;
+    dvp->id_intr = le_intr;
     ifp->if_softc = sc;
     ifp->if_mtu = ETHERMTU;
 
@@ -306,8 +306,10 @@ le_attach(struct isa_device *dvp)
 }
 
 static void
-le_intr(int unit)
+le_intr(void *arg)
 {
+    int unit = (int)arg;
+
     le_intrs[unit]++;
     (*le_intrvec[unit])(&le_softc[unit]);
 }
index a64a8fd..10e9636 100644 (file)
@@ -28,7 +28,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/cy.c,v 1.97.2.2 2001/08/22 13:04:58 bde Exp $
- * $DragonFly: src/sys/dev/serial/cy/cy.c,v 1.17 2005/06/16 21:12:39 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/cy/cy.c,v 1.18 2005/10/13 00:02:40 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -331,7 +331,7 @@ struct com_s {
 
 /* PCI driver entry point. */
 int    cyattach_common         (cy_addr cy_iobase, int cy_align);
-ointhand2_t    siointr;
+inthand2_t     siointr;
 
 static int     cy_units        (cy_addr cy_iobase, int cy_align);
 static int     sioattach       (struct isa_device *dev);
@@ -518,7 +518,7 @@ sioattach(isdp)
                printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
                isdp->id_unit = adapter;        /* XXX */
        }
-       isdp->id_ointr = siointr;
+       isdp->id_intr = siointr;
        /* isdp->id_ri_flags |= RI_FAST; XXX unimplemented - use newbus! */
        return (1);
 }
@@ -620,7 +620,7 @@ cyattach_common(cy_iobase, cy_align)
 
        if (!sio_registered) {
                callout_init(&sio_timeout_handle);
-               register_swi(SWI_TTY, siopoll, NULL, "cy");
+               register_swi(SWI_TTY, siopoll, NULL, "cy", NULL);
                sio_registered = TRUE;
        }
        minorbase = UNIT_TO_MINOR(unit);
@@ -1074,9 +1074,9 @@ sioinput(com)
 }
 
 void
-siointr(unit)
-       int     unit;
+siointr(void *arg)
 {
+       int     unit = (int)arg;
        int     baseu;
        int     cy_align;
        cy_addr cy_iobase;
@@ -1715,7 +1715,7 @@ sioioctl(dev_t dev, u_long cmd, caddr_t   data, int flag, struct thread *td)
 }
 
 static void
-siopoll(void *data)
+siopoll(void *data, void *frame)
 {
        int             unit;
 
index 702f867..61d4702 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/rc.c,v 1.53.2.1 2001/02/26 04:23:10 jlemon Exp $
- * $DragonFly: src/sys/dev/serial/rc/rc.c,v 1.15 2005/06/16 21:12:40 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/rc/rc.c,v 1.16 2005/10/13 00:02:41 dillon Exp $
  *
  */
 
@@ -175,7 +175,7 @@ static int rc_rcsrt[16] = {
 };
 
 /* Static prototypes */
-static ointhand2_t rcintr;
+static inthand2_t rcintr;
 static void rc_hwreset          (int, int, unsigned int);
 static int  rc_test             (int, int);
 static void rc_discard_output   (struct rc_chans *);
@@ -236,7 +236,7 @@ rcattach(dvp)
        static int              rc_started = 0;
        struct tty              *tp;
 
-       dvp->id_ointr = rcintr;
+       dvp->id_intr = rcintr;
 
        /* Thorooughly test the device */
        if (rcb->rcb_probed != RC_PROBED)
@@ -271,7 +271,7 @@ rcattach(dvp)
        rcb->rcb_probed = RC_ATTACHED;
        if (!rc_started) {
                cdevsw_add(&rc_cdevsw, -1, rcb->rcb_unit);
-               register_swi(SWI_TTY, rcpoll, NULL, "rcpoll");
+               register_swi(SWI_TTY, rcpoll, NULL, "rcpoll", NULL);
                callout_init(&rc_wakeup_ch);
                rc_wakeup(NULL);
                rc_started = 1;
@@ -281,9 +281,9 @@ rcattach(dvp)
 
 /* RC interrupt handling */
 static void
-rcintr(unit)
-       int             unit;
+rcintr(void *arg, void *frame)
 {
+       int unit = (int)arg;
        struct rc_softc        *rcb = &rc_softc[unit];
        struct rc_chans        *rc;
        int                    nec, resid;
@@ -561,7 +561,7 @@ out:
 
 /* Handle delayed events. */
 void 
-rcpoll(void *dummy)
+rcpoll(void *dummy, void *frame)
 {
        struct rc_chans *rc;
        struct rc_softc *rcb;
@@ -1421,7 +1421,7 @@ rc_wakeup(chan)
 {
        if (rc_scheduled_event != 0) {
                crit_enter();
-               rcpoll(NULL);
+               rcpoll(NULL, NULL);
                crit_exit();
        }
        callout_reset(&rc_wakeup_ch, 1, rc_wakeup, NULL);
index 41edca4..cfd35e1 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/isa/sio.c,v 1.291.2.35 2003/05/18 08:51:15 murray Exp $
- * $DragonFly: src/sys/dev/serial/sio/sio.c,v 1.30 2005/10/12 17:35:55 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/sio/sio.c,v 1.31 2005/10/13 00:02:42 dillon Exp $
  *     from: @(#)com.c 7.5 (Berkeley) 5/16/91
  *     from: i386/isa sio.c,v 1.234
  */
@@ -1199,7 +1199,7 @@ determined_type: ;
        printf("\n");
 
        if (!sio_registered) {
-               register_swi(SWI_TTY, siopoll, NULL ,"swi_siopoll");
+               register_swi(SWI_TTY, siopoll, NULL ,"swi_siopoll", NULL);
                sio_registered = TRUE;
        }
        minorbase = UNIT_TO_MINOR(unit);
@@ -2136,7 +2136,7 @@ sioioctl(dev_t dev, u_long cmd, caddr_t   data, int flag, struct thread *td)
 }
 
 static void
-siopoll(void *dummy)
+siopoll(void *dummy, void *frame)
 {
        int             unit;
 
index 0952a65..99b8abd 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/stallion.c,v 1.39.2.2 2001/08/30 12:29:57 murray Exp $
- * $DragonFly: src/sys/dev/serial/stl/stallion.c,v 1.14 2005/06/16 21:12:42 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/stl/stallion.c,v 1.15 2005/10/13 00:02:43 dillon Exp $
  */
 
 /*****************************************************************************/
@@ -512,7 +512,7 @@ static int  stl_getbrdstats(caddr_t data);
 static int     stl_getportstats(stlport_t *portp, caddr_t data);
 static int     stl_clrportstats(stlport_t *portp, caddr_t data);
 static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
-static ointhand2_t     stlintr;
+static inthand2_t stlintr;
 
 #if NPCI > 0
 static const char *stlpciprobe(pcici_t tag, pcidi_t type);
@@ -853,7 +853,7 @@ static int stlattach(struct isa_device *idp)
                idp->id_unit, idp->id_iobase);
 #endif
 
-/*     idp->id_ointr = stlintr; */
+/*     idp->id_intr = stlintr; */
 
        brdp = malloc(sizeof(stlbrd_t), M_TTYS, M_WAITOK | M_ZERO);
 
@@ -1760,10 +1760,11 @@ static void stl_flush(stlport_t *portp, int flag)
  *      are vectored through here.
  */
 
-void stlintr(int unit)
+void stlintr(void *arg)
 {
         stlbrd_t        *brdp;
         int             i;
+       int             unit = (int)arg;
 
 #if STLDEBUG
         printf("stlintr(unit=%d)\n", unit);
@@ -1784,7 +1785,7 @@ void stlintr(int unit)
 
 static void stlpciintr(void *arg)
 {
-       stlintr(0);
+       stlintr((void *)0);
 }
 
 #endif
index e7dda23..ec65a11 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
- * $DragonFly: src/sys/i386/apic/Attic/apic_vector.s,v 1.22 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/i386/apic/Attic/apic_vector.s,v 1.23 2005/10/13 00:02:47 dillon Exp $
  */
 
 
  * Test to see if the source is currntly masked, clear if so.
  */
 #define UNMASK_IRQ(irq_num)                                    \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        IMASK_LOCK ;                            /* into critical reg */ \
        testl   $IRQ_LBIT(irq_num), apic_imen ;                         \
        je      7f ;                    /* bit clear, not masked */     \
        movl    %eax,IOAPIC_WINDOW(%ecx) ;      /* new value */         \
 7: ;                                                                   \
        IMASK_UNLOCK ;                                                  \
+8: ;                                                                   \
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -164,40 +167,15 @@ IDTVEC(vec_name) ;                                                        \
        orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
-       /* try to get the MP lock */                                    \
-       call    try_mplock ;                                            \
-       testl   %eax,%eax ;                                             \
-       jz      6f ;                                                    \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;   /* returns 0 to unmask */      \
        addl    $4, %esp ;                                              \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
-       decl    PCPU(intr_nesting_level) ;                              \
-       call    rel_mplock ;                                            \
        UNMASK_IRQ(irq_num) ;                                           \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
-6: ;                                                                   \
-       /* could not get the MP lock, forward the interrupt */          \
-       movl    mp_lock, %eax ;          /* check race */               \
-       cmpl    $MP_FREE_LOCK,%eax ;                                    \
-       je      2b ;                                                    \
-       incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
-       subl    $12,%esp ;                                              \
-       movl    $irq_num,8(%esp) ;                                      \
-       movl    $forward_fastint_remote,4(%esp) ;                       \
-       movl    %eax,(%esp) ;                                           \
-       call    lwkt_send_ipiq_bycpu ;                                  \
-       addl    $12,%esp ;                                              \
-       jmp     5f ;                                                    \
 
 /*
  * Restart fast interrupt held up by critical section or cpl.
@@ -222,12 +200,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask */       \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(irq_num) ;                                           \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -280,9 +255,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
index 08a6b68..1b31cb1 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.17 2005/06/16 21:12:44 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.18 2005/10/13 00:02:44 dillon Exp $
  */
 
 /*
@@ -523,8 +523,13 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
        if (error)
                return (error);
 
+       /*
+        * XXX cast the interrupt handler function to an inthand2_t.  The
+        * difference is that an additional frame argument is passed which
+        * we do not currently want to expose the BUS subsystem to.
+        */
        *cookiep = inthand_add(device_get_nameunit(child), irq->r_start,
-           ihand, arg, icflags, serializer);
+           (inthand2_t *)ihand, arg, icflags, serializer);
        if (*cookiep == NULL)
                error = EINVAL; /* XXX ??? */
 
index 4d42046..5ac46eb 100644 (file)
@@ -39,7 +39,7 @@
  *     from: @(#)vm_machdep.c  7.3 (Berkeley) 5/13/91
  *     Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
  * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $
- * $DragonFly: src/sys/i386/i386/Attic/vm_machdep.c,v 1.36 2005/06/16 21:12:44 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/vm_machdep.c,v 1.37 2005/10/13 00:02:44 dillon Exp $
  */
 
 #include "use_npx.h"
@@ -576,7 +576,7 @@ vm_page_zero_idle()
 }
 
 static void
-swi_vm(void *arg)
+swi_vm(void *arg, void *frame)
 {
        if (busdma_swi_pending != 0)
                busdma_swi();
@@ -585,7 +585,7 @@ swi_vm(void *arg)
 static void
 swi_vm_setup(void *arg)
 {
-       register_swi(SWI_VM, swi_vm, NULL, "swi_vm");
+       register_swi(SWI_VM, swi_vm, NULL, "swi_vm", NULL);
 }
 
 SYSINIT(vm_setup, SI_SUB_CPU, SI_ORDER_ANY, swi_vm_setup, NULL);
index 9752648..4aa1244 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/icu_vector.s,v 1.14.2.2 2000/07/18 21:12:42 dfr Exp $
- * $DragonFly: src/sys/i386/icu/Attic/icu_vector.s,v 1.18 2005/06/16 21:12:47 dillon Exp $
+ * $DragonFly: src/sys/i386/icu/Attic/icu_vector.s,v 1.19 2005/10/13 00:02:47 dillon Exp $
  */
 
 #define ICU_IMR_OFFSET         1       /* IO_ICU{1,2} + 1 */
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
 
 #define UNMASK_IRQ(icu, irq_num)                                       \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        movb    imen + IRQ_BYTE(irq_num),%al ;                          \
        andb    $~IRQ_BIT(irq_num),%al ;                                \
        movb    %al,imen + IRQ_BYTE(irq_num) ;                          \
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
+8: ;                                                                   \
        
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -123,24 +126,17 @@ IDTVEC(vec_name) ;                                                        \
        jmp     5f ;                                                    \
 2: ;                                                                   \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4,%esp ;                                               \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       decl    PCPU(intr_nesting_level) ;                              \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
 
 /*
- * Restart fast interrupt held up by critical section or cpl.
+ * Restart fast interrupt held up by critical section.
  *
  *     - Push a dummy trap frame as required by doreti.
  *     - The interrupt source is already masked.
@@ -159,12 +155,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;                                      \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -219,9 +212,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
@@ -238,6 +228,7 @@ IDTVEC(vec_name) ;                                                  \
 IDTVEC(vec_name) ;                                                     \
        pushl %ebp ;     /* frame for ddb backtrace */                  \
        movl    %esp, %ebp ;                                            \
+       subl    %eax, %eax ;                                            \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        popl %ebp ;                                                     \
        ret ;                                                           \
index 664ec83..e4d8d42 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/i386/include/Attic/atomic.h,v 1.14 2005/08/28 15:27:05 hsu Exp $
+ * $DragonFly: src/sys/i386/include/Attic/atomic.h,v 1.15 2005/10/13 00:02:46 dillon Exp $
  */
 #ifndef _MACHINE_ATOMIC_H_
 #define _MACHINE_ATOMIC_H_
@@ -182,6 +182,13 @@ atomic_poll_release_int(volatile u_int *p)
  *                             acquired state.  Returns 0 if it not
  *                             acquired, non-zero if it is.
  *
+ * atomic_intr_cond_try(P)
+ *                             Increment the request counter and attempt to
+ *                             set bit 31 to acquire the interlock.  If
+ *                             we are unable to set bit 31 the request
+ *                             counter is decremented and we return -1,
+ *                             otherwise we return 0.
+ *
  * atomic_intr_cond_enter(P, func, arg)
  *                             Increment the request counter and attempt to
  *                             set bit 31 to acquire the interlock.  If
@@ -228,6 +235,7 @@ int atomic_intr_handler_disable(atomic_intr_t *p);
 void atomic_intr_handler_enable(atomic_intr_t *p);
 int atomic_intr_handler_is_enabled(atomic_intr_t *p);
 int atomic_intr_cond_test(atomic_intr_t *p);
+int atomic_intr_cond_try(atomic_intr_t *p);
 void atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg);
 void atomic_intr_cond_exit(atomic_intr_t *p, void (*func)(void *), void *arg);
 
@@ -285,6 +293,29 @@ atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg)
                         : "ax", "cx", "dx");
 }
 
+/*
+ * Attempt to enter the interrupt condition variable.  Returns zero on
+ * success, 1 on failure.
+ */
+static __inline
+int
+atomic_intr_cond_try(atomic_intr_t *p)
+{
+       int ret;
+
+       __asm __volatile(MPLOCKED "incl %0; " \
+                        "1: ;" \
+                        "subl %%eax,%%eax; " \
+                        MPLOCKED "btsl $31,%0; jnc 2f; " \
+                        MPLOCKED "decl %0; " \
+                        "movl $1,%%eax;" \
+                        "2: ;" \
+                        : "+m" (*p), "=a"(ret) \
+                        : : "cx", "dx");
+       return (ret);
+}
+
+
 static __inline
 int
 atomic_intr_cond_test(atomic_intr_t *p)
index fd5f40a..af1a1d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
- * $DragonFly: src/sys/i386/isa/Attic/apic_vector.s,v 1.22 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/apic_vector.s,v 1.23 2005/10/13 00:02:47 dillon Exp $
  */
 
 
  * Test to see if the source is currntly masked, clear if so.
  */
 #define UNMASK_IRQ(irq_num)                                    \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        IMASK_LOCK ;                            /* into critical reg */ \
        testl   $IRQ_LBIT(irq_num), apic_imen ;                         \
        je      7f ;                    /* bit clear, not masked */     \
        movl    %eax,IOAPIC_WINDOW(%ecx) ;      /* new value */         \
 7: ;                                                                   \
        IMASK_UNLOCK ;                                                  \
+8: ;                                                                   \
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -164,40 +167,15 @@ IDTVEC(vec_name) ;                                                        \
        orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
-       /* try to get the MP lock */                                    \
-       call    try_mplock ;                                            \
-       testl   %eax,%eax ;                                             \
-       jz      6f ;                                                    \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;   /* returns 0 to unmask */      \
        addl    $4, %esp ;                                              \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
-       decl    PCPU(intr_nesting_level) ;                              \
-       call    rel_mplock ;                                            \
        UNMASK_IRQ(irq_num) ;                                           \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
-6: ;                                                                   \
-       /* could not get the MP lock, forward the interrupt */          \
-       movl    mp_lock, %eax ;          /* check race */               \
-       cmpl    $MP_FREE_LOCK,%eax ;                                    \
-       je      2b ;                                                    \
-       incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
-       subl    $12,%esp ;                                              \
-       movl    $irq_num,8(%esp) ;                                      \
-       movl    $forward_fastint_remote,4(%esp) ;                       \
-       movl    %eax,(%esp) ;                                           \
-       call    lwkt_send_ipiq_bycpu ;                                  \
-       addl    $12,%esp ;                                              \
-       jmp     5f ;                                                    \
 
 /*
  * Restart fast interrupt held up by critical section or cpl.
@@ -222,12 +200,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask */       \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(irq_num) ;                                           \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -280,9 +255,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
index ba36f0a..d4ebb50 100644 (file)
@@ -35,7 +35,7 @@
  */
 /*
  * $FreeBSD: src/sys/i386/isa/asc.c,v 1.42.2.2 2001/03/01 03:22:39 jlemon Exp $
- * $DragonFly: src/sys/i386/isa/Attic/asc.c,v 1.9 2005/06/03 17:14:51 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/asc.c,v 1.10 2005/10/13 00:02:47 dillon Exp $
  */
 
 #include "use_asc.h"
@@ -177,7 +177,7 @@ static int ascprobe (struct isa_device *isdp);
 static int ascattach(struct isa_device *isdp);
 struct isa_driver ascdriver = { ascprobe, ascattach, "asc" };
 
-static ointhand2_t     ascintr;
+static inthand2_t      ascintr;
 
 static d_open_t                ascopen;
 static d_close_t       ascclose;
@@ -453,7 +453,7 @@ ascattach(struct isa_device *isdp)
   int unit = isdp->id_unit;
   struct asc_unit *scu = unittab + unit;
 
-  isdp->id_ointr = ascintr;
+  isdp->id_intr = ascintr;
   scu->flags |= FLAG_DEBUG;
   printf("asc%d: [GI1904/Trust Ami-Scan Grey/Color]\n", unit);
 
@@ -497,10 +497,11 @@ ascattach(struct isa_device *isdp)
  ***   the interrupt routine, at the end of DMA...
  ***/
 static void
-ascintr(int unit)
+ascintr(void *arg)
 {
     struct asc_unit *scu = unittab + unit;
     int chan_bit = 0x01 << scu->dma_num;
+    int unit = (int)arg;
 
     scu->icnt++;
     /* ignore stray interrupts... */
index 7b80ca9..7d96d6e 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)clock.c       7.2 (Berkeley) 5/12/91
  * $FreeBSD: src/sys/i386/isa/clock.c,v 1.149.2.6 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/i386/isa/Attic/clock.c,v 1.32 2005/09/12 21:32:03 joerg Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/clock.c,v 1.33 2005/10/13 00:02:47 dillon Exp $
  */
 
 /*
@@ -96,7 +96,6 @@
 #include <i386/isa/intr_machdep.h>
 /* The interrupt triggered by the 8254 (timer) chip */
 int apic_8254_intr;
-static u_long read_intr_count (int vec);
 static void setup_8254_mixed_mode (void);
 #endif
 static void i8254_restore(void);
@@ -163,7 +162,7 @@ static struct cputimer      i8254_cputimer = {
  * pending.
  */
 static void
-clkintr(struct intrframe frame)
+clkintr(void *dummy, void *frame_arg)
 {
        static sysclock_t timer1_count;
        struct globaldata *gd = mycpu;
@@ -188,7 +187,7 @@ clkintr(struct intrframe frame)
            if (gscan != gd) {
                lwkt_send_ipiq(gscan, (ipifunc_t)systimer_intr, &timer1_count);
            } else {
-               systimer_intr(&timer1_count, &frame);
+               systimer_intr(&timer1_count, frame_arg);
            }
        }
 }
@@ -245,11 +244,11 @@ release_timer2()
  * in the statistics, but the stat clock will no longer stop.
  */
 static void
-rtcintr(struct intrframe frame)
+rtcintr(void *dummy, void *frame)
 {
        while (rtcin(RTC_INTR) & RTCIR_PERIOD)
                ;
-               /* statclock(&frame); no longer used */
+               /* statclock(frame); no longer used */
 }
 
 #include "opt_ddb.h"
@@ -936,7 +935,7 @@ cpu_initclocks()
        int diag;
 #ifdef APIC_IO
        int apic_8254_trial;
-       struct intrec *clkdesc;
+       void *clkdesc;
 #endif /* APIC_IO */
 
        if (statclock_disable) {
@@ -970,13 +969,13 @@ cpu_initclocks()
                        panic("APIC_IO: Cannot route 8254 interrupt to CPU");
        }
 
-       clkdesc = inthand_add("clk", apic_8254_intr, (inthand2_t *)clkintr,
+       clkdesc = inthand_add("clk", apic_8254_intr, clkintr,
                              NULL, INTR_EXCL | INTR_FAST, NULL);
        INTREN(1 << apic_8254_intr);
        
 #else /* APIC_IO */
 
-       inthand_add("clk", 0, (inthand2_t *)clkintr, NULL,
+       inthand_add("clk", 0, clkintr, NULL,
                    INTR_EXCL | INTR_FAST, NULL);
        INTREN(IRQ0);
 
@@ -1011,7 +1010,9 @@ cpu_initclocks()
 #ifdef APIC_IO
        if (apic_8254_trial) {
                sysclock_t base;
-               int lastcnt = read_intr_count(apic_8254_intr);
+               long lastcnt;
+
+               lastcnt = get_interrupt_counter(apic_8254_intr);
 
                /*
                 * XXX this assumes the 8254 is the cpu timer.  Force an
@@ -1023,7 +1024,7 @@ cpu_initclocks()
                base = sys_cputimer->count();
                while (sys_cputimer->count() - base < sys_cputimer->freq / 100)
                        ;       /* nothing */
-               if (read_intr_count(apic_8254_intr) - lastcnt == 0) {
+               if (get_interrupt_counter(apic_8254_intr) - lastcnt == 0) {
                        /* 
                         * The MP table is broken.
                         * The 8254 was not connected to the specified pin
@@ -1051,7 +1052,7 @@ cpu_initclocks()
                        apic_8254_intr = apic_irq(0, 0);
                        setup_8254_mixed_mode();
                        inthand_add("clk", apic_8254_intr,
-                                   (inthand2_t *)clkintr,
+                                   clkintr,
                                    NULL,
                                    INTR_EXCL | INTR_FAST, NULL);
                        INTREN(1 << apic_8254_intr);
@@ -1073,15 +1074,6 @@ cpu_initclocks()
 }
 
 #ifdef APIC_IO
-static u_long
-read_intr_count(int vec)
-{
-       u_long *up;
-       up = intr_countp[vec];
-       if (up)
-               return *up;
-       return 0UL;
-}
 
 static void 
 setup_8254_mixed_mode()
index cb77729..9d76812 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/icu_vector.s,v 1.14.2.2 2000/07/18 21:12:42 dfr Exp $
- * $DragonFly: src/sys/i386/isa/Attic/icu_vector.s,v 1.18 2005/06/16 21:12:47 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/icu_vector.s,v 1.19 2005/10/13 00:02:47 dillon Exp $
  */
 
 #define ICU_IMR_OFFSET         1       /* IO_ICU{1,2} + 1 */
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
 
 #define UNMASK_IRQ(icu, irq_num)                                       \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        movb    imen + IRQ_BYTE(irq_num),%al ;                          \
        andb    $~IRQ_BIT(irq_num),%al ;                                \
        movb    %al,imen + IRQ_BYTE(irq_num) ;                          \
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
+8: ;                                                                   \
        
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -123,24 +126,17 @@ IDTVEC(vec_name) ;                                                        \
        jmp     5f ;                                                    \
 2: ;                                                                   \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4,%esp ;                                               \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       decl    PCPU(intr_nesting_level) ;                              \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
 
 /*
- * Restart fast interrupt held up by critical section or cpl.
+ * Restart fast interrupt held up by critical section.
  *
  *     - Push a dummy trap frame as required by doreti.
  *     - The interrupt source is already masked.
@@ -159,12 +155,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;                                      \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -219,9 +212,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
@@ -238,6 +228,7 @@ IDTVEC(vec_name) ;                                                  \
 IDTVEC(vec_name) ;                                                     \
        pushl %ebp ;     /* frame for ddb backtrace */                  \
        movl    %esp, %ebp ;                                            \
+       subl    %eax, %eax ;                                            \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        popl %ebp ;                                                     \
        ret ;                                                           \
index 2e3d97c..9c79354 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)isa.c 7.2 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/isa/intr_machdep.c,v 1.29.2.5 2001/10/14 06:54:27 luigi Exp $
- * $DragonFly: src/sys/i386/isa/Attic/intr_machdep.c,v 1.32 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/intr_machdep.c,v 1.33 2005/10/13 00:02:47 dillon Exp $
  */
 /*
  * This file contains an aggregated module marked:
 
 #define        NR_INTRNAMES    (1 + ICU_LEN + 2 * ICU_LEN)
 
-static inthand2_t isa_strayintr;
-#if defined(FAST_HI) && defined(APIC_IO)
-void do_wrongintr(int intr);
-#endif
 static void    init_i8259(void);
-
-void   *intr_unit[ICU_LEN*2];
-u_long *intr_countp[ICU_LEN*2];
-inthand2_t *intr_handler[ICU_LEN*2] = {
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-};
-
-static struct md_intr_info {
-    int                irq;
-    int                mihandler_installed;
-} intr_info[ICU_LEN*2];
+static int     icu_unset(int intr);
+static int     icu_setup(int intr, int flags);
 
 static inthand_t *fastintr[ICU_LEN] = {
        &IDTVEC(fastintr0), &IDTVEC(fastintr1),
@@ -240,12 +220,13 @@ isa_nmi(cd)
 void
 icu_reinit()
 {
-       int i;
+       int i;
 
-       init_i8259();
-       for(i=0;i<ICU_LEN;i++)
-               if(intr_handler[i] != isa_strayintr)
-                       INTREN(1<<i);
+       init_i8259();
+       for (i = 0; i < ICU_LEN; ++i) {
+               if (count_registered_ints(i))
+                       INTREN(1 << i);
+       }
 }
 
 /*
@@ -259,7 +240,7 @@ isa_defaultirq()
 
        /* icu vectors */
        for (i = 0; i < ICU_LEN; i++)
-               icu_unset(i, isa_strayintr);
+               icu_unset(i);
        init_i8259();
 }
 
@@ -291,61 +272,6 @@ init_i8259(void)
        outb(IO_ICU2, 0x0a);            /* default to IRR on read */
 }
 
-/*
- * Caught a stray interrupt, notify
- */
-static void
-isa_strayintr(void *vcookiep)
-{
-       int intr = (void **)vcookiep - &intr_unit[0];
-
-       /* DON'T BOTHER FOR NOW! */
-       /* for some reason, we get bursts of intr #7, even if not enabled! */
-       /*
-        * Well the reason you got bursts of intr #7 is because someone
-        * raised an interrupt line and dropped it before the 8259 could
-        * prioritize it.  This is documented in the intel data book.  This
-        * means you have BAD hardware!  I have changed this so that only
-        * the first 5 get logged, then it quits logging them, and puts
-        * out a special message. rgrimes 3/25/1993
-        */
-       /*
-        * XXX TODO print a different message for #7 if it is for a
-        * glitch.  Glitches can be distinguished from real #7's by
-        * testing that the in-service bit is _not_ set.  The test
-        * must be done before sending an EOI so it can't be done if
-        * we are using AUTO_EOI_1.
-        */
-       if (intrcnt[1 + intr] <= 5)
-               log(LOG_ERR, "stray irq %d\n", intr);
-       if (intrcnt[1 + intr] == 5)
-               log(LOG_CRIT,
-                   "too many stray irq %d's; not logging any more\n", intr);
-}
-
-#if defined(FAST_HI) && defined(APIC_IO)
-
-/*
- * This occurs if we've mis-programmed the APIC and its vector is still
- * pointing to the slow vector even when we thought we reprogrammed it
- * to the high vector.  This can occur when interrupts are improperly
- * routed by the APIC.  The unit data is opaque so we have to try to
- * find it in the unit array.
- */
-void
-do_wrongintr(int intr)
-{
-       if (intrcnt[1 + intr] <= 5) {
-               log(LOG_ERR, "stray irq ~%d on cpu %d (APIC misprogrammed)\n",
-                   intr, mycpu->gd_cpuid);
-       } else if (intrcnt[1 + intr] == 6) {
-               log(LOG_CRIT,
-                   "too many stray irq ~%d's; not logging any more\n", intr);
-       }
-}
-
-#endif
-
 #if NISA > 0
 /*
  * Return a bitmap of the current interrupt requests.  This is 8259-specific
@@ -363,61 +289,9 @@ isa_irq_pending(void)
 }
 #endif
 
-static void
-update_intrname(int intr, char *name)
-{
-       char buf[32];
-       char *cp;
-       int name_index, off, strayintr;
-
-       /*
-        * Initialise strings for bitbucket and stray interrupt counters.
-        * These have statically allocated indices 0 and 1 through ICU_LEN.
-        */
-       if (intrnames[0] == '\0') {
-               off = sprintf(intrnames, "???") + 1;
-               for (strayintr = 0; strayintr < ICU_LEN; strayintr++)
-                       off += sprintf(intrnames + off, "stray irq%d",
-                           strayintr) + 1;
-       }
-
-       if (name == NULL)
-               name = "???";
-       if (snprintf(buf, sizeof(buf), "%s irq%d", name, intr) >= sizeof(buf))
-               goto use_bitbucket;
-
-       /*
-        * Search for `buf' in `intrnames'.  In the usual case when it is
-        * not found, append it to the end if there is enough space (the \0
-        * terminator for the previous string, if any, becomes a separator).
-        */
-       for (cp = intrnames, name_index = 0;
-           cp != eintrnames && name_index < NR_INTRNAMES;
-           cp += strlen(cp) + 1, name_index++) {
-               if (*cp == '\0') {
-                       if (strlen(buf) >= eintrnames - cp)
-                               break;
-                       strcpy(cp, buf);
-                       goto found;
-               }
-               if (strcmp(cp, buf) == 0)
-                       goto found;
-       }
-
-use_bitbucket:
-       printf("update_intrname: counting %s irq%d as %s\n", name, intr,
-           intrnames);
-       name_index = 0;
-found:
-       intr_countp[intr] = &intrcnt[name_index];
-}
-
-/*
- * NOTE!  intr_handler[] is only used for FAST interrupts, the *vector.s
- * code ignores it for normal interrupts.
- */
+static
 int
-icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
+icu_setup(int intr, int flags)
 {
 #if defined(FAST_HI) && defined(APIC_IO)
        int             select;         /* the select register is 8 bits */
@@ -432,17 +306,9 @@ icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
        if ((u_int)intr >= ICU_LEN || intr == ICU_SLAVEID)
 #endif /* APIC_IO */
                return (EINVAL);
-       if (intr_handler[intr] != isa_strayintr)
-               return (EBUSY);
 
        ef = read_eflags();
        cpu_disable_intr();     /* YYY */
-       intr_handler[intr] = handler;
-       intr_unit[intr] = arg;
-#if 0
-       /* YYY  fast ints supported and mp protected but ... */
-       flags &= ~INTR_FAST;
-#endif
 #if defined(FAST_HI) && defined(APIC_IO)
        if (flags & INTR_FAST) {
                /*
@@ -493,25 +359,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
        return (0);
 }
 
-int
-icu_unset(intr, handler)
-       int     intr;
-       inthand2_t *handler;
+static int
+icu_unset(int intr)
 {
        u_long  ef;
 
-       if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) {
-               printf("icu_unset: invalid handler %d %p/%p\n", intr, handler, 
-                   (((u_int)intr >= ICU_LEN) ? (void *)-1 : intr_handler[intr]));
-               return (EINVAL);
-       }
-
+       KKASSERT((u_int)intr < ICU_LEN);
        INTRDIS(1 << intr);
        ef = read_eflags();
        cpu_disable_intr();     /* YYY */
-       intr_countp[intr] = &intrcnt[1 + intr];
-       intr_handler[intr] = isa_strayintr;
-       intr_unit[intr] = &intr_unit[intr];
 #ifdef FAST_HI_XXX
        /* XXX how do I re-create dvp here? */
        setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr,
@@ -559,151 +415,6 @@ icu_unset(intr, handler)
  *
  */
 
-typedef struct intrec {
-       inthand2_t      *handler;
-       void            *argument;
-       struct intrec   *next;
-       char            *name;
-       int             intr;
-       int             flags;
-       lwkt_serialize_t serializer;
-       volatile int    in_handler;
-} intrec;
-
-static intrec *intreclist_head[ICU_LEN];
-
-/*
- * The interrupt multiplexer calls each of the handlers in turn.  A handler
- * is called only if we can successfully obtain the interlock, meaning
- * (1) we aren't recursed and (2) the handler has not been disabled via
- * inthand_disabled().
- *
- * XXX the IPL is currently raised as necessary for the handler.  However,
- * IPLs are not MP safe so the IPL code will be removed when the device
- * drivers, BIO, and VM no longer depend on it.
- */
-static void
-intr_mux(void *arg)
-{
-       intrec **pp;
-       intrec *p;
-
-       for (pp = arg; (p = *pp) != NULL; pp = &p->next) {
-               if (p->serializer) {
-                       /*
-                        * New handler dispatch method.  Only the serializer
-                        * is used to interlock access.  Note that this
-                        * API includes a handler disablement feature.
-                        */
-                       lwkt_serialize_handler_call(p->serializer,
-                                                   p->handler, p->argument);
-               } else {
-                       /*
-                        * Old handlers may expect multiple interrupt
-                        * sources to be masked.  We must use a critical
-                        * section.
-                        */
-                       crit_enter();
-                       p->handler(p->argument);
-                       crit_exit();
-               }
-       }
-}
-
-/*
- * Add an interrupt handler to the linked list hung off of intreclist_head[irq]
- * and install a shared interrupt multiplex handler.  Install an interrupt
- * thread for each interrupt (though FAST interrupts will not use it).
- * The preemption procedure checks the CPL.  lwkt_preempt() will check
- * relative thread priorities for us as long as we properly pass through
- * critpri.
- *
- * The interrupt thread has already been put on the run queue, so if we cannot
- * preempt we should force a reschedule.
- *
- * This preemption check routine is currently empty, but will be used in the
- * future to pre-check interrupts for preemptability to avoid the
- * inefficiencies of having to instantly block.  We used to do a CPL check
- * here (otherwise the interrupt thread could preempt even when it wasn't
- * supposed to), but with CPLs gone we no longer have to do this.
- */
-static void
-cpu_intr_preempt(struct thread *td, int critpri)
-{
-       lwkt_preempt(td, critpri);
-}
-
-static int
-add_intrdesc(intrec *idesc)
-{
-       int irq = idesc->intr;
-       intrec *head;
-       intrec **headp;
-
-       /*
-        * There are two ways to enter intr_mux().  (1) via the scheduled
-        * interrupt thread or (2) directly.   The thread mechanism is the
-        * normal mechanism used by SLOW interrupts, while the direct method
-        * is used by FAST interrupts.
-        *
-        * We need to create an interrupt thread if none exists.
-        */
-       if (intr_info[irq].mihandler_installed == 0) {
-               struct thread *td;
-
-               intr_info[irq].mihandler_installed = 1;
-               intr_info[irq].irq = irq;
-               td = register_int(irq, intr_mux, &intreclist_head[irq], idesc->name);
-               td->td_info.intdata = &intr_info[irq];
-               td->td_preemptable = cpu_intr_preempt;
-               printf("installed MI handler for int %d\n", irq);
-       }
-
-       headp = &intreclist_head[irq];
-       head = *headp;
-
-       /*
-        * Check exclusion
-        */
-       if (head) {
-               if ((idesc->flags & INTR_EXCL) || (head->flags & INTR_EXCL)) {
-                       printf("\tdevice combination doesn't support "
-                              "shared irq%d\n", irq);
-                       return (-1);
-               }
-               if ((idesc->flags & INTR_FAST) || (head->flags & INTR_FAST)) {
-                       printf("\tdevice combination doesn't support "
-                              "multiple FAST interrupts on IRQ%d\n", irq);
-               }
-       }
-
-       /*
-        * Always install intr_mux as the hard handler so it can deal with
-        * individual enablement on handlers.
-        */
-       if (head == NULL) {
-               if (icu_setup(irq, idesc->handler, idesc->argument, idesc->flags) != 0)
-                       return (-1);
-               update_intrname(irq, idesc->name);
-       } else if (head->next == NULL) {
-               icu_unset(irq, head->handler);
-               if (icu_setup(irq, intr_mux, &intreclist_head[irq], 0) != 0)
-                       return (-1);
-               if (bootverbose && head->next == NULL)
-                       printf("\tusing shared irq%d.\n", irq);
-               update_intrname(irq, "mux");
-       }
-
-       /*
-        * Append to the end of the chain.
-        */
-       while (*headp != NULL)
-               headp = &(*headp)->next;
-       *headp = idesc;
-
-       return (0);
-}
-
 /*
  * Create and activate an interrupt handler descriptor data structure.
  *
@@ -722,52 +433,48 @@ add_intrdesc(intrec *idesc)
  * drivers.  It is subject to change without notice.
  */
 
-intrec *
+void *
 inthand_add(const char *name, int irq, inthand2_t handler, void *arg,
             int flags, lwkt_serialize_t serializer)
 {
-       intrec *idesc;
-       int errcode = -1;
+       int errcode = 0;
+       void *id;
 
        if ((unsigned)irq >= ICU_LEN) {
                printf("create_intr: requested irq%d too high, limit is %d\n",
                       irq, ICU_LEN -1);
                return (NULL);
        }
+       /*
+        * Register the interrupt, then setup the ICU
+        */
+       id = register_int(irq, handler, arg, name, serializer, flags);
 
-       idesc = malloc(sizeof *idesc, M_DEVBUF, M_WAITOK | M_ZERO);
-       if (idesc == NULL)
-               return NULL;
-
-       if (name == NULL)
-               name = "???";
-       idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
-       if (idesc->name == NULL) {
-               free(idesc, M_DEVBUF);
-               return NULL;
+       if (id == NULL) {
+               printf("Unable to install handler for %s\n", name);
+               printf("\tdevice combination not supported on irq %d\n", irq);
+               return(NULL);
        }
-       strcpy(idesc->name, name);
-
-       idesc->handler  = handler;
-       idesc->argument = arg;
-       idesc->intr     = irq;
-       idesc->flags    = flags;
-       idesc->serializer = serializer;
 
        crit_enter();
-       errcode = add_intrdesc(idesc);
+       if (count_registered_ints(irq) == 1) {
+               if (icu_setup(irq, flags))
+                       errcode = -1;
+       }
        crit_exit();
 
+       /*
+        * Cleanup
+        */
        if (errcode != 0) {
-               if (bootverbose)
-                       printf("\tintr_connect(irq%d) failed, result=%d\n", 
+               if (bootverbose) {
+                       printf("\tinthand_add(irq%d) failed, result=%d\n", 
                               irq, errcode);
-               free(idesc->name, M_DEVBUF);
-               free(idesc, M_DEVBUF);
-               idesc = NULL;
+               }
+               unregister_int(id);
+               id = NULL;
        }
-
-       return (idesc);
+       return (id);
 }
 
 /*
@@ -778,57 +485,19 @@ inthand_add(const char *name, int irq, inthand2_t handler, void *arg,
  * to the system. Make sure, the handler is not actively used anymore, before.
  */
 int
-inthand_remove(intrec *idesc)
+inthand_remove(void *id)
 {
-       intrec **hook, *head;
        int irq;
 
-       if (idesc == NULL)
-               return (-1);
+       if (id == NULL)
+               return(-1);
 
-       irq = idesc->intr;
        crit_enter();
-
-       /*
-        * Find and remove the interrupt descriptor.
-        */
-       hook = &intreclist_head[irq];
-       while (*hook != idesc) {
-               if (*hook == NULL) {
-                       crit_exit();
-                       return(-1);
-               }
-               hook = &(*hook)->next;
-       }
-       *hook = idesc->next;
-
-       /*
-        * If the list is now empty, revert the hard vector to the spurious
-        * interrupt.
-        */
-       head = intreclist_head[irq];
-       if (head == NULL) {
-               /*
-                * No more interrupts on this irq
-                */
-               icu_unset(irq, idesc->handler);
-               update_intrname(irq, NULL);
-       } else if (head->next) {
-               /*
-                * This irq is still shared (has at least two handlers)
-                * (the name should already be set to "mux").
-                */
-       } else {
-               /*
-                * This irq is no longer shared
-                */
-               icu_unset(irq, intr_mux);
-               icu_setup(irq, head->handler, head->argument, head->flags);
-               update_intrname(irq, head->name);
+       irq = get_registered_intr(id);
+       if (unregister_int(id) == 0) {
+               icu_unset(irq);
        }
        crit_exit();
-       free(idesc, M_DEVBUF);
-
        return (0);
 }
 
index 41a8a26..19b12b0 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/intr_machdep.h,v 1.19.2.2 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/i386/isa/Attic/intr_machdep.h,v 1.17 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/intr_machdep.h,v 1.18 2005/10/13 00:02:47 dillon Exp $
  */
 
 #ifndef _I386_ISA_INTR_MACHDEP_H_
@@ -147,10 +147,6 @@ typedef void unpendhand_t(void);
 
 #define        IDTVEC(name)    __CONCAT(X,name)
 
-extern u_long *intr_countp[];  /* pointers into intrcnt[] */
-extern inthand2_t *intr_handler[];     /* C entry points for FAST ints */
-extern void *intr_unit[];      /* cookies to pass to intr handlers */
-
 inthand_t
        IDTVEC(fastintr0), IDTVEC(fastintr1),
        IDTVEC(fastintr2), IDTVEC(fastintr3),
@@ -230,18 +226,15 @@ inthand_t
 void   call_fast_unpend(int irq);
 void   isa_defaultirq (void);
 int    isa_nmi (int cd);
-int    icu_setup (int intr, inthand2_t *func, void *arg, int flags);
-int    icu_unset (int intr, inthand2_t *handler);
 void   icu_reinit (void);
 
 /*
  * WARNING: These are internal functions and not to be used by device drivers!
  * They are subject to change without notice. 
  */
-struct intrec *inthand_add(const char *name, int irq, inthand2_t handler,
-                          void *arg, int flags, lwkt_serialize_t serializer);
-
-int inthand_remove(struct intrec *idesc);
+void *inthand_add(const char *name, int irq, inthand2_t handler,
+                 void *arg, int flags, lwkt_serialize_t serializer);
+int inthand_remove(void *id);
 void forward_fastint_remote(void *arg);
 
 #endif /* LOCORE */
index 969e92d..82e6e34 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/vector.s,v 1.32 1999/08/28 00:45:04 peter Exp $
- * $DragonFly: src/sys/i386/isa/Attic/vector.s,v 1.6 2005/02/27 12:44:43 asmodai Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/vector.s,v 1.7 2005/10/13 00:02:47 dillon Exp $
  */
 
 #include "opt_auto_eoi.h"
@@ -9,27 +9,6 @@
 #include <i386/isa/icu.h>
 #include <bus/isa/i386/isa.h>
 
-       .data
-       ALIGN_DATA
-
-/*
- * Interrupt counters and names for export to vmstat(8) and friends.
- *
- * XXX this doesn't really belong here; everything except the labels
- * for the endpointers is almost machine-independent.
- */
-#define        NR_INTRNAMES    (1 + ICU_LEN + 2 * ICU_LEN)
-
-       .globl  intrcnt, eintrcnt
-intrcnt:
-       .space  NR_INTRNAMES * 4
-eintrcnt:
-
-       .globl  intrnames, eintrnames
-intrnames:
-       .space  NR_INTRNAMES * 16
-eintrnames:
-
        .text
 
 /*
index ac14836..1d6e11b 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_intr.c,v 1.24.2.1 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/kern/kern_intr.c,v 1.23 2005/10/12 17:39:49 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_intr.c,v 1.24 2005/10/13 00:02:22 dillon Exp $
  *
  */
 
 #include <sys/proc.h>
 #include <sys/thread2.h>
 #include <sys/random.h>
+#include <sys/serialize.h>
+#include <sys/bus.h>
 
 #include <machine/ipl.h>
+#include <machine/frame.h>
 
 #include <sys/interrupt.h>
 
@@ -46,15 +49,24 @@ typedef struct intrec {
     struct intrec *next;
     inthand2_t *handler;
     void       *argument;
-    const char *name;
+    char       *name;
     int                intr;
-} intrec_t;
-
-static intrec_t        *intlists[NHWI+NSWI];
-static thread_t ithreads[NHWI+NSWI];
-static struct thread ithread_ary[NHWI+NSWI];
-static struct random_softc irandom_ary[NHWI+NSWI];
-static int irunning[NHWI+NSWI];
+    int                intr_flags;
+    struct lwkt_serialize *serializer;
+} *intrec_t;
+
+struct intr_info {
+       intrec_t        i_reclist;
+       struct thread   i_thread;
+       struct random_softc i_random;
+       int             i_running;
+       long            i_count;
+       int             i_fast;
+       int             i_slow;
+       int             i_valid_thread;
+} intr_info_ary[NHWI + NSWI];
+
+int intr_info_size = sizeof(intr_info_ary) / sizeof(intr_info_ary[0]);
 
 #define LIVELOCK_NONE          0
 #define LIVELOCK_LIMITED       1
@@ -71,48 +83,64 @@ static void ithread_handler(void *arg);
 /*
  * Register an SWI or INTerrupt handler.
  */
-thread_t
-register_swi(int intr, inthand2_t *handler, void *arg, const char *name)
+void *
+register_swi(int intr, inthand2_t *handler, void *arg, const char *name,
+               struct lwkt_serialize *serializer)
 {
     if (intr < NHWI || intr >= NHWI + NSWI)
        panic("register_swi: bad intr %d", intr);
-    return(register_int(intr, handler, arg, name));
+    return(register_int(intr, handler, arg, name, serializer, 0));
 }
 
-thread_t
-register_int(int intr, inthand2_t *handler, void *arg, const char *name)
+void *
+register_int(int intr, inthand2_t *handler, void *arg, const char *name,
+               struct lwkt_serialize *serializer, int intr_flags)
 {
-    intrec_t **list;
-    intrec_t *rec;
-    thread_t td;
+    struct intr_info *info;
+    struct intrec **list;
+    intrec_t rec;
 
     if (intr < 0 || intr >= NHWI + NSWI)
        panic("register_int: bad intr %d", intr);
+    if (name == NULL)
+       name = "???";
+    info = &intr_info_ary[intr];
+
+    rec = malloc(sizeof(struct intrec), M_DEVBUF, M_INTWAIT);
+    rec->name = malloc(strlen(name) + 1, M_DEVBUF, M_INTWAIT);
+    strcpy(rec->name, name);
 
-    rec = malloc(sizeof(intrec_t), M_DEVBUF, M_NOWAIT);
-    if (rec == NULL)
-       panic("register_swi: malloc failed");
     rec->handler = handler;
     rec->argument = arg;
-    rec->name = name;
     rec->intr = intr;
+    rec->intr_flags = intr_flags;
     rec->next = NULL;
+    rec->serializer = serializer;
 
-    list = &intlists[intr];
+    list = &info->i_reclist;
+
+    /*
+     * Keep track of how many fast and slow interrupts we have.
+     */
+    if (intr_flags & INTR_FAST)
+       ++info->i_fast;
+    else
+       ++info->i_slow;
 
     /*
      * Create an interrupt thread if necessary, leave it in an unscheduled
      * state.
      */
-    if ((td = ithreads[intr]) == NULL) {
-       lwkt_create((void *)ithread_handler, (void *)intr, &ithreads[intr],
-           &ithread_ary[intr], TDF_STOPREQ|TDF_INTTHREAD, -1, 
+    if (info->i_valid_thread == 0) {
+       info->i_valid_thread = 1;
+       lwkt_create((void *)ithread_handler, (void *)intr, NULL,
+           &info->i_thread, TDF_STOPREQ|TDF_INTTHREAD, -1, 
            "ithread %d", intr);
-       td = ithreads[intr];
        if (intr >= NHWI && intr < NHWI + NSWI)
-           lwkt_setpri(td, TDPRI_SOFT_NORM);
+           lwkt_setpri(&info->i_thread, TDPRI_SOFT_NORM);
        else
-           lwkt_setpri(td, TDPRI_INT_MED);
+           lwkt_setpri(&info->i_thread, TDPRI_INT_MED);
+       info->i_thread.td_preemptable = lwkt_preempt;
     }
 
     /*
@@ -123,74 +151,150 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name)
        list = &(*list)->next;
     *list = rec;
     crit_exit();
-    return(td);
+    return(rec);
 }
 
-void
-unregister_swi(int intr, inthand2_t *handler)
+int
+unregister_swi(void *id)
 {
-    if (intr < NHWI || intr >= NHWI + NSWI)
-       panic("register_swi: bad intr %d", intr);
-    unregister_int(intr, handler);
+    return(unregister_int(id));
 }
 
-void
-unregister_int(int intr, inthand2_t handler)
+int
+unregister_int(void *id)
 {
-    intrec_t **list;
-    intrec_t *rec;
+    struct intr_info *info;
+    struct intrec **list;
+    intrec_t rec;
+    int intr;
+
+    intr = ((intrec_t)id)->intr;
 
     if (intr < 0 || intr > NHWI + NSWI)
        panic("register_int: bad intr %d", intr);
-    list = &intlists[intr];
+
+    info = &intr_info_ary[intr];
+
+    /*
+     * Remove the interrupt descriptor
+     */
     crit_enter();
+    list = &info->i_reclist;
     while ((rec = *list) != NULL) {
-       if (rec->handler == (void *)handler) {
+       if (rec == id) {
            *list = rec->next;
            break;
        }
        list = &rec->next;
     }
     crit_exit();
+
+    /*
+     * Free it, adjust interrupt type counts
+     */
     if (rec != NULL) {
+       if (rec->intr_flags & INTR_FAST)
+           --info->i_fast;
+       else
+           --info->i_slow;
+       free(rec->name, M_DEVBUF);
        free(rec, M_DEVBUF);
     } else {
-       printf("warning: unregister_int: int %d handler %p not found\n",
-           intr, handler);
+       printf("warning: unregister_int: int %d handler for %s not found\n",
+               intr, ((intrec_t)id)->name);
     }
+
+    /*
+     * Return the number of interrupt vectors still registered on this intr
+     */
+    return(info->i_fast + info->i_slow);
+}
+
+int
+get_registered_intr(void *id)
+{
+    return(((intrec_t)id)->intr);
+}
+
+const char *
+get_registered_name(int intr)
+{
+    intrec_t rec;
+
+    if (intr < 0 || intr > NHWI + NSWI)
+       panic("register_int: bad intr %d", intr);
+
+    if ((rec = intr_info_ary[intr].i_reclist) == NULL)
+       return(NULL);
+    else if (rec->next)
+       return("mux");
+    else
+       return(rec->name);
 }
 
+int
+count_registered_ints(int intr)
+{
+    struct intr_info *info;
+
+    if (intr < 0 || intr > NHWI + NSWI)
+       panic("register_int: bad intr %d", intr);
+    info = &intr_info_ary[intr];
+    return(info->i_fast + info->i_slow);
+}
+
+long
+get_interrupt_counter(int intr)
+{
+    struct intr_info *info;
+
+    if (intr < 0 || intr > NHWI + NSWI)
+       panic("register_int: bad intr %d", intr);
+    info = &intr_info_ary[intr];
+    return(info->i_count);
+}
+
+
 void
 swi_setpriority(int intr, int pri)
 {
-    struct thread *td;
+    struct intr_info *info;
 
     if (intr < NHWI || intr >= NHWI + NSWI)
        panic("register_swi: bad intr %d", intr);
-    if ((td = ithreads[intr]) != NULL)
-       lwkt_setpri(td, pri);
+    info = &intr_info_ary[intr];
+    if (info->i_valid_thread)
+       lwkt_setpri(&info->i_thread, pri);
 }
 
 void
 register_randintr(int intr)
 {
-    struct random_softc *sc = &irandom_ary[intr];
-    sc->sc_intr = intr;
-    sc->sc_enabled = 1;
+    struct intr_info *info;
+
+    if (intr < NHWI || intr >= NHWI + NSWI)
+       panic("register_swi: bad intr %d", intr);
+    info = &intr_info_ary[intr];
+    info->i_random.sc_intr = intr;
+    info->i_random.sc_enabled = 1;
 }
 
 void
 unregister_randintr(int intr)
 {
-    struct random_softc *sc = &irandom_ary[intr];
-    sc->sc_enabled = 0;
+    struct intr_info *info;
+
+    if (intr < NHWI || intr >= NHWI + NSWI)
+       panic("register_swi: bad intr %d", intr);
+    info = &intr_info_ary[intr];
+    info->i_random.sc_enabled = 0;
 }
 
 /*
  * Dispatch an interrupt.  If there's nothing to do we have a stray
  * interrupt and can just return, leaving the interrupt masked.
  *
- * We need to schedule the interrupt and set its irunning[] bit.  If
+ * We need to schedule the interrupt and set its i_running bit.  If
  * we are not on the interrupt thread's cpu we have to send a message
  * to the correct cpu that will issue the desired action (interlocking
  * with the interrupt thread's critical section).
@@ -207,17 +311,22 @@ sched_ithd_remote(void *arg)
 void
 sched_ithd(int intr)
 {
-    thread_t td;
+    struct intr_info *info;
 
-    if ((td = ithreads[intr]) != NULL) {
-       if (intlists[intr] == NULL) {
+    info = &intr_info_ary[intr];
+
+    ++info->i_count;
+    if (info->i_valid_thread) {
+       if (info->i_reclist == NULL) {
            printf("sched_ithd: stray interrupt %d\n", intr);
        } else {
-           if (td->td_gd == mycpu) {
-               irunning[intr] = 1;
-               lwkt_schedule(td);      /* preemption handled internally */
+           if (info->i_thread.td_gd == mycpu) {
+               info->i_running = 1;
+               /* preemption handled internally */
+               lwkt_schedule(&info->i_thread);
            } else {
-               lwkt_send_ipiq(td->td_gd, sched_ithd_remote, (void *)intr);
+               lwkt_send_ipiq(info->i_thread.td_gd, 
+                               sched_ithd_remote, (void *)intr);
            }
        }
     } else {
@@ -230,18 +339,145 @@ sched_ithd(int intr)
  * might not be held).
  */
 static void
-ithread_livelock_wakeup(systimer_t info)
+ithread_livelock_wakeup(systimer_t st)
 {
-    int intr = (int)info->data;
-    thread_t td;
+    struct intr_info *info;
 
-    if ((td = ithreads[intr]) != NULL)
-       lwkt_schedule(td);
+    info = &intr_info_ary[(int)st->data];
+    if (info->i_valid_thread)
+       lwkt_schedule(&info->i_thread);
 }
 
 /*
- * This is run from a periodic SYSTIMER.  It resets the
+ * This function is called drectly from the ICU or APIC vector code assembly
+ * to process an interrupt.  The critical section and interrupt deferral
+ * checks have already been done but the function is entered WITHOUT
+ * a critical section held.  The BGL may or may not be held.
+ *
+ * Must return non-zero if we do not want the vector code to re-enable
+ * the interrupt (which we don't if we have to schedule the interrupt)
  */
+int ithread_fast_handler(struct intrframe frame);
+
+int
+ithread_fast_handler(struct intrframe frame)
+{
+    int intr;
+    struct intr_info *info;
+    struct intrec **list;
+    int must_schedule;
+#ifdef SMP
+    int got_mplock;
+#endif
+    intrec_t rec, next_rec;
+    globaldata_t gd;
+
+    intr = frame.if_vec;
+    gd = mycpu;
+
+    info = &intr_info_ary[intr];
+
+    /*
+     * If we are not processing any FAST interrupts, just schedule the thing.
+     * (since we aren't in a critical section, this can result in a
+     * preemption)
+     */
+    if (info->i_fast == 0) {
+       sched_ithd(intr);
+       return(1);
+    }
+
+    /*
+     * This should not normally occur since interrupts ought to be 
+     * masked if the ithread has been scheduled or is running.
+     */
+    if (info->i_running)
+       return(1);
+
+    /*
+     * Bump the interrupt nesting level to process any FAST interrupts.
+     * Obtain the MP lock as necessary.  If the MP lock cannot be obtained,
+     * schedule the interrupt thread to deal with the issue instead.
+     *
+     * To reduce overhead, just leave the MP lock held once it has been
+     * obtained.
+     */
+    crit_enter_gd(gd);
+    ++gd->gd_intr_nesting_level;
+    ++gd->gd_cnt.v_intr;
+    must_schedule = info->i_slow;
+#ifdef SMP
+    got_mplock = 0;
+#endif
+
+    list = &info->i_reclist;
+    for (rec = *list; rec; rec = next_rec) {
+       next_rec = rec->next;   /* rec may be invalid after call */
+
+       if (rec->intr_flags & INTR_FAST) {
+#ifdef SMP
+           if ((rec->intr_flags & INTR_MPSAFE) == 0 && got_mplock == 0) {
+               if (try_mplock() == 0) {
+                   /*
+                    * XXX forward to the cpu holding the MP lock
+                    */
+                   must_schedule = 1;
+                   break;
+               }
+               got_mplock = 1;
+           }
+#endif
+           if (rec->serializer) {
+               must_schedule += lwkt_serialize_handler_try(
+                                       rec->serializer, rec->handler,
+                                       rec->argument, &frame);
+           } else {
+               rec->handler(rec->argument, &frame);
+           }
+       }
+    }
+
+    /*
+     * Cleanup
+     */
+    --gd->gd_intr_nesting_level;
+#ifdef SMP
+    if (got_mplock)
+       rel_mplock();
+#endif
+    crit_exit_gd(gd);
+
+    /*
+     * If we had a problem, schedule the thread to catch the missed
+     * records (it will just re-run all of them).  A return value of 0
+     * indicates that all handlers have been run and the interrupt can
+     * be re-enabled, and a non-zero return indicates that the interrupt
+     * thread controls re-enablement.
+     */
+    if (must_schedule)
+       sched_ithd(intr);
+    else
+       ++info->i_count;
+    return(must_schedule);
+}
+
+#if 0
+
+6: ;                                                                    \
+        /* could not get the MP lock, forward the interrupt */          \
+        movl    mp_lock, %eax ;          /* check race */               \
+        cmpl    $MP_FREE_LOCK,%eax ;                                    \
+        je      2b ;                                                    \
+        incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
+        subl    $12,%esp ;                                              \
+        movl    $irq_num,8(%esp) ;                                      \
+        movl    $forward_fastint_remote,4(%esp) ;                       \
+        movl    %eax,(%esp) ;                                           \
+        call    lwkt_send_ipiq_bycpu ;                                  \
+        addl    $12,%esp ;                                              \
+        jmp     5f ;                   
+
+#endif
 
 
 /*
@@ -250,14 +486,14 @@ ithread_livelock_wakeup(systimer_t info)
  * The handler begins execution outside a critical section and with the BGL
  * held.
  *
- * The irunning state starts at 0.  When an interrupt occurs, the hardware
+ * The i_running state starts at 0.  When an interrupt occurs, the hardware
  * interrupt is disabled and sched_ithd() The HW interrupt remains disabled
  * until all routines have run.  We then call ithread_done() to reenable 
  * the HW interrupt and deschedule us until the next interrupt. 
  *
- * We are responsible for atomically checking irunning[] and ithread_done()
+ * We are responsible for atomically checking i_running and ithread_done()
  * is responsible for atomically checking for platform-specific delayed
- * interrupts.  irunning[] for our irq is only set in the context of our cpu,
+ * interrupts.  i_running for our irq is only set in the context of our cpu,
  * so a critical section is a sufficient interlock.
  */
 #define LIVELOCK_TIMEFRAME(freq)       ((freq) >> 2)   /* 1/4 second */
@@ -265,14 +501,13 @@ ithread_livelock_wakeup(systimer_t info)
 static void
 ithread_handler(void *arg)
 {
-    int intr = (int)arg;
-    int freq;
-    u_int bticks;
+    struct intr_info *info;
     u_int cputicks;
-    intrec_t **list = &intlists[intr];
-    intrec_t *rec;
-    intrec_t *nrec;
-    struct random_softc *sc = &irandom_ary[intr];
+    u_int bticks;
+    int intr;
+    int freq;
+    struct intrec **list;
+    intrec_t rec, nrec;
     globaldata_t gd = mycpu;
     struct systimer ill_timer; /* enforced freq. timer */
     struct systimer ill_rtimer;        /* recovery timer */
@@ -281,6 +516,11 @@ ithread_handler(void *arg)
     u_int ill_delta = 0;       /* track elapsed to calculate freq */
     int ill_state = 0;         /* current state */
 
+    intr = (int)arg;
+    info = &intr_info_ary[intr];
+    list = &info->i_reclist;
+    gd = mycpu;
+
     /*
      * The loop must be entered with one critical section held.
      */
@@ -291,15 +531,21 @@ ithread_handler(void *arg)
         * We can get woken up by the livelock periodic code too, run the 
         * handlers only if there is a real interrupt pending.  XXX
         *
-        * Clear irunning[] prior to running the handlers to interlock
+        * Clear i_running prior to running the handlers to interlock
         * again new events occuring during processing of existing events.
         *
-        * For now run each handler in a critical section.
+        * Run each handler in a critical section.  Note that we run both
+        * FAST and SLOW designated service routines.
         */
-       irunning[intr] = 0;
+       info->i_running = 0;
        for (rec = *list; rec; rec = nrec) {
            nrec = rec->next;
-           rec->handler(rec->argument);
+           if (rec->serializer) {
+               lwkt_serialize_handler_call(rec->serializer,
+                                       rec->handler, rec->argument, NULL);
+           } else {
+               rec->handler(rec->argument, NULL);
+           }
        }
 
        /*
@@ -314,7 +560,7 @@ ithread_handler(void *arg)
         * This is our interrupt hook to add rate randomness to the random
         * number generator.
         */
-       if (sc->sc_enabled)
+       if (info->i_random.sc_enabled)
            add_interrupt_randomness(intr);
 
        /*
@@ -383,13 +629,13 @@ ithread_handler(void *arg)
        }
 
        /*
-        * There are two races here.  irunning[] is set by sched_ithd()
+        * There are two races here.  i_running is set by sched_ithd()
         * in the context of our cpu and is critical-section safe.  We
         * are responsible for checking it.  ipending is not critical
         * section safe and must be handled by the platform specific
         * ithread_done() routine.
         */
-       if (irunning[intr] == 0)
+       if (info->i_running == 0)
            ithread_done(intr);
        /* must be in critical section on loop */
     }
@@ -405,22 +651,57 @@ ithread_handler(void *arg)
  * We do not know the length of intrcnt and intrnames at compile time, so
  * calculate things at run time.
  */
+
 static int
 sysctl_intrnames(SYSCTL_HANDLER_ARGS)
 {
-       return (sysctl_handle_opaque(oidp, intrnames, eintrnames - intrnames, 
-           req));
+    struct intr_info *info;
+    intrec_t rec;
+    int error = 0;
+    int len;
+    int intr;
+    char buf[64];
+
+    for (intr = 0; error == 0 && intr < NHWI + NSWI; ++intr) {
+       info = &intr_info_ary[intr];
+
+       len = 0;
+       buf[0] = 0;
+       for (rec = info->i_reclist; rec; rec = rec->next) {
+           snprintf(buf + len, sizeof(buf) - len, "%s%s", 
+               (len ? "/" : ""), rec->name);
+           len += strlen(buf + len);
+       }
+       if (len == 0) {
+           snprintf(buf, sizeof(buf), "irq%d", intr);
+           len = strlen(buf);
+       }
+       error = SYSCTL_OUT(req, buf, len + 1);
+    }
+    return (error);
 }
 
+
 SYSCTL_PROC(_hw, OID_AUTO, intrnames, CTLTYPE_OPAQUE | CTLFLAG_RD,
        NULL, 0, sysctl_intrnames, "", "Interrupt Names");
 
 static int
 sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
 {
-       return (sysctl_handle_opaque(oidp, intrcnt, 
-           (char *)eintrcnt - (char *)intrcnt, req));
+    struct intr_info *info;
+    int error = 0;
+    int intr;
+
+    for (intr = 0; intr < NHWI + NSWI; ++intr) {
+       info = &intr_info_ary[intr];
+
+       error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
+       if (error)
+               break;
+    }
+    return(error);
 }
 
 SYSCTL_PROC(_hw, OID_AUTO, intrcnt, CTLTYPE_OPAQUE | CTLFLAG_RD,
        NULL, 0, sysctl_intrcnt, "", "Interrupt Counts");
+
index 5bb8cbc..f87aff6 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/lwkt_serialize.c,v 1.5 2005/09/12 21:40:24 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_serialize.c,v 1.6 2005/10/13 00:02:22 dillon Exp $
  */
 /*
  * This API provides a fast locked-bus-cycle-based serializer.  It's
@@ -109,7 +109,8 @@ lwkt_serialize_handler_enable(lwkt_serialize_t s)
 }
 
 void
-lwkt_serialize_handler_call(lwkt_serialize_t s, void (*func)(void *), void *arg)
+lwkt_serialize_handler_call(lwkt_serialize_t s, void (*func)(void *, void *), 
+                           void *arg, void *frame)
 {
     /*
      * note: a return value of 0 indicates that the interrupt handler is 
@@ -118,11 +119,33 @@ lwkt_serialize_handler_call(lwkt_serialize_t s, void (*func)(void *), void *arg)
     if (atomic_intr_handler_is_enabled(&s->interlock) == 0) {
        atomic_intr_cond_enter(&s->interlock, lwkt_serialize_sleep, s);
        if (atomic_intr_handler_is_enabled(&s->interlock) == 0)
-           func(arg);
+           func(arg, frame);
        atomic_intr_cond_exit(&s->interlock, lwkt_serialize_wakeup, s);
     }
 }
 
+/*
+ * Similar to handler_call but does not block.  Returns 0 on success, 
+ * and 1 on failure.
+ */
+int
+lwkt_serialize_handler_try(lwkt_serialize_t s, void (*func)(void *, void *),
+                          void *arg, void *frame)
+{
+    /*
+     * note: a return value of 0 indicates that the interrupt handler is 
+     * enabled.
+     */
+    if (atomic_intr_handler_is_enabled(&s->interlock) == 0) {
+       if (atomic_intr_cond_try(&s->interlock) == 0) {
+           func(arg, frame);
+           return(0);
+       }
+    }
+    return(1);
+}
+
+
 /*
  * Helper functions
  *
index 0d03a1c..a49aab1 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  *      $FreeBSD: src/sys/kern/subr_taskqueue.c,v 1.1.2.3 2003/09/10 00:40:39 ken Exp $
- *     $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.8 2005/09/21 18:58:55 hsu Exp $
+ *     $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.9 2005/10/13 00:02:22 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -197,13 +197,13 @@ taskqueue_swi_enqueue(void *context)
 }
 
 static void
-taskqueue_swi_run(void *arg)
+taskqueue_swi_run(void *arg, void *frame)
 {
        taskqueue_run(taskqueue_swi);
 }
 
 TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0,
-                register_swi(SWI_TQ, taskqueue_swi_run, NULL, "swi_taskq"));
+        register_swi(SWI_TQ, taskqueue_swi_run, NULL, "swi_taskq", NULL));
 
 static void
 taskqueue_kthread(void *arg)
index c6cad1a..bfaf8dc 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.7 2003/06/03 00:09:02 sam Exp $   */
-/*     $DragonFly: src/sys/opencrypto/crypto.c,v 1.9 2005/06/16 21:12:49 dillon Exp $  */
+/*     $DragonFly: src/sys/opencrypto/crypto.c,v 1.10 2005/10/13 00:02:48 dillon Exp $ */
 /*     $OpenBSD: crypto.c,v 1.38 2002/06/11 11:14:29 beck Exp $        */
 /*
  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -112,7 +112,7 @@ MALLOC_DEFINE(M_CRYPTO_DATA, "crypto", "crypto session records");
  *
  * This scheme is not intended for SMP machines.
  */ 
-static void cryptointr(void *dummy);   /* swi thread to dispatch ops */
+static inthand2_t cryptointr;
 static void cryptoret(void);           /* kernel thread for callbacks*/
 static struct thread *cryptothread;
 static void crypto_destroy(void);
@@ -129,6 +129,8 @@ SYSCTL_INT(_debug, OID_AUTO, crypto_timing, CTLFLAG_RW,
           &crypto_timing, 0, "Enable/disable crypto timing support");
 #endif
 
+static void *crypto_int_id;
+
 static int
 crypto_init(void)
 {
@@ -156,7 +158,8 @@ crypto_init(void)
        TAILQ_INIT(&crp_ret_q);
        TAILQ_INIT(&crp_ret_kq);
 
-       register_swi(SWI_CRYPTO, cryptointr, NULL, "swi_crypto");
+       crypto_int_id = register_swi(SWI_CRYPTO, cryptointr, NULL, 
+                                       "swi_crypto", NULL);
        error = kthread_create((void (*)(void *)) cryptoret, NULL,
                    &cryptothread, "cryptoret");
        if (error) {
@@ -173,7 +176,7 @@ crypto_destroy(void)
        /* XXX no wait to reclaim zones */
        if (crypto_drivers != NULL)
                free(crypto_drivers, M_CRYPTO_DATA);
-       unregister_swi(SWI_CRYPTO, cryptointr);
+       unregister_swi(crypto_int_id);
 }
 
 /*
@@ -985,7 +988,7 @@ out:
  * Software interrupt thread to dispatch crypto requests.
  */
 static void
-cryptointr(void *dummy)
+cryptointr(void *dummy, void *frame)
 {
        struct cryptop *crp, *submit;
        struct cryptkop *krp;
index 001c55b..0ef6b52 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
- * $DragonFly: src/sys/platform/pc32/apic/apic_vector.s,v 1.22 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/apic/apic_vector.s,v 1.23 2005/10/13 00:02:47 dillon Exp $
  */
 
 
  * Test to see if the source is currntly masked, clear if so.
  */
 #define UNMASK_IRQ(irq_num)                                    \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        IMASK_LOCK ;                            /* into critical reg */ \
        testl   $IRQ_LBIT(irq_num), apic_imen ;                         \
        je      7f ;                    /* bit clear, not masked */     \
        movl    %eax,IOAPIC_WINDOW(%ecx) ;      /* new value */         \
 7: ;                                                                   \
        IMASK_UNLOCK ;                                                  \
+8: ;                                                                   \
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -164,40 +167,15 @@ IDTVEC(vec_name) ;                                                        \
        orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
-       /* try to get the MP lock */                                    \
-       call    try_mplock ;                                            \
-       testl   %eax,%eax ;                                             \
-       jz      6f ;                                                    \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;   /* returns 0 to unmask */      \
        addl    $4, %esp ;                                              \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
-       decl    PCPU(intr_nesting_level) ;                              \
-       call    rel_mplock ;                                            \
        UNMASK_IRQ(irq_num) ;                                           \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
-6: ;                                                                   \
-       /* could not get the MP lock, forward the interrupt */          \
-       movl    mp_lock, %eax ;          /* check race */               \
-       cmpl    $MP_FREE_LOCK,%eax ;                                    \
-       je      2b ;                                                    \
-       incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
-       subl    $12,%esp ;                                              \
-       movl    $irq_num,8(%esp) ;                                      \
-       movl    $forward_fastint_remote,4(%esp) ;                       \
-       movl    %eax,(%esp) ;                                           \
-       call    lwkt_send_ipiq_bycpu ;                                  \
-       addl    $12,%esp ;                                              \
-       jmp     5f ;                                                    \
 
 /*
  * Restart fast interrupt held up by critical section or cpl.
@@ -222,12 +200,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask */       \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(irq_num) ;                                           \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -280,9 +255,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
index 5f60e2d..ac8128c 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.17 2005/06/16 21:12:44 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.18 2005/10/13 00:02:44 dillon Exp $
  */
 
 /*
@@ -523,8 +523,13 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
        if (error)
                return (error);
 
+       /*
+        * XXX cast the interrupt handler function to an inthand2_t.  The
+        * difference is that an additional frame argument is passed which
+        * we do not currently want to expose the BUS subsystem to.
+        */
        *cookiep = inthand_add(device_get_nameunit(child), irq->r_start,
-           ihand, arg, icflags, serializer);
+           (inthand2_t *)ihand, arg, icflags, serializer);
        if (*cookiep == NULL)
                error = EINVAL; /* XXX ??? */
 
index 21062c4..4a7110e 100644 (file)
@@ -39,7 +39,7 @@
  *     from: @(#)vm_machdep.c  7.3 (Berkeley) 5/13/91
  *     Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
  * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $
- * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.36 2005/06/16 21:12:44 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.37 2005/10/13 00:02:44 dillon Exp $
  */
 
 #include "use_npx.h"
@@ -576,7 +576,7 @@ vm_page_zero_idle()
 }
 
 static void
-swi_vm(void *arg)
+swi_vm(void *arg, void *frame)
 {
        if (busdma_swi_pending != 0)
                busdma_swi();
@@ -585,7 +585,7 @@ swi_vm(void *arg)
 static void
 swi_vm_setup(void *arg)
 {
-       register_swi(SWI_VM, swi_vm, NULL, "swi_vm");
+       register_swi(SWI_VM, swi_vm, NULL, "swi_vm", NULL);
 }
 
 SYSINIT(vm_setup, SI_SUB_CPU, SI_ORDER_ANY, swi_vm_setup, NULL);
index 3341e19..5bdd4cf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/icu_vector.s,v 1.14.2.2 2000/07/18 21:12:42 dfr Exp $
- * $DragonFly: src/sys/platform/pc32/icu/icu_vector.s,v 1.18 2005/06/16 21:12:47 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/icu/icu_vector.s,v 1.19 2005/10/13 00:02:47 dillon Exp $
  */
 
 #define ICU_IMR_OFFSET         1       /* IO_ICU{1,2} + 1 */
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
 
 #define UNMASK_IRQ(icu, irq_num)                                       \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        movb    imen + IRQ_BYTE(irq_num),%al ;                          \
        andb    $~IRQ_BIT(irq_num),%al ;                                \
        movb    %al,imen + IRQ_BYTE(irq_num) ;                          \
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
+8: ;                                                                   \
        
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -123,24 +126,17 @@ IDTVEC(vec_name) ;                                                        \
        jmp     5f ;                                                    \
 2: ;                                                                   \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4,%esp ;                                               \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       decl    PCPU(intr_nesting_level) ;                              \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
 
 /*
- * Restart fast interrupt held up by critical section or cpl.
+ * Restart fast interrupt held up by critical section.
  *
  *     - Push a dummy trap frame as required by doreti.
  *     - The interrupt source is already masked.
@@ -159,12 +155,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;                                      \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -219,9 +212,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
@@ -238,6 +228,7 @@ IDTVEC(vec_name) ;                                                  \
 IDTVEC(vec_name) ;                                                     \
        pushl %ebp ;     /* frame for ddb backtrace */                  \
        movl    %esp, %ebp ;                                            \
+       subl    %eax, %eax ;                                            \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        popl %ebp ;                                                     \
        ret ;                                                           \
index eb5b7be..6a646be 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
- * $DragonFly: src/sys/platform/pc32/isa/Attic/apic_vector.s,v 1.22 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/Attic/apic_vector.s,v 1.23 2005/10/13 00:02:47 dillon Exp $
  */
 
 
  * Test to see if the source is currntly masked, clear if so.
  */
 #define UNMASK_IRQ(irq_num)                                    \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        IMASK_LOCK ;                            /* into critical reg */ \
        testl   $IRQ_LBIT(irq_num), apic_imen ;                         \
        je      7f ;                    /* bit clear, not masked */     \
        movl    %eax,IOAPIC_WINDOW(%ecx) ;      /* new value */         \
 7: ;                                                                   \
        IMASK_UNLOCK ;                                                  \
+8: ;                                                                   \
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -164,40 +167,15 @@ IDTVEC(vec_name) ;                                                        \
        orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
-       /* try to get the MP lock */                                    \
-       call    try_mplock ;                                            \
-       testl   %eax,%eax ;                                             \
-       jz      6f ;                                                    \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;   /* returns 0 to unmask */      \
        addl    $4, %esp ;                                              \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
-       decl    PCPU(intr_nesting_level) ;                              \
-       call    rel_mplock ;                                            \
        UNMASK_IRQ(irq_num) ;                                           \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
-6: ;                                                                   \
-       /* could not get the MP lock, forward the interrupt */          \
-       movl    mp_lock, %eax ;          /* check race */               \
-       cmpl    $MP_FREE_LOCK,%eax ;                                    \
-       je      2b ;                                                    \
-       incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
-       subl    $12,%esp ;                                              \
-       movl    $irq_num,8(%esp) ;                                      \
-       movl    $forward_fastint_remote,4(%esp) ;                       \
-       movl    %eax,(%esp) ;                                           \
-       call    lwkt_send_ipiq_bycpu ;                                  \
-       addl    $12,%esp ;                                              \
-       jmp     5f ;                                                    \
 
 /*
  * Restart fast interrupt held up by critical section or cpl.
@@ -222,12 +200,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ; /* do the work ASAP */  \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask */       \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(irq_num) ;                                           \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -280,9 +255,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
index e81a234..3f85e54 100644 (file)
@@ -35,7 +35,7 @@
  */
 /*
  * $FreeBSD: src/sys/i386/isa/asc.c,v 1.42.2.2 2001/03/01 03:22:39 jlemon Exp $
- * $DragonFly: src/sys/platform/pc32/isa/asc.c,v 1.9 2005/06/03 17:14:51 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/asc.c,v 1.10 2005/10/13 00:02:47 dillon Exp $
  */
 
 #include "use_asc.h"
@@ -177,7 +177,7 @@ static int ascprobe (struct isa_device *isdp);
 static int ascattach(struct isa_device *isdp);
 struct isa_driver ascdriver = { ascprobe, ascattach, "asc" };
 
-static ointhand2_t     ascintr;
+static inthand2_t      ascintr;
 
 static d_open_t                ascopen;
 static d_close_t       ascclose;
@@ -453,7 +453,7 @@ ascattach(struct isa_device *isdp)
   int unit = isdp->id_unit;
   struct asc_unit *scu = unittab + unit;
 
-  isdp->id_ointr = ascintr;
+  isdp->id_intr = ascintr;
   scu->flags |= FLAG_DEBUG;
   printf("asc%d: [GI1904/Trust Ami-Scan Grey/Color]\n", unit);
 
@@ -497,10 +497,11 @@ ascattach(struct isa_device *isdp)
  ***   the interrupt routine, at the end of DMA...
  ***/
 static void
-ascintr(int unit)
+ascintr(void *arg)
 {
     struct asc_unit *scu = unittab + unit;
     int chan_bit = 0x01 << scu->dma_num;
+    int unit = (int)arg;
 
     scu->icnt++;
     /* ignore stray interrupts... */
index 73677d4..b5b6b7e 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)clock.c       7.2 (Berkeley) 5/12/91
  * $FreeBSD: src/sys/i386/isa/clock.c,v 1.149.2.6 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/platform/pc32/isa/clock.c,v 1.32 2005/09/12 21:32:03 joerg Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/clock.c,v 1.33 2005/10/13 00:02:47 dillon Exp $
  */
 
 /*
@@ -96,7 +96,6 @@
 #include <i386/isa/intr_machdep.h>
 /* The interrupt triggered by the 8254 (timer) chip */
 int apic_8254_intr;
-static u_long read_intr_count (int vec);
 static void setup_8254_mixed_mode (void);
 #endif
 static void i8254_restore(void);
@@ -163,7 +162,7 @@ static struct cputimer      i8254_cputimer = {
  * pending.
  */
 static void
-clkintr(struct intrframe frame)
+clkintr(void *dummy, void *frame_arg)
 {
        static sysclock_t timer1_count;
        struct globaldata *gd = mycpu;
@@ -188,7 +187,7 @@ clkintr(struct intrframe frame)
            if (gscan != gd) {
                lwkt_send_ipiq(gscan, (ipifunc_t)systimer_intr, &timer1_count);
            } else {
-               systimer_intr(&timer1_count, &frame);
+               systimer_intr(&timer1_count, frame_arg);
            }
        }
 }
@@ -245,11 +244,11 @@ release_timer2()
  * in the statistics, but the stat clock will no longer stop.
  */
 static void
-rtcintr(struct intrframe frame)
+rtcintr(void *dummy, void *frame)
 {
        while (rtcin(RTC_INTR) & RTCIR_PERIOD)
                ;
-               /* statclock(&frame); no longer used */
+               /* statclock(frame); no longer used */
 }
 
 #include "opt_ddb.h"
@@ -936,7 +935,7 @@ cpu_initclocks()
        int diag;
 #ifdef APIC_IO
        int apic_8254_trial;
-       struct intrec *clkdesc;
+       void *clkdesc;
 #endif /* APIC_IO */
 
        if (statclock_disable) {
@@ -970,13 +969,13 @@ cpu_initclocks()
                        panic("APIC_IO: Cannot route 8254 interrupt to CPU");
        }
 
-       clkdesc = inthand_add("clk", apic_8254_intr, (inthand2_t *)clkintr,
+       clkdesc = inthand_add("clk", apic_8254_intr, clkintr,
                              NULL, INTR_EXCL | INTR_FAST, NULL);
        INTREN(1 << apic_8254_intr);
        
 #else /* APIC_IO */
 
-       inthand_add("clk", 0, (inthand2_t *)clkintr, NULL,
+       inthand_add("clk", 0, clkintr, NULL,
                    INTR_EXCL | INTR_FAST, NULL);
        INTREN(IRQ0);
 
@@ -1011,7 +1010,9 @@ cpu_initclocks()
 #ifdef APIC_IO
        if (apic_8254_trial) {
                sysclock_t base;
-               int lastcnt = read_intr_count(apic_8254_intr);
+               long lastcnt;
+
+               lastcnt = get_interrupt_counter(apic_8254_intr);
 
                /*
                 * XXX this assumes the 8254 is the cpu timer.  Force an
@@ -1023,7 +1024,7 @@ cpu_initclocks()
                base = sys_cputimer->count();
                while (sys_cputimer->count() - base < sys_cputimer->freq / 100)
                        ;       /* nothing */
-               if (read_intr_count(apic_8254_intr) - lastcnt == 0) {
+               if (get_interrupt_counter(apic_8254_intr) - lastcnt == 0) {
                        /* 
                         * The MP table is broken.
                         * The 8254 was not connected to the specified pin
@@ -1051,7 +1052,7 @@ cpu_initclocks()
                        apic_8254_intr = apic_irq(0, 0);
                        setup_8254_mixed_mode();
                        inthand_add("clk", apic_8254_intr,
-                                   (inthand2_t *)clkintr,
+                                   clkintr,
                                    NULL,
                                    INTR_EXCL | INTR_FAST, NULL);
                        INTREN(1 << apic_8254_intr);
@@ -1073,15 +1074,6 @@ cpu_initclocks()
 }
 
 #ifdef APIC_IO
-static u_long
-read_intr_count(int vec)
-{
-       u_long *up;
-       up = intr_countp[vec];
-       if (up)
-               return *up;
-       return 0UL;
-}
 
 static void 
 setup_8254_mixed_mode()
index a597255..dce8cd1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/icu_vector.s,v 1.14.2.2 2000/07/18 21:12:42 dfr Exp $
- * $DragonFly: src/sys/platform/pc32/isa/Attic/icu_vector.s,v 1.18 2005/06/16 21:12:47 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/Attic/icu_vector.s,v 1.19 2005/10/13 00:02:47 dillon Exp $
  */
 
 #define ICU_IMR_OFFSET         1       /* IO_ICU{1,2} + 1 */
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
 
 #define UNMASK_IRQ(icu, irq_num)                                       \
+       cmpl    $0,%eax ;                                               \
+       jnz     8f ;                                                    \
        movb    imen + IRQ_BYTE(irq_num),%al ;                          \
        andb    $~IRQ_BIT(irq_num),%al ;                                \
        movb    %al,imen + IRQ_BYTE(irq_num) ;                          \
        outb    %al,$icu+ICU_IMR_OFFSET ;                               \
+8: ;                                                                   \
        
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -123,24 +126,17 @@ IDTVEC(vec_name) ;                                                        \
        jmp     5f ;                                                    \
 2: ;                                                                   \
        /* clear pending bit, run handler */                            \
-       incl    PCPU(intr_nesting_level) ;                              \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4,%esp ;                                               \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       decl    PCPU(intr_nesting_level) ;                              \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
 
 /*
- * Restart fast interrupt held up by critical section or cpl.
+ * Restart fast interrupt held up by critical section.
  *
  *     - Push a dummy trap frame as required by doreti.
  *     - The interrupt source is already masked.
@@ -159,12 +155,9 @@ IDTVEC(vec_name) ;                                                 \
        pushl   %ebp ;                                                  \
        movl    %esp,%ebp ;                                             \
        PUSH_DUMMY ;                                                    \
-       pushl   intr_unit + (irq_num) * 4 ;                             \
-       call    *intr_handler + (irq_num) * 4 ;                         \
+       pushl   $irq_num ;                                              \
+       call    ithread_fast_handler ;  /* returns 0 to unmask int */   \
        addl    $4, %esp ;                                              \
-       incl    PCPU(cnt)+V_INTR ;                                      \
-       movl    intr_countp + (irq_num) * 4, %eax ;                     \
-       incl    (%eax) ;                                                \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        POP_DUMMY ;                                                     \
        popl %ebp ;                                                     \
@@ -219,9 +212,6 @@ IDTVEC(vec_name) ;                                                  \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
-       movl    intr_countp + (irq_num) * 4,%eax ;                      \
-       incl    (%eax) ;                                                \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
@@ -238,6 +228,7 @@ IDTVEC(vec_name) ;                                                  \
 IDTVEC(vec_name) ;                                                     \
        pushl %ebp ;     /* frame for ddb backtrace */                  \
        movl    %esp, %ebp ;                                            \
+       subl    %eax, %eax ;                                            \
        UNMASK_IRQ(icu, irq_num) ;                                      \
        popl %ebp ;                                                     \
        ret ;                                                           \
index 2d8eae6..88c5769 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)isa.c 7.2 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/isa/intr_machdep.c,v 1.29.2.5 2001/10/14 06:54:27 luigi Exp $
- * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.c,v 1.32 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.c,v 1.33 2005/10/13 00:02:47 dillon Exp $
  */
 /*
  * This file contains an aggregated module marked:
 
 #define        NR_INTRNAMES    (1 + ICU_LEN + 2 * ICU_LEN)
 
-static inthand2_t isa_strayintr;
-#if defined(FAST_HI) && defined(APIC_IO)
-void do_wrongintr(int intr);
-#endif
 static void    init_i8259(void);
-
-void   *intr_unit[ICU_LEN*2];
-u_long *intr_countp[ICU_LEN*2];
-inthand2_t *intr_handler[ICU_LEN*2] = {
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-       isa_strayintr, isa_strayintr, isa_strayintr, isa_strayintr,
-};
-
-static struct md_intr_info {
-    int                irq;
-    int                mihandler_installed;
-} intr_info[ICU_LEN*2];
+static int     icu_unset(int intr);
+static int     icu_setup(int intr, int flags);
 
 static inthand_t *fastintr[ICU_LEN] = {
        &IDTVEC(fastintr0), &IDTVEC(fastintr1),
@@ -240,12 +220,13 @@ isa_nmi(cd)
 void
 icu_reinit()
 {
-       int i;
+       int i;
 
-       init_i8259();
-       for(i=0;i<ICU_LEN;i++)
-               if(intr_handler[i] != isa_strayintr)
-                       INTREN(1<<i);
+       init_i8259();
+       for (i = 0; i < ICU_LEN; ++i) {
+               if (count_registered_ints(i))
+                       INTREN(1 << i);
+       }
 }
 
 /*
@@ -259,7 +240,7 @@ isa_defaultirq()
 
        /* icu vectors */
        for (i = 0; i < ICU_LEN; i++)
-               icu_unset(i, isa_strayintr);
+               icu_unset(i);
        init_i8259();
 }
 
@@ -291,61 +272,6 @@ init_i8259(void)
        outb(IO_ICU2, 0x0a);            /* default to IRR on read */
 }
 
-/*
- * Caught a stray interrupt, notify
- */
-static void
-isa_strayintr(void *vcookiep)
-{
-       int intr = (void **)vcookiep - &intr_unit[0];
-
-       /* DON'T BOTHER FOR NOW! */
-       /* for some reason, we get bursts of intr #7, even if not enabled! */
-       /*
-        * Well the reason you got bursts of intr #7 is because someone
-        * raised an interrupt line and dropped it before the 8259 could
-        * prioritize it.  This is documented in the intel data book.  This
-        * means you have BAD hardware!  I have changed this so that only
-        * the first 5 get logged, then it quits logging them, and puts
-        * out a special message. rgrimes 3/25/1993
-        */
-       /*
-        * XXX TODO print a different message for #7 if it is for a
-        * glitch.  Glitches can be distinguished from real #7's by
-        * testing that the in-service bit is _not_ set.  The test
-        * must be done before sending an EOI so it can't be done if
-        * we are using AUTO_EOI_1.
-        */
-       if (intrcnt[1 + intr] <= 5)
-               log(LOG_ERR, "stray irq %d\n", intr);
-       if (intrcnt[1 + intr] == 5)
-               log(LOG_CRIT,
-                   "too many stray irq %d's; not logging any more\n", intr);
-}
-
-#if defined(FAST_HI) && defined(APIC_IO)
-
-/*
- * This occurs if we've mis-programmed the APIC and its vector is still
- * pointing to the slow vector even when we thought we reprogrammed it
- * to the high vector.  This can occur when interrupts are improperly
- * routed by the APIC.  The unit data is opaque so we have to try to
- * find it in the unit array.
- */
-void
-do_wrongintr(int intr)
-{
-       if (intrcnt[1 + intr] <= 5) {
-               log(LOG_ERR, "stray irq ~%d on cpu %d (APIC misprogrammed)\n",
-                   intr, mycpu->gd_cpuid);
-       } else if (intrcnt[1 + intr] == 6) {
-               log(LOG_CRIT,
-                   "too many stray irq ~%d's; not logging any more\n", intr);
-       }
-}
-
-#endif
-
 #if NISA > 0
 /*
  * Return a bitmap of the current interrupt requests.  This is 8259-specific
@@ -363,61 +289,9 @@ isa_irq_pending(void)
 }
 #endif
 
-static void
-update_intrname(int intr, char *name)
-{
-       char buf[32];
-       char *cp;
-       int name_index, off, strayintr;
-
-       /*
-        * Initialise strings for bitbucket and stray interrupt counters.
-        * These have statically allocated indices 0 and 1 through ICU_LEN.
-        */
-       if (intrnames[0] == '\0') {
-               off = sprintf(intrnames, "???") + 1;
-               for (strayintr = 0; strayintr < ICU_LEN; strayintr++)
-                       off += sprintf(intrnames + off, "stray irq%d",
-                           strayintr) + 1;
-       }
-
-       if (name == NULL)
-               name = "???";
-       if (snprintf(buf, sizeof(buf), "%s irq%d", name, intr) >= sizeof(buf))
-               goto use_bitbucket;
-
-       /*
-        * Search for `buf' in `intrnames'.  In the usual case when it is
-        * not found, append it to the end if there is enough space (the \0
-        * terminator for the previous string, if any, becomes a separator).
-        */
-       for (cp = intrnames, name_index = 0;
-           cp != eintrnames && name_index < NR_INTRNAMES;
-           cp += strlen(cp) + 1, name_index++) {
-               if (*cp == '\0') {
-                       if (strlen(buf) >= eintrnames - cp)
-                               break;
-                       strcpy(cp, buf);
-                       goto found;
-               }
-               if (strcmp(cp, buf) == 0)
-                       goto found;
-       }
-
-use_bitbucket:
-       printf("update_intrname: counting %s irq%d as %s\n", name, intr,
-           intrnames);
-       name_index = 0;
-found:
-       intr_countp[intr] = &intrcnt[name_index];
-}
-
-/*
- * NOTE!  intr_handler[] is only used for FAST interrupts, the *vector.s
- * code ignores it for normal interrupts.
- */
+static
 int
-icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
+icu_setup(int intr, int flags)
 {
 #if defined(FAST_HI) && defined(APIC_IO)
        int             select;         /* the select register is 8 bits */
@@ -432,17 +306,9 @@ icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
        if ((u_int)intr >= ICU_LEN || intr == ICU_SLAVEID)
 #endif /* APIC_IO */
                return (EINVAL);
-       if (intr_handler[intr] != isa_strayintr)
-               return (EBUSY);
 
        ef = read_eflags();
        cpu_disable_intr();     /* YYY */
-       intr_handler[intr] = handler;
-       intr_unit[intr] = arg;
-#if 0
-       /* YYY  fast ints supported and mp protected but ... */
-       flags &= ~INTR_FAST;
-#endif
 #if defined(FAST_HI) && defined(APIC_IO)
        if (flags & INTR_FAST) {
                /*
@@ -493,25 +359,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, int flags)
        return (0);
 }
 
-int
-icu_unset(intr, handler)
-       int     intr;
-       inthand2_t *handler;
+static int
+icu_unset(int intr)
 {
        u_long  ef;
 
-       if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) {
-               printf("icu_unset: invalid handler %d %p/%p\n", intr, handler, 
-                   (((u_int)intr >= ICU_LEN) ? (void *)-1 : intr_handler[intr]));
-               return (EINVAL);
-       }
-
+       KKASSERT((u_int)intr < ICU_LEN);
        INTRDIS(1 << intr);
        ef = read_eflags();
        cpu_disable_intr();     /* YYY */
-       intr_countp[intr] = &intrcnt[1 + intr];
-       intr_handler[intr] = isa_strayintr;
-       intr_unit[intr] = &intr_unit[intr];
 #ifdef FAST_HI_XXX
        /* XXX how do I re-create dvp here? */
        setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr,
@@ -559,151 +415,6 @@ icu_unset(intr, handler)
  *
  */
 
-typedef struct intrec {
-       inthand2_t      *handler;
-       void            *argument;
-       struct intrec   *next;
-       char            *name;
-       int             intr;
-       int             flags;
-       lwkt_serialize_t serializer;
-       volatile int    in_handler;
-} intrec;
-
-static intrec *intreclist_head[ICU_LEN];
-
-/*
- * The interrupt multiplexer calls each of the handlers in turn.  A handler
- * is called only if we can successfully obtain the interlock, meaning
- * (1) we aren't recursed and (2) the handler has not been disabled via
- * inthand_disabled().
- *
- * XXX the IPL is currently raised as necessary for the handler.  However,
- * IPLs are not MP safe so the IPL code will be removed when the device
- * drivers, BIO, and VM no longer depend on it.
- */
-static void
-intr_mux(void *arg)
-{
-       intrec **pp;
-       intrec *p;
-
-       for (pp = arg; (p = *pp) != NULL; pp = &p->next) {
-               if (p->serializer) {
-                       /*
-                        * New handler dispatch method.  Only the serializer
-                        * is used to interlock access.  Note that this
-                        * API includes a handler disablement feature.
-                        */
-                       lwkt_serialize_handler_call(p->serializer,
-                                                   p->handler, p->argument);
-               } else {
-                       /*
-                        * Old handlers may expect multiple interrupt
-                        * sources to be masked.  We must use a critical
-                        * section.
-                        */
-                       crit_enter();
-                       p->handler(p->argument);
-                       crit_exit();
-               }
-       }
-}
-
-/*
- * Add an interrupt handler to the linked list hung off of intreclist_head[irq]
- * and install a shared interrupt multiplex handler.  Install an interrupt
- * thread for each interrupt (though FAST interrupts will not use it).
- * The preemption procedure checks the CPL.  lwkt_preempt() will check
- * relative thread priorities for us as long as we properly pass through
- * critpri.
- *
- * The interrupt thread has already been put on the run queue, so if we cannot
- * preempt we should force a reschedule.
- *
- * This preemption check routine is currently empty, but will be used in the
- * future to pre-check interrupts for preemptability to avoid the
- * inefficiencies of having to instantly block.  We used to do a CPL check
- * here (otherwise the interrupt thread could preempt even when it wasn't
- * supposed to), but with CPLs gone we no longer have to do this.
- */
-static void
-cpu_intr_preempt(struct thread *td, int critpri)
-{
-       lwkt_preempt(td, critpri);
-}
-
-static int
-add_intrdesc(intrec *idesc)
-{
-       int irq = idesc->intr;
-       intrec *head;
-       intrec **headp;
-
-       /*
-        * There are two ways to enter intr_mux().  (1) via the scheduled
-        * interrupt thread or (2) directly.   The thread mechanism is the
-        * normal mechanism used by SLOW interrupts, while the direct method
-        * is used by FAST interrupts.
-        *
-        * We need to create an interrupt thread if none exists.
-        */
-       if (intr_info[irq].mihandler_installed == 0) {
-               struct thread *td;
-
-               intr_info[irq].mihandler_installed = 1;
-               intr_info[irq].irq = irq;
-               td = register_int(irq, intr_mux, &intreclist_head[irq], idesc->name);
-               td->td_info.intdata = &intr_info[irq];
-               td->td_preemptable = cpu_intr_preempt;
-               printf("installed MI handler for int %d\n", irq);
-       }
-
-       headp = &intreclist_head[irq];
-       head = *headp;
-
-       /*
-        * Check exclusion
-        */
-       if (head) {
-               if ((idesc->flags & INTR_EXCL) || (head->flags & INTR_EXCL)) {
-                       printf("\tdevice combination doesn't support "
-                              "shared irq%d\n", irq);
-                       return (-1);
-               }
-               if ((idesc->flags & INTR_FAST) || (head->flags & INTR_FAST)) {
-                       printf("\tdevice combination doesn't support "
-                              "multiple FAST interrupts on IRQ%d\n", irq);
-               }
-       }
-
-       /*
-        * Always install intr_mux as the hard handler so it can deal with
-        * individual enablement on handlers.
-        */
-       if (head == NULL) {
-               if (icu_setup(irq, idesc->handler, idesc->argument, idesc->flags) != 0)
-                       return (-1);
-               update_intrname(irq, idesc->name);
-       } else if (head->next == NULL) {
-               icu_unset(irq, head->handler);
-               if (icu_setup(irq, intr_mux, &intreclist_head[irq], 0) != 0)
-                       return (-1);
-               if (bootverbose && head->next == NULL)
-                       printf("\tusing shared irq%d.\n", irq);
-               update_intrname(irq, "mux");
-       }
-
-       /*
-        * Append to the end of the chain.
-        */
-       while (*headp != NULL)
-               headp = &(*headp)->next;
-       *headp = idesc;
-
-       return (0);
-}
-
 /*
  * Create and activate an interrupt handler descriptor data structure.
  *
@@ -722,52 +433,48 @@ add_intrdesc(intrec *idesc)
  * drivers.  It is subject to change without notice.
  */
 
-intrec *
+void *
 inthand_add(const char *name, int irq, inthand2_t handler, void *arg,
             int flags, lwkt_serialize_t serializer)
 {
-       intrec *idesc;
-       int errcode = -1;
+       int errcode = 0;
+       void *id;
 
        if ((unsigned)irq >= ICU_LEN) {
                printf("create_intr: requested irq%d too high, limit is %d\n",
                       irq, ICU_LEN -1);
                return (NULL);
        }
+       /*
+        * Register the interrupt, then setup the ICU
+        */
+       id = register_int(irq, handler, arg, name, serializer, flags);
 
-       idesc = malloc(sizeof *idesc, M_DEVBUF, M_WAITOK | M_ZERO);
-       if (idesc == NULL)
-               return NULL;
-
-       if (name == NULL)
-               name = "???";
-       idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
-       if (idesc->name == NULL) {
-               free(idesc, M_DEVBUF);
-               return NULL;
+       if (id == NULL) {
+               printf("Unable to install handler for %s\n", name);
+               printf("\tdevice combination not supported on irq %d\n", irq);
+               return(NULL);
        }
-       strcpy(idesc->name, name);
-
-       idesc->handler  = handler;
-       idesc->argument = arg;
-       idesc->intr     = irq;
-       idesc->flags    = flags;
-       idesc->serializer = serializer;
 
        crit_enter();
-       errcode = add_intrdesc(idesc);
+       if (count_registered_ints(irq) == 1) {
+               if (icu_setup(irq, flags))
+                       errcode = -1;
+       }
        crit_exit();
 
+       /*
+        * Cleanup
+        */
        if (errcode != 0) {
-               if (bootverbose)
-                       printf("\tintr_connect(irq%d) failed, result=%d\n", 
+               if (bootverbose) {
+                       printf("\tinthand_add(irq%d) failed, result=%d\n", 
                               irq, errcode);
-               free(idesc->name, M_DEVBUF);
-               free(idesc, M_DEVBUF);
-               idesc = NULL;
+               }
+               unregister_int(id);
+               id = NULL;
        }
-
-       return (idesc);
+       return (id);
 }
 
 /*
@@ -778,57 +485,19 @@ inthand_add(const char *name, int irq, inthand2_t handler, void *arg,
  * to the system. Make sure, the handler is not actively used anymore, before.
  */
 int
-inthand_remove(intrec *idesc)
+inthand_remove(void *id)
 {
-       intrec **hook, *head;
        int irq;
 
-       if (idesc == NULL)
-               return (-1);
+       if (id == NULL)
+               return(-1);
 
-       irq = idesc->intr;
        crit_enter();
-
-       /*
-        * Find and remove the interrupt descriptor.
-        */
-       hook = &intreclist_head[irq];
-       while (*hook != idesc) {
-               if (*hook == NULL) {
-                       crit_exit();
-                       return(-1);
-               }
-               hook = &(*hook)->next;
-       }
-       *hook = idesc->next;
-
-       /*
-        * If the list is now empty, revert the hard vector to the spurious
-        * interrupt.
-        */
-       head = intreclist_head[irq];
-       if (head == NULL) {
-               /*
-                * No more interrupts on this irq
-                */
-               icu_unset(irq, idesc->handler);
-               update_intrname(irq, NULL);
-       } else if (head->next) {
-               /*
-                * This irq is still shared (has at least two handlers)
-                * (the name should already be set to "mux").
-                */
-       } else {
-               /*
-                * This irq is no longer shared
-                */
-               icu_unset(irq, intr_mux);
-               icu_setup(irq, head->handler, head->argument, head->flags);
-               update_intrname(irq, head->name);
+       irq = get_registered_intr(id);
+       if (unregister_int(id) == 0) {
+               icu_unset(irq);
        }
        crit_exit();
-       free(idesc, M_DEVBUF);
-
        return (0);
 }
 
index 0c8ad12..49b2f8d 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/intr_machdep.h,v 1.19.2.2 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.h,v 1.17 2005/09/10 06:48:08 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.h,v 1.18 2005/10/13 00:02:47 dillon Exp $
  */
 
 #ifndef _I386_ISA_INTR_MACHDEP_H_
@@ -147,10 +147,6 @@ typedef void unpendhand_t(void);
 
 #define        IDTVEC(name)    __CONCAT(X,name)
 
-extern u_long *intr_countp[];  /* pointers into intrcnt[] */
-extern inthand2_t *intr_handler[];     /* C entry points for FAST ints */
-extern void *intr_unit[];      /* cookies to pass to intr handlers */
-
 inthand_t
        IDTVEC(fastintr0), IDTVEC(fastintr1),
        IDTVEC(fastintr2), IDTVEC(fastintr3),
@@ -230,18 +226,15 @@ inthand_t
 void   call_fast_unpend(int irq);
 void   isa_defaultirq (void);
 int    isa_nmi (int cd);
-int    icu_setup (int intr, inthand2_t *func, void *arg, int flags);
-int    icu_unset (int intr, inthand2_t *handler);
 void   icu_reinit (void);
 
 /*
  * WARNING: These are internal functions and not to be used by device drivers!
  * They are subject to change without notice. 
  */
-struct intrec *inthand_add(const char *name, int irq, inthand2_t handler,
-                          void *arg, int flags, lwkt_serialize_t serializer);
-
-int inthand_remove(struct intrec *idesc);
+void *inthand_add(const char *name, int irq, inthand2_t handler,
+                 void *arg, int flags, lwkt_serialize_t serializer);
+int inthand_remove(void *id);
 void forward_fastint_remote(void *arg);
 
 #endif /* LOCORE */
index fb97fdf..fe25575 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     from: vector.s, 386BSD 0.1 unknown origin
  * $FreeBSD: src/sys/i386/isa/vector.s,v 1.32 1999/08/28 00:45:04 peter Exp $
- * $DragonFly: src/sys/platform/pc32/isa/Attic/vector.s,v 1.6 2005/02/27 12:44:43 asmodai Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/Attic/vector.s,v 1.7 2005/10/13 00:02:47 dillon Exp $
  */
 
 #include "opt_auto_eoi.h"
@@ -9,27 +9,6 @@
 #include <i386/isa/icu.h>
 #include <bus/isa/i386/isa.h>
 
-       .data
-       ALIGN_DATA
-
-/*
- * Interrupt counters and names for export to vmstat(8) and friends.
- *
- * XXX this doesn't really belong here; everything except the labels
- * for the endpointers is almost machine-independent.
- */
-#define        NR_INTRNAMES    (1 + ICU_LEN + 2 * ICU_LEN)
-
-       .globl  intrcnt, eintrcnt
-intrcnt:
-       .space  NR_INTRNAMES * 4
-eintrcnt:
-
-       .globl  intrnames, eintrnames
-intrnames:
-       .space  NR_INTRNAMES * 16
-eintrnames:
-
        .text
 
 /*
index 526d4ea..5c1dd8e 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/bus.h,v 1.30.2.5 2004/03/17 17:54:25 njl Exp $
- * $DragonFly: src/sys/sys/bus.h,v 1.15 2005/10/12 17:35:44 dillon Exp $
+ * $DragonFly: src/sys/sys/bus.h,v 1.16 2005/10/13 00:02:23 dillon Exp $
  */
 
 #ifndef _SYS_BUS_H_
@@ -54,6 +54,7 @@ typedef void driver_intr_t(void*);
 #define        INTR_EXCL       0x0100
 #define        INTR_MPSAFE     0x0200
 #define        INTR_ENTROPY    0x0400
+#define INTR_NOPOLL    0x0800  /* interrupt cannot be polled (e.g. ata) */
 
 enum intr_trigger {
     INTR_TRIGGER_CONFORM = 0,
index ffe9b6b..3a26831 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/interrupt.h,v 1.9.2.1 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/sys/interrupt.h,v 1.10 2005/06/16 21:12:21 dillon Exp $
+ * $DragonFly: src/sys/sys/interrupt.h,v 1.11 2005/10/13 00:02:23 dillon Exp $
  */
 
 #ifndef _SYS_INTERRUPT_H_
 
 #define MAX_INTS       32
 
-typedef void inthand2_t (void *);
-typedef void ointhand2_t (int);
+typedef void inthand2_t (void *, void *);
 
 #ifdef _KERNEL
 
+struct intrframe;
 struct thread;
-struct thread *register_swi(int intr, inthand2_t *handler, void *arg,
-                           const char *name);
-struct thread *register_int(int intr, inthand2_t *handler, void *arg,
-                           const char *name);
+struct lwkt_serialize;
+void *register_swi(int intr, inthand2_t *handler, void *arg,
+                           const char *name, 
+                           struct lwkt_serialize *serializer);
+void *register_int(int intr, inthand2_t *handler, void *arg,
+                           const char *name, 
+                           struct lwkt_serialize *serializer, int flags);
+int get_registered_intr(void *id);
+long get_interrupt_counter(int intr);
+int count_registered_ints(int intr);
+const char *get_registered_name(int intr);
+
 void register_randintr(int intr);
 
 void swi_setpriority(int intr, int pri);
-void unregister_swi(int intr, inthand2_t *handler);
-void unregister_int(int intr, inthand2_t *handler);
+int unregister_swi(void *id);
+int unregister_int(void *id);
 void unregister_randintr(int intr);
 void ithread_done(int intr);   /* procedure defined in MD */
 void sched_ithd(int intr);     /* procedure called from MD */
 
-/* Counts and names for statistics (defined in MD code). */
-extern u_long  eintrcnt[];     /* end of intrcnt[] */
 extern char    eintrnames[];   /* end of intrnames[] */
-extern u_long  intrcnt[];      /* counts for for each device and stray */
 extern char    intrnames[];    /* string table containing device names */
 
 #endif
index e09a412..dc73e5a 100644 (file)
@@ -8,7 +8,7 @@
  * required.  Unlike tokens this serialization is not safe from deadlocks
  * nor is it recursive, and care must be taken when using it. 
  *
- * $DragonFly: src/sys/sys/serialize.h,v 1.1 2005/05/24 20:58:44 dillon Exp $
+ * $DragonFly: src/sys/sys/serialize.h,v 1.2 2005/10/13 00:02:23 dillon Exp $
  */
 
 #ifndef _SYS_SERIALIZE_H_
@@ -32,6 +32,7 @@ void lwkt_serialize_enter(lwkt_serialize_t);
 void lwkt_serialize_exit(lwkt_serialize_t);
 void lwkt_serialize_handler_disable(lwkt_serialize_t);
 void lwkt_serialize_handler_enable(lwkt_serialize_t);
-void lwkt_serialize_handler_call(lwkt_serialize_t, void (*)(void *), void *);
+void lwkt_serialize_handler_call(lwkt_serialize_t, void (*)(void *, void *), void *, void *);
+int lwkt_serialize_handler_try(lwkt_serialize_t, void (*)(void *, void *), void *, void *);
 
 #endif
index 2c090b9..7ee1abb 100644 (file)
@@ -7,7 +7,7 @@
  * Types which must already be defined when this header is included by
  * userland:   struct md_thread
  * 
- * $DragonFly: src/sys/sys/thread.h,v 1.69 2005/10/11 09:59:56 corecode Exp $
+ * $DragonFly: src/sys/sys/thread.h,v 1.70 2005/10/13 00:02:23 dillon Exp $
  */
 
 #ifndef _SYS_THREAD_H_
@@ -234,9 +234,6 @@ struct thread {
     int                td_wdomain;     /* domain for wchan address (typ 0) */
     void       (*td_preemptable)(struct thread *td, int critpri);
     void       (*td_release)(struct thread *td);
-    union {
-       struct md_intr_info *intdata;
-    } td_info;
     char       *td_kstack;     /* kernel stack */
     int                td_kstack_size; /* size of kernel stack */
     char       *td_sp;         /* kernel stack pointer for LWKT restore */