From: Jorrit Herder Date: Fri, 29 Jul 2005 12:44:42 +0000 (+0000) Subject: Small update to SYS_IRQCTL -> setting an interrupt policy now allows the caller X-Git-Tag: v3.1.0~497 X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch08.html?a=commitdiff_plain;h=d62e5156607d2d7ebd85247a7cee70fb8d9c8001;p=minix.git 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. --- diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 2ccf933c3..479037539 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -475,6 +475,7 @@ PRIVATE int w_identify() /* 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_hook_id = wn->irq; /* id to be returned if interrupt occurs */ if ((s=sys_irqsetpolicy(wn->irq, IRQ_REENABLE, &wn->irq_hook_id)) != OK) panic(w_name(), "coudn't set IRQ policy", s); if ((s=sys_irqenable(&wn->irq_hook_id)) != OK) diff --git a/drivers/dpeth/dp.c b/drivers/dpeth/dp.c index b84a1386f..e1ad6dabf 100644 --- a/drivers/dpeth/dp.c +++ b/drivers/dpeth/dp.c @@ -49,6 +49,12 @@ ** +------------+---------+---------+---------------+ ** ** $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 ** 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 */ (*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_irqenable(&dep->de_hook); diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index cf101807c..eb6b83992 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -300,7 +300,10 @@ PUBLIC void main() 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) panic("FLOPPY", "Couldn't set IRQ policy", s); if ((s=sys_irqenable(&irq_hook_id)) != OK) diff --git a/drivers/fxp/fxp.c b/drivers/fxp/fxp.c index 63463488a..bf411560c 100644 --- a/drivers/fxp/fxp.c +++ b/drivers/fxp/fxp.c @@ -736,7 +736,10 @@ fxp_t *fp; fp->fxp_flags = FF_EMPTY; 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); if (r != OK) panic("FXP","sys_irqsetpolicy failed", r); diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index 8b0d47ffb..81b0538dd 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -340,6 +340,7 @@ PRIVATE void do_initialize() tickdelay(1); /* easily satisfies Centronics minimum */ /* was 2 millisecs; now is ~17 millisecs */ sys_outb(port_base + 2, PR_SELECT); + irq_hook_id = 0; sys_irqsetpolicy(PRINTER_IRQ, 0, &irq_hook_id); sys_irqenable(&irq_hook_id); diff --git a/drivers/rtl8139/rtl8139.c b/drivers/rtl8139/rtl8139.c index 56fda570e..337bda7d7 100755 --- a/drivers/rtl8139/rtl8139.c +++ b/drivers/rtl8139/rtl8139.c @@ -747,8 +747,11 @@ re_t *rep; rep->re_flags = REF_EMPTY; rep->re_flags |= REF_ENABLED; - /* set the interrupt handler */ - /* only send HARD_INT notifications */ + /* Set the interrupt handler. The policy is to only send HARD_INT + * 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) printf("RTL8139: error, couldn't set IRQ policy: %d\n", s); diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 2039ab6ee..215ffa32d 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -401,6 +401,7 @@ tty_t *tp; } /* 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) panic("TTY", "Couldn't set keyboard IRQ policy", i); if ((i=sys_irqenable(&irq_hook_id)) != OK) diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index cdfaf0c44..26dcbad7b 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -210,12 +210,15 @@ PUBLIC void main(void) } case SYS_EVENT: { /* new kernel message is available */ sigset_t sigset = (sigset_t) tty_mess.NOTIFY_ARG; + if (sigismember(&sigset, SIGKSTOP)) { cons_stop(); /* switch to primary console */ +#if DEAD_CODE if (irq_hook_id != -1) { sys_irqdisable(&irq_hook_id); sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id); } +#endif } if (sigismember(&sigset, SIGTERM)) cons_stop(); if (sigismember(&sigset, SIGKMESS)) do_new_kmess(&tty_mess); diff --git a/kernel/priv.h b/kernel/priv.h index 6444204c4..1d4f8dddd 100755 --- a/kernel/priv.h +++ b/kernel/priv.h @@ -25,7 +25,7 @@ struct priv { long s_sys_mask; /* allowed kernel calls */ 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 */ timer_t s_alarm_timer; /* synchronous alarm timer */ diff --git a/kernel/system.c b/kernel/system.c index 66875b7dc..b4f19d016 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -248,7 +248,7 @@ irq_hook_t *hook; * sending the notification message, this bit map will be magically set * 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. */ lock_notify(HARDWARE, hook->proc_nr); diff --git a/kernel/system/do_irqctl.c b/kernel/system/do_irqctl.c index c87b21597..7d7d89f17 100644 --- a/kernel/system/do_irqctl.c +++ b/kernel/system/do_irqctl.c @@ -24,6 +24,7 @@ register message *m_ptr; /* pointer to request message */ /* Dismember the request message. */ int irq_vec; int irq_hook_id; + int notify_id; int r = OK; irq_hook_t *hook_ptr; @@ -65,8 +66,15 @@ register message *m_ptr; /* pointer to request message */ } 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->notify_id = notify_id; /* identifier to pass */ hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */ put_irq_handler(hook_ptr, irq_vec, generic_handler); diff --git a/kernel/type.h b/kernel/type.h index 8bdfebf2c..4d9a8890a 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -86,6 +86,7 @@ struct segdesc_s { /* segment descriptor for protected mode */ }; typedef unsigned long irq_policy_t; +typedef unsigned long irq_id_t; typedef struct irq_hook { struct irq_hook *next; /* next hook in chain */ @@ -93,6 +94,7 @@ typedef struct irq_hook { int irq; /* IRQ vector number */ int id; /* id of this hook */ 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_hook_t; diff --git a/servers/is/dmp_kernel.c b/servers/is/dmp_kernel.c index 6331ea820..558631adc 100644 --- a/servers/is/dmp_kernel.c +++ b/servers/is/dmp_kernel.c @@ -161,7 +161,7 @@ PUBLIC void irqtab_dmp() } 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; iproc_nr); 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"); }