- 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:
parent
650789cb1b
commit
8088699f79
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67551
@ -27,7 +27,9 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/malloc.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,
|
||||
map, links);
|
||||
busdma_swi_pending = 1;
|
||||
setsoftvm();
|
||||
sched_swi(vm_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
@ -398,7 +398,6 @@ handleclock(void* arg)
|
||||
}
|
||||
|
||||
hardclock(arg);
|
||||
setdelayed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -341,7 +341,7 @@ alpha_setup_intr(const char *name, int vector, driver_intr_t *handler,
|
||||
{
|
||||
int h = HASHVEC(vector);
|
||||
struct alpha_intr *i;
|
||||
struct intrec *head, *idesc;
|
||||
struct intrhand *head, *idesc;
|
||||
struct ithd *ithd;
|
||||
struct proc *p;
|
||||
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. */
|
||||
idesc = malloc(sizeof (struct intrec), M_DEVBUF, M_WAITOK);
|
||||
idesc = malloc(sizeof (struct intrhand), M_DEVBUF, M_WAITOK);
|
||||
if (idesc == NULL)
|
||||
return ENOMEM;
|
||||
bzero(idesc, sizeof(struct intrec));
|
||||
bzero(idesc, sizeof(struct intrhand));
|
||||
|
||||
idesc->handler = handler;
|
||||
idesc->argument = arg;
|
||||
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->name == NULL) {
|
||||
idesc->ih_handler = handler;
|
||||
idesc->ih_argument = arg;
|
||||
idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->ih_name == NULL) {
|
||||
free(idesc, M_DEVBUF);
|
||||
return(NULL);
|
||||
}
|
||||
strcpy(idesc->name, name);
|
||||
strcpy(idesc->ih_name, name);
|
||||
|
||||
/* Fourth, add our handler to the end of the ithread's handler list. */
|
||||
head = ithd->it_ih;
|
||||
if (head) {
|
||||
while (head->next != NULL)
|
||||
head = head->next;
|
||||
head->next = idesc;
|
||||
while (head->ih_next != NULL)
|
||||
head = head->ih_next;
|
||||
head->ih_next = idesc;
|
||||
} else
|
||||
ithd->it_ih = idesc;
|
||||
|
||||
@ -440,27 +440,27 @@ alpha_setup_intr(const char *name, int vector, driver_intr_t *handler,
|
||||
int
|
||||
alpha_teardown_intr(void *cookie)
|
||||
{
|
||||
struct intrec *idesc = cookie;
|
||||
struct intrhand *idesc = cookie;
|
||||
struct ithd *ithd;
|
||||
struct intrec *head;
|
||||
struct intrhand *head;
|
||||
#if 0
|
||||
struct alpha_intr *i;
|
||||
int s;
|
||||
#endif
|
||||
|
||||
/* First, detach ourself from our interrupt thread. */
|
||||
ithd = idesc->ithd;
|
||||
ithd = idesc->ih_ithd;
|
||||
KASSERT(ithd != NULL, ("idesc without an interrupt thread"));
|
||||
|
||||
head = ithd->it_ih;
|
||||
if (head == idesc)
|
||||
ithd->it_ih = idesc->next;
|
||||
ithd->it_ih = idesc->ih_next;
|
||||
else {
|
||||
while (head != NULL && head->next != idesc)
|
||||
head = head->next;
|
||||
while (head != NULL && head->ih_next != idesc)
|
||||
head = head->ih_next;
|
||||
if (head == NULL)
|
||||
return (-1); /* couldn't find ourself */
|
||||
head->next = idesc->next;
|
||||
head->ih_next = idesc->ih_next;
|
||||
}
|
||||
free(idesc, M_DEVBUF);
|
||||
|
||||
@ -541,7 +541,7 @@ void
|
||||
ithd_loop(void *dummy)
|
||||
{
|
||||
struct ithd *ithd; /* our thread context */
|
||||
struct intrec *ih; /* list of handlers */
|
||||
struct intrhand *ih; /* list of handlers */
|
||||
struct alpha_intr *i; /* interrupt source */
|
||||
|
||||
ithd = curproc->p_ithd;
|
||||
@ -565,17 +565,17 @@ ithd_loop(void *dummy)
|
||||
|
||||
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,
|
||||
"ithd_loop pid %d ih=%p: %p(%p) flg=%x",
|
||||
ithd->it_proc->p_pid, (void *)ih,
|
||||
(void *)ih->handler, ih->argument,
|
||||
ih->flags);
|
||||
(void *)ih->ih_handler, ih->ih_argument,
|
||||
ih->ih_flags);
|
||||
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
ih->handler(ih->argument);
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
ih->ih_handler(ih->ih_argument);
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
}
|
||||
|
||||
|
@ -27,64 +27,9 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.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 cam_imask; /* XXX */
|
||||
unsigned int net_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;
|
||||
}
|
||||
}
|
||||
|
@ -96,12 +96,6 @@ static struct cdevsw mem_cdevsw = {
|
||||
/* bmaj */ -1
|
||||
};
|
||||
|
||||
#if NHWI > 0
|
||||
#define ICU_LEN (NHWI)
|
||||
#else
|
||||
#define ICU_LEN (NSWI)
|
||||
#endif
|
||||
|
||||
struct mem_range_softc mem_range_softc;
|
||||
|
||||
static int
|
||||
|
@ -470,7 +470,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
|
@ -32,9 +32,6 @@
|
||||
|
||||
#include <machine/cpu.h> /* for pal inlines */
|
||||
|
||||
#define NSWI 32
|
||||
#define HWHI 0
|
||||
|
||||
/*
|
||||
* Interprocessor interrupts for SMP.
|
||||
*/
|
||||
|
@ -50,7 +50,7 @@ void busdma_swi __P((void));
|
||||
void cpu_halt __P((void));
|
||||
void cpu_reset __P((void));
|
||||
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 fill_regs __P((struct proc *, struct reg *));
|
||||
int set_regs __P((struct proc *, struct reg *));
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
|
||||
#include <vm/vm.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,
|
||||
map, links);
|
||||
busdma_swi_pending = 1;
|
||||
setsoftvm();
|
||||
sched_swi(vm_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case ACQUIRED:
|
||||
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
|
||||
>= hardclock_max_count) {
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
|
||||
mtx_exit(&clock_lock, MTX_SPIN);
|
||||
timer_func = new_function;
|
||||
timer0_state = ACQUIRED;
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +963,7 @@ cpu_initclocks()
|
||||
int diag;
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
|
||||
if (statclock_disable) {
|
||||
|
@ -591,7 +591,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
|
@ -94,8 +94,7 @@ int is_physical_memory __P((vm_offset_t addr));
|
||||
u_long kvtop __P((void *addr));
|
||||
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
|
||||
int selec));
|
||||
void swi_vm __P((void));
|
||||
void swi_net __P((void));
|
||||
void swi_vm __P((void *));
|
||||
void userconfig __P((void));
|
||||
int user_dbreg_trap __P((void));
|
||||
int vm_page_zero_idle __P((void));
|
||||
|
@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case ACQUIRED:
|
||||
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
|
||||
>= hardclock_max_count) {
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
|
||||
mtx_exit(&clock_lock, MTX_SPIN);
|
||||
timer_func = new_function;
|
||||
timer0_state = ACQUIRED;
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +963,7 @@ cpu_initclocks()
|
||||
int diag;
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
|
||||
if (statclock_disable) {
|
||||
|
@ -531,13 +531,13 @@ icu_unset(intr, handler)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct intrec *
|
||||
struct intrhand *
|
||||
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
int pri, int flags)
|
||||
{
|
||||
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
|
||||
struct intrec *head; /* chain of handlers for IRQ */
|
||||
struct intrec *idesc; /* descriptor for this handler */
|
||||
struct intrhand *head; /* chain of handlers for IRQ */
|
||||
struct intrhand *idesc; /* descriptor for this handler */
|
||||
struct proc *p; /* interrupt thread */
|
||||
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");
|
||||
}
|
||||
} 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
|
||||
* 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)
|
||||
printf("\tdevice combination %s and %s "
|
||||
"doesn't support shared irq%d\n",
|
||||
ithd->it_ih->name, name, irq);
|
||||
ithd->it_ih->ih_name, name, irq);
|
||||
return(NULL);
|
||||
} else if (flags & INTR_FAST) {
|
||||
/* We can only have one fast interrupt by itself. */
|
||||
if (bootverbose)
|
||||
printf("\tCan't add fast interrupt %s"
|
||||
" to normal interrupt %s on irq%d",
|
||||
name, ithd->it_ih->name, irq);
|
||||
name, ithd->it_ih->ih_name, irq);
|
||||
return (NULL);
|
||||
} else { /* update p_comm */
|
||||
p = ithd->it_proc;
|
||||
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
else
|
||||
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)
|
||||
return (NULL);
|
||||
bzero(idesc, sizeof (struct intrec));
|
||||
bzero(idesc, sizeof (struct intrhand));
|
||||
|
||||
idesc->handler = handler;
|
||||
idesc->argument = arg;
|
||||
idesc->flags = flags;
|
||||
idesc->ithd = ithd;
|
||||
idesc->ih_handler = handler;
|
||||
idesc->ih_argument = arg;
|
||||
idesc->ih_flags = flags;
|
||||
idesc->ih_ithd = ithd;
|
||||
|
||||
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->name == NULL) {
|
||||
idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->ih_name == NULL) {
|
||||
free(idesc, M_DEVBUF);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(idesc->name, name);
|
||||
strcpy(idesc->ih_name, name);
|
||||
|
||||
/* Slow interrupts got set up above. */
|
||||
if ((flags & INTR_FAST)
|
||||
&& (icu_setup(irq, idesc->handler, idesc->argument,
|
||||
idesc->flags) != 0) ) {
|
||||
&& (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
|
||||
idesc->ih_flags) != 0) ) {
|
||||
if (bootverbose)
|
||||
printf("\tinthand_add(irq%d) failed, result=%d\n",
|
||||
irq, errcode);
|
||||
free(idesc->name, M_DEVBUF);
|
||||
free(idesc->ih_name, M_DEVBUF);
|
||||
free(idesc, M_DEVBUF);
|
||||
return NULL;
|
||||
}
|
||||
head = ithd->it_ih; /* look at chain of handlers */
|
||||
if (head) {
|
||||
while (head->next != NULL)
|
||||
head = head->next; /* find the end */
|
||||
head->next = idesc; /* hook it in there */
|
||||
while (head->ih_next != NULL)
|
||||
head = head->ih_next; /* find the end */
|
||||
head->ih_next = idesc; /* hook it in there */
|
||||
} else
|
||||
ithd->it_ih = idesc; /* put it up front */
|
||||
update_intrname(irq, idesc->name);
|
||||
update_intrname(irq, idesc->ih_name);
|
||||
return (idesc);
|
||||
}
|
||||
|
||||
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
*/
|
||||
|
||||
int
|
||||
inthand_remove(struct intrec *idesc)
|
||||
inthand_remove(struct intrhand *idesc)
|
||||
{
|
||||
struct ithd *ithd; /* descriptor for the IRQ */
|
||||
struct intrec *ih; /* chain of handlers */
|
||||
struct intrhand *ih; /* chain of handlers */
|
||||
|
||||
if (idesc == NULL)
|
||||
return (-1);
|
||||
ithd = idesc->ithd;
|
||||
ithd = idesc->ih_ithd;
|
||||
ih = ithd->it_ih;
|
||||
|
||||
if (ih == idesc) /* first in the chain */
|
||||
ithd->it_ih = idesc->next; /* unhook it */
|
||||
ithd->it_ih = idesc->ih_next; /* unhook it */
|
||||
else {
|
||||
while ((ih != NULL)
|
||||
&& (ih->next != idesc) )
|
||||
ih = ih->next;
|
||||
if (ih->next != idesc)
|
||||
return (-1);
|
||||
ih->next = ih->next->next;
|
||||
}
|
||||
&& (ih->ih_next != idesc) )
|
||||
ih = ih->ih_next;
|
||||
if (ih->ih_next != idesc)
|
||||
return (-1);
|
||||
ih->ih_next = ih->ih_next->ih_next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
|
@ -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!
|
||||
* 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);
|
||||
int inthand_remove(struct intrec *idesc);
|
||||
int inthand_remove(struct intrhand *idesc);
|
||||
void sched_ithd(void *);
|
||||
void ithd_loop(void *);
|
||||
void start_softintr(void *);
|
||||
|
@ -165,7 +165,7 @@ void
|
||||
ithd_loop(void *dummy)
|
||||
{
|
||||
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 */
|
||||
|
||||
@ -200,17 +200,17 @@ ithd_loop(void *dummy)
|
||||
#if 0
|
||||
membar_unlock(); /* push out "it_need=0" */
|
||||
#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,
|
||||
"ithd_loop pid %d ih=%p: %p(%p) flg=%x",
|
||||
me->it_proc->p_pid, (void *)ih,
|
||||
(void *)ih->handler, ih->argument,
|
||||
ih->flags);
|
||||
(void *)ih->ih_handler, ih->ih_argument,
|
||||
ih->ih_flags);
|
||||
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
ih->handler(ih->argument);
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
ih->ih_handler(ih->ih_argument);
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
}
|
||||
}
|
||||
|
@ -531,13 +531,13 @@ icu_unset(intr, handler)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct intrec *
|
||||
struct intrhand *
|
||||
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
int pri, int flags)
|
||||
{
|
||||
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
|
||||
struct intrec *head; /* chain of handlers for IRQ */
|
||||
struct intrec *idesc; /* descriptor for this handler */
|
||||
struct intrhand *head; /* chain of handlers for IRQ */
|
||||
struct intrhand *idesc; /* descriptor for this handler */
|
||||
struct proc *p; /* interrupt thread */
|
||||
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");
|
||||
}
|
||||
} 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
|
||||
* 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)
|
||||
printf("\tdevice combination %s and %s "
|
||||
"doesn't support shared irq%d\n",
|
||||
ithd->it_ih->name, name, irq);
|
||||
ithd->it_ih->ih_name, name, irq);
|
||||
return(NULL);
|
||||
} else if (flags & INTR_FAST) {
|
||||
/* We can only have one fast interrupt by itself. */
|
||||
if (bootverbose)
|
||||
printf("\tCan't add fast interrupt %s"
|
||||
" to normal interrupt %s on irq%d",
|
||||
name, ithd->it_ih->name, irq);
|
||||
name, ithd->it_ih->ih_name, irq);
|
||||
return (NULL);
|
||||
} else { /* update p_comm */
|
||||
p = ithd->it_proc;
|
||||
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
else
|
||||
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)
|
||||
return (NULL);
|
||||
bzero(idesc, sizeof (struct intrec));
|
||||
bzero(idesc, sizeof (struct intrhand));
|
||||
|
||||
idesc->handler = handler;
|
||||
idesc->argument = arg;
|
||||
idesc->flags = flags;
|
||||
idesc->ithd = ithd;
|
||||
idesc->ih_handler = handler;
|
||||
idesc->ih_argument = arg;
|
||||
idesc->ih_flags = flags;
|
||||
idesc->ih_ithd = ithd;
|
||||
|
||||
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->name == NULL) {
|
||||
idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->ih_name == NULL) {
|
||||
free(idesc, M_DEVBUF);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(idesc->name, name);
|
||||
strcpy(idesc->ih_name, name);
|
||||
|
||||
/* Slow interrupts got set up above. */
|
||||
if ((flags & INTR_FAST)
|
||||
&& (icu_setup(irq, idesc->handler, idesc->argument,
|
||||
idesc->flags) != 0) ) {
|
||||
&& (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
|
||||
idesc->ih_flags) != 0) ) {
|
||||
if (bootverbose)
|
||||
printf("\tinthand_add(irq%d) failed, result=%d\n",
|
||||
irq, errcode);
|
||||
free(idesc->name, M_DEVBUF);
|
||||
free(idesc->ih_name, M_DEVBUF);
|
||||
free(idesc, M_DEVBUF);
|
||||
return NULL;
|
||||
}
|
||||
head = ithd->it_ih; /* look at chain of handlers */
|
||||
if (head) {
|
||||
while (head->next != NULL)
|
||||
head = head->next; /* find the end */
|
||||
head->next = idesc; /* hook it in there */
|
||||
while (head->ih_next != NULL)
|
||||
head = head->ih_next; /* find the end */
|
||||
head->ih_next = idesc; /* hook it in there */
|
||||
} else
|
||||
ithd->it_ih = idesc; /* put it up front */
|
||||
update_intrname(irq, idesc->name);
|
||||
update_intrname(irq, idesc->ih_name);
|
||||
return (idesc);
|
||||
}
|
||||
|
||||
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
*/
|
||||
|
||||
int
|
||||
inthand_remove(struct intrec *idesc)
|
||||
inthand_remove(struct intrhand *idesc)
|
||||
{
|
||||
struct ithd *ithd; /* descriptor for the IRQ */
|
||||
struct intrec *ih; /* chain of handlers */
|
||||
struct intrhand *ih; /* chain of handlers */
|
||||
|
||||
if (idesc == NULL)
|
||||
return (-1);
|
||||
ithd = idesc->ithd;
|
||||
ithd = idesc->ih_ithd;
|
||||
ih = ithd->it_ih;
|
||||
|
||||
if (ih == idesc) /* first in the chain */
|
||||
ithd->it_ih = idesc->next; /* unhook it */
|
||||
ithd->it_ih = idesc->ih_next; /* unhook it */
|
||||
else {
|
||||
while ((ih != NULL)
|
||||
&& (ih->next != idesc) )
|
||||
ih = ih->next;
|
||||
if (ih->next != idesc)
|
||||
return (-1);
|
||||
ih->next = ih->next->next;
|
||||
}
|
||||
&& (ih->ih_next != idesc) )
|
||||
ih = ih->ih_next;
|
||||
if (ih->ih_next != idesc)
|
||||
return (-1);
|
||||
ih->ih_next = ih->ih_next->ih_next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
|
@ -605,6 +605,10 @@ u_int32_t cam_dflags;
|
||||
u_int32_t cam_debug_delay;
|
||||
#endif
|
||||
|
||||
/* Pointers to software interrupt handlers */
|
||||
struct intrhand *camnet_ih;
|
||||
struct intrhand *cambio_ih;
|
||||
|
||||
#if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
|
||||
#error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS"
|
||||
#endif
|
||||
@ -693,9 +697,7 @@ static xpt_devicefunc_t xptpassannouncefunc;
|
||||
static void xpt_finishconfig(struct cam_periph *periph, union ccb *ccb);
|
||||
static void xptaction(struct cam_sim *sim, union ccb *work_ccb);
|
||||
static void xptpoll(struct cam_sim *sim);
|
||||
static swihand_t swi_camnet;
|
||||
static swihand_t swi_cambio;
|
||||
static void camisr(cam_isrq_t *queue);
|
||||
static void camisr(void *);
|
||||
#if 0
|
||||
static void xptstart(struct cam_periph *periph, union ccb *work_ccb);
|
||||
static void xptasync(struct cam_periph *periph,
|
||||
@ -1363,8 +1365,10 @@ xpt_init(dummy)
|
||||
}
|
||||
|
||||
/* Install our software interrupt handlers */
|
||||
register_swi(SWI_CAMNET, swi_camnet);
|
||||
register_swi(SWI_CAMBIO, swi_cambio);
|
||||
camnet_ih = sinthand_add("camnet", NULL, camisr, &cam_netq,
|
||||
SWI_CAMNET, 0);
|
||||
cambio_ih = sinthand_add("cambio", NULL, camisr, &cam_bioq,
|
||||
SWI_CAMBIO, 0);
|
||||
}
|
||||
|
||||
static cam_status
|
||||
@ -3400,8 +3404,8 @@ xpt_polled_action(union ccb *start_ccb)
|
||||
&& (--timeout > 0)) {
|
||||
DELAY(1000);
|
||||
(*(sim->sim_poll))(sim);
|
||||
swi_camnet();
|
||||
swi_cambio();
|
||||
camisr(&cam_netq);
|
||||
camisr(&cam_bioq);
|
||||
}
|
||||
|
||||
dev->ccbq.devq_openings++;
|
||||
@ -3411,8 +3415,8 @@ xpt_polled_action(union ccb *start_ccb)
|
||||
xpt_action(start_ccb);
|
||||
while(--timeout > 0) {
|
||||
(*(sim->sim_poll))(sim);
|
||||
swi_camnet();
|
||||
swi_cambio();
|
||||
camisr(&cam_netq);
|
||||
camisr(&cam_bioq);
|
||||
if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)
|
||||
!= CAM_REQ_INPROG)
|
||||
break;
|
||||
@ -4527,13 +4531,13 @@ xpt_done(union ccb *done_ccb)
|
||||
TAILQ_INSERT_TAIL(&cam_bioq, &done_ccb->ccb_h,
|
||||
sim_links.tqe);
|
||||
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
|
||||
setsoftcambio();
|
||||
sched_swi(cambio_ih, SWI_NOSWITCH);
|
||||
break;
|
||||
case CAM_PERIPH_NET:
|
||||
TAILQ_INSERT_TAIL(&cam_netq, &done_ccb->ccb_h,
|
||||
sim_links.tqe);
|
||||
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
|
||||
setsoftcamnet();
|
||||
sched_swi(camnet_ih, SWI_NOSWITCH);
|
||||
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
|
||||
swi_camnet(void)
|
||||
{
|
||||
camisr(&cam_netq);
|
||||
}
|
||||
|
||||
static void
|
||||
swi_cambio(void)
|
||||
{
|
||||
camisr(&cam_bioq);
|
||||
}
|
||||
|
||||
static void
|
||||
camisr(cam_isrq_t *queue)
|
||||
camisr(void *V_queue)
|
||||
{
|
||||
cam_isrq_t *queue = V_queue;
|
||||
int s;
|
||||
struct ccb_hdr *ccb_h;
|
||||
|
||||
|
@ -133,7 +133,7 @@
|
||||
#define siosetwater cysetwater
|
||||
#define comstop cystop
|
||||
#define siowrite cywrite
|
||||
#define sio_registered cy_registered
|
||||
#define sio_irec cy_irec
|
||||
#define sio_timeout cy_timeout
|
||||
#define sio_timeout_handle cy_timeout_handle
|
||||
#define sio_timeouts_until_log cy_timeouts_until_log
|
||||
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
|
||||
static int comconsole = -1;
|
||||
static speed_t comdefaultrate = TTYDEF_SPEED;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
|
||||
com_addr(unit) = com;
|
||||
splx(s);
|
||||
|
||||
if (!sio_registered) {
|
||||
if (sio_ih == NULL)
|
||||
cdevsw_add(&sio_cdevsw);
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
|
||||
SWI_TTY, 0);
|
||||
}
|
||||
make_dev(&sio_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
|
||||
@ -1174,7 +1174,8 @@ siointr(unit)
|
||||
#ifndef SOFT_HOTCHAR
|
||||
if (line_status & CD1400_RDSR_SPECIAL
|
||||
&& com->hotchar != 0)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
#endif
|
||||
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
|
||||
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
|
||||
@ -1201,7 +1202,7 @@ siointr(unit)
|
||||
++com->bytes_in;
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
@ -1251,7 +1252,7 @@ siointr(unit)
|
||||
if (com->hotchar != 0
|
||||
&& recv_data
|
||||
== com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1266,7 +1267,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
} while (--count != 0);
|
||||
} else {
|
||||
@ -1291,7 +1292,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1356,7 +1357,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
#ifdef SOFT_CTS_OFLOW
|
||||
@ -1487,7 +1488,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
break;
|
||||
case ETC_BREAK_ENDED:
|
||||
@ -1501,7 +1502,7 @@ siointr(unit)
|
||||
if (!(com->extra_state & CSE_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->extra_state |= CSE_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||
com->intr_enable
|
||||
@ -1559,7 +1560,7 @@ siointr(unit)
|
||||
com->state |= CS_ODONE;
|
||||
|
||||
/* 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 */
|
||||
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||
|
||||
schedsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
COM_UNLOCK();
|
||||
}
|
||||
|
@ -133,7 +133,7 @@
|
||||
#define siosetwater cysetwater
|
||||
#define comstop cystop
|
||||
#define siowrite cywrite
|
||||
#define sio_registered cy_registered
|
||||
#define sio_irec cy_irec
|
||||
#define sio_timeout cy_timeout
|
||||
#define sio_timeout_handle cy_timeout_handle
|
||||
#define sio_timeouts_until_log cy_timeouts_until_log
|
||||
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
|
||||
static int comconsole = -1;
|
||||
static speed_t comdefaultrate = TTYDEF_SPEED;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
|
||||
com_addr(unit) = com;
|
||||
splx(s);
|
||||
|
||||
if (!sio_registered) {
|
||||
if (sio_ih == NULL)
|
||||
cdevsw_add(&sio_cdevsw);
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
|
||||
SWI_TTY, 0);
|
||||
}
|
||||
make_dev(&sio_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
|
||||
@ -1174,7 +1174,8 @@ siointr(unit)
|
||||
#ifndef SOFT_HOTCHAR
|
||||
if (line_status & CD1400_RDSR_SPECIAL
|
||||
&& com->hotchar != 0)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
#endif
|
||||
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
|
||||
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
|
||||
@ -1201,7 +1202,7 @@ siointr(unit)
|
||||
++com->bytes_in;
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
@ -1251,7 +1252,7 @@ siointr(unit)
|
||||
if (com->hotchar != 0
|
||||
&& recv_data
|
||||
== com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1266,7 +1267,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
} while (--count != 0);
|
||||
} else {
|
||||
@ -1291,7 +1292,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1356,7 +1357,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
#ifdef SOFT_CTS_OFLOW
|
||||
@ -1487,7 +1488,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
break;
|
||||
case ETC_BREAK_ENDED:
|
||||
@ -1501,7 +1502,7 @@ siointr(unit)
|
||||
if (!(com->extra_state & CSE_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->extra_state |= CSE_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||
com->intr_enable
|
||||
@ -1559,7 +1560,7 @@ siointr(unit)
|
||||
com->state |= CS_ODONE;
|
||||
|
||||
/* 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 */
|
||||
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||
|
||||
schedsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
COM_UNLOCK();
|
||||
}
|
||||
|
@ -172,6 +172,8 @@ static int rc_rcsrt[16] = {
|
||||
TTY_BI|TTY_PE|TTY_FE|TTY_OE
|
||||
};
|
||||
|
||||
static struct intrhand *rc_ih;
|
||||
|
||||
/* Static prototypes */
|
||||
static ointhand2_t rcintr;
|
||||
static void rc_hwreset __P((int, int, unsigned int));
|
||||
@ -268,7 +270,8 @@ rcattach(dvp)
|
||||
rcb->rcb_probed = RC_ATTACHED;
|
||||
if (!rc_started) {
|
||||
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_started = 1;
|
||||
}
|
||||
@ -362,7 +365,7 @@ rcintr(unit)
|
||||
optr++;
|
||||
rc_scheduled_event++;
|
||||
if (val != 0 && val == rc->rc_hotchar)
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
} else {
|
||||
/* Store also status data */
|
||||
@ -393,7 +396,7 @@ rcintr(unit)
|
||||
&& (rc->rc_tp->t_iflag & INPCK))))
|
||||
val = 0;
|
||||
else if (val != 0 && val == rc->rc_hotchar)
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
optr[0] = val;
|
||||
optr[INPUT_FLAGS_SHIFT] = iack;
|
||||
optr++;
|
||||
@ -440,7 +443,7 @@ rcintr(unit)
|
||||
if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) {
|
||||
rc_scheduled_event += LOTS_OF_EVENTS;
|
||||
rc->rc_flags |= RC_MODCHG;
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
goto more_intrs;
|
||||
}
|
||||
@ -481,7 +484,7 @@ rcintr(unit)
|
||||
if (!(rc->rc_flags & RC_DOXXFER)) {
|
||||
rc_scheduled_event += LOTS_OF_EVENTS;
|
||||
rc->rc_flags |= RC_DOXXFER;
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ static void siointr1 __P((struct com_s *com));
|
||||
static void siointr __P((void *arg));
|
||||
static int commctl __P((struct com_s *com, int bits, int how));
|
||||
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 sio_isa_probe __P((device_t dev));
|
||||
static void siosettimeout __P((void));
|
||||
@ -413,7 +413,8 @@ static int siocnunit;
|
||||
#endif
|
||||
static Port_t siogdbiobase;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -1322,9 +1323,11 @@ determined_type: ;
|
||||
printf(" with a bogus IIR_TXRDY register");
|
||||
printf("\n");
|
||||
|
||||
if (!sio_registered) {
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
if (sio_fast_ih == NULL) {
|
||||
sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
|
||||
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,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
|
||||
@ -1979,7 +1982,7 @@ siointr1(com)
|
||||
}
|
||||
++com->bytes_in;
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
@ -1987,10 +1990,10 @@ siointr1(com)
|
||||
if (com->do_timestamp)
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
schedsofttty();
|
||||
sched_swi(sio_slow_ih, SWI_DELAY);
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
if (com->iptr - com->ibuf == 8)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = line_status;
|
||||
@ -2028,7 +2031,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
/* handle CTS change immediately for crisp flow ctl */
|
||||
@ -2082,7 +2085,8 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
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)) {
|
||||
@ -2257,7 +2261,7 @@ sioioctl(dev, cmd, data, flag, p)
|
||||
|
||||
/* software interrupt handler for SWI_TTY */
|
||||
static void
|
||||
siopoll()
|
||||
siopoll(void *dummy)
|
||||
{
|
||||
int unit;
|
||||
int intrsave;
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
|
||||
#include <vm/vm.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,
|
||||
map, links);
|
||||
busdma_swi_pending = 1;
|
||||
setsoftvm();
|
||||
sched_swi(vm_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case ACQUIRED:
|
||||
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
|
||||
>= hardclock_max_count) {
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
|
||||
mtx_exit(&clock_lock, MTX_SPIN);
|
||||
timer_func = new_function;
|
||||
timer0_state = ACQUIRED;
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +963,7 @@ cpu_initclocks()
|
||||
int diag;
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
|
||||
if (statclock_disable) {
|
||||
|
@ -591,7 +591,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
|
@ -42,6 +42,4 @@
|
||||
#include <i386/isa/icu_ipl.h>
|
||||
#endif
|
||||
|
||||
#define NSWI 7
|
||||
|
||||
#endif /* !_MACHINE_IPL_H_ */
|
||||
|
@ -94,8 +94,7 @@ int is_physical_memory __P((vm_offset_t addr));
|
||||
u_long kvtop __P((void *addr));
|
||||
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
|
||||
int selec));
|
||||
void swi_vm __P((void));
|
||||
void swi_net __P((void));
|
||||
void swi_vm __P((void *));
|
||||
void userconfig __P((void));
|
||||
int user_dbreg_trap __P((void));
|
||||
int vm_page_zero_idle __P((void));
|
||||
|
@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case ACQUIRED:
|
||||
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
|
||||
>= hardclock_max_count) {
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
|
||||
mtx_exit(&clock_lock, MTX_SPIN);
|
||||
timer_func = new_function;
|
||||
timer0_state = ACQUIRED;
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +963,7 @@ cpu_initclocks()
|
||||
int diag;
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
|
||||
if (statclock_disable) {
|
||||
|
@ -133,7 +133,7 @@
|
||||
#define siosetwater cysetwater
|
||||
#define comstop cystop
|
||||
#define siowrite cywrite
|
||||
#define sio_registered cy_registered
|
||||
#define sio_irec cy_irec
|
||||
#define sio_timeout cy_timeout
|
||||
#define sio_timeout_handle cy_timeout_handle
|
||||
#define sio_timeouts_until_log cy_timeouts_until_log
|
||||
@ -391,7 +391,7 @@ static struct cdevsw sio_cdevsw = {
|
||||
static int comconsole = -1;
|
||||
static speed_t comdefaultrate = TTYDEF_SPEED;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -607,10 +607,10 @@ cyattach_common(cy_iobase, cy_align)
|
||||
com_addr(unit) = com;
|
||||
splx(s);
|
||||
|
||||
if (!sio_registered) {
|
||||
if (sio_ih == NULL)
|
||||
cdevsw_add(&sio_cdevsw);
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
|
||||
SWI_TTY, 0);
|
||||
}
|
||||
make_dev(&sio_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
|
||||
@ -1174,7 +1174,8 @@ siointr(unit)
|
||||
#ifndef SOFT_HOTCHAR
|
||||
if (line_status & CD1400_RDSR_SPECIAL
|
||||
&& com->hotchar != 0)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
#endif
|
||||
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
|
||||
if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
|
||||
@ -1201,7 +1202,7 @@ siointr(unit)
|
||||
++com->bytes_in;
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
@ -1251,7 +1252,7 @@ siointr(unit)
|
||||
if (com->hotchar != 0
|
||||
&& recv_data
|
||||
== com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1266,7 +1267,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
} while (--count != 0);
|
||||
} else {
|
||||
@ -1291,7 +1292,7 @@ siointr(unit)
|
||||
#ifdef SOFT_HOTCHAR
|
||||
if (com->hotchar != 0
|
||||
&& recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = 0;
|
||||
@ -1356,7 +1357,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
#ifdef SOFT_CTS_OFLOW
|
||||
@ -1487,7 +1488,7 @@ siointr(unit)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
break;
|
||||
case ETC_BREAK_ENDED:
|
||||
@ -1501,7 +1502,7 @@ siointr(unit)
|
||||
if (!(com->extra_state & CSE_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->extra_state |= CSE_ODONE;
|
||||
setsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
}
|
||||
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||
com->intr_enable
|
||||
@ -1559,7 +1560,7 @@ siointr(unit)
|
||||
com->state |= CS_ODONE;
|
||||
|
||||
/* 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 */
|
||||
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||
|
||||
schedsofttty();
|
||||
sched_swi(sio_ih, SWI_NOSWITCH);
|
||||
|
||||
COM_UNLOCK();
|
||||
}
|
||||
|
@ -531,13 +531,13 @@ icu_unset(intr, handler)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct intrec *
|
||||
struct intrhand *
|
||||
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
int pri, int flags)
|
||||
{
|
||||
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
|
||||
struct intrec *head; /* chain of handlers for IRQ */
|
||||
struct intrec *idesc; /* descriptor for this handler */
|
||||
struct intrhand *head; /* chain of handlers for IRQ */
|
||||
struct intrhand *idesc; /* descriptor for this handler */
|
||||
struct proc *p; /* interrupt thread */
|
||||
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");
|
||||
}
|
||||
} 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
|
||||
* 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)
|
||||
printf("\tdevice combination %s and %s "
|
||||
"doesn't support shared irq%d\n",
|
||||
ithd->it_ih->name, name, irq);
|
||||
ithd->it_ih->ih_name, name, irq);
|
||||
return(NULL);
|
||||
} else if (flags & INTR_FAST) {
|
||||
/* We can only have one fast interrupt by itself. */
|
||||
if (bootverbose)
|
||||
printf("\tCan't add fast interrupt %s"
|
||||
" to normal interrupt %s on irq%d",
|
||||
name, ithd->it_ih->name, irq);
|
||||
name, ithd->it_ih->ih_name, irq);
|
||||
return (NULL);
|
||||
} else { /* update p_comm */
|
||||
p = ithd->it_proc;
|
||||
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
else
|
||||
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)
|
||||
return (NULL);
|
||||
bzero(idesc, sizeof (struct intrec));
|
||||
bzero(idesc, sizeof (struct intrhand));
|
||||
|
||||
idesc->handler = handler;
|
||||
idesc->argument = arg;
|
||||
idesc->flags = flags;
|
||||
idesc->ithd = ithd;
|
||||
idesc->ih_handler = handler;
|
||||
idesc->ih_argument = arg;
|
||||
idesc->ih_flags = flags;
|
||||
idesc->ih_ithd = ithd;
|
||||
|
||||
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->name == NULL) {
|
||||
idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->ih_name == NULL) {
|
||||
free(idesc, M_DEVBUF);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(idesc->name, name);
|
||||
strcpy(idesc->ih_name, name);
|
||||
|
||||
/* Slow interrupts got set up above. */
|
||||
if ((flags & INTR_FAST)
|
||||
&& (icu_setup(irq, idesc->handler, idesc->argument,
|
||||
idesc->flags) != 0) ) {
|
||||
&& (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
|
||||
idesc->ih_flags) != 0) ) {
|
||||
if (bootverbose)
|
||||
printf("\tinthand_add(irq%d) failed, result=%d\n",
|
||||
irq, errcode);
|
||||
free(idesc->name, M_DEVBUF);
|
||||
free(idesc->ih_name, M_DEVBUF);
|
||||
free(idesc, M_DEVBUF);
|
||||
return NULL;
|
||||
}
|
||||
head = ithd->it_ih; /* look at chain of handlers */
|
||||
if (head) {
|
||||
while (head->next != NULL)
|
||||
head = head->next; /* find the end */
|
||||
head->next = idesc; /* hook it in there */
|
||||
while (head->ih_next != NULL)
|
||||
head = head->ih_next; /* find the end */
|
||||
head->ih_next = idesc; /* hook it in there */
|
||||
} else
|
||||
ithd->it_ih = idesc; /* put it up front */
|
||||
update_intrname(irq, idesc->name);
|
||||
update_intrname(irq, idesc->ih_name);
|
||||
return (idesc);
|
||||
}
|
||||
|
||||
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
*/
|
||||
|
||||
int
|
||||
inthand_remove(struct intrec *idesc)
|
||||
inthand_remove(struct intrhand *idesc)
|
||||
{
|
||||
struct ithd *ithd; /* descriptor for the IRQ */
|
||||
struct intrec *ih; /* chain of handlers */
|
||||
struct intrhand *ih; /* chain of handlers */
|
||||
|
||||
if (idesc == NULL)
|
||||
return (-1);
|
||||
ithd = idesc->ithd;
|
||||
ithd = idesc->ih_ithd;
|
||||
ih = ithd->it_ih;
|
||||
|
||||
if (ih == idesc) /* first in the chain */
|
||||
ithd->it_ih = idesc->next; /* unhook it */
|
||||
ithd->it_ih = idesc->ih_next; /* unhook it */
|
||||
else {
|
||||
while ((ih != NULL)
|
||||
&& (ih->next != idesc) )
|
||||
ih = ih->next;
|
||||
if (ih->next != idesc)
|
||||
return (-1);
|
||||
ih->next = ih->next->next;
|
||||
}
|
||||
&& (ih->ih_next != idesc) )
|
||||
ih = ih->ih_next;
|
||||
if (ih->ih_next != idesc)
|
||||
return (-1);
|
||||
ih->ih_next = ih->ih_next->ih_next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
|
@ -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!
|
||||
* 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);
|
||||
int inthand_remove(struct intrec *idesc);
|
||||
int inthand_remove(struct intrhand *idesc);
|
||||
void sched_ithd(void *);
|
||||
void ithd_loop(void *);
|
||||
void start_softintr(void *);
|
||||
|
@ -172,44 +172,12 @@ doreti_ast:
|
||||
movb $1,_intr_nesting_level /* for doreti_next to decrement */
|
||||
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
|
||||
dummynetisr:
|
||||
MCOUNT
|
||||
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
|
||||
#include "i386/isa/apic_ipl.s"
|
||||
|
@ -32,8 +32,3 @@
|
||||
#include <sys/ipl.h>
|
||||
#include <sys/interrupt.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
|
||||
};
|
||||
|
@ -165,7 +165,7 @@ void
|
||||
ithd_loop(void *dummy)
|
||||
{
|
||||
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 */
|
||||
|
||||
@ -200,17 +200,17 @@ ithd_loop(void *dummy)
|
||||
#if 0
|
||||
membar_unlock(); /* push out "it_need=0" */
|
||||
#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,
|
||||
"ithd_loop pid %d ih=%p: %p(%p) flg=%x",
|
||||
me->it_proc->p_pid, (void *)ih,
|
||||
(void *)ih->handler, ih->argument,
|
||||
ih->flags);
|
||||
(void *)ih->ih_handler, ih->ih_argument,
|
||||
ih->ih_flags);
|
||||
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
ih->handler(ih->argument);
|
||||
if ((ih->flags & INTR_MPSAFE) == 0)
|
||||
ih->ih_handler(ih->ih_argument);
|
||||
if ((ih->ih_flags & INTR_MPSAFE) == 0)
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
}
|
||||
}
|
||||
|
@ -531,13 +531,13 @@ icu_unset(intr, handler)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct intrec *
|
||||
struct intrhand *
|
||||
inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
int pri, int flags)
|
||||
{
|
||||
struct ithd *ithd = ithds[irq]; /* descriptor for the IRQ */
|
||||
struct intrec *head; /* chain of handlers for IRQ */
|
||||
struct intrec *idesc; /* descriptor for this handler */
|
||||
struct intrhand *head; /* chain of handlers for IRQ */
|
||||
struct intrhand *idesc; /* descriptor for this handler */
|
||||
struct proc *p; /* interrupt thread */
|
||||
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");
|
||||
}
|
||||
} 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
|
||||
* 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)
|
||||
printf("\tdevice combination %s and %s "
|
||||
"doesn't support shared irq%d\n",
|
||||
ithd->it_ih->name, name, irq);
|
||||
ithd->it_ih->ih_name, name, irq);
|
||||
return(NULL);
|
||||
} else if (flags & INTR_FAST) {
|
||||
/* We can only have one fast interrupt by itself. */
|
||||
if (bootverbose)
|
||||
printf("\tCan't add fast interrupt %s"
|
||||
" to normal interrupt %s on irq%d",
|
||||
name, ithd->it_ih->name, irq);
|
||||
name, ithd->it_ih->ih_name, irq);
|
||||
return (NULL);
|
||||
} else { /* update p_comm */
|
||||
p = ithd->it_proc;
|
||||
@ -620,42 +620,42 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
else
|
||||
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)
|
||||
return (NULL);
|
||||
bzero(idesc, sizeof (struct intrec));
|
||||
bzero(idesc, sizeof (struct intrhand));
|
||||
|
||||
idesc->handler = handler;
|
||||
idesc->argument = arg;
|
||||
idesc->flags = flags;
|
||||
idesc->ithd = ithd;
|
||||
idesc->ih_handler = handler;
|
||||
idesc->ih_argument = arg;
|
||||
idesc->ih_flags = flags;
|
||||
idesc->ih_ithd = ithd;
|
||||
|
||||
idesc->name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->name == NULL) {
|
||||
idesc->ih_name = malloc(strlen(name) + 1, M_DEVBUF, M_WAITOK);
|
||||
if (idesc->ih_name == NULL) {
|
||||
free(idesc, M_DEVBUF);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(idesc->name, name);
|
||||
strcpy(idesc->ih_name, name);
|
||||
|
||||
/* Slow interrupts got set up above. */
|
||||
if ((flags & INTR_FAST)
|
||||
&& (icu_setup(irq, idesc->handler, idesc->argument,
|
||||
idesc->flags) != 0) ) {
|
||||
&& (icu_setup(irq, idesc->ih_handler, idesc->ih_argument,
|
||||
idesc->ih_flags) != 0) ) {
|
||||
if (bootverbose)
|
||||
printf("\tinthand_add(irq%d) failed, result=%d\n",
|
||||
irq, errcode);
|
||||
free(idesc->name, M_DEVBUF);
|
||||
free(idesc->ih_name, M_DEVBUF);
|
||||
free(idesc, M_DEVBUF);
|
||||
return NULL;
|
||||
}
|
||||
head = ithd->it_ih; /* look at chain of handlers */
|
||||
if (head) {
|
||||
while (head->next != NULL)
|
||||
head = head->next; /* find the end */
|
||||
head->next = idesc; /* hook it in there */
|
||||
while (head->ih_next != NULL)
|
||||
head = head->ih_next; /* find the end */
|
||||
head->ih_next = idesc; /* hook it in there */
|
||||
} else
|
||||
ithd->it_ih = idesc; /* put it up front */
|
||||
update_intrname(irq, idesc->name);
|
||||
update_intrname(irq, idesc->ih_name);
|
||||
return (idesc);
|
||||
}
|
||||
|
||||
@ -670,29 +670,29 @@ inthand_add(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
*/
|
||||
|
||||
int
|
||||
inthand_remove(struct intrec *idesc)
|
||||
inthand_remove(struct intrhand *idesc)
|
||||
{
|
||||
struct ithd *ithd; /* descriptor for the IRQ */
|
||||
struct intrec *ih; /* chain of handlers */
|
||||
struct intrhand *ih; /* chain of handlers */
|
||||
|
||||
if (idesc == NULL)
|
||||
return (-1);
|
||||
ithd = idesc->ithd;
|
||||
ithd = idesc->ih_ithd;
|
||||
ih = ithd->it_ih;
|
||||
|
||||
if (ih == idesc) /* first in the chain */
|
||||
ithd->it_ih = idesc->next; /* unhook it */
|
||||
ithd->it_ih = idesc->ih_next; /* unhook it */
|
||||
else {
|
||||
while ((ih != NULL)
|
||||
&& (ih->next != idesc) )
|
||||
ih = ih->next;
|
||||
if (ih->next != idesc)
|
||||
return (-1);
|
||||
ih->next = ih->next->next;
|
||||
}
|
||||
&& (ih->ih_next != idesc) )
|
||||
ih = ih->ih_next;
|
||||
if (ih->ih_next != idesc)
|
||||
return (-1);
|
||||
ih->ih_next = ih->ih_next->ih_next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
|
@ -172,6 +172,8 @@ static int rc_rcsrt[16] = {
|
||||
TTY_BI|TTY_PE|TTY_FE|TTY_OE
|
||||
};
|
||||
|
||||
static struct intrhand *rc_ih;
|
||||
|
||||
/* Static prototypes */
|
||||
static ointhand2_t rcintr;
|
||||
static void rc_hwreset __P((int, int, unsigned int));
|
||||
@ -268,7 +270,8 @@ rcattach(dvp)
|
||||
rcb->rcb_probed = RC_ATTACHED;
|
||||
if (!rc_started) {
|
||||
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_started = 1;
|
||||
}
|
||||
@ -362,7 +365,7 @@ rcintr(unit)
|
||||
optr++;
|
||||
rc_scheduled_event++;
|
||||
if (val != 0 && val == rc->rc_hotchar)
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
} else {
|
||||
/* Store also status data */
|
||||
@ -393,7 +396,7 @@ rcintr(unit)
|
||||
&& (rc->rc_tp->t_iflag & INPCK))))
|
||||
val = 0;
|
||||
else if (val != 0 && val == rc->rc_hotchar)
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
optr[0] = val;
|
||||
optr[INPUT_FLAGS_SHIFT] = iack;
|
||||
optr++;
|
||||
@ -440,7 +443,7 @@ rcintr(unit)
|
||||
if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) {
|
||||
rc_scheduled_event += LOTS_OF_EVENTS;
|
||||
rc->rc_flags |= RC_MODCHG;
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
goto more_intrs;
|
||||
}
|
||||
@ -481,7 +484,7 @@ rcintr(unit)
|
||||
if (!(rc->rc_flags & RC_DOXXFER)) {
|
||||
rc_scheduled_event += LOTS_OF_EVENTS;
|
||||
rc->rc_flags |= RC_DOXXFER;
|
||||
setsofttty();
|
||||
sched_swi(rc_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
|
||||
STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
|
||||
map, links);
|
||||
busdma_swi_pending = 1;
|
||||
setsoftvm();
|
||||
sched_swi(vm_ih, SWI_NOSWITCH);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
@ -27,64 +27,9 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.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 cam_imask; /* XXX */
|
||||
unsigned int net_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;
|
||||
}
|
||||
}
|
||||
|
@ -95,12 +95,6 @@ static struct cdevsw mem_cdevsw = {
|
||||
/* bmaj */ -1
|
||||
};
|
||||
|
||||
#if NHWI > 0
|
||||
#define ICU_LEN (NHWI)
|
||||
#else
|
||||
#define ICU_LEN (NSWI)
|
||||
#endif
|
||||
|
||||
struct mem_range_softc mem_range_softc;
|
||||
|
||||
static int
|
||||
|
@ -519,7 +519,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
#if 0
|
||||
if (busdma_swi_pending != 0)
|
||||
|
@ -29,12 +29,6 @@
|
||||
#ifndef _MACHINE_IPL_H_
|
||||
#define _MACHINE_IPL_H_
|
||||
|
||||
/*
|
||||
* Software interrupt bit numbers
|
||||
*/
|
||||
#define NSWI 32
|
||||
#define NHWI 0
|
||||
|
||||
/*
|
||||
* 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_handle_ipi(struct trapframe *frame);
|
||||
|
||||
#endif /* !_MACHINE_MD_VAR_H_ */
|
||||
#endif /* !_MACHINE_IPL_H_ */
|
||||
|
@ -47,7 +47,7 @@ void busdma_swi __P((void));
|
||||
void cpu_halt __P((void));
|
||||
void cpu_reset __P((void));
|
||||
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 fill_regs __P((struct proc *, struct reg *));
|
||||
int set_regs __P((struct proc *, struct reg *));
|
||||
|
@ -216,7 +216,6 @@ clkintr(struct clockframe frame)
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case ACQUIRED:
|
||||
@ -224,7 +223,6 @@ clkintr(struct clockframe frame)
|
||||
>= hardclock_max_count) {
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -239,7 +237,6 @@ clkintr(struct clockframe frame)
|
||||
mtx_exit(&clock_lock, MTX_SPIN);
|
||||
timer_func = new_function;
|
||||
timer0_state = ACQUIRED;
|
||||
setdelayed();
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
@ -258,7 +255,6 @@ clkintr(struct clockframe frame)
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +963,7 @@ cpu_initclocks()
|
||||
int diag;
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
|
||||
if (statclock_disable) {
|
||||
|
@ -300,7 +300,7 @@ static void siointr1 __P((struct com_s *com));
|
||||
static void siointr __P((void *arg));
|
||||
static int commctl __P((struct com_s *com, int bits, int how));
|
||||
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 sio_isa_probe __P((device_t dev));
|
||||
static void siosettimeout __P((void));
|
||||
@ -413,7 +413,8 @@ static int siocnunit;
|
||||
#endif
|
||||
static Port_t siogdbiobase;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -1322,9 +1323,11 @@ determined_type: ;
|
||||
printf(" with a bogus IIR_TXRDY register");
|
||||
printf("\n");
|
||||
|
||||
if (!sio_registered) {
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
if (sio_fast_ih == NULL) {
|
||||
sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
|
||||
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,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
|
||||
@ -1979,7 +1982,7 @@ siointr1(com)
|
||||
}
|
||||
++com->bytes_in;
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
@ -1987,10 +1990,10 @@ siointr1(com)
|
||||
if (com->do_timestamp)
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
schedsofttty();
|
||||
sched_swi(sio_slow_ih, SWI_DELAY);
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
if (com->iptr - com->ibuf == 8)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = line_status;
|
||||
@ -2028,7 +2031,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
/* handle CTS change immediately for crisp flow ctl */
|
||||
@ -2082,7 +2085,8 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
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)) {
|
||||
@ -2257,7 +2261,7 @@ sioioctl(dev, cmd, data, flag, p)
|
||||
|
||||
/* software interrupt handler for SWI_TTY */
|
||||
static void
|
||||
siopoll()
|
||||
siopoll(void *dummy)
|
||||
{
|
||||
int unit;
|
||||
int intrsave;
|
||||
|
@ -58,6 +58,8 @@
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/limits.h>
|
||||
@ -192,7 +194,7 @@ hardclock(frame)
|
||||
* relatively high clock interrupt priority any longer than necessary.
|
||||
*/
|
||||
if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) {
|
||||
setsoftclock();
|
||||
sched_swi(softclock_ih, SWI_NOSWITCH);
|
||||
} else if (softticks + 1 == ticks)
|
||||
++softticks;
|
||||
}
|
||||
|
@ -44,105 +44,18 @@
|
||||
#include <sys/vmmeter.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
struct swilist {
|
||||
swihand_t *sl_handler;
|
||||
struct swilist *sl_next;
|
||||
};
|
||||
#include <net/netisr.h> /* prototype for legacy_setsoftnet */
|
||||
|
||||
static struct swilist swilists[NSWI];
|
||||
u_long softintr_count[NSWI];
|
||||
static struct proc *softithd;
|
||||
volatile u_int sdelayed;
|
||||
volatile u_int spending;
|
||||
struct intrhand *net_ih;
|
||||
struct intrhand *vm_ih;
|
||||
struct intrhand *softclock_ih;
|
||||
struct ithd *clk_ithd;
|
||||
struct ithd *tty_ithd;
|
||||
|
||||
static void start_softintr(void *);
|
||||
static void intr_soft(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);
|
||||
}
|
||||
static void swi_net(void *);
|
||||
|
||||
int
|
||||
ithread_priority(flags)
|
||||
@ -181,175 +94,197 @@ ithread_priority(flags)
|
||||
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
|
||||
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 */
|
||||
|
||||
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
|
||||
* this IRQ, log it as a stray interrupt.
|
||||
* Set it_need so that if the thread is already running but close
|
||||
* 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)
|
||||
panic("soft interrupt scheduled too early");
|
||||
|
||||
CTR3(KTR_INTR, "sched_softintr pid %d(%s) spending=0x%x",
|
||||
softithd->p_pid, softithd->p_comm, spending);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
ih->ih_need = 1;
|
||||
if (!(flag & SWI_DELAY)) {
|
||||
it->it_need = 1;
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
if (p->p_stat == SWAIT) { /* not on run queue */
|
||||
CTR1(KTR_INTR, "sched_ithd: setrunqueue %d", p->p_pid);
|
||||
/* membar_lock(); */
|
||||
p->p_stat = SRUN;
|
||||
setrunqueue(p);
|
||||
aston();
|
||||
}
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
mtx_enter(&sched_lock, MTX_SPIN);
|
||||
if (spending == 0) {
|
||||
CTR1(KTR_INTR, "intr_soft pid %d: done",
|
||||
curproc->p_pid);
|
||||
curproc->p_stat = SWAIT; /* we're idle */
|
||||
if (!it->it_need) {
|
||||
p->p_stat = SWAIT; /* we're idle */
|
||||
CTR1(KTR_INTR, "sithd_loop pid %d: done", p->p_pid);
|
||||
mi_switch();
|
||||
CTR1(KTR_INTR, "intr_soft pid %d: resumed",
|
||||
curproc->p_pid);
|
||||
CTR1(KTR_INTR, "sithd_loop pid %d: resumed", p->p_pid);
|
||||
}
|
||||
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
|
||||
* 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.
|
||||
* Start standard software interrupt threads
|
||||
*/
|
||||
#define DO_SETBITS(name, var, bits) \
|
||||
void name(void) \
|
||||
{ \
|
||||
atomic_set_int(var, bits); \
|
||||
sched_softintr(); \
|
||||
static void
|
||||
start_softintr(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
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
|
||||
setdelayed(void)
|
||||
legacy_setsoftnet()
|
||||
{
|
||||
int pend;
|
||||
|
||||
pend = atomic_readandclear_int(&sdelayed);
|
||||
if (pend != 0) {
|
||||
atomic_set_int(&spending, pend);
|
||||
sched_softintr();
|
||||
}
|
||||
sched_swi(net_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -75,7 +75,7 @@ static struct callout *nextsoftcheck; /* Next callout to be checked. */
|
||||
* Run periodic events from timeout queue.
|
||||
*/
|
||||
void
|
||||
softclock()
|
||||
softclock(void *dummy)
|
||||
{
|
||||
register struct callout *c;
|
||||
register struct callout_tailq *bucket;
|
||||
|
@ -40,6 +40,8 @@ MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues");
|
||||
|
||||
static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues;
|
||||
|
||||
static struct intrhand *taskqueue_ih;
|
||||
|
||||
struct taskqueue {
|
||||
STAILQ_ENTRY(taskqueue) tq_link;
|
||||
STAILQ_HEAD(, task) tq_queue;
|
||||
@ -191,14 +193,15 @@ taskqueue_run(struct taskqueue *queue)
|
||||
static void
|
||||
taskqueue_swi_enqueue(void *context)
|
||||
{
|
||||
setsofttq();
|
||||
sched_swi(taskqueue_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
static void
|
||||
taskqueue_swi_run(void)
|
||||
taskqueue_swi_run(void *dummy)
|
||||
{
|
||||
taskqueue_run(taskqueue_swi);
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -68,8 +68,10 @@
|
||||
#ifndef LOCORE
|
||||
#ifdef _KERNEL
|
||||
|
||||
void legacy_setsoftnet __P((void));
|
||||
|
||||
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));
|
||||
|
||||
|
@ -1298,7 +1298,7 @@ cpu_initclocks()
|
||||
{
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
#ifndef PC98
|
||||
int diag;
|
||||
|
@ -1298,7 +1298,7 @@ cpu_initclocks()
|
||||
{
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
#ifndef PC98
|
||||
int diag;
|
||||
|
@ -533,7 +533,8 @@ static int siocnunit;
|
||||
#endif
|
||||
static Port_t siogdbiobase;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -2083,9 +2084,11 @@ determined_type: ;
|
||||
printf(" with a bogus IIR_TXRDY register");
|
||||
printf("\n");
|
||||
|
||||
if (!sio_registered) {
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
if (sio_fast_ih == NULL) {
|
||||
sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
|
||||
NULL, SWI_TTY, 0);
|
||||
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
|
||||
NULL, SWI_TTY, 0);
|
||||
}
|
||||
make_dev(&sio_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
|
||||
@ -2917,7 +2920,7 @@ status_read:;
|
||||
}
|
||||
++com->bytes_in;
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
@ -2926,14 +2929,10 @@ status_read:;
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
/* XXX - needs to go away when alpha gets ithreads */
|
||||
#ifdef __alpha__
|
||||
schedsofttty();
|
||||
#else
|
||||
setsofttty();
|
||||
#endif
|
||||
sched_swi(sio_slow_ih, SWI_DELAY);
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
if (com->iptr - com->ibuf == 8)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = line_status;
|
||||
@ -2987,7 +2986,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
/* handle CTS change immediately for crisp flow ctl */
|
||||
@ -3089,7 +3088,8 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
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)) {
|
||||
|
@ -1298,7 +1298,7 @@ cpu_initclocks()
|
||||
{
|
||||
#ifdef APIC_IO
|
||||
int apic_8254_trial;
|
||||
struct intrec *clkdesc;
|
||||
struct intrhand *clkdesc;
|
||||
#endif /* APIC_IO */
|
||||
#ifndef PC98
|
||||
int diag;
|
||||
|
@ -533,7 +533,8 @@ static int siocnunit;
|
||||
#endif
|
||||
static Port_t siogdbiobase;
|
||||
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_timeouts_until_log;
|
||||
static struct callout_handle sio_timeout_handle
|
||||
@ -2083,9 +2084,11 @@ determined_type: ;
|
||||
printf(" with a bogus IIR_TXRDY register");
|
||||
printf("\n");
|
||||
|
||||
if (!sio_registered) {
|
||||
register_swi(SWI_TTY, siopoll);
|
||||
sio_registered = TRUE;
|
||||
if (sio_fast_ih == NULL) {
|
||||
sio_fast_ih = sinthand_add("tty:sio", &tty_ithd, siopoll,
|
||||
NULL, SWI_TTY, 0);
|
||||
sio_slow_ih = sinthand_add("tty:sio", &clk_ithd, siopoll,
|
||||
NULL, SWI_TTY, 0);
|
||||
}
|
||||
make_dev(&sio_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
|
||||
@ -2917,7 +2920,7 @@ status_read:;
|
||||
}
|
||||
++com->bytes_in;
|
||||
if (com->hotchar != 0 && recv_data == com->hotchar)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
ioptr = com->iptr;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
@ -2926,14 +2929,10 @@ status_read:;
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
/* XXX - needs to go away when alpha gets ithreads */
|
||||
#ifdef __alpha__
|
||||
schedsofttty();
|
||||
#else
|
||||
setsofttty();
|
||||
#endif
|
||||
sched_swi(sio_slow_ih, SWI_DELAY);
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
if (com->iptr - com->ibuf == 8)
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
#endif
|
||||
ioptr[0] = recv_data;
|
||||
ioptr[com->ierroff] = line_status;
|
||||
@ -2987,7 +2986,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_CHECKMSR)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
com->state |= CS_CHECKMSR;
|
||||
setsofttty();
|
||||
sched_swi(sio_fast_ih, SWI_NOSWITCH);
|
||||
}
|
||||
|
||||
/* handle CTS change immediately for crisp flow ctl */
|
||||
@ -3089,7 +3088,8 @@ if (com->iptr - com->ibuf == 8)
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
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)) {
|
||||
|
@ -470,7 +470,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
|
@ -50,7 +50,7 @@ void busdma_swi __P((void));
|
||||
void cpu_halt __P((void));
|
||||
void cpu_reset __P((void));
|
||||
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 fill_regs __P((struct proc *, struct reg *));
|
||||
int set_regs __P((struct proc *, struct reg *));
|
||||
|
@ -470,7 +470,7 @@ vm_page_zero_idle()
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm()
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
|
@ -36,27 +36,30 @@
|
||||
* together via the 'next' pointer.
|
||||
*/
|
||||
|
||||
struct ithd;
|
||||
|
||||
struct intrec {
|
||||
driver_intr_t *handler; /* code address of handler */
|
||||
void *argument; /* argument to pass to handler */
|
||||
enum intr_type flags; /* flag bits (sys/bus.h) */
|
||||
char *name; /* name of handler */
|
||||
struct ithd *ithd; /* handler we're connected to */
|
||||
struct intrec *next; /* next handler for this irq */
|
||||
struct intrhand {
|
||||
driver_intr_t *ih_handler; /* code address of handler */
|
||||
void *ih_argument; /* argument to pass to handler */
|
||||
enum intr_type ih_flags; /* flag bits (sys/bus.h) */
|
||||
char *ih_name; /* name of handler */
|
||||
struct ithd *ih_ithd; /* handler we're connected to */
|
||||
struct intrhand *ih_next; /* next handler for this irq */
|
||||
int ih_need; /* need interrupt */
|
||||
};
|
||||
|
||||
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));
|
||||
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
|
||||
|
@ -348,7 +348,7 @@ struct ithd {
|
||||
LIST_ENTRY(ithd) it_list; /* All interrupt threads */
|
||||
int it_need; /* Needs service */
|
||||
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 */
|
||||
|
||||
/* Fields used only for hard interrupt threads */
|
||||
|
@ -159,7 +159,7 @@ int susword __P((void *base, int word));
|
||||
void realitexpire __P((void *));
|
||||
|
||||
void hardclock __P((struct clockframe *frame));
|
||||
void softclock __P((void));
|
||||
void softclock __P((void *));
|
||||
void statclock __P((struct clockframe *frame));
|
||||
|
||||
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));
|
||||
|
||||
/* 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));
|
||||
intrmask_t splbio __P((void));
|
||||
intrmask_t splcam __P((void));
|
||||
|
Loading…
Reference in New Issue
Block a user