- Overhaul the software interrupt code to use interrupt threads for each

type of software interrupt.  Roughly, what used to be a bit in spending
  now maps to a swi thread.  Each thread can have multiple handlers, just
  like a hardware interrupt thread.
- Instead of using a bitmask of pending interrupts, we schedule the specific
  software interrupt thread to run, so spending, NSWI, and the shandlers
  array are no longer needed.  We can now have an arbitrary number of
  software interrupt threads.  When you register a software interrupt
  thread via sinthand_add(), you get back a struct intrhand that you pass
  to sched_swi() when you wish to schedule your swi thread to run.
- Convert the name of 'struct intrec' to 'struct intrhand' as it is a bit
  more intuitive.  Also, prefix all the members of struct intrhand with
  'ih_'.
- Make swi_net() a MI function since there is now no point in it being
  MD.

Submitted by:	cp
This commit is contained in:
John Baldwin 2000-10-25 05:19:40 +00:00
parent 650789cb1b
commit 8088699f79
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67551
60 changed files with 549 additions and 802 deletions

View File

@ -27,7 +27,9 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/interrupt.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <vm/vm.h> #include <vm/vm.h>
@ -689,7 +691,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
STAILQ_INSERT_TAIL(&bounce_map_callbacklist, STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links); map, links);
busdma_swi_pending = 1; busdma_swi_pending = 1;
setsoftvm(); sched_swi(vm_ih, SWI_NOSWITCH);
} }
} }
splx(s); splx(s);

View File

@ -398,7 +398,6 @@ handleclock(void* arg)
} }
hardclock(arg); hardclock(arg);
setdelayed();
} }
/* /*

View File

@ -341,7 +341,7 @@ alpha_setup_intr(const char *name, int vector, driver_intr_t *handler,
{ {
int h = HASHVEC(vector); int h = HASHVEC(vector);
struct alpha_intr *i; struct alpha_intr *i;
struct intrec *head, *idesc; struct intrhand *head, *idesc;
struct ithd *ithd; struct ithd *ithd;
struct proc *p; struct proc *p;
int s, errcode; int s, errcode;
@ -410,26 +410,26 @@ alpha_setup_intr(const char *name, int vector, driver_intr_t *handler,
} }
/* Third, setup the interrupt descriptor for this handler. */ /* Third, setup the interrupt descriptor for this handler. */
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK); idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
if (idesc == NULL) if (idesc == NULL)
return ENOMEM; return ENOMEM;
bzero(idesc, sizeof(struct intrec)); bzero(idesc, sizeof(struct intrhand));
idesc->handler = handler; idesc->ih_handler = handler;
idesc->argument = arg; idesc->ih_argument = arg;
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK); idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if (idesc->name == NULL) { if (idesc->ih_name == NULL) {
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return(NULL); return(NULL);
} }
strcpy(idesc->name, name); strcpy(idesc->ih_name, name);
/* Fourth, add our handler to the end of the ithread's handler list. */ /* Fourth, add our handler to the end of the ithread's handler list. */
head = ithd->it_ih; head = ithd->it_ih;
if (head) { if (head) {
while (head->next != NULL) while (head->ih_next != NULL)
head = head->next; head = head->ih_next;
head->next = idesc; head->ih_next = idesc;
} else } else
ithd->it_ih = idesc; ithd->it_ih = idesc;
@ -440,27 +440,27 @@ alpha_setup_intr(const char *name, int vector, driver_intr_t *handler,
int int
alpha_teardown_intr(void *cookie) alpha_teardown_intr(void *cookie)
{ {
struct intrec *idesc = cookie; struct intrhand *idesc = cookie;
struct ithd *ithd; struct ithd *ithd;
struct intrec *head; struct intrhand *head;
#if 0 #if 0
struct alpha_intr *i; struct alpha_intr *i;
int s; int s;
#endif #endif
/* First, detach ourself from our interrupt thread. */ /* First, detach ourself from our interrupt thread. */
ithd = idesc->ithd; ithd = idesc->ih_ithd;
KASSERT(ithd != NULL, ("idesc without an interrupt thread")); KASSERT(ithd != NULL, ("idesc without an interrupt thread"));
head = ithd->it_ih; head = ithd->it_ih;
if (head == idesc) if (head == idesc)
ithd->it_ih = idesc->next; ithd->it_ih = idesc->ih_next;
else { else {
while (head != NULL && head->next != idesc) while (head != NULL && head->ih_next != idesc)
head = head->next; head = head->ih_next;
if (head == NULL) if (head == NULL)
return (-1); /* couldn't find ourself */ return (-1); /* couldn't find ourself */
head->next = idesc->next; head->ih_next = idesc->ih_next;
} }
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
@ -541,7 +541,7 @@ void
ithd_loop(void *dummy) ithd_loop(void *dummy)
{ {
struct ithd *ithd; /* our thread context */ struct ithd *ithd; /* our thread context */
struct intrec *ih; /* list of handlers */ struct intrhand *ih; /* list of handlers */
struct alpha_intr *i; /* interrupt source */ struct alpha_intr *i; /* interrupt source */
ithd = curproc->p_ithd; ithd = curproc->p_ithd;
@ -565,17 +565,17 @@ ithd_loop(void *dummy)
alpha_wmb(); /* push out "it_need=0" */ alpha_wmb(); /* push out "it_need=0" */
for (ih = ithd->it_ih; ih != NULL; ih = ih->next) { for (ih = ithd->it_ih; ih != NULL; ih = ih->ih_next) {
CTR5(KTR_INTR, CTR5(KTR_INTR,
"ithd_loop pid %d ih=%p: %p(%p) flg=%x", "ithd_loop pid %d ih=%p: %p(%p) flg=%x",
ithd->it_proc->p_pid, (void *)ih, ithd->it_proc->p_pid, (void *)ih,
(void *)ih->handler, ih->argument, (void *)ih->ih_handler, ih->ih_argument,
ih->flags); ih->ih_flags);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_enter(&Giant, MTX_DEF); mtx_enter(&Giant, MTX_DEF);
ih->handler(ih->argument); ih->ih_handler(ih->ih_argument);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_exit(&Giant, MTX_DEF); mtx_exit(&Giant, MTX_DEF);
} }

View File

@ -27,64 +27,9 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/ipl.h>
#include <sys/ktr.h>
#include <sys/mutex.h>
#include <sys/interrupt.h>
#include <machine/cpu.h>
#include <machine/globaldata.h>
#include <machine/globals.h>
#include <net/netisr.h>
#include "sio.h"
unsigned int bio_imask; /* XXX */ unsigned int bio_imask; /* XXX */
unsigned int cam_imask; /* XXX */ unsigned int cam_imask; /* XXX */
unsigned int net_imask; /* XXX */ unsigned int net_imask; /* XXX */
unsigned int tty_imask; /* XXX */ unsigned int tty_imask; /* XXX */
static void swi_net(void);
void (*netisrs[32]) __P((void));
swihand_t *shandlers[NSWI] = { /* software interrupts */
swi_null, swi_net, swi_null, swi_null,
swi_null, swi_null, softclock, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
};
u_int32_t netisr;
void
swi_null()
{
/* No interrupt registered, do nothing */
}
void
swi_generic()
{
/* Just a placeholder, we call swi_dispatcher directly */
panic("swi_generic() called");
}
static void
swi_net()
{
u_int32_t bits = atomic_readandclear_32(&netisr);
int i;
for (i = 0; i < 32; i++) {
if (bits & 1)
netisrs[i]();
bits >>= 1;
}
}

View File

@ -96,12 +96,6 @@ static struct cdevsw mem_cdevsw = {
/* bmaj */ -1 /* bmaj */ -1
}; };
#if NHWI > 0
#define ICU_LEN (NHWI)
#else
#define ICU_LEN (NSWI)
#endif
struct mem_range_softc mem_range_softc; struct mem_range_softc mem_range_softc;
static int static int

View File

@ -470,7 +470,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)
busdma_swi(); busdma_swi();

View File

@ -32,9 +32,6 @@
#include <machine/cpu.h> /* for pal inlines */ #include <machine/cpu.h> /* for pal inlines */
#define NSWI 32
#define HWHI 0
/* /*
* Interprocessor interrupts for SMP. * Interprocessor interrupts for SMP.
*/ */

View File

@ -50,7 +50,7 @@ void busdma_swi __P((void));
void cpu_halt __P((void)); void cpu_halt __P((void));
void cpu_reset __P((void)); void cpu_reset __P((void));
int is_physical_memory __P((vm_offset_t addr)); int is_physical_memory __P((vm_offset_t addr));
void swi_vm __P((void)); void swi_vm __P((void *));
int vm_page_zero_idle __P((void)); int vm_page_zero_idle __P((void));
int fill_regs __P((struct proc *, struct reg *)); int fill_regs __P((struct proc *, struct reg *));
int set_regs __P((struct proc *, struct reg *)); int set_regs __P((struct proc *, struct reg *));

View File

@ -29,6 +29,8 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <vm/vm.h> #include <vm/vm.h>
#include <vm/vm_page.h> #include <vm/vm_page.h>
@ -639,7 +641,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
STAILQ_INSERT_TAIL(&bounce_map_callbacklist, STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links); map, links);
busdma_swi_pending = 1; busdma_swi_pending = 1;
setsoftvm(); sched_swi(vm_ih, SWI_NOSWITCH);
} }
} }
splx(s); splx(s);

View File

@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
switch (timer0_state) { switch (timer0_state) {
case RELEASED: case RELEASED:
setdelayed();
break; break;
case ACQUIRED: case ACQUIRED:
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
>= hardclock_max_count) { >= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count; timer0_prescaler_count -= hardclock_max_count;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
mtx_exit(&clock_lock, MTX_SPIN); mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function; timer_func = new_function;
timer0_state = ACQUIRED; timer0_state = ACQUIRED;
setdelayed();
break; break;
case RELEASE_PENDING: case RELEASE_PENDING:
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
timer_func = hardclock; timer_func = hardclock;
timer0_state = RELEASED; timer0_state = RELEASED;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
} }
@ -967,7 +963,7 @@ cpu_initclocks()
int diag; int diag;
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
if (statclock_disable) { if (statclock_disable) {

View File

@ -591,7 +591,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)
busdma_swi(); busdma_swi();

View File

@ -94,8 +94,7 @@ int is_physical_memory __P((vm_offset_t addr));
u_long kvtop __P((void *addr)); u_long kvtop __P((void *addr));
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl, void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
int selec)); int selec));
void swi_vm __P((void)); void swi_vm __P((void *));
void swi_net __P((void));
void userconfig __P((void)); void userconfig __P((void));
int user_dbreg_trap __P((void)); int user_dbreg_trap __P((void));
int vm_page_zero_idle __P((void)); int vm_page_zero_idle __P((void));

View File

@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
switch (timer0_state) { switch (timer0_state) {
case RELEASED: case RELEASED:
setdelayed();
break; break;
case ACQUIRED: case ACQUIRED:
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
>= hardclock_max_count) { >= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count; timer0_prescaler_count -= hardclock_max_count;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
mtx_exit(&clock_lock, MTX_SPIN); mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function; timer_func = new_function;
timer0_state = ACQUIRED; timer0_state = ACQUIRED;
setdelayed();
break; break;
case RELEASE_PENDING: case RELEASE_PENDING:
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
timer_func = hardclock; timer_func = hardclock;
timer0_state = RELEASED; timer0_state = RELEASED;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
} }
@ -967,7 +963,7 @@ cpu_initclocks()
int diag; int diag;
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
if (statclock_disable) { if (statclock_disable) {

View File

@ -531,13 +531,13 @@ icu_unset(intr, handler)
return (0); return (0);
} }
struct intrec * struct intrhand *
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg, inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
int pri, int flags) int pri, int flags)
{ {
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */ struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
struct intrec *head; /* chain of handlers for IRQ */ struct intrhand *head; /* chain of handlers for IRQ */
struct intrec *idesc; /* descriptor for this handler */ struct intrhand *idesc; /* descriptor for this handler */
struct proc *p; /* interrupt thread */ struct proc *p; /* interrupt thread */
int errcode = 0; int errcode = 0;
@ -592,7 +592,7 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
panic("inthand_add: Can't initialize ICU"); panic("inthand_add: Can't initialize ICU");
} }
} else if ((flags & INTR_EXCL) != 0 } else if ((flags & INTR_EXCL) != 0
|| (ithd->it_ih->flags & INTR_EXCL) != 0) { || (ithd->it_ih->ih_flags & INTR_EXCL) != 0) {
/* /*
* We can't append the new handler if either * We can't append the new handler if either
* list ithd or new handler do not allow * list ithd or new handler do not allow
@ -601,14 +601,14 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
if (bootverbose) if (bootverbose)
printf("\tdevice combination %s and %s " printf("\tdevice combination %s and %s "
"doesn't support shared irq%d\n", "doesn't support shared irq%d\n",
ithd->it_ih->name, name, irq); ithd->it_ih->ih_name, name, irq);
return(NULL); return(NULL);
} else if (flags & INTR_FAST) { } else if (flags & INTR_FAST) {
/* We can only have one fast interrupt by itself. */ /* We can only have one fast interrupt by itself. */
if (bootverbose) if (bootverbose)
printf("\tCan't add fast interrupt %s" printf("\tCan't add fast interrupt %s"
" to normal interrupt %s on irq%d", " to normal interrupt %s on irq%d",
name, ithd->it_ih->name, irq); name, ithd->it_ih->ih_name, irq);
return (NULL); return (NULL);
} else { /* update p_comm */ } else { /* update p_comm */
p = ithd->it_proc; p = ithd->it_proc;
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
else else
strcat(p->p_comm, "+"); strcat(p->p_comm, "+");
} }
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK); idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
if (idesc == NULL) if (idesc == NULL)
return (NULL); return (NULL);
bzero(idesc, sizeof (struct intrec)); bzero(idesc, sizeof (struct intrhand));
idesc->handler = handler; idesc->ih_handler = handler;
idesc->argument = arg; idesc->ih_argument = arg;
idesc->flags = flags; idesc->ih_flags = flags;
idesc->ithd = ithd; idesc->ih_ithd = ithd;
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK); idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if (idesc->name == NULL) { if (idesc->ih_name == NULL) {
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return (NULL); return (NULL);
} }
strcpy(idesc->name, name); strcpy(idesc->ih_name, name);
/* Slow interrupts got set up above. */ /* Slow interrupts got set up above. */
if ((flags & INTR_FAST) if ((flags & INTR_FAST)
&& (icu_setup(irq, idesc->handler, idesc->argument, && (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
idesc->flags) != 0) ) { idesc->ih_flags) != 0) ) {
if (bootverbose) if (bootverbose)
printf("\tinthand_add(irq%d) failed, result=%d\n", printf("\tinthand_add(irq%d) failed, result=%d\n",
irq, errcode); irq, errcode);
free(idesc->name, M_DEVBUF); free(idesc->ih_name, M_DEVBUF);
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return NULL; return NULL;
} }
head = ithd->it_ih; /* look at chain of handlers */ head = ithd->it_ih; /* look at chain of handlers */
if (head) { if (head) {
while (head->next != NULL) while (head->ih_next != NULL)
head = head->next; /* find the end */ head = head->ih_next; /* find the end */
head->next = idesc; /* hook it in there */ head->ih_next = idesc; /* hook it in there */
} else } else
ithd->it_ih = idesc; /* put it up front */ ithd->it_ih = idesc; /* put it up front */
update_intrname(irq, idesc->name); update_intrname(irq, idesc->ih_name);
return (idesc); return (idesc);
} }
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
*/ */
int int
inthand_remove(struct intrec *idesc) inthand_remove(struct intrhand *idesc)
{ {
struct ithd *ithd; /* descriptor for the IRQ */ struct ithd *ithd; /* descriptor for the IRQ */
struct intrec *ih; /* chain of handlers */ struct intrhand *ih; /* chain of handlers */
if (idesc == NULL) if (idesc == NULL)
return (-1); return (-1);
ithd = idesc->ithd; ithd = idesc->ih_ithd;
ih = ithd->it_ih; ih = ithd->it_ih;
if (ih == idesc) /* first in the chain */ if (ih == idesc) /* first in the chain */
ithd->it_ih = idesc->next; /* unhook it */ ithd->it_ih = idesc->ih_next; /* unhook it */
else { else {
while ((ih != NULL) while ((ih != NULL)
&& (ih->next != idesc) ) && (ih->ih_next != idesc) )
ih = ih->next; ih = ih->ih_next;
if (ih->next != idesc) if (ih->ih_next != idesc)
return (-1); return (-1);
ih->next = ih->next->next; ih->ih_next = ih->ih_next->ih_next;
} }
if (ithd->it_ih == NULL) { /* no handlers left, */ if (ithd->it_ih == NULL) { /* no handlers left, */
icu_unset(ithd->irq, idesc->handler); icu_unset(ithd->irq, idesc->ih_handler);
ithds[ithd->irq] = NULL; ithds[ithd->irq] = NULL;
mtx_enter(&sched_lock, MTX_SPIN); mtx_enter(&sched_lock, MTX_SPIN);

View File

@ -218,9 +218,9 @@ int icu_unset __P((int intr, driver_intr_t *handler));
* WARNING: These are internal functions and not to be used by device drivers! * WARNING: These are internal functions and not to be used by device drivers!
* They are subject to change without notice. * They are subject to change without notice.
*/ */
struct intrec *inthand_add(const char *name, int irq, driver_intr_t handler, struct intrhand *inthand_add(const char *name, int irq, driver_intr_t handler,
void *arg, int pri, int flags); void *arg, int pri, int flags);
int inthand_remove(struct intrec *idesc); int inthand_remove(struct intrhand *idesc);
void sched_ithd(void *); void sched_ithd(void *);
void ithd_loop(void *); void ithd_loop(void *);
void start_softintr(void *); void start_softintr(void *);

View File

@ -165,7 +165,7 @@ void
ithd_loop(void *dummy) ithd_loop(void *dummy)
{ {
struct ithd *me; /* our thread context */ struct ithd *me; /* our thread context */
struct intrec *ih; /* and our interrupt handler chain */ struct intrhand *ih; /* and our interrupt handler chain */
me = curproc->p_ithd; /* point to myself */ me = curproc->p_ithd; /* point to myself */
@ -200,17 +200,17 @@ ithd_loop(void *dummy)
#if 0 #if 0
membar_unlock(); /* push out "it_need=0" */ membar_unlock(); /* push out "it_need=0" */
#endif #endif
for (ih = me->it_ih; ih != NULL; ih = ih->next) { for (ih = me->it_ih; ih != NULL; ih = ih->ih_next) {
CTR5(KTR_INTR, CTR5(KTR_INTR,
"ithd_loop pid %d ih=%p: %p(%p) flg=%x", "ithd_loop pid %d ih=%p: %p(%p) flg=%x",
me->it_proc->p_pid, (void *)ih, me->it_proc->p_pid, (void *)ih,
(void *)ih->handler, ih->argument, (void *)ih->ih_handler, ih->ih_argument,
ih->flags); ih->ih_flags);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_enter(&Giant, MTX_DEF); mtx_enter(&Giant, MTX_DEF);
ih->handler(ih->argument); ih->ih_handler(ih->ih_argument);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_exit(&Giant, MTX_DEF); mtx_exit(&Giant, MTX_DEF);
} }
} }

View File

@ -531,13 +531,13 @@ icu_unset(intr, handler)
return (0); return (0);
} }
struct intrec * struct intrhand *
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg, inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
int pri, int flags) int pri, int flags)
{ {
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */ struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
struct intrec *head; /* chain of handlers for IRQ */ struct intrhand *head; /* chain of handlers for IRQ */
struct intrec *idesc; /* descriptor for this handler */ struct intrhand *idesc; /* descriptor for this handler */
struct proc *p; /* interrupt thread */ struct proc *p; /* interrupt thread */
int errcode = 0; int errcode = 0;
@ -592,7 +592,7 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
panic("inthand_add: Can't initialize ICU"); panic("inthand_add: Can't initialize ICU");
} }
} else if ((flags & INTR_EXCL) != 0 } else if ((flags & INTR_EXCL) != 0
|| (ithd->it_ih->flags & INTR_EXCL) != 0) { || (ithd->it_ih->ih_flags & INTR_EXCL) != 0) {
/* /*
* We can't append the new handler if either * We can't append the new handler if either
* list ithd or new handler do not allow * list ithd or new handler do not allow
@ -601,14 +601,14 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
if (bootverbose) if (bootverbose)
printf("\tdevice combination %s and %s " printf("\tdevice combination %s and %s "
"doesn't support shared irq%d\n", "doesn't support shared irq%d\n",
ithd->it_ih->name, name, irq); ithd->it_ih->ih_name, name, irq);
return(NULL); return(NULL);
} else if (flags & INTR_FAST) { } else if (flags & INTR_FAST) {
/* We can only have one fast interrupt by itself. */ /* We can only have one fast interrupt by itself. */
if (bootverbose) if (bootverbose)
printf("\tCan't add fast interrupt %s" printf("\tCan't add fast interrupt %s"
" to normal interrupt %s on irq%d", " to normal interrupt %s on irq%d",
name, ithd->it_ih->name, irq); name, ithd->it_ih->ih_name, irq);
return (NULL); return (NULL);
} else { /* update p_comm */ } else { /* update p_comm */
p = ithd->it_proc; p = ithd->it_proc;
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
else else
strcat(p->p_comm, "+"); strcat(p->p_comm, "+");
} }
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK); idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
if (idesc == NULL) if (idesc == NULL)
return (NULL); return (NULL);
bzero(idesc, sizeof (struct intrec)); bzero(idesc, sizeof (struct intrhand));
idesc->handler = handler; idesc->ih_handler = handler;
idesc->argument = arg; idesc->ih_argument = arg;
idesc->flags = flags; idesc->ih_flags = flags;
idesc->ithd = ithd; idesc->ih_ithd = ithd;
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK); idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if (idesc->name == NULL) { if (idesc->ih_name == NULL) {
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return (NULL); return (NULL);
} }
strcpy(idesc->name, name); strcpy(idesc->ih_name, name);
/* Slow interrupts got set up above. */ /* Slow interrupts got set up above. */
if ((flags & INTR_FAST) if ((flags & INTR_FAST)
&& (icu_setup(irq, idesc->handler, idesc->argument, && (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
idesc->flags) != 0) ) { idesc->ih_flags) != 0) ) {
if (bootverbose) if (bootverbose)
printf("\tinthand_add(irq%d) failed, result=%d\n", printf("\tinthand_add(irq%d) failed, result=%d\n",
irq, errcode); irq, errcode);
free(idesc->name, M_DEVBUF); free(idesc->ih_name, M_DEVBUF);
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return NULL; return NULL;
} }
head = ithd->it_ih; /* look at chain of handlers */ head = ithd->it_ih; /* look at chain of handlers */
if (head) { if (head) {
while (head->next != NULL) while (head->ih_next != NULL)
head = head->next; /* find the end */ head = head->ih_next; /* find the end */
head->next = idesc; /* hook it in there */ head->ih_next = idesc; /* hook it in there */
} else } else
ithd->it_ih = idesc; /* put it up front */ ithd->it_ih = idesc; /* put it up front */
update_intrname(irq, idesc->name); update_intrname(irq, idesc->ih_name);
return (idesc); return (idesc);
} }
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
*/ */
int int
inthand_remove(struct intrec *idesc) inthand_remove(struct intrhand *idesc)
{ {
struct ithd *ithd; /* descriptor for the IRQ */ struct ithd *ithd; /* descriptor for the IRQ */
struct intrec *ih; /* chain of handlers */ struct intrhand *ih; /* chain of handlers */
if (idesc == NULL) if (idesc == NULL)
return (-1); return (-1);
ithd = idesc->ithd; ithd = idesc->ih_ithd;
ih = ithd->it_ih; ih = ithd->it_ih;
if (ih == idesc) /* first in the chain */ if (ih == idesc) /* first in the chain */
ithd->it_ih = idesc->next; /* unhook it */ ithd->it_ih = idesc->ih_next; /* unhook it */
else { else {
while ((ih != NULL) while ((ih != NULL)
&& (ih->next != idesc) ) && (ih->ih_next != idesc) )
ih = ih->next; ih = ih->ih_next;
if (ih->next != idesc) if (ih->ih_next != idesc)
return (-1); return (-1);
ih->next = ih->next->next; ih->ih_next = ih->ih_next->ih_next;
} }
if (ithd->it_ih == NULL) { /* no handlers left, */ if (ithd->it_ih == NULL) { /* no handlers left, */
icu_unset(ithd->irq, idesc->handler); icu_unset(ithd->irq, idesc->ih_handler);
ithds[ithd->irq] = NULL; ithds[ithd->irq] = NULL;
mtx_enter(&sched_lock, MTX_SPIN); mtx_enter(&sched_lock, MTX_SPIN);

View File

@ -605,6 +605,10 @@ u_int32_t cam_dflags;
u_int32_t cam_debug_delay; u_int32_t cam_debug_delay;
#endif #endif
/* Pointers to software interrupt handlers */
struct intrhand *camnet_ih;
struct intrhand *cambio_ih;
#if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG) #if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
#error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS" #error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS"
#endif #endif
@ -693,9 +697,7 @@ static xpt_devicefunc_t xptpassannouncefunc;
static void xpt_finishconfig(struct cam_periph *periph, union ccb *ccb); static void xpt_finishconfig(struct cam_periph *periph, union ccb *ccb);
static void xptaction(struct cam_sim *sim, union ccb *work_ccb); static void xptaction(struct cam_sim *sim, union ccb *work_ccb);
static void xptpoll(struct cam_sim *sim); static void xptpoll(struct cam_sim *sim);
static swihand_t swi_camnet; static void camisr(void *);
static swihand_t swi_cambio;
static void camisr(cam_isrq_t *queue);
#if 0 #if 0
static void xptstart(struct cam_periph *periph, union ccb *work_ccb); static void xptstart(struct cam_periph *periph, union ccb *work_ccb);
static void xptasync(struct cam_periph *periph, static void xptasync(struct cam_periph *periph,
@ -1363,8 +1365,10 @@ xpt_init(dummy)
} }
/* Install our software interrupt handlers */ /* Install our software interrupt handlers */
register_swi(SWI_CAMNET, swi_camnet); camnet_ih = sinthand_add("camnet", NULL, camisr, &cam_netq,
register_swi(SWI_CAMBIO, swi_cambio); SWI_CAMNET, 0);
cambio_ih = sinthand_add("cambio", NULL, camisr, &cam_bioq,
SWI_CAMBIO, 0);
} }
static cam_status static cam_status
@ -3400,8 +3404,8 @@ xpt_polled_action(union ccb *start_ccb)
&& (--timeout > 0)) { && (--timeout > 0)) {
DELAY(1000); DELAY(1000);
(*(sim->sim_poll))(sim); (*(sim->sim_poll))(sim);
swi_camnet(); camisr(&cam_netq);
swi_cambio(); camisr(&cam_bioq);
} }
dev->ccbq.devq_openings++; dev->ccbq.devq_openings++;
@ -3411,8 +3415,8 @@ xpt_polled_action(union ccb *start_ccb)
xpt_action(start_ccb); xpt_action(start_ccb);
while(--timeout > 0) { while(--timeout > 0) {
(*(sim->sim_poll))(sim); (*(sim->sim_poll))(sim);
swi_camnet(); camisr(&cam_netq);
swi_cambio(); camisr(&cam_bioq);
if ((start_ccb->ccb_h.status & CAM_STATUS_MASK) if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)
!= CAM_REQ_INPROG) != CAM_REQ_INPROG)
break; break;
@ -4527,13 +4531,13 @@ xpt_done(union ccb *done_ccb)
TAILQ_INSERT_TAIL(&cam_bioq, &done_ccb->ccb_h, TAILQ_INSERT_TAIL(&cam_bioq, &done_ccb->ccb_h,
sim_links.tqe); sim_links.tqe);
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX; done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
setsoftcambio(); sched_swi(cambio_ih, SWI_NOSWITCH);
break; break;
case CAM_PERIPH_NET: case CAM_PERIPH_NET:
TAILQ_INSERT_TAIL(&cam_netq, &done_ccb->ccb_h, TAILQ_INSERT_TAIL(&cam_netq, &done_ccb->ccb_h,
sim_links.tqe); sim_links.tqe);
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX; done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
setsoftcamnet(); sched_swi(camnet_ih, SWI_NOSWITCH);
break; break;
} }
} }
@ -6240,26 +6244,10 @@ xptpoll(struct cam_sim *sim)
{ {
} }
/*
* Should only be called by the machine interrupt dispatch routines,
* so put these prototypes here instead of in the header.
*/
static void static void
swi_camnet(void) camisr(void *V_queue)
{
camisr(&cam_netq);
}
static void
swi_cambio(void)
{
camisr(&cam_bioq);
}
static void
camisr(cam_isrq_t *queue)
{ {
cam_isrq_t *queue = V_queue;
int s; int s;
struct ccb_hdr *ccb_h; struct ccb_hdr *ccb_h;

View File

@ -133,7 +133,7 @@
#define siosetwater cysetwater #define siosetwater cysetwater
#define comstop cystop #define comstop cystop
#define siowrite cywrite #define siowrite cywrite
#define sio_registered cy_registered #define sio_irec cy_irec
#define sio_timeout cy_timeout #define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle #define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log #define sio_timeouts_until_log cy_timeouts_until_log
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1; static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED; static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */ static u_int com_events; /* input chars + weighted output completions */
static bool_t sio_registered; static struct intrhand *sio_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
com_addr(unit) = com; com_addr(unit) = com;
splx(s); splx(s);
if (!sio_registered) { if (sio_ih == NULL)
cdevsw_add(&sio_cdevsw); cdevsw_add(&sio_cdevsw);
register_swi(SWI_TTY, siopoll); sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
sio_registered = TRUE; SWI_TTY, 0);
} }
make_dev(&sio_cdevsw, unit, make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter, UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -1174,7 +1174,8 @@ siointr(unit)
#ifndef SOFT_HOTCHAR #ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0) && com->hotchar != 0)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */ #if 1 /* XXX "intelligent" PFO error handling would break O error handling */
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) { if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
@ -1201,7 +1202,7 @@ siointr(unit)
++com->bytes_in; ++com->bytes_in;
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
@ -1251,7 +1252,7 @@ siointr(unit)
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data && recv_data
== com->hotchar) == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1266,7 +1267,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
} while (--count != 0); } while (--count != 0);
} else { } else {
@ -1291,7 +1292,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1356,7 +1357,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
@ -1487,7 +1488,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
break; break;
case ETC_BREAK_ENDED: case ETC_BREAK_ENDED:
@ -1501,7 +1502,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) { if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE; com->extra_state |= CSE_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
cd_outb(iobase, CD1400_SRER, cy_align, cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable com->intr_enable
@ -1559,7 +1560,7 @@ siointr(unit)
com->state |= CS_ODONE; com->state |= CS_ODONE;
/* handle at high level ASAP */ /* handle at high level ASAP */
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
} }
} }
@ -1579,7 +1580,7 @@ siointr(unit)
/* ensure an edge for the next interrupt */ /* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
schedsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
COM_UNLOCK(); COM_UNLOCK();
} }

View File

@ -133,7 +133,7 @@
#define siosetwater cysetwater #define siosetwater cysetwater
#define comstop cystop #define comstop cystop
#define siowrite cywrite #define siowrite cywrite
#define sio_registered cy_registered #define sio_irec cy_irec
#define sio_timeout cy_timeout #define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle #define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log #define sio_timeouts_until_log cy_timeouts_until_log
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1; static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED; static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */ static u_int com_events; /* input chars + weighted output completions */
static bool_t sio_registered; static struct intrhand *sio_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
com_addr(unit) = com; com_addr(unit) = com;
splx(s); splx(s);
if (!sio_registered) { if (sio_ih == NULL)
cdevsw_add(&sio_cdevsw); cdevsw_add(&sio_cdevsw);
register_swi(SWI_TTY, siopoll); sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
sio_registered = TRUE; SWI_TTY, 0);
} }
make_dev(&sio_cdevsw, unit, make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter, UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -1174,7 +1174,8 @@ siointr(unit)
#ifndef SOFT_HOTCHAR #ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0) && com->hotchar != 0)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */ #if 1 /* XXX "intelligent" PFO error handling would break O error handling */
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) { if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
@ -1201,7 +1202,7 @@ siointr(unit)
++com->bytes_in; ++com->bytes_in;
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
@ -1251,7 +1252,7 @@ siointr(unit)
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data && recv_data
== com->hotchar) == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1266,7 +1267,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
} while (--count != 0); } while (--count != 0);
} else { } else {
@ -1291,7 +1292,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1356,7 +1357,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
@ -1487,7 +1488,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
break; break;
case ETC_BREAK_ENDED: case ETC_BREAK_ENDED:
@ -1501,7 +1502,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) { if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE; com->extra_state |= CSE_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
cd_outb(iobase, CD1400_SRER, cy_align, cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable com->intr_enable
@ -1559,7 +1560,7 @@ siointr(unit)
com->state |= CS_ODONE; com->state |= CS_ODONE;
/* handle at high level ASAP */ /* handle at high level ASAP */
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
} }
} }
@ -1579,7 +1580,7 @@ siointr(unit)
/* ensure an edge for the next interrupt */ /* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
schedsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
COM_UNLOCK(); COM_UNLOCK();
} }

View File

@ -172,6 +172,8 @@ static int rc_rcsrt[16] = {
TTY_BI|TTY_PE|TTY_FE|TTY_OE TTY_BI|TTY_PE|TTY_FE|TTY_OE
}; };
static struct intrhand *rc_ih;
/* Static prototypes */ /* Static prototypes */
static ointhand2_t rcintr; static ointhand2_t rcintr;
static void rc_hwreset __P((int, int, unsigned int)); static void rc_hwreset __P((int, int, unsigned int));
@ -268,7 +270,8 @@ rcattach(dvp)
rcb->rcb_probed = RC_ATTACHED; rcb->rcb_probed = RC_ATTACHED;
if (!rc_started) { if (!rc_started) {
cdevsw_add(&rc_cdevsw); cdevsw_add(&rc_cdevsw);
register_swi(SWI_TTY, rcpoll); rc_ih = sinthand_add("tty:rc", &tty_ithd, rcpoll, NULL,
SWI_TTY, 0);
rc_wakeup((void *)NULL); rc_wakeup((void *)NULL);
rc_started = 1; rc_started = 1;
} }
@ -362,7 +365,7 @@ rcintr(unit)
optr++; optr++;
rc_scheduled_event++; rc_scheduled_event++;
if (val != 0 && val == rc->rc_hotchar) if (val != 0 && val == rc->rc_hotchar)
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
} else { } else {
/* Store also status data */ /* Store also status data */
@ -393,7 +396,7 @@ rcintr(unit)
&& (rc->rc_tp->t_iflag & INPCK)))) && (rc->rc_tp->t_iflag & INPCK))))
val = 0; val = 0;
else if (val != 0 && val == rc->rc_hotchar) else if (val != 0 && val == rc->rc_hotchar)
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
optr[0] = val; optr[0] = val;
optr[INPUT_FLAGS_SHIFT] = iack; optr[INPUT_FLAGS_SHIFT] = iack;
optr++; optr++;
@ -440,7 +443,7 @@ rcintr(unit)
if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) { if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) {
rc_scheduled_event += LOTS_OF_EVENTS; rc_scheduled_event += LOTS_OF_EVENTS;
rc->rc_flags |= RC_MODCHG; rc->rc_flags |= RC_MODCHG;
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
goto more_intrs; goto more_intrs;
} }
@ -481,7 +484,7 @@ rcintr(unit)
if (!(rc->rc_flags & RC_DOXXFER)) { if (!(rc->rc_flags & RC_DOXXFER)) {
rc_scheduled_event += LOTS_OF_EVENTS; rc_scheduled_event += LOTS_OF_EVENTS;
rc->rc_flags |= RC_DOXXFER; rc->rc_flags |= RC_DOXXFER;
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
} }
} }

View File

@ -300,7 +300,7 @@ static void siointr1 __P((struct com_s *com));
static void siointr __P((void *arg)); static void siointr __P((void *arg));
static int commctl __P((struct com_s *com, int bits, int how)); static int commctl __P((struct com_s *com, int bits, int how));
static int comparam __P((struct tty *tp, struct termios *t)); static int comparam __P((struct tty *tp, struct termios *t));
static swihand_t siopoll; static void siopoll __P((void *));
static int sioprobe __P((device_t dev, int xrid)); static int sioprobe __P((device_t dev, int xrid));
static int sio_isa_probe __P((device_t dev)); static int sio_isa_probe __P((device_t dev));
static void siosettimeout __P((void)); static void siosettimeout __P((void));
@ -413,7 +413,8 @@ static int siocnunit;
#endif #endif
static Port_t siogdbiobase; static Port_t siogdbiobase;
static int siogdbunit = -1; static int siogdbunit = -1;
static bool_t sio_registered; static struct intrhand *sio_slow_ih;
static struct intrhand *sio_fast_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -1322,9 +1323,11 @@ determined_type: ;
printf(" with a bogus IIR_TXRDY register"); printf(" with a bogus IIR_TXRDY register");
printf("\n"); printf("\n");
if (!sio_registered) { if (sio_fast_ih == NULL) {
register_swi(SWI_TTY, siopoll); sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
sio_registered = TRUE; NULL, SWI_TTY, 0);
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
NULL, SWI_TTY, 0);
} }
com->devs[0] = make_dev(&sio_cdevsw, unit, com->devs[0] = make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit); UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
@ -1979,7 +1982,7 @@ siointr1(com)
} }
++com->bytes_in; ++com->bytes_in;
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
@ -1987,10 +1990,10 @@ siointr1(com)
if (com->do_timestamp) if (com->do_timestamp)
microtime(&com->timestamp); microtime(&com->timestamp);
++com_events; ++com_events;
schedsofttty(); sched_swi(sio_slow_ih, SWI_DELAY);
#if 0 /* for testing input latency vs efficiency */ #if 0 /* for testing input latency vs efficiency */
if (com->iptr - com->ibuf == 8) if (com->iptr - com->ibuf == 8)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = line_status; ioptr[com->ierroff] = line_status;
@ -2028,7 +2031,7 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
/* handle CTS change immediately for crisp flow ctl */ /* handle CTS change immediately for crisp flow ctl */
@ -2082,7 +2085,8 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); /* handle at high level ASAP */ /* handle at high level ASAP */
sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
} }
if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
@ -2257,7 +2261,7 @@ sioioctl(dev, cmd, data, flag, p)
/* software interrupt handler for SWI_TTY */ /* software interrupt handler for SWI_TTY */
static void static void
siopoll() siopoll(void *dummy)
{ {
int unit; int unit;
int intrsave; int intrsave;

View File

@ -29,6 +29,8 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <vm/vm.h> #include <vm/vm.h>
#include <vm/vm_page.h> #include <vm/vm_page.h>
@ -639,7 +641,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
STAILQ_INSERT_TAIL(&bounce_map_callbacklist, STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links); map, links);
busdma_swi_pending = 1; busdma_swi_pending = 1;
setsoftvm(); sched_swi(vm_ih, SWI_NOSWITCH);
} }
} }
splx(s); splx(s);

View File

@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
switch (timer0_state) { switch (timer0_state) {
case RELEASED: case RELEASED:
setdelayed();
break; break;
case ACQUIRED: case ACQUIRED:
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
>= hardclock_max_count) { >= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count; timer0_prescaler_count -= hardclock_max_count;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
mtx_exit(&clock_lock, MTX_SPIN); mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function; timer_func = new_function;
timer0_state = ACQUIRED; timer0_state = ACQUIRED;
setdelayed();
break; break;
case RELEASE_PENDING: case RELEASE_PENDING:
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
timer_func = hardclock; timer_func = hardclock;
timer0_state = RELEASED; timer0_state = RELEASED;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
} }
@ -967,7 +963,7 @@ cpu_initclocks()
int diag; int diag;
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
if (statclock_disable) { if (statclock_disable) {

View File

@ -591,7 +591,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)
busdma_swi(); busdma_swi();

View File

@ -42,6 +42,4 @@
#include <i386/isa/icu_ipl.h> #include <i386/isa/icu_ipl.h>
#endif #endif
#define NSWI 7
#endif /* !_MACHINE_IPL_H_ */ #endif /* !_MACHINE_IPL_H_ */

View File

@ -94,8 +94,7 @@ int is_physical_memory __P((vm_offset_t addr));
u_long kvtop __P((void *addr)); u_long kvtop __P((void *addr));
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl, void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
int selec)); int selec));
void swi_vm __P((void)); void swi_vm __P((void *));
void swi_net __P((void));
void userconfig __P((void)); void userconfig __P((void));
int user_dbreg_trap __P((void)); int user_dbreg_trap __P((void));
int vm_page_zero_idle __P((void)); int vm_page_zero_idle __P((void));

View File

@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
switch (timer0_state) { switch (timer0_state) {
case RELEASED: case RELEASED:
setdelayed();
break; break;
case ACQUIRED: case ACQUIRED:
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
>= hardclock_max_count) { >= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count; timer0_prescaler_count -= hardclock_max_count;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
mtx_exit(&clock_lock, MTX_SPIN); mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function; timer_func = new_function;
timer0_state = ACQUIRED; timer0_state = ACQUIRED;
setdelayed();
break; break;
case RELEASE_PENDING: case RELEASE_PENDING:
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
timer_func = hardclock; timer_func = hardclock;
timer0_state = RELEASED; timer0_state = RELEASED;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
} }
@ -967,7 +963,7 @@ cpu_initclocks()
int diag; int diag;
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
if (statclock_disable) { if (statclock_disable) {

View File

@ -133,7 +133,7 @@
#define siosetwater cysetwater #define siosetwater cysetwater
#define comstop cystop #define comstop cystop
#define siowrite cywrite #define siowrite cywrite
#define sio_registered cy_registered #define sio_irec cy_irec
#define sio_timeout cy_timeout #define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle #define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log #define sio_timeouts_until_log cy_timeouts_until_log
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1; static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED; static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */ static u_int com_events; /* input chars + weighted output completions */
static bool_t sio_registered; static struct intrhand *sio_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
com_addr(unit) = com; com_addr(unit) = com;
splx(s); splx(s);
if (!sio_registered) { if (sio_ih == NULL)
cdevsw_add(&sio_cdevsw); cdevsw_add(&sio_cdevsw);
register_swi(SWI_TTY, siopoll); sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
sio_registered = TRUE; SWI_TTY, 0);
} }
make_dev(&sio_cdevsw, unit, make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter, UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -1174,7 +1174,8 @@ siointr(unit)
#ifndef SOFT_HOTCHAR #ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0) && com->hotchar != 0)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */ #if 1 /* XXX "intelligent" PFO error handling would break O error handling */
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) { if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
@ -1201,7 +1202,7 @@ siointr(unit)
++com->bytes_in; ++com->bytes_in;
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
@ -1251,7 +1252,7 @@ siointr(unit)
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data && recv_data
== com->hotchar) == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1266,7 +1267,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
} while (--count != 0); } while (--count != 0);
} else { } else {
@ -1291,7 +1292,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR #ifdef SOFT_HOTCHAR
if (com->hotchar != 0 if (com->hotchar != 0
&& recv_data == com->hotchar) && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = 0; ioptr[com->ierroff] = 0;
@ -1356,7 +1357,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
@ -1487,7 +1488,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
break; break;
case ETC_BREAK_ENDED: case ETC_BREAK_ENDED:
@ -1501,7 +1502,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) { if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE; com->extra_state |= CSE_ODONE;
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
cd_outb(iobase, CD1400_SRER, cy_align, cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable com->intr_enable
@ -1559,7 +1560,7 @@ siointr(unit)
com->state |= CS_ODONE; com->state |= CS_ODONE;
/* handle at high level ASAP */ /* handle at high level ASAP */
setsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
} }
} }
} }
@ -1579,7 +1580,7 @@ siointr(unit)
/* ensure an edge for the next interrupt */ /* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
schedsofttty(); sched_swi(sio_ih, SWI_NOSWITCH);
COM_UNLOCK(); COM_UNLOCK();
} }

View File

@ -531,13 +531,13 @@ icu_unset(intr, handler)
return (0); return (0);
} }
struct intrec * struct intrhand *
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg, inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
int pri, int flags) int pri, int flags)
{ {
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */ struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
struct intrec *head; /* chain of handlers for IRQ */ struct intrhand *head; /* chain of handlers for IRQ */
struct intrec *idesc; /* descriptor for this handler */ struct intrhand *idesc; /* descriptor for this handler */
struct proc *p; /* interrupt thread */ struct proc *p; /* interrupt thread */
int errcode = 0; int errcode = 0;
@ -592,7 +592,7 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
panic("inthand_add: Can't initialize ICU"); panic("inthand_add: Can't initialize ICU");
} }
} else if ((flags & INTR_EXCL) != 0 } else if ((flags & INTR_EXCL) != 0
|| (ithd->it_ih->flags & INTR_EXCL) != 0) { || (ithd->it_ih->ih_flags & INTR_EXCL) != 0) {
/* /*
* We can't append the new handler if either * We can't append the new handler if either
* list ithd or new handler do not allow * list ithd or new handler do not allow
@ -601,14 +601,14 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
if (bootverbose) if (bootverbose)
printf("\tdevice combination %s and %s " printf("\tdevice combination %s and %s "
"doesn't support shared irq%d\n", "doesn't support shared irq%d\n",
ithd->it_ih->name, name, irq); ithd->it_ih->ih_name, name, irq);
return(NULL); return(NULL);
} else if (flags & INTR_FAST) { } else if (flags & INTR_FAST) {
/* We can only have one fast interrupt by itself. */ /* We can only have one fast interrupt by itself. */
if (bootverbose) if (bootverbose)
printf("\tCan't add fast interrupt %s" printf("\tCan't add fast interrupt %s"
" to normal interrupt %s on irq%d", " to normal interrupt %s on irq%d",
name, ithd->it_ih->name, irq); name, ithd->it_ih->ih_name, irq);
return (NULL); return (NULL);
} else { /* update p_comm */ } else { /* update p_comm */
p = ithd->it_proc; p = ithd->it_proc;
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
else else
strcat(p->p_comm, "+"); strcat(p->p_comm, "+");
} }
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK); idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
if (idesc == NULL) if (idesc == NULL)
return (NULL); return (NULL);
bzero(idesc, sizeof (struct intrec)); bzero(idesc, sizeof (struct intrhand));
idesc->handler = handler; idesc->ih_handler = handler;
idesc->argument = arg; idesc->ih_argument = arg;
idesc->flags = flags; idesc->ih_flags = flags;
idesc->ithd = ithd; idesc->ih_ithd = ithd;
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK); idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if (idesc->name == NULL) { if (idesc->ih_name == NULL) {
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return (NULL); return (NULL);
} }
strcpy(idesc->name, name); strcpy(idesc->ih_name, name);
/* Slow interrupts got set up above. */ /* Slow interrupts got set up above. */
if ((flags & INTR_FAST) if ((flags & INTR_FAST)
&& (icu_setup(irq, idesc->handler, idesc->argument, && (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
idesc->flags) != 0) ) { idesc->ih_flags) != 0) ) {
if (bootverbose) if (bootverbose)
printf("\tinthand_add(irq%d) failed, result=%d\n", printf("\tinthand_add(irq%d) failed, result=%d\n",
irq, errcode); irq, errcode);
free(idesc->name, M_DEVBUF); free(idesc->ih_name, M_DEVBUF);
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return NULL; return NULL;
} }
head = ithd->it_ih; /* look at chain of handlers */ head = ithd->it_ih; /* look at chain of handlers */
if (head) { if (head) {
while (head->next != NULL) while (head->ih_next != NULL)
head = head->next; /* find the end */ head = head->ih_next; /* find the end */
head->next = idesc; /* hook it in there */ head->ih_next = idesc; /* hook it in there */
} else } else
ithd->it_ih = idesc; /* put it up front */ ithd->it_ih = idesc; /* put it up front */
update_intrname(irq, idesc->name); update_intrname(irq, idesc->ih_name);
return (idesc); return (idesc);
} }
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
*/ */
int int
inthand_remove(struct intrec *idesc) inthand_remove(struct intrhand *idesc)
{ {
struct ithd *ithd; /* descriptor for the IRQ */ struct ithd *ithd; /* descriptor for the IRQ */
struct intrec *ih; /* chain of handlers */ struct intrhand *ih; /* chain of handlers */
if (idesc == NULL) if (idesc == NULL)
return (-1); return (-1);
ithd = idesc->ithd; ithd = idesc->ih_ithd;
ih = ithd->it_ih; ih = ithd->it_ih;
if (ih == idesc) /* first in the chain */ if (ih == idesc) /* first in the chain */
ithd->it_ih = idesc->next; /* unhook it */ ithd->it_ih = idesc->ih_next; /* unhook it */
else { else {
while ((ih != NULL) while ((ih != NULL)
&& (ih->next != idesc) ) && (ih->ih_next != idesc) )
ih = ih->next; ih = ih->ih_next;
if (ih->next != idesc) if (ih->ih_next != idesc)
return (-1); return (-1);
ih->next = ih->next->next; ih->ih_next = ih->ih_next->ih_next;
} }
if (ithd->it_ih == NULL) { /* no handlers left, */ if (ithd->it_ih == NULL) { /* no handlers left, */
icu_unset(ithd->irq, idesc->handler); icu_unset(ithd->irq, idesc->ih_handler);
ithds[ithd->irq] = NULL; ithds[ithd->irq] = NULL;
mtx_enter(&sched_lock, MTX_SPIN); mtx_enter(&sched_lock, MTX_SPIN);

View File

@ -218,9 +218,9 @@ int icu_unset __P((int intr, driver_intr_t *handler));
* WARNING: These are internal functions and not to be used by device drivers! * WARNING: These are internal functions and not to be used by device drivers!
* They are subject to change without notice. * They are subject to change without notice.
*/ */
struct intrec *inthand_add(const char *name, int irq, driver_intr_t handler, struct intrhand *inthand_add(const char *name, int irq, driver_intr_t handler,
void *arg, int pri, int flags); void *arg, int pri, int flags);
int inthand_remove(struct intrec *idesc); int inthand_remove(struct intrhand *idesc);
void sched_ithd(void *); void sched_ithd(void *);
void ithd_loop(void *); void ithd_loop(void *);
void start_softintr(void *); void start_softintr(void *);

View File

@ -172,44 +172,12 @@ doreti_ast:
movb $1,_intr_nesting_level /* for doreti_next to decrement */ movb $1,_intr_nesting_level /* for doreti_next to decrement */
jmp doreti_next jmp doreti_next
ALIGN_TEXT
.globl _swi_net
.type _swi_net,@function
_swi_net:
MCOUNT
bsfl _netisr,%eax
je swi_net_done
swi_net_more:
btrl %eax,_netisr
jnc swi_net_next
call *_netisrs(,%eax,4)
swi_net_next:
bsfl _netisr,%eax
jne swi_net_more
swi_net_done:
ret
ALIGN_TEXT ALIGN_TEXT
dummynetisr: dummynetisr:
MCOUNT MCOUNT
ret ret
/*
* The arg is in a nonstandard place, so swi_dispatcher() can't be called
* directly and swi_generic() can't use ENTRY() or MCOUNT.
*/
ALIGN_TEXT
.globl _swi_generic
.type _swi_generic,@function
_swi_generic:
pushl %ecx
FAKE_MCOUNT(4(%esp))
call _swi_dispatcher
popl %ecx
ret
ENTRY(swi_null)
ret
#ifdef APIC_IO #ifdef APIC_IO
#include "i386/isa/apic_ipl.s" #include "i386/isa/apic_ipl.s"

View File

@ -32,8 +32,3 @@
#include <sys/ipl.h> #include <sys/ipl.h>
#include <sys/interrupt.h> #include <sys/interrupt.h>
#include <machine/md_var.h> #include <machine/md_var.h>
swihand_t *shandlers[NSWI] = { /* software interrupts */
swi_null, swi_net, swi_null, swi_null,
swi_vm, swi_null, softclock
};

View File

@ -165,7 +165,7 @@ void
ithd_loop(void *dummy) ithd_loop(void *dummy)
{ {
struct ithd *me; /* our thread context */ struct ithd *me; /* our thread context */
struct intrec *ih; /* and our interrupt handler chain */ struct intrhand *ih; /* and our interrupt handler chain */
me = curproc->p_ithd; /* point to myself */ me = curproc->p_ithd; /* point to myself */
@ -200,17 +200,17 @@ ithd_loop(void *dummy)
#if 0 #if 0
membar_unlock(); /* push out "it_need=0" */ membar_unlock(); /* push out "it_need=0" */
#endif #endif
for (ih = me->it_ih; ih != NULL; ih = ih->next) { for (ih = me->it_ih; ih != NULL; ih = ih->ih_next) {
CTR5(KTR_INTR, CTR5(KTR_INTR,
"ithd_loop pid %d ih=%p: %p(%p) flg=%x", "ithd_loop pid %d ih=%p: %p(%p) flg=%x",
me->it_proc->p_pid, (void *)ih, me->it_proc->p_pid, (void *)ih,
(void *)ih->handler, ih->argument, (void *)ih->ih_handler, ih->ih_argument,
ih->flags); ih->ih_flags);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_enter(&Giant, MTX_DEF); mtx_enter(&Giant, MTX_DEF);
ih->handler(ih->argument); ih->ih_handler(ih->ih_argument);
if ((ih->flags & INTR_MPSAFE) == 0) if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_exit(&Giant, MTX_DEF); mtx_exit(&Giant, MTX_DEF);
} }
} }

View File

@ -531,13 +531,13 @@ icu_unset(intr, handler)
return (0); return (0);
} }
struct intrec * struct intrhand *
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg, inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
int pri, int flags) int pri, int flags)
{ {
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */ struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
struct intrec *head; /* chain of handlers for IRQ */ struct intrhand *head; /* chain of handlers for IRQ */
struct intrec *idesc; /* descriptor for this handler */ struct intrhand *idesc; /* descriptor for this handler */
struct proc *p; /* interrupt thread */ struct proc *p; /* interrupt thread */
int errcode = 0; int errcode = 0;
@ -592,7 +592,7 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
panic("inthand_add: Can't initialize ICU"); panic("inthand_add: Can't initialize ICU");
} }
} else if ((flags & INTR_EXCL) != 0 } else if ((flags & INTR_EXCL) != 0
|| (ithd->it_ih->flags & INTR_EXCL) != 0) { || (ithd->it_ih->ih_flags & INTR_EXCL) != 0) {
/* /*
* We can't append the new handler if either * We can't append the new handler if either
* list ithd or new handler do not allow * list ithd or new handler do not allow
@ -601,14 +601,14 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
if (bootverbose) if (bootverbose)
printf("\tdevice combination %s and %s " printf("\tdevice combination %s and %s "
"doesn't support shared irq%d\n", "doesn't support shared irq%d\n",
ithd->it_ih->name, name, irq); ithd->it_ih->ih_name, name, irq);
return(NULL); return(NULL);
} else if (flags & INTR_FAST) { } else if (flags & INTR_FAST) {
/* We can only have one fast interrupt by itself. */ /* We can only have one fast interrupt by itself. */
if (bootverbose) if (bootverbose)
printf("\tCan't add fast interrupt %s" printf("\tCan't add fast interrupt %s"
" to normal interrupt %s on irq%d", " to normal interrupt %s on irq%d",
name, ithd->it_ih->name, irq); name, ithd->it_ih->ih_name, irq);
return (NULL); return (NULL);
} else { /* update p_comm */ } else { /* update p_comm */
p = ithd->it_proc; p = ithd->it_proc;
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
else else
strcat(p->p_comm, "+"); strcat(p->p_comm, "+");
} }
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK); idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
if (idesc == NULL) if (idesc == NULL)
return (NULL); return (NULL);
bzero(idesc, sizeof (struct intrec)); bzero(idesc, sizeof (struct intrhand));
idesc->handler = handler; idesc->ih_handler = handler;
idesc->argument = arg; idesc->ih_argument = arg;
idesc->flags = flags; idesc->ih_flags = flags;
idesc->ithd = ithd; idesc->ih_ithd = ithd;
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK); idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if (idesc->name == NULL) { if (idesc->ih_name == NULL) {
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return (NULL); return (NULL);
} }
strcpy(idesc->name, name); strcpy(idesc->ih_name, name);
/* Slow interrupts got set up above. */ /* Slow interrupts got set up above. */
if ((flags & INTR_FAST) if ((flags & INTR_FAST)
&& (icu_setup(irq, idesc->handler, idesc->argument, && (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
idesc->flags) != 0) ) { idesc->ih_flags) != 0) ) {
if (bootverbose) if (bootverbose)
printf("\tinthand_add(irq%d) failed, result=%d\n", printf("\tinthand_add(irq%d) failed, result=%d\n",
irq, errcode); irq, errcode);
free(idesc->name, M_DEVBUF); free(idesc->ih_name, M_DEVBUF);
free(idesc, M_DEVBUF); free(idesc, M_DEVBUF);
return NULL; return NULL;
} }
head = ithd->it_ih; /* look at chain of handlers */ head = ithd->it_ih; /* look at chain of handlers */
if (head) { if (head) {
while (head->next != NULL) while (head->ih_next != NULL)
head = head->next; /* find the end */ head = head->ih_next; /* find the end */
head->next = idesc; /* hook it in there */ head->ih_next = idesc; /* hook it in there */
} else } else
ithd->it_ih = idesc; /* put it up front */ ithd->it_ih = idesc; /* put it up front */
update_intrname(irq, idesc->name); update_intrname(irq, idesc->ih_name);
return (idesc); return (idesc);
} }
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
*/ */
int int
inthand_remove(struct intrec *idesc) inthand_remove(struct intrhand *idesc)
{ {
struct ithd *ithd; /* descriptor for the IRQ */ struct ithd *ithd; /* descriptor for the IRQ */
struct intrec *ih; /* chain of handlers */ struct intrhand *ih; /* chain of handlers */
if (idesc == NULL) if (idesc == NULL)
return (-1); return (-1);
ithd = idesc->ithd; ithd = idesc->ih_ithd;
ih = ithd->it_ih; ih = ithd->it_ih;
if (ih == idesc) /* first in the chain */ if (ih == idesc) /* first in the chain */
ithd->it_ih = idesc->next; /* unhook it */ ithd->it_ih = idesc->ih_next; /* unhook it */
else { else {
while ((ih != NULL) while ((ih != NULL)
&& (ih->next != idesc) ) && (ih->ih_next != idesc) )
ih = ih->next; ih = ih->ih_next;
if (ih->next != idesc) if (ih->ih_next != idesc)
return (-1); return (-1);
ih->next = ih->next->next; ih->ih_next = ih->ih_next->ih_next;
} }
if (ithd->it_ih == NULL) { /* no handlers left, */ if (ithd->it_ih == NULL) { /* no handlers left, */
icu_unset(ithd->irq, idesc->handler); icu_unset(ithd->irq, idesc->ih_handler);
ithds[ithd->irq] = NULL; ithds[ithd->irq] = NULL;
mtx_enter(&sched_lock, MTX_SPIN); mtx_enter(&sched_lock, MTX_SPIN);

View File

@ -172,6 +172,8 @@ static int rc_rcsrt[16] = {
TTY_BI|TTY_PE|TTY_FE|TTY_OE TTY_BI|TTY_PE|TTY_FE|TTY_OE
}; };
static struct intrhand *rc_ih;
/* Static prototypes */ /* Static prototypes */
static ointhand2_t rcintr; static ointhand2_t rcintr;
static void rc_hwreset __P((int, int, unsigned int)); static void rc_hwreset __P((int, int, unsigned int));
@ -268,7 +270,8 @@ rcattach(dvp)
rcb->rcb_probed = RC_ATTACHED; rcb->rcb_probed = RC_ATTACHED;
if (!rc_started) { if (!rc_started) {
cdevsw_add(&rc_cdevsw); cdevsw_add(&rc_cdevsw);
register_swi(SWI_TTY, rcpoll); rc_ih = sinthand_add("tty:rc", &tty_ithd, rcpoll, NULL,
SWI_TTY, 0);
rc_wakeup((void *)NULL); rc_wakeup((void *)NULL);
rc_started = 1; rc_started = 1;
} }
@ -362,7 +365,7 @@ rcintr(unit)
optr++; optr++;
rc_scheduled_event++; rc_scheduled_event++;
if (val != 0 && val == rc->rc_hotchar) if (val != 0 && val == rc->rc_hotchar)
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
} else { } else {
/* Store also status data */ /* Store also status data */
@ -393,7 +396,7 @@ rcintr(unit)
&& (rc->rc_tp->t_iflag & INPCK)))) && (rc->rc_tp->t_iflag & INPCK))))
val = 0; val = 0;
else if (val != 0 && val == rc->rc_hotchar) else if (val != 0 && val == rc->rc_hotchar)
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
optr[0] = val; optr[0] = val;
optr[INPUT_FLAGS_SHIFT] = iack; optr[INPUT_FLAGS_SHIFT] = iack;
optr++; optr++;
@ -440,7 +443,7 @@ rcintr(unit)
if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) { if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) {
rc_scheduled_event += LOTS_OF_EVENTS; rc_scheduled_event += LOTS_OF_EVENTS;
rc->rc_flags |= RC_MODCHG; rc->rc_flags |= RC_MODCHG;
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
goto more_intrs; goto more_intrs;
} }
@ -481,7 +484,7 @@ rcintr(unit)
if (!(rc->rc_flags & RC_DOXXFER)) { if (!(rc->rc_flags & RC_DOXXFER)) {
rc_scheduled_event += LOTS_OF_EVENTS; rc_scheduled_event += LOTS_OF_EVENTS;
rc->rc_flags |= RC_DOXXFER; rc->rc_flags |= RC_DOXXFER;
setsofttty(); sched_swi(rc_ih, SWI_NOSWITCH);
} }
} }
} }

View File

@ -694,7 +694,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
STAILQ_INSERT_TAIL(&bounce_map_callbacklist, STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links); map, links);
busdma_swi_pending = 1; busdma_swi_pending = 1;
setsoftvm(); sched_swi(vm_ih, SWI_NOSWITCH);
} }
} }
splx(s); splx(s);

View File

@ -27,64 +27,9 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/ktr.h>
#include <sys/interrupt.h>
#include <machine/ipl.h>
#include <machine/cpu.h>
#include <machine/globaldata.h>
#include <machine/globals.h>
#include <machine/mutex.h>
#include <net/netisr.h>
#include "sio.h"
unsigned int bio_imask; /* XXX */ unsigned int bio_imask; /* XXX */
unsigned int cam_imask; /* XXX */ unsigned int cam_imask; /* XXX */
unsigned int net_imask; /* XXX */ unsigned int net_imask; /* XXX */
unsigned int tty_imask; /* XXX */ unsigned int tty_imask; /* XXX */
static void swi_net(void);
void (*netisrs[32]) __P((void));
swihand_t *shandlers[32] = { /* software interrupts */
swi_null, swi_net, swi_null, swi_null,
swi_null, swi_null, softclock, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
swi_null, swi_null, swi_null, swi_null,
};
u_int32_t netisr;
void
swi_null()
{
/* No interrupt registered, do nothing */
}
void
swi_generic()
{
/* Just a placeholder, we call swi_dispatcher directly */
panic("swi_generic() called");
}
static void
swi_net()
{
u_int32_t bits = atomic_readandclear_32(&netisr);
int i;
for (i = 0; i < 32; i++) {
if (bits & 1)
netisrs[i]();
bits >>= 1;
}
}

View File

@ -95,12 +95,6 @@ static struct cdevsw mem_cdevsw = {
/* bmaj */ -1 /* bmaj */ -1
}; };
#if NHWI > 0
#define ICU_LEN (NHWI)
#else
#define ICU_LEN (NSWI)
#endif
struct mem_range_softc mem_range_softc; struct mem_range_softc mem_range_softc;
static int static int

View File

@ -519,7 +519,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
#if 0 #if 0
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)

View File

@ -29,12 +29,6 @@
#ifndef _MACHINE_IPL_H_ #ifndef _MACHINE_IPL_H_
#define _MACHINE_IPL_H_ #define _MACHINE_IPL_H_
/*
* Software interrupt bit numbers
*/
#define NSWI 32
#define NHWI 0
/* /*
* Interprocessor interrupts for SMP. * Interprocessor interrupts for SMP.
*/ */
@ -50,4 +44,4 @@ void smp_ipi_all_but_self(u_int64_t ipi);
void smp_ipi_self(u_int64_t ipi); void smp_ipi_self(u_int64_t ipi);
void smp_handle_ipi(struct trapframe *frame); void smp_handle_ipi(struct trapframe *frame);
#endif /* !_MACHINE_MD_VAR_H_ */ #endif /* !_MACHINE_IPL_H_ */

View File

@ -47,7 +47,7 @@ void busdma_swi __P((void));
void cpu_halt __P((void)); void cpu_halt __P((void));
void cpu_reset __P((void)); void cpu_reset __P((void));
int is_physical_memory __P((vm_offset_t addr)); int is_physical_memory __P((vm_offset_t addr));
void swi_vm __P((void)); void swi_vm __P((void *));
int vm_page_zero_idle __P((void)); int vm_page_zero_idle __P((void));
int fill_regs __P((struct proc *, struct reg *)); int fill_regs __P((struct proc *, struct reg *));
int set_regs __P((struct proc *, struct reg *)); int set_regs __P((struct proc *, struct reg *));

View File

@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
switch (timer0_state) { switch (timer0_state) {
case RELEASED: case RELEASED:
setdelayed();
break; break;
case ACQUIRED: case ACQUIRED:
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
>= hardclock_max_count) { >= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count; timer0_prescaler_count -= hardclock_max_count;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
mtx_exit(&clock_lock, MTX_SPIN); mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function; timer_func = new_function;
timer0_state = ACQUIRED; timer0_state = ACQUIRED;
setdelayed();
break; break;
case RELEASE_PENDING: case RELEASE_PENDING:
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
timer_func = hardclock; timer_func = hardclock;
timer0_state = RELEASED; timer0_state = RELEASED;
hardclock(&frame); hardclock(&frame);
setdelayed();
} }
break; break;
} }
@ -967,7 +963,7 @@ cpu_initclocks()
int diag; int diag;
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
if (statclock_disable) { if (statclock_disable) {

View File

@ -300,7 +300,7 @@ static void siointr1 __P((struct com_s *com));
static void siointr __P((void *arg)); static void siointr __P((void *arg));
static int commctl __P((struct com_s *com, int bits, int how)); static int commctl __P((struct com_s *com, int bits, int how));
static int comparam __P((struct tty *tp, struct termios *t)); static int comparam __P((struct tty *tp, struct termios *t));
static swihand_t siopoll; static void siopoll __P((void *));
static int sioprobe __P((device_t dev, int xrid)); static int sioprobe __P((device_t dev, int xrid));
static int sio_isa_probe __P((device_t dev)); static int sio_isa_probe __P((device_t dev));
static void siosettimeout __P((void)); static void siosettimeout __P((void));
@ -413,7 +413,8 @@ static int siocnunit;
#endif #endif
static Port_t siogdbiobase; static Port_t siogdbiobase;
static int siogdbunit = -1; static int siogdbunit = -1;
static bool_t sio_registered; static struct intrhand *sio_slow_ih;
static struct intrhand *sio_fast_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -1322,9 +1323,11 @@ determined_type: ;
printf(" with a bogus IIR_TXRDY register"); printf(" with a bogus IIR_TXRDY register");
printf("\n"); printf("\n");
if (!sio_registered) { if (sio_fast_ih == NULL) {
register_swi(SWI_TTY, siopoll); sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
sio_registered = TRUE; NULL, SWI_TTY, 0);
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
NULL, SWI_TTY, 0);
} }
com->devs[0] = make_dev(&sio_cdevsw, unit, com->devs[0] = make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit); UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
@ -1979,7 +1982,7 @@ siointr1(com)
} }
++com->bytes_in; ++com->bytes_in;
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
@ -1987,10 +1990,10 @@ siointr1(com)
if (com->do_timestamp) if (com->do_timestamp)
microtime(&com->timestamp); microtime(&com->timestamp);
++com_events; ++com_events;
schedsofttty(); sched_swi(sio_slow_ih, SWI_DELAY);
#if 0 /* for testing input latency vs efficiency */ #if 0 /* for testing input latency vs efficiency */
if (com->iptr - com->ibuf == 8) if (com->iptr - com->ibuf == 8)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = line_status; ioptr[com->ierroff] = line_status;
@ -2028,7 +2031,7 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
/* handle CTS change immediately for crisp flow ctl */ /* handle CTS change immediately for crisp flow ctl */
@ -2082,7 +2085,8 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); /* handle at high level ASAP */ /* handle at high level ASAP */
sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
} }
if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
@ -2257,7 +2261,7 @@ sioioctl(dev, cmd, data, flag, p)
/* software interrupt handler for SWI_TTY */ /* software interrupt handler for SWI_TTY */
static void static void
siopoll() siopoll(void *dummy)
{ {
int unit; int unit;
int intrsave; int intrsave;

View File

@ -58,6 +58,8 @@
#include <vm/pmap.h> #include <vm/pmap.h>
#include <vm/vm_map.h> #include <vm/vm_map.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/limits.h> #include <machine/limits.h>
@ -192,7 +194,7 @@ hardclock(frame)
* relatively high clock interrupt priority any longer than necessary. * relatively high clock interrupt priority any longer than necessary.
*/ */
if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) { if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) {
setsoftclock(); sched_swi(softclock_ih, SWI_NOSWITCH);
} else if (softticks + 1 == ticks) } else if (softticks + 1 == ticks)
++softticks; ++softticks;
} }

View File

@ -44,105 +44,18 @@
#include <sys/vmmeter.h> #include <sys/vmmeter.h>
#include <machine/atomic.h> #include <machine/atomic.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/md_var.h>
struct swilist { #include <net/netisr.h> /* prototype for legacy_setsoftnet */
swihand_t *sl_handler;
struct swilist *sl_next;
};
static struct swilist swilists[NSWI]; struct intrhand *net_ih;
u_long softintr_count[NSWI]; struct intrhand *vm_ih;
static struct proc *softithd; struct intrhand *softclock_ih;
volatile u_int sdelayed; struct ithd *clk_ithd;
volatile u_int spending; struct ithd *tty_ithd;
static void start_softintr(void *); static void start_softintr(void *);
static void intr_soft(void *); static void swi_net(void *);
void
register_swi(intr, handler)
int intr;
swihand_t *handler;
{
struct swilist *slp, *slq;
int s;
if (intr < 0 || intr >= NSWI)
panic("register_swi: bad intr %d", intr);
if (handler == swi_generic || handler == swi_null)
panic("register_swi: bad handler %p", (void *)handler);
slp = &swilists[intr];
s = splhigh();
if (shandlers[intr] == swi_null)
shandlers[intr] = handler;
else {
if (slp->sl_next == NULL) {
slp->sl_handler = shandlers[intr];
shandlers[intr] = swi_generic;
}
slq = malloc(sizeof(*slq), M_DEVBUF, M_NOWAIT);
if (slq == NULL)
panic("register_swi: malloc failed");
slq->sl_handler = handler;
slq->sl_next = NULL;
while (slp->sl_next != NULL)
slp = slp->sl_next;
slp->sl_next = slq;
}
splx(s);
}
void
swi_dispatcher(intr)
int intr;
{
struct swilist *slp;
slp = &swilists[intr];
do {
(*slp->sl_handler)();
slp = slp->sl_next;
} while (slp != NULL);
}
void
unregister_swi(intr, handler)
int intr;
swihand_t *handler;
{
struct swilist *slfoundpred, *slp, *slq;
int s;
if (intr < 0 || intr >= NSWI)
panic("unregister_swi: bad intr %d", intr);
if (handler == swi_generic || handler == swi_null)
panic("unregister_swi: bad handler %p", (void *)handler);
slp = &swilists[intr];
s = splhigh();
if (shandlers[intr] == handler)
shandlers[intr] = swi_null;
else if (slp->sl_next != NULL) {
slfoundpred = NULL;
for (slq = slp->sl_next; slq != NULL;
slp = slq, slq = slp->sl_next)
if (slq->sl_handler == handler)
slfoundpred = slp;
slp = &swilists[intr];
if (slfoundpred != NULL) {
slq = slfoundpred->sl_next;
slfoundpred->sl_next = slq->sl_next;
free(slq, M_DEVBUF);
} else if (slp->sl_handler == handler) {
slq = slp->sl_next;
slp->sl_next = slq->sl_next;
slp->sl_handler = slq->sl_handler;
free(slq, M_DEVBUF);
}
if (slp->sl_next == NULL)
shandlers[intr] = slp->sl_handler;
}
splx(s);
}
int int
ithread_priority(flags) ithread_priority(flags)
@ -181,175 +94,197 @@ ithread_priority(flags)
return pri; return pri;
} }
void sithd_loop(void *);
struct intrhand *
sinthand_add(const char *name, struct ithd **ithdp, driver_intr_t handler,
void *arg, int pri, int flags)
{
struct proc *p;
struct ithd *ithd;
struct intrhand *ih;
struct intrhand *this_ih;
ithd = (ithdp != NULL) ? *ithdp : NULL;
if (ithd == NULL) {
int error;
ithd = malloc(sizeof (struct ithd), M_DEVBUF, M_WAITOK | M_ZERO);
error = kthread_create(sithd_loop, NULL, &p,
RFSTOPPED | RFHIGHPID, "swi%d: %s", pri, name);
if (error)
panic("inthand_add: Can't create interrupt thread");
ithd->it_proc = p;
p->p_ithd = ithd;
p->p_rtprio.type = RTP_PRIO_ITHREAD;
p->p_rtprio.prio = pri + PI_SOFT; /* soft interrupt */
p->p_stat = SWAIT; /* we're idle */
/* XXX - some hacks are _really_ gross */
if (pri == SWI_CLOCK)
p->p_flag |= P_NOLOAD;
if (ithdp != NULL)
*ithdp = ithd;
}
this_ih = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK | M_ZERO);
this_ih->ih_handler = handler;
this_ih->ih_argument = arg;
this_ih->ih_flags = flags;
this_ih->ih_ithd = ithd;
this_ih->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
if ((ih = ithd->it_ih)) {
while (ih->ih_next != NULL)
ih = ih->ih_next;
ih->ih_next = this_ih;
} else
ithd->it_ih = this_ih;
strcpy(this_ih->ih_name, name);
return (this_ih);
}
/* /*
* Schedule the soft interrupt handler thread. * Schedule a heavyweight software interrupt process.
*/ */
void void
sched_softintr(void) sched_swi(struct intrhand *ih, int flag)
{ {
struct ithd *it = ih->ih_ithd; /* and the process that does it */
struct proc *p = it->it_proc;
atomic_add_int(&cnt.v_intr, 1); /* one more global interrupt */ atomic_add_int(&cnt.v_intr, 1); /* one more global interrupt */
CTR3(KTR_INTR, "sched_sihand pid %d(%s) need=%d",
p->p_pid, p->p_comm, it->it_need);
/* /*
* If we don't have an interrupt resource or an interrupt thread for * Set it_need so that if the thread is already running but close
* this IRQ, log it as a stray interrupt. * to done, it will do another go-round. Then get the sched lock
* and see if the thread is on whichkqs yet. If not, put it on
* there. In any case, kick everyone so that if the new thread
* is higher priority than their current thread, it gets run now.
*/ */
if (softithd == NULL) ih->ih_need = 1;
panic("soft interrupt scheduled too early"); if (!(flag & SWI_DELAY)) {
it->it_need = 1;
CTR3(KTR_INTR, "sched_softintr pid %d(%s) spending=0x%x", mtx_enter(&sched_lock, MTX_SPIN);
softithd->p_pid, softithd->p_comm, spending); if (p->p_stat == SWAIT) { /* not on run queue */
CTR1(KTR_INTR, "sched_ithd: setrunqueue %d", p->p_pid);
/* /* membar_lock(); */
* Get the sched lock and see if the thread is on whichkqs yet. p->p_stat = SRUN;
* If not, put it on there. In any case, kick everyone so that if setrunqueue(p);
* the new thread is higher priority than their current thread, it aston();
* gets run now.
*/
mtx_enter(&sched_lock, MTX_SPIN);
if (softithd->p_stat == SWAIT) { /* not on run queue */
CTR1(KTR_INTR, "sched_softintr: setrunqueue %d",
softithd->p_pid);
/* membar_lock(); */
softithd->p_stat = SRUN;
setrunqueue(softithd);
aston();
}
mtx_exit(&sched_lock, MTX_SPIN);
#if 0
aston(); /* ??? check priorities first? */
#else
need_resched();
#endif
}
SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, NULL)
/*
* Start soft interrupt thread.
*/
static void
start_softintr(dummy)
void *dummy;
{
int error;
if (softithd != NULL) { /* we already have a thread */
printf("start_softintr: already running");
return;
}
error = kthread_create(intr_soft, NULL, &softithd,
RFSTOPPED | RFHIGHPID, "softinterrupt");
if (error)
panic("start_softintr: kthread_create error %d\n", error);
softithd->p_rtprio.type = RTP_PRIO_ITHREAD;
softithd->p_rtprio.prio = PI_SOFT; /* soft interrupt */
softithd->p_stat = SWAIT; /* we're idle */
softithd->p_flag |= P_NOLOAD;
}
/*
* Software interrupt process code.
*/
static void
intr_soft(dummy)
void *dummy;
{
int i;
u_int pend;
/* Main loop */
for (;;) {
CTR3(KTR_INTR, "intr_soft pid %d(%s) spending=0x%x",
curproc->p_pid, curproc->p_comm, spending);
/*
* Service interrupts. If another interrupt arrives
* while we are running, they will set spending to
* denote that we should make another pass.
*/
pend = atomic_readandclear_int(&spending);
while ((i = ffs(pend))) {
i--;
atomic_add_long(&softintr_count[i], 1);
pend &= ~ (1 << i);
mtx_enter(&Giant, MTX_DEF);
if (shandlers[i] == swi_generic)
swi_dispatcher(i);
else
(shandlers[i])();
mtx_exit(&Giant, MTX_DEF);
} }
else {
CTR3(KTR_INTR, "sched_ithd %d: it_need %d, state %d",
p->p_pid, it->it_need, p->p_stat );
}
mtx_exit(&sched_lock, MTX_SPIN);
need_resched();
}
}
/*
* This is the main code for soft interrupt threads.
*/
void
sithd_loop(void *dummy)
{
struct ithd *it; /* our thread context */
struct intrhand *ih; /* and our interrupt handler chain */
struct proc *p = curproc;
it = p->p_ithd; /* point to myself */
/*
* As long as we have interrupts outstanding, go through the
* list of handlers, giving each one a go at it.
*/
for (;;) {
CTR3(KTR_INTR, "sithd_loop pid %d(%s) need=%d",
p->p_pid, p->p_comm, it->it_need);
while (it->it_need) {
/*
* Service interrupts. If another interrupt
* arrives while we are running, they will set
* it_need to denote that we should make
* another pass.
*/
it->it_need = 0;
for (ih = it->it_ih; ih != NULL; ih = ih->ih_next) {
if (!ih->ih_need)
continue;
ih->ih_need = 0;
CTR5(KTR_INTR,
"ithd_loop pid %d ih=%p: %p(%p) flg=%x",
p->p_pid, (void *)ih,
(void *)ih->ih_handler, ih->ih_argument,
ih->ih_flags);
if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_enter(&Giant, MTX_DEF);
ih->ih_handler(ih->ih_argument);
if ((ih->ih_flags & INTR_MPSAFE) == 0)
mtx_exit(&Giant, MTX_DEF);
}
}
/* /*
* Processed all our interrupts. Now get the sched * Processed all our interrupts. Now get the sched
* lock. This may take a while and spending may get * lock. This may take a while and it_need may get
* set again, so we have to check it again. * set again, so we have to check it again.
*/ */
mtx_enter(&sched_lock, MTX_SPIN); mtx_enter(&sched_lock, MTX_SPIN);
if (spending == 0) { if (!it->it_need) {
CTR1(KTR_INTR, "intr_soft pid %d: done", p->p_stat = SWAIT; /* we're idle */
curproc->p_pid); CTR1(KTR_INTR, "sithd_loop pid %d: done", p->p_pid);
curproc->p_stat = SWAIT; /* we're idle */
mi_switch(); mi_switch();
CTR1(KTR_INTR, "intr_soft pid %d: resumed", CTR1(KTR_INTR, "sithd_loop pid %d: resumed", p->p_pid);
curproc->p_pid);
} }
mtx_exit(&sched_lock, MTX_SPIN); mtx_exit(&sched_lock, MTX_SPIN);
} }
} }
SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, NULL)
/* /*
* Bits in the spending bitmap variable must be set atomically because * Start standard software interrupt threads
* spending may be manipulated by interrupts or other cpu's without holding
* any locks.
*
* Note: setbits uses a locked or, making simple cases MP safe.
*/ */
#define DO_SETBITS(name, var, bits) \ static void
void name(void) \ start_softintr(dummy)
{ \ void *dummy;
atomic_set_int(var, bits); \ {
sched_softintr(); \ net_ih = sinthand_add("net", NULL, swi_net, NULL, SWI_NET, 0);
softclock_ih =
sinthand_add("clock", &clk_ithd, softclock, NULL, SWI_CLOCK, 0);
vm_ih = sinthand_add("vm", NULL, swi_vm, NULL, SWI_VM, 0);
} }
#define DO_SETBITS_AND_NO_MORE(name, var, bits) \
void name(void) \
{ \
atomic_set_int(var, bits); \
}
DO_SETBITS(setsoftcamnet,&spending, SWI_CAMNET_PENDING)
DO_SETBITS(setsoftcambio,&spending, SWI_CAMBIO_PENDING)
DO_SETBITS(setsoftclock, &spending, SWI_CLOCK_PENDING)
DO_SETBITS(setsoftnet, &spending, SWI_NET_PENDING)
DO_SETBITS(setsofttty, &spending, SWI_TTY_PENDING)
DO_SETBITS(setsoftvm, &spending, SWI_VM_PENDING)
DO_SETBITS(setsofttq, &spending, SWI_TQ_PENDING)
DO_SETBITS_AND_NO_MORE(schedsoftcamnet, &sdelayed, SWI_CAMNET_PENDING)
DO_SETBITS_AND_NO_MORE(schedsoftcambio, &sdelayed, SWI_CAMBIO_PENDING)
DO_SETBITS_AND_NO_MORE(schedsoftnet, &sdelayed, SWI_NET_PENDING)
DO_SETBITS_AND_NO_MORE(schedsofttty, &sdelayed, SWI_TTY_PENDING)
DO_SETBITS_AND_NO_MORE(schedsoftvm, &sdelayed, SWI_VM_PENDING)
DO_SETBITS_AND_NO_MORE(schedsofttq, &sdelayed, SWI_TQ_PENDING)
void void
setdelayed(void) legacy_setsoftnet()
{ {
int pend; sched_swi(net_ih, SWI_NOSWITCH);
pend = atomic_readandclear_int(&sdelayed);
if (pend != 0) {
atomic_set_int(&spending, pend);
sched_softintr();
}
} }
intrmask_t /*
softclockpending(void) * XXX: This should really be in the network code somewhere and installed
* via a SI_SUB_SOFINTR, SI_ORDER_MIDDLE sysinit.
*/
void (*netisrs[32]) __P((void));
u_int netisr;
static void
swi_net(void *dummy)
{ {
return (spending & SWI_CLOCK_PENDING); u_int bits;
int i;
bits = atomic_readandclear_int(&netisr);
while ((i = ffs(bits)) != 0) {
i--;
netisrs[i]();
bits &= ~(1 << i);
}
} }
/* /*

View File

@ -75,7 +75,7 @@ static struct callout *nextsoftcheck; /* Next callout to be checked. */
* Run periodic events from timeout queue. * Run periodic events from timeout queue.
*/ */
void void
softclock() softclock(void *dummy)
{ {
register struct callout *c; register struct callout *c;
register struct callout_tailq *bucket; register struct callout_tailq *bucket;

View File

@ -40,6 +40,8 @@ MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues");
static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues;
static struct intrhand *taskqueue_ih;
struct taskqueue { struct taskqueue {
STAILQ_ENTRY(taskqueue) tq_link; STAILQ_ENTRY(taskqueue) tq_link;
STAILQ_HEAD(, task) tq_queue; STAILQ_HEAD(, task) tq_queue;
@ -191,14 +193,15 @@ taskqueue_run(struct taskqueue *queue)
static void static void
taskqueue_swi_enqueue(void *context) taskqueue_swi_enqueue(void *context)
{ {
setsofttq(); sched_swi(taskqueue_ih, SWI_NOSWITCH);
} }
static void static void
taskqueue_swi_run(void) taskqueue_swi_run(void *dummy)
{ {
taskqueue_run(taskqueue_swi); taskqueue_run(taskqueue_swi);
} }
TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0, TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0,
register_swi(SWI_TQ, taskqueue_swi_run)); taskqueue_ih = sinthand_add("task queue", NULL,
taskqueue_swi_run, NULL, SWI_TQ, 0));

View File

@ -68,8 +68,10 @@
#ifndef LOCORE #ifndef LOCORE
#ifdef _KERNEL #ifdef _KERNEL
void legacy_setsoftnet __P((void));
extern volatile unsigned int netisr; /* scheduling bits for network */ extern volatile unsigned int netisr; /* scheduling bits for network */
#define schednetisr(anisr) { netisr |= 1 << (anisr); setsoftnet(); } #define schednetisr(anisr) { netisr |= 1 << (anisr); legacy_setsoftnet(); }
typedef void netisr_t __P((void)); typedef void netisr_t __P((void));

View File

@ -1298,7 +1298,7 @@ cpu_initclocks()
{ {
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
#ifndef PC98 #ifndef PC98
int diag; int diag;

View File

@ -1298,7 +1298,7 @@ cpu_initclocks()
{ {
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
#ifndef PC98 #ifndef PC98
int diag; int diag;

View File

@ -533,7 +533,8 @@ static int siocnunit;
#endif #endif
static Port_t siogdbiobase; static Port_t siogdbiobase;
static int siogdbunit = -1; static int siogdbunit = -1;
static bool_t sio_registered; static struct intrhand *sio_slow_ih;
static struct intrhand *sio_fast_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -2083,9 +2084,11 @@ determined_type: ;
printf(" with a bogus IIR_TXRDY register"); printf(" with a bogus IIR_TXRDY register");
printf("\n"); printf("\n");
if (!sio_registered) { if (sio_fast_ih == NULL) {
register_swi(SWI_TTY, siopoll); sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
sio_registered = TRUE; NULL, SWI_TTY, 0);
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
NULL, SWI_TTY, 0);
} }
make_dev(&sio_cdevsw, unit, make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit); UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
@ -2917,7 +2920,7 @@ status_read:;
} }
++com->bytes_in; ++com->bytes_in;
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
@ -2926,14 +2929,10 @@ status_read:;
microtime(&com->timestamp); microtime(&com->timestamp);
++com_events; ++com_events;
/* XXX - needs to go away when alpha gets ithreads */ /* XXX - needs to go away when alpha gets ithreads */
#ifdef __alpha__ sched_swi(sio_slow_ih, SWI_DELAY);
schedsofttty();
#else
setsofttty();
#endif
#if 0 /* for testing input latency vs efficiency */ #if 0 /* for testing input latency vs efficiency */
if (com->iptr - com->ibuf == 8) if (com->iptr - com->ibuf == 8)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = line_status; ioptr[com->ierroff] = line_status;
@ -2987,7 +2986,7 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
/* handle CTS change immediately for crisp flow ctl */ /* handle CTS change immediately for crisp flow ctl */
@ -3089,7 +3088,8 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); /* handle at high level ASAP */ /* handle at high level ASAP */
sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
} }
if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {

View File

@ -1298,7 +1298,7 @@ cpu_initclocks()
{ {
#ifdef APIC_IO #ifdef APIC_IO
int apic_8254_trial; int apic_8254_trial;
struct intrec *clkdesc; struct intrhand *clkdesc;
#endif /* APIC_IO */ #endif /* APIC_IO */
#ifndef PC98 #ifndef PC98
int diag; int diag;

View File

@ -533,7 +533,8 @@ static int siocnunit;
#endif #endif
static Port_t siogdbiobase; static Port_t siogdbiobase;
static int siogdbunit = -1; static int siogdbunit = -1;
static bool_t sio_registered; static struct intrhand *sio_slow_ih;
static struct intrhand *sio_fast_ih;
static int sio_timeout; static int sio_timeout;
static int sio_timeouts_until_log; static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle static struct callout_handle sio_timeout_handle
@ -2083,9 +2084,11 @@ determined_type: ;
printf(" with a bogus IIR_TXRDY register"); printf(" with a bogus IIR_TXRDY register");
printf("\n"); printf("\n");
if (!sio_registered) { if (sio_fast_ih == NULL) {
register_swi(SWI_TTY, siopoll); sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
sio_registered = TRUE; NULL, SWI_TTY, 0);
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
NULL, SWI_TTY, 0);
} }
make_dev(&sio_cdevsw, unit, make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit); UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
@ -2917,7 +2920,7 @@ status_read:;
} }
++com->bytes_in; ++com->bytes_in;
if (com->hotchar != 0 && recv_data == com->hotchar) if (com->hotchar != 0 && recv_data == com->hotchar)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
ioptr = com->iptr; ioptr = com->iptr;
if (ioptr >= com->ibufend) if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
@ -2926,14 +2929,10 @@ status_read:;
microtime(&com->timestamp); microtime(&com->timestamp);
++com_events; ++com_events;
/* XXX - needs to go away when alpha gets ithreads */ /* XXX - needs to go away when alpha gets ithreads */
#ifdef __alpha__ sched_swi(sio_slow_ih, SWI_DELAY);
schedsofttty();
#else
setsofttty();
#endif
#if 0 /* for testing input latency vs efficiency */ #if 0 /* for testing input latency vs efficiency */
if (com->iptr - com->ibuf == 8) if (com->iptr - com->ibuf == 8)
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
#endif #endif
ioptr[0] = recv_data; ioptr[0] = recv_data;
ioptr[com->ierroff] = line_status; ioptr[com->ierroff] = line_status;
@ -2987,7 +2986,7 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_CHECKMSR)) { if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR; com->state |= CS_CHECKMSR;
setsofttty(); sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
/* handle CTS change immediately for crisp flow ctl */ /* handle CTS change immediately for crisp flow ctl */
@ -3089,7 +3088,8 @@ if (com->iptr - com->ibuf == 8)
if (!(com->state & CS_ODONE)) { if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS; com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE; com->state |= CS_ODONE;
setsofttty(); /* handle at high level ASAP */ /* handle at high level ASAP */
sched_swi(sio_fast_ih, SWI_NOSWITCH);
} }
} }
if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {

View File

@ -470,7 +470,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)
busdma_swi(); busdma_swi();

View File

@ -50,7 +50,7 @@ void busdma_swi __P((void));
void cpu_halt __P((void)); void cpu_halt __P((void));
void cpu_reset __P((void)); void cpu_reset __P((void));
int is_physical_memory __P((vm_offset_t addr)); int is_physical_memory __P((vm_offset_t addr));
void swi_vm __P((void)); void swi_vm __P((void *));
int vm_page_zero_idle __P((void)); int vm_page_zero_idle __P((void));
int fill_regs __P((struct proc *, struct reg *)); int fill_regs __P((struct proc *, struct reg *));
int set_regs __P((struct proc *, struct reg *)); int set_regs __P((struct proc *, struct reg *));

View File

@ -470,7 +470,7 @@ vm_page_zero_idle()
* Software interrupt handler for queued VM system processing. * Software interrupt handler for queued VM system processing.
*/ */
void void
swi_vm() swi_vm(void *dummy)
{ {
if (busdma_swi_pending != 0) if (busdma_swi_pending != 0)
busdma_swi(); busdma_swi();

View File

@ -36,27 +36,30 @@
* together via the 'next' pointer. * together via the 'next' pointer.
*/ */
struct ithd; struct intrhand {
driver_intr_t *ih_handler; /* code address of handler */
struct intrec { void *ih_argument; /* argument to pass to handler */
driver_intr_t *handler; /* code address of handler */ enum intr_type ih_flags; /* flag bits (sys/bus.h) */
void *argument; /* argument to pass to handler */ char *ih_name; /* name of handler */
enum intr_type flags; /* flag bits (sys/bus.h) */ struct ithd *ih_ithd; /* handler we're connected to */
char *name; /* name of handler */ struct intrhand *ih_next; /* next handler for this irq */
struct ithd *ithd; /* handler we're connected to */ int ih_need; /* need interrupt */
struct intrec *next; /* next handler for this irq */
}; };
typedef void swihand_t __P((void));
extern swihand_t *shandlers[];
void register_swi __P((int intr, swihand_t *handler));
void swi_dispatcher __P((int intr));
swihand_t swi_generic;
swihand_t swi_null;
void unregister_swi __P((int intr, swihand_t *handler));
int ithread_priority __P((int flags)); int ithread_priority __P((int flags));
void sched_softintr __P((void)); void sched_swi __P((struct intrhand *, int));
#define SWI_SWITCH 0x1
#define SWI_NOSWITCH 0x2
#define SWI_DELAY 0x4 /* implies NOSWITCH */
struct intrhand * sinthand_add __P((const char *name, struct ithd **,
driver_intr_t, void *arg, int pri, int flags));
extern struct ithd *tty_ithd;
extern struct ithd *clk_ithd;
extern struct intrhand *net_ih;
extern struct intrhand *softclock_ih;
extern struct intrhand *vm_ih;
#endif #endif

View File

@ -348,7 +348,7 @@ struct ithd {
LIST_ENTRY(ithd) it_list; /* All interrupt threads */ LIST_ENTRY(ithd) it_list; /* All interrupt threads */
int it_need; /* Needs service */ int it_need; /* Needs service */
int irq; /* irq */ int irq; /* irq */
struct intrec *it_ih; /* head of handler queue */ struct intrhand *it_ih; /* head of handler queue */
struct ithd *it_interrupted; /* Who we interrupted */ struct ithd *it_interrupted; /* Who we interrupted */
/* Fields used only for hard interrupt threads */ /* Fields used only for hard interrupt threads */

View File

@ -159,7 +159,7 @@ int susword __P((void *base, int word));
void realitexpire __P((void *)); void realitexpire __P((void *));
void hardclock __P((struct clockframe *frame)); void hardclock __P((struct clockframe *frame));
void softclock __P((void)); void softclock __P((void *));
void statclock __P((struct clockframe *frame)); void statclock __P((struct clockframe *frame));
void startprofclock __P((struct proc *)); void startprofclock __P((struct proc *));
@ -204,22 +204,6 @@ struct callout_handle timeout __P((timeout_t *, void *, int));
void untimeout __P((timeout_t *, void *, struct callout_handle)); void untimeout __P((timeout_t *, void *, struct callout_handle));
/* Interrupt management */ /* Interrupt management */
void setdelayed __P((void));
void setsoftast __P((void));
void setsoftcambio __P((void));
void setsoftcamnet __P((void));
void setsoftclock __P((void));
void setsoftnet __P((void));
void setsofttty __P((void));
void setsoftvm __P((void));
void setsofttq __P((void));
void schedsoftcamnet __P((void));
void schedsoftcambio __P((void));
void schedsoftnet __P((void));
void schedsofttty __P((void));
void schedsoftvm __P((void));
void schedsofttq __P((void));
intrmask_t softclockpending __P((void));
void spl0 __P((void)); void spl0 __P((void));
intrmask_t splbio __P((void)); intrmask_t splbio __P((void));
intrmask_t splcam __P((void)); intrmask_t splcam __P((void));