Small update to SYS_IRQCTL -> setting an interrupt policy now allows the caller
to provide an index (0 .. 31) that is passed in the HARD_INT message when an interrupt occurs. The NOTIFY_ARG field contains a bitmap with all indexes for which an interrupt occured.
This commit is contained in:
parent
bd8762263a
commit
d62e515660
|
@ -475,6 +475,7 @@ PRIVATE int w_identify()
|
||||||
|
|
||||||
/* Everything looks OK; register IRQ so we can stop polling. */
|
/* Everything looks OK; register IRQ so we can stop polling. */
|
||||||
wn->irq = w_drive < 2 ? AT_WINI_0_IRQ : AT_WINI_1_IRQ;
|
wn->irq = w_drive < 2 ? AT_WINI_0_IRQ : AT_WINI_1_IRQ;
|
||||||
|
wn->irq_hook_id = wn->irq; /* id to be returned if interrupt occurs */
|
||||||
if ((s=sys_irqsetpolicy(wn->irq, IRQ_REENABLE, &wn->irq_hook_id)) != OK)
|
if ((s=sys_irqsetpolicy(wn->irq, IRQ_REENABLE, &wn->irq_hook_id)) != OK)
|
||||||
panic(w_name(), "coudn't set IRQ policy", s);
|
panic(w_name(), "coudn't set IRQ policy", s);
|
||||||
if ((s=sys_irqenable(&wn->irq_hook_id)) != OK)
|
if ((s=sys_irqenable(&wn->irq_hook_id)) != OK)
|
||||||
|
|
|
@ -49,6 +49,12 @@
|
||||||
** +------------+---------+---------+---------------+
|
** +------------+---------+---------+---------------+
|
||||||
**
|
**
|
||||||
** $Log$
|
** $Log$
|
||||||
|
** Revision 1.4 2005/07/29 12:44:41 jnherder
|
||||||
|
** Small update to SYS_IRQCTL -> setting an interrupt policy now allows the caller
|
||||||
|
** to provide an index (0 .. 31) that is passed in the HARD_INT message when an
|
||||||
|
** interrupt occurs. The NOTIFY_ARG field contains a bitmap with all indexes for
|
||||||
|
** which an interrupt occured.
|
||||||
|
**
|
||||||
** Revision 1.3 2005/07/20 15:28:04 jnherder
|
** Revision 1.3 2005/07/20 15:28:04 jnherder
|
||||||
** Kernel sends SIGKSTOP just before shutdown. Drivers do clean up and exit.
|
** Kernel sends SIGKSTOP just before shutdown. Drivers do clean up and exit.
|
||||||
**
|
**
|
||||||
|
@ -267,7 +273,10 @@ static void do_first_init(dpeth_t *dep, dp_conf_t *dcp)
|
||||||
/* Device specific initialization */
|
/* Device specific initialization */
|
||||||
(*dep->de_initf) (dep);
|
(*dep->de_initf) (dep);
|
||||||
|
|
||||||
/* Set the interrupt handler policy */
|
/* Set the interrupt handler policy. Request interrupts to be reenabled
|
||||||
|
* automatically. Return the IRQ line number when an interrupt occurs.
|
||||||
|
*/
|
||||||
|
dep->de_hook = dep->de_irq;
|
||||||
sys_irqsetpolicy(dep->de_irq, IRQ_REENABLE, &dep->de_hook);
|
sys_irqsetpolicy(dep->de_irq, IRQ_REENABLE, &dep->de_hook);
|
||||||
sys_irqenable(&dep->de_hook);
|
sys_irqenable(&dep->de_hook);
|
||||||
|
|
||||||
|
|
|
@ -300,7 +300,10 @@ PUBLIC void main()
|
||||||
tmr_inittimer(&fp->fl_tmr_stop);
|
tmr_inittimer(&fp->fl_tmr_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set IRQ policy, only request notifications. */
|
/* Set IRQ policy, only request notifications, do not automatically
|
||||||
|
* reenable interrupts. ID return on interrupt is the IRQ line number.
|
||||||
|
*/
|
||||||
|
irq_hook_id = FLOPPY_IRQ;
|
||||||
if ((s=sys_irqsetpolicy(FLOPPY_IRQ, 0, &irq_hook_id )) != OK)
|
if ((s=sys_irqsetpolicy(FLOPPY_IRQ, 0, &irq_hook_id )) != OK)
|
||||||
panic("FLOPPY", "Couldn't set IRQ policy", s);
|
panic("FLOPPY", "Couldn't set IRQ policy", s);
|
||||||
if ((s=sys_irqenable(&irq_hook_id)) != OK)
|
if ((s=sys_irqenable(&irq_hook_id)) != OK)
|
||||||
|
|
|
@ -736,7 +736,10 @@ fxp_t *fp;
|
||||||
fp->fxp_flags = FF_EMPTY;
|
fp->fxp_flags = FF_EMPTY;
|
||||||
fp->fxp_flags |= FF_ENABLED;
|
fp->fxp_flags |= FF_ENABLED;
|
||||||
|
|
||||||
/* set the interrupt handler */
|
/* Set the interrupt handler and policy. Do not automatically
|
||||||
|
* reenable interrupts. Return the IRQ line number on interrupts.
|
||||||
|
*/
|
||||||
|
fp->fxp_hook = fp->fxp_irq;
|
||||||
r= sys_irqsetpolicy(fp->fxp_irq, 0, &fp->fxp_hook);
|
r= sys_irqsetpolicy(fp->fxp_irq, 0, &fp->fxp_hook);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
panic("FXP","sys_irqsetpolicy failed", r);
|
panic("FXP","sys_irqsetpolicy failed", r);
|
||||||
|
|
|
@ -340,6 +340,7 @@ PRIVATE void do_initialize()
|
||||||
tickdelay(1); /* easily satisfies Centronics minimum */
|
tickdelay(1); /* easily satisfies Centronics minimum */
|
||||||
/* was 2 millisecs; now is ~17 millisecs */
|
/* was 2 millisecs; now is ~17 millisecs */
|
||||||
sys_outb(port_base + 2, PR_SELECT);
|
sys_outb(port_base + 2, PR_SELECT);
|
||||||
|
irq_hook_id = 0;
|
||||||
sys_irqsetpolicy(PRINTER_IRQ, 0, &irq_hook_id);
|
sys_irqsetpolicy(PRINTER_IRQ, 0, &irq_hook_id);
|
||||||
sys_irqenable(&irq_hook_id);
|
sys_irqenable(&irq_hook_id);
|
||||||
|
|
||||||
|
|
|
@ -747,8 +747,11 @@ re_t *rep;
|
||||||
rep->re_flags = REF_EMPTY;
|
rep->re_flags = REF_EMPTY;
|
||||||
rep->re_flags |= REF_ENABLED;
|
rep->re_flags |= REF_ENABLED;
|
||||||
|
|
||||||
/* set the interrupt handler */
|
/* Set the interrupt handler. The policy is to only send HARD_INT
|
||||||
/* only send HARD_INT notifications */
|
* notifications. Don't reenable interrupts automatically. The id
|
||||||
|
* that is passed back is the interrupt line number.
|
||||||
|
*/
|
||||||
|
rep->re_hook_id = rep->re_irq;
|
||||||
if ((s=sys_irqsetpolicy(rep->re_irq, 0, &rep->re_hook_id)) != OK)
|
if ((s=sys_irqsetpolicy(rep->re_irq, 0, &rep->re_hook_id)) != OK)
|
||||||
printf("RTL8139: error, couldn't set IRQ policy: %d\n", s);
|
printf("RTL8139: error, couldn't set IRQ policy: %d\n", s);
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,7 @@ tty_t *tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set interrupt handler and enable keyboard IRQ. */
|
/* Set interrupt handler and enable keyboard IRQ. */
|
||||||
|
irq_hook_id = KEYBOARD_IRQ; /* id to be returned on interrupt */
|
||||||
if ((i=sys_irqsetpolicy(KEYBOARD_IRQ, IRQ_REENABLE, &irq_hook_id)) != OK)
|
if ((i=sys_irqsetpolicy(KEYBOARD_IRQ, IRQ_REENABLE, &irq_hook_id)) != OK)
|
||||||
panic("TTY", "Couldn't set keyboard IRQ policy", i);
|
panic("TTY", "Couldn't set keyboard IRQ policy", i);
|
||||||
if ((i=sys_irqenable(&irq_hook_id)) != OK)
|
if ((i=sys_irqenable(&irq_hook_id)) != OK)
|
||||||
|
|
|
@ -210,12 +210,15 @@ PUBLIC void main(void)
|
||||||
}
|
}
|
||||||
case SYS_EVENT: { /* new kernel message is available */
|
case SYS_EVENT: { /* new kernel message is available */
|
||||||
sigset_t sigset = (sigset_t) tty_mess.NOTIFY_ARG;
|
sigset_t sigset = (sigset_t) tty_mess.NOTIFY_ARG;
|
||||||
|
|
||||||
if (sigismember(&sigset, SIGKSTOP)) {
|
if (sigismember(&sigset, SIGKSTOP)) {
|
||||||
cons_stop(); /* switch to primary console */
|
cons_stop(); /* switch to primary console */
|
||||||
|
#if DEAD_CODE
|
||||||
if (irq_hook_id != -1) {
|
if (irq_hook_id != -1) {
|
||||||
sys_irqdisable(&irq_hook_id);
|
sys_irqdisable(&irq_hook_id);
|
||||||
sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id);
|
sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (sigismember(&sigset, SIGTERM)) cons_stop();
|
if (sigismember(&sigset, SIGTERM)) cons_stop();
|
||||||
if (sigismember(&sigset, SIGKMESS)) do_new_kmess(&tty_mess);
|
if (sigismember(&sigset, SIGKMESS)) do_new_kmess(&tty_mess);
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct priv {
|
||||||
long s_sys_mask; /* allowed kernel calls */
|
long s_sys_mask; /* allowed kernel calls */
|
||||||
|
|
||||||
sys_map_t s_notify_pending; /* bit map with pending notifications */
|
sys_map_t s_notify_pending; /* bit map with pending notifications */
|
||||||
short s_int_pending; /* pending hardware interrupts */
|
irq_id_t s_int_pending; /* pending hardware interrupts */
|
||||||
sigset_t s_sig_pending; /* pending signals */
|
sigset_t s_sig_pending; /* pending signals */
|
||||||
|
|
||||||
timer_t s_alarm_timer; /* synchronous alarm timer */
|
timer_t s_alarm_timer; /* synchronous alarm timer */
|
||||||
|
|
|
@ -248,7 +248,7 @@ irq_hook_t *hook;
|
||||||
* sending the notification message, this bit map will be magically set
|
* sending the notification message, this bit map will be magically set
|
||||||
* as an argument.
|
* as an argument.
|
||||||
*/
|
*/
|
||||||
priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->irq);
|
priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->notify_id);
|
||||||
|
|
||||||
/* Build notification message and return. */
|
/* Build notification message and return. */
|
||||||
lock_notify(HARDWARE, hook->proc_nr);
|
lock_notify(HARDWARE, hook->proc_nr);
|
||||||
|
|
|
@ -24,6 +24,7 @@ register message *m_ptr; /* pointer to request message */
|
||||||
/* Dismember the request message. */
|
/* Dismember the request message. */
|
||||||
int irq_vec;
|
int irq_vec;
|
||||||
int irq_hook_id;
|
int irq_hook_id;
|
||||||
|
int notify_id;
|
||||||
int r = OK;
|
int r = OK;
|
||||||
irq_hook_t *hook_ptr;
|
irq_hook_t *hook_ptr;
|
||||||
|
|
||||||
|
@ -65,8 +66,15 @@ register message *m_ptr; /* pointer to request message */
|
||||||
}
|
}
|
||||||
if (hook_ptr == NULL) return(ENOSPC);
|
if (hook_ptr == NULL) return(ENOSPC);
|
||||||
|
|
||||||
/* Only caller can request IRQ mappings. Install handler. */
|
/* When setting a policy, the caller must provide an identifier that
|
||||||
|
* is returned on the notification message if a interrupt occurs.
|
||||||
|
*/
|
||||||
|
notify_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
||||||
|
if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL);
|
||||||
|
|
||||||
|
/* Install the handler. */
|
||||||
hook_ptr->proc_nr = m_ptr->m_source; /* process to notify */
|
hook_ptr->proc_nr = m_ptr->m_source; /* process to notify */
|
||||||
|
hook_ptr->notify_id = notify_id; /* identifier to pass */
|
||||||
hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */
|
hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */
|
||||||
put_irq_handler(hook_ptr, irq_vec, generic_handler);
|
put_irq_handler(hook_ptr, irq_vec, generic_handler);
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct segdesc_s { /* segment descriptor for protected mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned long irq_policy_t;
|
typedef unsigned long irq_policy_t;
|
||||||
|
typedef unsigned long irq_id_t;
|
||||||
|
|
||||||
typedef struct irq_hook {
|
typedef struct irq_hook {
|
||||||
struct irq_hook *next; /* next hook in chain */
|
struct irq_hook *next; /* next hook in chain */
|
||||||
|
@ -93,6 +94,7 @@ typedef struct irq_hook {
|
||||||
int irq; /* IRQ vector number */
|
int irq; /* IRQ vector number */
|
||||||
int id; /* id of this hook */
|
int id; /* id of this hook */
|
||||||
int proc_nr; /* NONE if not in use */
|
int proc_nr; /* NONE if not in use */
|
||||||
|
irq_id_t notify_id; /* id to return on interrupt */
|
||||||
irq_policy_t policy; /* bit mask for policy */
|
irq_policy_t policy; /* bit mask for policy */
|
||||||
} irq_hook_t;
|
} irq_hook_t;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ PUBLIC void irqtab_dmp()
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
|
printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
|
||||||
printf("-h.id- -proc.nr- -IRQ vector (nr.)- -policy- \n");
|
printf("-h.id- -proc.nr- -IRQ vector (nr.)- -policy- -notify id-\n");
|
||||||
for (i=0; i<NR_IRQ_HOOKS; i++) {
|
for (i=0; i<NR_IRQ_HOOKS; i++) {
|
||||||
e = &irq_hooks[i];
|
e = &irq_hooks[i];
|
||||||
printf("%3d", i);
|
printf("%3d", i);
|
||||||
|
@ -171,7 +171,8 @@ PUBLIC void irqtab_dmp()
|
||||||
}
|
}
|
||||||
printf("%10d ", e->proc_nr);
|
printf("%10d ", e->proc_nr);
|
||||||
printf(" %9.9s (%02d) ", irq[e->irq], e->irq);
|
printf(" %9.9s (%02d) ", irq[e->irq], e->irq);
|
||||||
printf(" %s\n", (e->policy & IRQ_REENABLE) ? "reenable" : "-");
|
printf(" %s", (e->policy & IRQ_REENABLE) ? "reenable" : " - ");
|
||||||
|
printf(" %d\n", e->notify_id);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue