diff --git a/docs/UPDATING b/docs/UPDATING index ce81b18a1..2f63a02d9 100644 --- a/docs/UPDATING +++ b/docs/UPDATING @@ -1,3 +1,5 @@ +20100408: + /usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc. 20100318: Gas2ack updates: Run 'make install' in commands/i386/gas2ack 20100317: diff --git a/drivers/amddev/Makefile b/drivers/amddev/Makefile index 6ea1e8c27..bcb972ef7 100644 --- a/drivers/amddev/Makefile +++ b/drivers/amddev/Makefile @@ -2,8 +2,8 @@ PROG= amddev SRCS= amddev.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys MAN= diff --git a/drivers/amddev/amddev.c b/drivers/amddev/amddev.c index 97e7a3fec..02c74dbe8 100644 --- a/drivers/amddev/amddev.c +++ b/drivers/amddev/amddev.c @@ -4,9 +4,7 @@ amddev.c Driver for the AMD Device Exclusion Vector (DEV) */ -#define _SYSTEM -#define _MINIX - +#include #include #include @@ -69,6 +67,7 @@ int main(void) { int r; message m; + int ipc_status; /* SEF local startup. */ sef_local_startup(); @@ -77,9 +76,9 @@ int main(void) { report_exceptions(); - r= sef_receive(ANY, &m); + r= driver_receive(ANY, &m, &ipc_status); if (r != OK) - panic("sef_receive failed: %d", r); + panic("driver_receive failed: %d", r); if (m.m_type == IOMMU_MAP) { r= do_add4pci(&m); m.m_type= r; @@ -151,6 +150,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0)); + /* Announce we are up! */ + driver_announce(); + return(OK); } diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 734bfa645..a2eee5558 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Variables. */ @@ -258,7 +259,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) /* Initialize the at_wini driver. */ system_hz = sys_hz(); - init_buffer(); + driver_init_buffer(); w_identify_wakeup_ticks = WAKEUP_TICKS; wakeup_ticks = WAKEUP_TICKS; @@ -266,6 +267,9 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) /* Set special disk parameters. */ init_params(); + /* Announce we are up! */ + driver_announce(); + return(OK); } @@ -1836,6 +1840,7 @@ PRIVATE void w_intr_wait() int r; unsigned long w_status; message m; + int ipc_status; if (w_wn->irq != NO_IRQ) { /* Wait for an interrupt that sets w_status to "not busy". @@ -1843,9 +1848,9 @@ PRIVATE void w_intr_wait() */ while (w_wn->w_status & (STATUS_ADMBSY|STATUS_BSY)) { int rr; - if((rr=sef_receive(ANY, &m)) != OK) - panic("sef_receive(ANY) failed: %d", rr); - if (is_notify(m.m_type)) { + if((rr=driver_receive(ANY, &m, &ipc_status)) != OK) + panic("driver_receive failed: %d", rr); + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case CLOCK: /* Timeout. */ @@ -1865,7 +1870,7 @@ PRIVATE void w_intr_wait() * unhandled message. queue it and * handle it in the libdriver loop. */ - mq_queue(&m); + driver_mq_queue(&m, ipc_status); } } else { @@ -1873,7 +1878,7 @@ PRIVATE void w_intr_wait() * unhandled message. queue it and handle it in the * libdriver loop. */ - mq_queue(&m); + driver_mq_queue(&m, ipc_status); } } } else { diff --git a/drivers/atl2/Makefile b/drivers/atl2/Makefile index 94b3b208e..48f41908d 100644 --- a/drivers/atl2/Makefile +++ b/drivers/atl2/Makefile @@ -2,8 +2,8 @@ PROG= atl2 SRCS= atl2.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBNETDRIVER} ${LIBSYS} +LDADD+= -lnetdriver -lsys MAN= diff --git a/drivers/atl2/atl2.c b/drivers/atl2/atl2.c index 0c7d918cd..b462260ca 100644 --- a/drivers/atl2/atl2.c +++ b/drivers/atl2/atl2.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -1210,7 +1211,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the atl2 driver. */ - u32_t inet_endpt; int r, devind; #if ATL2_FKEY int fkeys, sfkeys; @@ -1229,13 +1229,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) /* Initialize the device. */ atl2_init(devind); - /* Notify Inet of our presence, if it has already been started. */ - r = ds_retrieve_label_num("inet", &inet_endpt); - if (r == OK) - notify(inet_endpt); - else if (r != ESRCH) - printf("ATL2: ds_retrieve_label_num failed for 'inet': %d\n", - r); + /* Announce we are up! */ + netdriver_announce(); #if ATL2_FKEY /* Register debug dump function key. */ @@ -1283,14 +1278,14 @@ PRIVATE void sef_cb_signal_handler(int signo) *===========================================================================*/ PRIVATE void sef_local_startup(void) { - /* Initialize SEF. - */ - /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No support for live update yet. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -1307,6 +1302,7 @@ int main(int argc, char **argv) /* Driver task. */ message m; + int ipc_status; int r; /* Initialize SEF. */ @@ -1314,10 +1310,10 @@ int main(int argc, char **argv) sef_local_startup(); while (TRUE) { - if ((r = sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (m.m_source) { case HARDWARE: /* interrupt */ atl2_intr(&m); diff --git a/drivers/audio/Makefile.inc b/drivers/audio/Makefile.inc index 8bc08c94f..8e2d82c1b 100644 --- a/drivers/audio/Makefile.inc +++ b/drivers/audio/Makefile.inc @@ -5,8 +5,8 @@ CPPFLAGS+=-I${.CURDIR}/../common DPADD+= ${LIBCOMMON}/libcommon.a LDADD+= -L${LIBCOMMON} -lcommon -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys .if exists(${.CURDIR}/../../Makefile.inc) .include "${.CURDIR}/../../Makefile.inc" diff --git a/drivers/audio/common/audio_fw.c b/drivers/audio/common/audio_fw.c index 766ef3eff..5ba67d6cc 100644 --- a/drivers/audio/common/audio_fw.c +++ b/drivers/audio/common/audio_fw.c @@ -87,6 +87,7 @@ PUBLIC void main(void) { int r, caller; message mess, repl_mess; + int ipc_status; /* SEF local startup. */ sef_local_startup(); @@ -95,11 +96,13 @@ PUBLIC void main(void) carries it out, and sends a reply. */ while(1) { - sef_receive(ANY, &mess); + if(driver_receive(ANY, &mess, &ipc_status) != OK) { + panic("driver_receive failed"); + } caller = mess.m_source; /* Now carry out the work. First check for notifications. */ - if (is_notify(mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case HARDWARE: msg_hardware(); @@ -249,6 +252,10 @@ PRIVATE int init_driver(void) { return EIO; } irq_hook_set = TRUE; /* now signal handler knows it must unregister policy*/ + + /* Announce we are up! */ + driver_announce(); + return OK; } @@ -977,7 +984,7 @@ PRIVATE int init_buffers(sub_dev_t *sub_dev_ptr) return OK; #else /* CHIP != INTEL */ - error("%s: init_buffer() failed, CHIP != INTEL", drv.DriverName); + error("%s: init_buffers() failed, CHIP != INTEL", drv.DriverName); return EIO; #endif /* CHIP == INTEL */ } @@ -1023,21 +1030,18 @@ int pci_func; { int r; endpoint_t dev_e; - u32_t u32; message m; - r= ds_retrieve_label_num("amddev", &u32); + r= ds_retrieve_label_endpt("amddev", &dev_e); if (r != OK) { #if 0 - printf("tell_dev: ds_retrieve_label_num failed for 'amddev': %d\n", + printf("tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n", r); #endif return; } - dev_e= u32; - m.m_type= IOMMU_MAP; m.m2_i1= pci_bus; m.m2_i2= pci_dev; diff --git a/drivers/audio/common/audio_fw.h b/drivers/audio/common/audio_fw.h index dd18704c4..b7570ca40 100644 --- a/drivers/audio/common/audio_fw.h +++ b/drivers/audio/common/audio_fw.h @@ -2,6 +2,7 @@ #define AUDIO_FW_H #include +#include #include diff --git a/drivers/audio/es1370/Makefile b/drivers/audio/es1370/Makefile index eb237c596..bf335820f 100644 --- a/drivers/audio/es1370/Makefile +++ b/drivers/audio/es1370/Makefile @@ -4,6 +4,8 @@ SRCS= es1370.c ak4531.c pci_helper.c MAN= +LIBS += -ldriver + BINDIR?= /usr/sbin .include diff --git a/drivers/audio/es1370/es1370.h b/drivers/audio/es1370/es1370.h index 41a6a2e45..420d7eeb1 100644 --- a/drivers/audio/es1370/es1370.h +++ b/drivers/audio/es1370/es1370.h @@ -3,7 +3,6 @@ /* best viewed with tabsize=4 */ #include -#include #include diff --git a/drivers/audio/es1371/es1371.h b/drivers/audio/es1371/es1371.h index 0395cbc19..1e3743973 100644 --- a/drivers/audio/es1371/es1371.h +++ b/drivers/audio/es1371/es1371.h @@ -1,9 +1,9 @@ #ifndef ES1371_H #define ES1371_H /* best viewed with tabsize=4 */ - + +#include "audio_fw.h" #include -#include #include #include diff --git a/drivers/bios_wini/bios_wini.c b/drivers/bios_wini/bios_wini.c index 2e1c36b49..bd44a5313 100644 --- a/drivers/bios_wini/bios_wini.c +++ b/drivers/bios_wini/bios_wini.c @@ -135,6 +135,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) env_parse("bios_remap_first", "d", 0, &v, 0, 1); remap_first = v; + /* Announce we are up! */ + driver_announce(); + return(OK); } diff --git a/drivers/dec21140A/Makefile b/drivers/dec21140A/Makefile index a22fb4df7..75824a41e 100644 --- a/drivers/dec21140A/Makefile +++ b/drivers/dec21140A/Makefile @@ -4,8 +4,8 @@ PROG= dec21140A SRCS= dec21140A.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBNETDRIVER} ${LIBSYS} +LDADD+= -lnetdriver -lsys MAN= diff --git a/drivers/dec21140A/dec21140A.c b/drivers/dec21140A/dec21140A.c index 797383495..a9f3b60f5 100644 --- a/drivers/dec21140A/dec21140A.c +++ b/drivers/dec21140A/dec21140A.c @@ -10,6 +10,7 @@ */ #include +#include #include #include @@ -76,6 +77,7 @@ int main(int argc, char *argv[]) { dpeth_t *dep; message m; + int ipc_status; int r; /* SEF local startup. */ @@ -84,14 +86,11 @@ int main(int argc, char *argv[]) while (TRUE) { - if ((r= sef_receive(ANY, &m)) != OK) - panic("minix msg sef_receive failed: %d", r); + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); - if(is_notify(m.m_type)) { + if(is_ipc_notify(ipc_status)) { switch(_ENDPOINT_P(m.m_source)) { - case RS_PROC_NR: - notify(m.m_source); - break; case CLOCK: do_watchdog(&m); break; @@ -137,9 +136,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_setcb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); - /* No support for live update yet. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler_term); @@ -156,7 +158,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) /* Initialize the DEC 21140A driver. */ int r; int fkeys, sfkeys; - endpoint_t tasknr; (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); @@ -166,12 +167,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) if ((fkey_map(&fkeys, &sfkeys)) != OK) printf("%s: error using Shift+F%d key(%d)\n", str_DevName, DE_FKEY, errno); - /* Try to notify inet that we are present (again) */ - r = ds_retrieve_label_num("inet", &tasknr); - if (r == OK) - notify(tasknr); - else if(r != ESRCH) - printf("%s unable to notify inet: %d\n", str_DevName, r); + /* Announce we are up! */ + netdriver_announce(); return OK; } diff --git a/drivers/dp8390/Makefile b/drivers/dp8390/Makefile index 68bd5eeea..c2a2c075d 100644 --- a/drivers/dp8390/Makefile +++ b/drivers/dp8390/Makefile @@ -2,8 +2,8 @@ PROG= dp8390 SRCS= 3c503.c dp8390.c ne2000.c rtl8029.c wdeth.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/dp8390/dp8390.c b/drivers/dp8390/dp8390.c index ab2f419eb..9c152ce80 100644 --- a/drivers/dp8390/dp8390.c +++ b/drivers/dp8390/dp8390.c @@ -53,10 +53,12 @@ */ #include +#include #include #include #include +#include #include #include #include @@ -201,6 +203,13 @@ _PROTOTYPE( static void do_vir_outsb, (port_t port, int proc, _PROTOTYPE( static void do_vir_outsw, (port_t port, int proc, vir_bytes buf, size_t size) ); +/* SEF functions and variables. */ +FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) ); +EXTERN int env_argc; +EXTERN char **env_argv; + PRIVATE int handle_hw_intr(void) { int i, r, irq; @@ -228,19 +237,13 @@ PRIVATE int handle_hw_intr(void) return r; } -/* SEF functions and variables. */ -FORWARD _PROTOTYPE( void sef_local_startup, (void) ); -FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); -FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) ); -EXTERN int env_argc; -EXTERN char **env_argv; - /*===========================================================================* * dpeth_task * *===========================================================================*/ int main(int argc, char *argv[]) { message m; + int ipc_status; int r; /* SEF local startup. */ @@ -249,10 +252,10 @@ int main(int argc, char *argv[]) while (TRUE) { - if ((r= sef_receive(ANY, &m)) != OK) - panic("dp8390: sef_receive failed: %d", r); + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("dp8390: netdriver_receive failed: %d", r); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case HARDWARE: r = handle_hw_intr(); @@ -295,9 +298,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -312,7 +318,7 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the dp8390 driver. */ - int i, r, tasknr; + int i, r; dpeth_t *dep; long v; @@ -334,10 +340,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); eth_ign_proto= htons((u16_t) v); - /* Try to notify inet that we are present (again) */ - r = _pm_findproc("inet", &tasknr); - if (r == OK) - notify(tasknr); + /* Announce we are up! */ + netdriver_announce(); return(OK); } diff --git a/drivers/dpeth/Makefile b/drivers/dpeth/Makefile index ba9e822dc..e6c07cb47 100644 --- a/drivers/dpeth/Makefile +++ b/drivers/dpeth/Makefile @@ -4,8 +4,8 @@ PROG= dpeth SRCS= 3c501.c 3c509.c 3c503.c ne.c wd.c 8390.c devio.c netbuff.c dp.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBNETDRIVER} ${LIBSYS} +LDADD+= -lnetdriver -lsys MAN= diff --git a/drivers/dpeth/dp.c b/drivers/dpeth/dp.c index 31c008360..927848ac0 100644 --- a/drivers/dpeth/dp.c +++ b/drivers/dpeth/dp.c @@ -55,7 +55,9 @@ */ #include +#include #include +#include #include #include @@ -84,7 +86,7 @@ static dp_conf_t dp_conf[DE_PORT_NR] = { static char CopyErrMsg[] = "unable to read/write user data"; static char PortErrMsg[] = "illegal port"; -static char RecvErrMsg[] = "sef_receive failed"; +static char RecvErrMsg[] = "netdriver_receive failed"; static char SendErrMsg[] = "send failed"; static char SizeErrMsg[] = "illegal packet size"; static char TypeErrMsg[] = "illegal message type"; @@ -574,6 +576,7 @@ EXTERN char **env_argv; PUBLIC int main(int argc, char **argv) { message m; + int ipc_status; int rc; /* SEF local startup. */ @@ -581,13 +584,13 @@ PUBLIC int main(int argc, char **argv) sef_local_startup(); while (TRUE) { - if ((rc = sef_receive(ANY, &m)) != OK){ + if ((rc = netdriver_receive(ANY, &m, &ipc_status)) != OK){ panic(RecvErrMsg, rc); } DEBUG(printf("eth: got message %d, ", m.m_type)); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch(_ENDPOINT_P(m.m_source)) { case CLOCK: /* to be defined */ @@ -644,9 +647,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -661,7 +667,7 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the dpeth driver. */ - int rc, fkeys, sfkeys, tasknr; + int r, rc, fkeys, sfkeys; (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); @@ -680,10 +686,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) } #endif - /* Try to notify inet that we are present (again) */ - rc = _pm_findproc("inet", &tasknr); - if (rc == OK) - notify(tasknr); + /* Announce we are up! */ + netdriver_announce(); return(OK); } diff --git a/drivers/e1000/Makefile b/drivers/e1000/Makefile index 04650d9b8..7298b225f 100644 --- a/drivers/e1000/Makefile +++ b/drivers/e1000/Makefile @@ -4,8 +4,8 @@ PROG= e1000 SRCS= e1000.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/e1000/e1000.c b/drivers/e1000/e1000.c index d19dc0e0a..e328ae757 100644 --- a/drivers/e1000/e1000.c +++ b/drivers/e1000/e1000.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -72,6 +73,7 @@ EXTERN char **env_argv; int main(int argc, char *argv[]) { message m; + int ipc_status; int r; /* SEF local startup. */ @@ -83,11 +85,12 @@ int main(int argc, char *argv[]) */ while (TRUE) { - if ((r= sef_receive(ANY, &m)) != OK) + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) { - panic("sef_receive failed: %d", r); + panic("netdriver_receive failed: %d", r); } - if (is_notify(m.m_type)) + + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { @@ -121,9 +124,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -139,7 +145,6 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the e1000 driver. */ int r; - u32_t tasknr; /* Verify command-line arguments. */ if (env_argc < 1) @@ -158,15 +163,9 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { panic("tsc_calibrate failed: %d", r); } - /* Try to notify inet that we are present (again) */ - if ((r = ds_retrieve_label_num("inet", &tasknr)) == OK) - { - notify(tasknr); - } - else if (r != ESRCH) - { - printf("e1000: ds_retrieve_label_num failed for 'inet': %d\n", r); - } + + /* Announce we are up! */ + netdriver_announce(); return(OK); } diff --git a/drivers/filter/Makefile b/drivers/filter/Makefile index 41425fede..d419e4721 100644 --- a/drivers/filter/Makefile +++ b/drivers/filter/Makefile @@ -2,8 +2,8 @@ PROG= filter SRCS= main.c sum.c driver.c util.c optset.c crc.c md5.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys MAN= diff --git a/drivers/filter/driver.c b/drivers/filter/driver.c index 00db8d001..4738ef99a 100644 --- a/drivers/filter/driver.c +++ b/drivers/filter/driver.c @@ -3,16 +3,7 @@ #include "inc.h" /* Drivers. */ -static struct { - char *label; - int minor; - endpoint_t endpt; - - int problem; /* one of BD_* */ - int error; /* one of E*, only relevant if problem>0 */ - int retries; - int kills; -} driver[2]; +static struct driverinfo driver[2]; /* State variables. */ static endpoint_t self_ep; @@ -156,8 +147,12 @@ void driver_init(void) driver[DRIVER_MAIN].label = MAIN_LABEL; driver[DRIVER_MAIN].minor = MAIN_MINOR; - r = ds_retrieve_label_num(driver[DRIVER_MAIN].label, - (u32_t *) &driver[DRIVER_MAIN].endpt); + /* No up received yet but expected when the driver starts. */ + driver[DRIVER_MAIN].up_event = UP_EXPECTED; + driver[DRIVER_BACKUP].up_event = UP_EXPECTED; + + r = ds_retrieve_label_endpt(driver[DRIVER_MAIN].label, + &driver[DRIVER_MAIN].endpt); if (r != OK) { printf("Filter: failed to get main disk driver's endpoint: " "%d\n", r); @@ -177,8 +172,8 @@ void driver_init(void) panic("same driver: not tested"); } - r = ds_retrieve_label_num(driver[DRIVER_BACKUP].label, - (u32_t *) &driver[DRIVER_BACKUP].endpt); + r = ds_retrieve_label_endpt(driver[DRIVER_BACKUP].label, + &driver[DRIVER_BACKUP].endpt); if (r != OK) { printf("Filter: failed to get backup disk driver's " "endpoint: %d\n", r); @@ -262,7 +257,7 @@ static int new_driver_ep(int which) int r; endpoint_t endpt; - r = ds_retrieve_label_num(driver[which].label, (u32_t *) &endpt); + r = ds_retrieve_label_endpt(driver[which].label, &endpt); if (r != OK) { printf("Filter: DS query for %s failed\n", @@ -367,7 +362,7 @@ static int check_problem(int which, int problem, int retries, int *tell_rs) "threshold, restarting driver\n", which); #endif - *tell_rs = 1; + *tell_rs = (driver[which].up_event != UP_PENDING); break; case BD_DEAD: @@ -423,6 +418,7 @@ static void restart_driver(int which, int tell_rs) /* Restart the given driver. Block until the new instance is up. */ message msg; + int ipc_status; endpoint_t endpt; int r, w = 0; @@ -453,24 +449,16 @@ static void restart_driver(int which, int tell_rs) which, driver[which].endpt); #endif - do { - if(w) flt_sleep(1); - w = 1; + if(driver[which].up_event == UP_EXPECTED) { + driver[which].up_event = UP_NONE; + } + while(driver[which].up_event != UP_PENDING) { + r = driver_receive(DS_PROC_NR, &msg, &ipc_status); + if(r != OK) + panic("driver_receive returned error: %d", r); - r = ds_retrieve_label_num(driver[which].label, - (u32_t *) &endpt); - -#if DEBUG2 - if (r != OK) - printf("Filter: DS request failed (%d)\n", r); - else if (endpt == driver[which].endpt) - printf("Filter: DS returned same endpoint\n"); - else - printf("Filter: DS request OK, new endpoint\n"); -#endif - } while (r != OK || endpt == driver[which].endpt); - - driver[which].endpt = endpt; + ds_event(); + } } /*===========================================================================* @@ -580,13 +568,19 @@ static int flt_receive(message *mess, int which) * occurs. Can only return OK or RET_REDO. */ int r; + int ipc_status; for (;;) { - r = sef_receive(ANY, mess); + r = driver_receive(ANY, mess, &ipc_status); if(r != OK) - panic("sef_receive returned error: %d", r); + panic("driver_receive returned error: %d", r); - if(mess->m_source == CLOCK && is_notify(mess->m_type)) { + if(mess->m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) { + ds_event(); + continue; + } + + if(mess->m_source == CLOCK && is_ipc_notify(ipc_status)) { if (mess->NOTIFY_TIMESTAMP < flt_alarm(-1)) { #if DEBUG printf("Filter: SKIPPING old alarm " @@ -1000,3 +994,52 @@ int read_write(u64_t pos, char *bufa, char *bufb, size_t *sizep, int request) return OK; } + +/*===========================================================================* + * ds_event * + *===========================================================================*/ +void ds_event() +{ + char key[DS_MAX_KEYLEN]; + char *driver_prefix = "drv.vfs."; + u32_t value; + int type; + endpoint_t owner_endpoint; + int r; + int which; + + /* Get the event and the owner from DS. */ + r = ds_check(key, &type, &owner_endpoint); + if(r != OK) { + if(r != ENOENT) + printf("Filter: ds_event: ds_check failed: %d\n", r); + return; + } + r = ds_retrieve_u32(key, &value); + if(r != OK) { + printf("Filter: ds_event: ds_retrieve_u32 failed\n"); + return; + } + + /* Only check for VFS driver up events. */ + if(strncmp(key, driver_prefix, sizeof(driver_prefix)) + || value != DS_DRIVER_UP) { + return; + } + + /* See if this is a driver we are responsible for. */ + if(driver[DRIVER_MAIN].endpt == owner_endpoint) { + which = DRIVER_MAIN; + } + else if(driver[DRIVER_BACKUP].endpt == owner_endpoint) { + which = DRIVER_BACKUP; + } + else { + return; + } + + /* Mark the driver as (re)started. */ + driver[which].up_event = driver[which].up_event == UP_EXPECTED ? + UP_NONE : UP_PENDING; +} + diff --git a/drivers/filter/inc.h b/drivers/filter/inc.h index 5a936872c..693b8d5ba 100644 --- a/drivers/filter/inc.h +++ b/drivers/filter/inc.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,23 @@ typedef enum { FLT_READ2 /* read from both disks */ } disk_operation; +struct driverinfo { + char *label; + int minor; + endpoint_t endpt; + int up_event; + + int problem; /* one of BD_* */ + int error; /* one of E*, only relevant if problem>0 */ + int retries; + int kills; +}; + +/* UP event characterization. */ +#define UP_EXPECTED 0 +#define UP_NONE 1 +#define UP_PENDING 2 + /* Something was wrong and the disk driver has been restarted/refreshed, * so the request needs to be redone. */ @@ -94,10 +112,11 @@ extern int check_driver(int which); extern int bad_driver(int which, int type, int error); extern int read_write(u64_t pos, char *bufa, char *bufb, size_t *sizep, int flag_rw); +extern void ds_event(void); /* util.c */ extern char *flt_malloc(size_t size, char *sbuf, size_t ssize); extern void flt_free(char *buf, size_t size, const char *sbuf); extern char *print64(u64_t p); extern clock_t flt_alarm(clock_t dt); -extern void flt_sleep(int secs); + diff --git a/drivers/filter/main.c b/drivers/filter/main.c index 6d62a85df..54a7c3522 100644 --- a/drivers/filter/main.c +++ b/drivers/filter/main.c @@ -375,6 +375,7 @@ static int parse_arguments(int argc, char *argv[]) int main(int argc, char *argv[]) { message m_out; + int ipc_status; int r; /* SEF local startup. */ @@ -383,8 +384,8 @@ int main(int argc, char *argv[]) for (;;) { /* Wait for request. */ - if(sef_receive(ANY, &m_in) != OK) { - panic("sef_receive failed"); + if(driver_receive(ANY, &m_in, &ipc_status) != OK) { + panic("driver_receive failed"); } #if DEBUG2 @@ -392,6 +393,11 @@ int main(int argc, char *argv[]) m_in.m_type, m_in.m_source); #endif + if(m_in.m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) { + ds_event(); + continue; + } + who_e = m_in.m_source; proc_e = m_in.IO_ENDPT; grant_id = (cp_grant_id_t) m_in.IO_GRANT; @@ -465,6 +471,15 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) driver_init(); + /* Subscribe to driver events for VFS drivers. */ + r = ds_subscribe("drv\.vfs\..*", DSF_INITIAL | DSF_OVERWRITE); + if(r != OK) { + panic("Filter: can't subscribe to driver events"); + } + + /* Announce we are up! */ + driver_announce(); + return(OK); } diff --git a/drivers/filter/util.c b/drivers/filter/util.c index 0eda31908..af3135e37 100644 --- a/drivers/filter/util.c +++ b/drivers/filter/util.c @@ -91,15 +91,3 @@ static void got_alarm(int sig) /* Do nothing. */ } -/*===========================================================================* - * flt_sleep * - *===========================================================================*/ -void flt_sleep(int secs) -{ - u32_t system_hz; - - /* Sleep for the given number of seconds. */ - system_hz = sys_hz(); - tickdelay(system_hz * secs); -} - diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index 33114dd1d..cf8cd9080 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -367,6 +367,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) if ((s=sys_irqenable(&irq_hook_id)) != OK) panic("Couldn't enable IRQs: %d", s); + /* Announce we are up! */ + driver_announce(); + return(OK); } @@ -799,6 +802,7 @@ PRIVATE void start_motor(void) int s, motor_bit, running; message mess; + int ipc_status; motor_bit = 1 << f_drive; /* bit mask for this drive */ running = motor_status & motor_bit; /* nonzero if this motor is running */ @@ -817,9 +821,9 @@ PRIVATE void start_motor(void) f_set_timer(&f_tmr_timeout, f_dp->start_ms * system_hz / 1000, f_timeout); f_busy = BSY_IO; do { - sef_receive(ANY, &mess); + driver_receive(ANY, &mess, &ipc_status); - if (is_notify(mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case CLOCK: f_expire_tmrs(NULL, NULL); @@ -861,6 +865,7 @@ PRIVATE int seek(void) struct floppy *fp = f_fp; int r; message mess; + int ipc_status; u8_t cmd[3]; /* Are we already on the correct cylinder? */ @@ -891,9 +896,9 @@ PRIVATE int seek(void) f_set_timer(&f_tmr_timeout, system_hz/30, f_timeout); f_busy = BSY_IO; do { - sef_receive(ANY, &mess); + driver_receive(ANY, &mess, &ipc_status); - if (is_notify(mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case CLOCK: f_expire_tmrs(NULL, NULL); @@ -1149,6 +1154,7 @@ PRIVATE void f_reset(void) pvb_pair_t byte_out[2]; int s,i; message mess; + int ipc_status; /* Disable interrupts and strobe reset bit low. */ need_reset = FALSE; @@ -1173,8 +1179,8 @@ PRIVATE void f_reset(void) * but be prepared to handle a timeout. */ do { - sef_receive(ANY, &mess); - if (is_notify(mess.m_type)) { + driver_receive(ANY, &mess, &ipc_status); + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case CLOCK: f_expire_tmrs(NULL, NULL); @@ -1219,11 +1225,12 @@ PRIVATE int f_intr_wait(void) * the world, but we humans do not. */ message mess; + int ipc_status; /* We expect an interrupt, but if a timeout, occurs, report an error. */ do { - sef_receive(ANY, &mess); - if (is_notify(mess.m_type)) { + driver_receive(ANY, &mess, &ipc_status); + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case CLOCK: f_expire_tmrs(NULL, NULL); diff --git a/drivers/fxp/Makefile b/drivers/fxp/Makefile index e26523fa7..d1f5f59ca 100644 --- a/drivers/fxp/Makefile +++ b/drivers/fxp/Makefile @@ -2,8 +2,8 @@ PROG= fxp SRCS= fxp.c mii.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/fxp/fxp.c b/drivers/fxp/fxp.c index af44d779e..09aa88e6f 100644 --- a/drivers/fxp/fxp.c +++ b/drivers/fxp/fxp.c @@ -53,6 +53,7 @@ */ #include +#include #include #include @@ -301,6 +302,7 @@ EXTERN char **env_argv; int main(int argc, char *argv[]) { message m; + int ipc_status; int r; /* SEF local startup. */ @@ -309,10 +311,10 @@ int main(int argc, char *argv[]) while (TRUE) { - if ((r= sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case HARDWARE: handle_hw_intr(); @@ -353,9 +355,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -371,7 +376,6 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the fxp driver. */ int r; - u32_t tasknr; long v; vir_bytes ft; @@ -397,12 +401,8 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) if((r=tsc_calibrate()) != OK) panic("tsc_calibrate failed: %d", r); - /* Try to notify inet that we are present (again) */ - r= ds_retrieve_label_num("inet", &tasknr); - if (r == OK) - notify(tasknr); - else if (r != ESRCH) - printf("fxp: ds_retrieve_label_num failed for 'inet': %d\n", r); + /* Announce we are up! */ + netdriver_announce(); return(OK); } @@ -2952,22 +2952,19 @@ int pci_func; { int r; endpoint_t dev_e; - u32_t u32; message m; - r= ds_retrieve_label_num("amddev", &u32); + r= ds_retrieve_label_endpt("amddev", &dev_e); if (r != OK) { #if 0 printf( - "fxp`tell_dev: ds_retrieve_label_num failed for 'amddev': %d\n", + "fxp`tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n", r); #endif return; } - dev_e= u32; - m.m_type= IOMMU_MAP; m.m2_i1= pci_bus; m.m2_i2= pci_dev; diff --git a/drivers/hello/hello.c b/drivers/hello/hello.c index dbcaff3f5..1846468d0 100644 --- a/drivers/hello/hello.c +++ b/drivers/hello/hello.c @@ -165,7 +165,7 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init(int type, sef_init_info_t *info) { /* Initialize the hello driver. */ - int do_mapdriver = TRUE; + int do_announce_driver = TRUE; open_counter = 0; switch(type) { @@ -176,7 +176,7 @@ PRIVATE int sef_cb_init(int type, sef_init_info_t *info) case SEF_INIT_LU: /* Restore the state. */ lu_state_restore(); - do_mapdriver = FALSE; + do_announce_driver = FALSE; printf("%sHey, I'm a new version!\n", HELLO_MESSAGE); break; @@ -186,12 +186,9 @@ PRIVATE int sef_cb_init(int type, sef_init_info_t *info) break; } - /* Map major number to our process. */ - if (do_mapdriver && mapdriver("hello", HELLO_MAJOR, STYLE_DEV, TRUE) != OK) - { - printf("hello: mapdriver() failed: %s\n", - strerror(errno)); - return EINVAL; + /* Announce we are up when necessary. */ + if (do_announce_driver) { + driver_announce(); } /* Initialization completed successfully. */ diff --git a/drivers/lance/Makefile b/drivers/lance/Makefile index f2c13efc3..d15557514 100644 --- a/drivers/lance/Makefile +++ b/drivers/lance/Makefile @@ -2,8 +2,8 @@ PROG= lance SRCS= lance.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBNETDRIVER} ${LIBSYS} +LDADD+= -lnetdriver -lsys MAN= diff --git a/drivers/lance/lance.c b/drivers/lance/lance.c index 7415adc2f..10eb68f07 100644 --- a/drivers/lance/lance.c +++ b/drivers/lance/lance.c @@ -41,6 +41,7 @@ #define LANCE_FKEY 0 /* Use function key to dump Lance stats */ #include +#include #include #include @@ -272,6 +273,7 @@ EXTERN char **env_argv; void main( int argc, char **argv ) { message m; + int ipc_status; int i,r; ether_card_t *ec; @@ -288,8 +290,8 @@ void main( int argc, char **argv ) sys_irqenable(&ec->ec_hook); } - if ((r= sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); for (i=0;iec_hook); } - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch(_ENDPOINT_P(m.m_source)) { case TTY_PROC_NR: lance_dump(); @@ -358,9 +360,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -376,7 +381,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the lance driver. */ int r; - u32_t tasknr; long v; #if LANCE_FKEY int fkeys, sfkeys; @@ -395,12 +399,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); eth_ign_proto= htons((u16_t) v); - /* Try to notify inet that we are present (again) */ - r= ds_retrieve_label_num("inet", &tasknr); - if (r == OK) - notify(tasknr); - else if (r != ESRCH) - printf("lance: ds_retrieve_label_num failed for 'inet': %d\n", r); + /* Announce we are up! */ + netdriver_announce(); return OK; } diff --git a/drivers/orinoco/Makefile b/drivers/orinoco/Makefile index 54fd98b7f..4db8d2dbc 100644 --- a/drivers/orinoco/Makefile +++ b/drivers/orinoco/Makefile @@ -2,8 +2,8 @@ PROG= orinoco SRCS= orinoco.c hermes.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/orinoco/orinoco.c b/drivers/orinoco/orinoco.c index e91f3c204..61c8e5310 100644 --- a/drivers/orinoco/orinoco.c +++ b/drivers/orinoco/orinoco.c @@ -54,6 +54,7 @@ */ #include +#include #include #include #include @@ -241,16 +242,17 @@ EXTERN char **env_argv; *****************************************************************************/ int main(int argc, char *argv[]) { int r; + int ipc_status; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { - if ((r = sef_receive (ANY, &m)) != OK) - panic("orinoco: sef_receive failed"); + if ((r = netdriver_receive (ANY, &m, &ipc_status)) != OK) + panic("orinoco: netdriver_receive failed"); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case CLOCK: or_watchdog_f(NULL); @@ -316,9 +318,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -334,7 +339,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the orinoco driver. */ int fkeys, sfkeys, r; - u32_t inet_proc_nr; system_hz = sys_hz(); @@ -346,14 +350,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) if ((r=fkey_map(&fkeys, &sfkeys)) != OK) printf("Warning: orinoco couldn't observe F-key(s): %d\n",r); - /* Try to notify INET that we are present (again). If INET cannot - * be found, assume this is the first time we started and INET is - * not yet alive. */ - r = ds_retrieve_label_num("inet", &inet_proc_nr); - if (r == OK) - notify(inet_proc_nr); - else if (r != ESRCH) - printf("orinoco: ds_retrieve_label_num failed for 'inet': %d\n", r); + /* Announce we are up! */ + netdriver_announce(); return(OK); } diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ce07655b6..4e2c5b121 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -2,8 +2,8 @@ PROG= pci SRCS= main.c pci.c pci_table.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -ldriver -lsys -ltimers MAN= diff --git a/drivers/pci/main.c b/drivers/pci/main.c index d0b042546..64812764d 100644 --- a/drivers/pci/main.c +++ b/drivers/pci/main.c @@ -2,11 +2,6 @@ main.c */ -#include - -#include -#include - #include "pci.h" PUBLIC struct pci_acl pci_acl[NR_DRIVERS]; @@ -41,20 +36,21 @@ int main(void) { int i, r; message m; + int ipc_status; /* SEF local startup. */ sef_local_startup(); for(;;) { - r= sef_receive(ANY, &m); + r= driver_receive(ANY, &m, &ipc_status); if (r < 0) { - printf("PCI: sef_receive from ANY failed: %d\n", r); + printf("PCI: driver_receive failed: %d\n", r); break; } - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { printf("PCI: got notify from %d\n", m.m_source); /* done, get a new message */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index dd572ea0e..6362ce4f9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -8,7 +8,6 @@ Configure devices on the PCI bus Created: Jan 2000 by Philip Homburg */ -#include #include #include #include diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index ee717436d..9f91f3191 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -4,6 +4,8 @@ pci.h Created: Jan 2000 by Philip Homburg */ +#include +#include #include /* tempory functions: to be replaced later (see pci_intel.h) */ diff --git a/drivers/printer/Makefile b/drivers/printer/Makefile index 215ac7b89..37abf14be 100644 --- a/drivers/printer/Makefile +++ b/drivers/printer/Makefile @@ -2,8 +2,8 @@ PROG= printer SRCS= printer.c liveupdate.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys MAN= diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index 6c25e49e7..905406ac0 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -34,6 +34,7 @@ #include #include +#include /* Control bits (in port_base + 2). "+" means positive logic and "-" means * negative logic. Most of the signals are negative logic on the pins but @@ -114,6 +115,7 @@ FORWARD _PROTOTYPE( void do_printer_output, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -126,14 +128,17 @@ PUBLIC void main(void) { /* Main routine of the printer task. */ message pr_mess; /* buffer for all incoming messages */ + int ipc_status; /* SEF local startup. */ sef_local_startup(); while (TRUE) { - sef_receive(ANY, &pr_mess); + if(driver_receive(ANY, &pr_mess, &ipc_status) != OK) { + panic("driver_receive failed"); + } - if (is_notify(pr_mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(pr_mess.m_source)) { case HARDWARE: do_printer_output(); @@ -166,7 +171,10 @@ PUBLIC void main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { - /* Nothing to on initialization. */ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare); @@ -180,6 +188,18 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the printer driver. */ + /* Announce we are up! */ + driver_announce(); + + return OK; +} + /*===========================================================================* * do_write * *===========================================================================*/ diff --git a/drivers/random/main.c b/drivers/random/main.c index 712772968..28cc902df 100644 --- a/drivers/random/main.c +++ b/drivers/random/main.c @@ -118,6 +118,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) for(i = 0; i < RANDOM_SOURCES; i++) r_updatebin(i, &krandom.bin[i]); + /* Announce we are up! */ + driver_announce(); + return(OK); } diff --git a/drivers/readclock/Makefile b/drivers/readclock/Makefile index 984cbe626..2096f3615 100644 --- a/drivers/readclock/Makefile +++ b/drivers/readclock/Makefile @@ -2,8 +2,8 @@ PROG= readclock.drv SRCS= readclock.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys MAN= diff --git a/drivers/rtl8139/Makefile b/drivers/rtl8139/Makefile index 0eb6dd3a9..a5aeffbf7 100644 --- a/drivers/rtl8139/Makefile +++ b/drivers/rtl8139/Makefile @@ -2,8 +2,8 @@ PROG= rtl8139 SRCS= rtl8139.c liveupdate.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/rtl8139/rtl8139.c b/drivers/rtl8139/rtl8139.c index 0ef5ca6cf..3be5331e5 100644 --- a/drivers/rtl8139/rtl8139.c +++ b/drivers/rtl8139/rtl8139.c @@ -204,6 +204,7 @@ EXTERN char **env_argv; int main(int argc, char *argv[]) { int r; + int ipc_status; /* SEF local startup. */ env_setargs(argc, argv); @@ -211,10 +212,10 @@ int main(int argc, char *argv[]) while (TRUE) { - if ((r= sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case CLOCK: /* @@ -301,7 +302,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) #if RTL8139_FKEY int fkeys, sfkeys; #endif - u32_t inet_proc_nr; int r; re_t *rep; long v; @@ -326,16 +326,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) rl_init_buf(rep); - /* Try to notify INET that we are present (again). If INET cannot - * be found, assume this is the first time we started and INET is - * not yet alive. - */ - r= ds_retrieve_label_num("inet", &inet_proc_nr); - if (r == OK) - notify(inet_proc_nr); - else if (r != ESRCH) - printf("rtl8139: ds_retrieve_label_num failed for 'inet': %d\n", - r); + /* Announce we are up! */ + netdriver_announce(); return(OK); } @@ -2970,22 +2962,19 @@ int pci_func; { int r; endpoint_t dev_e; - u32_t u32; message m; - r= ds_retrieve_label_num("amddev", &u32); + r= ds_retrieve_label_endpt("amddev", &dev_e); if (r != OK) { #if 0 printf( - "rtl8139`tell_dev: ds_retrieve_label_num failed for 'amddev': %d\n", + "rtl8139`tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n", r); #endif return; } - dev_e= u32; - m.m_type= IOMMU_MAP; m.m2_i1= pci_bus; m.m2_i2= pci_dev; diff --git a/drivers/rtl8139/rtl8139.h b/drivers/rtl8139/rtl8139.h index 4ad1543aa..d0e6c2dd5 100644 --- a/drivers/rtl8139/rtl8139.h +++ b/drivers/rtl8139/rtl8139.h @@ -5,6 +5,7 @@ Created: Aug 2003 by Philip Homburg */ #include +#include #include #include diff --git a/drivers/rtl8169/Makefile b/drivers/rtl8169/Makefile index 6174e3a83..04051400e 100644 --- a/drivers/rtl8169/Makefile +++ b/drivers/rtl8169/Makefile @@ -2,8 +2,8 @@ PROG= rtl8169 SRCS= rtl8169.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -lnetdriver -lsys -ltimers MAN= diff --git a/drivers/rtl8169/rtl8169.c b/drivers/rtl8169/rtl8169.c index 181ef485a..8b84edcfd 100644 --- a/drivers/rtl8169/rtl8169.c +++ b/drivers/rtl8169/rtl8169.c @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -286,16 +287,17 @@ EXTERN char **env_argv; int main(int argc, char *argv[]) { int r; + int ipc_status; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { - if ((r = sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); - if (is_notify(m.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case CLOCK: /* @@ -346,9 +348,12 @@ PRIVATE void sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); sef_setcb_init_restart(sef_cb_init_fresh); - /* No live update support for now. */ + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); /* Register signal callbacks. */ sef_setcb_signal_handler(sef_cb_signal_handler); @@ -363,7 +368,6 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the rtl8169 driver. */ - u32_t inet_proc_nr; int r; re_t *rep; long v; @@ -381,19 +385,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++) rl_init_buf(rep); - /* - * Try to notify INET that we are present (again). If INET cannot - * be found, assume this is the first time we started and INET is - * not yet alive. - */ -#if 0 - r = ds_retrieve_label_num("inet", &inet_proc_nr); - if (r == OK) - notify(inet_proc_nr); - else if (r != ESRCH) - printf("rtl8169: ds_retrieve_label_num failed for 'inet': %d\n", - r); -#endif + /* Announce we are up! */ + netdriver_announce(); return(OK); } @@ -1260,6 +1253,7 @@ re_t *rep; void transmittest(re_t *rep) { int tx_head; + int ipc_status; tx_head = rep->re_tx_head; @@ -1267,8 +1261,8 @@ void transmittest(re_t *rep) do { message m; int r; - if ((r = sef_receive(ANY, &m)) != OK) - panic("sef_receive failed: %d", r); + if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) + panic("netdriver_receive failed: %d", r); } while(m.m_source != HARDWARE); assert(!(rep->re_flags & REF_SEND_AVAIL)); rep->re_flags |= REF_SEND_AVAIL; diff --git a/drivers/sb16/Makefile.inc b/drivers/sb16/Makefile.inc index 8bc08c94f..8e2d82c1b 100644 --- a/drivers/sb16/Makefile.inc +++ b/drivers/sb16/Makefile.inc @@ -5,8 +5,8 @@ CPPFLAGS+=-I${.CURDIR}/../common DPADD+= ${LIBCOMMON}/libcommon.a LDADD+= -L${LIBCOMMON} -lcommon -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys .if exists(${.CURDIR}/../../Makefile.inc) .include "${.CURDIR}/../../Makefile.inc" diff --git a/drivers/sb16/common/sb16.h b/drivers/sb16/common/sb16.h index 0b1d4562f..28e103b1c 100644 --- a/drivers/sb16/common/sb16.h +++ b/drivers/sb16/common/sb16.h @@ -2,6 +2,7 @@ #define SB16_H #include +#include #include #include diff --git a/drivers/sb16/dsp/sb16_dsp.c b/drivers/sb16/dsp/sb16_dsp.c index f71bf51b6..052c28bba 100644 --- a/drivers/sb16/dsp/sb16_dsp.c +++ b/drivers/sb16/dsp/sb16_dsp.c @@ -94,18 +94,19 @@ PUBLIC void main() endpoint_t caller; int proc_nr; message mess; + int ipc_status; /* SEF local startup. */ sef_local_startup(); while(TRUE) { /* Wait for an incoming message */ - sef_receive(ANY, &mess); + driver_receive(ANY, &mess, &ipc_status); caller = mess.m_source; proc_nr = mess.IO_ENDPT; - if (is_notify(mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case HARDWARE: dsp_hardware_msg(); @@ -185,6 +186,9 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) panic("initialization failed: CHIP != INTEL: %d", 0); #endif /* CHIP == INTEL */ + /* Announce we are up! */ + driver_announce(); + return(OK); } @@ -275,6 +279,7 @@ PRIVATE int dsp_ioctl(const message *m_ptr) PRIVATE void dsp_write(const message *m_ptr) { message mess; + int ipc_status; dprint("sb16_dsp.c: dsp_write()\n"); @@ -316,7 +321,7 @@ PRIVATE void dsp_write(const message *m_ptr) } else { /* Dma buffer is full, filling second buffer */ while(BufReadNext == BufFillNext) { /* Second buffer also full, wait for space to become available */ - sef_receive(HARDWARE, &mess); + driver_receive(HARDWARE, &mess, &ipc_status); dsp_hardware_msg(); } sys_datacopy(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->ADDRESS, SELF, (vir_bytes)Buffer + BufFillNext * DspFragmentSize, (phys_bytes)DspFragmentSize); diff --git a/drivers/sb16/mixer/sb16_mixer.c b/drivers/sb16/mixer/sb16_mixer.c index cff70fdce..e7583de61 100644 --- a/drivers/sb16/mixer/sb16_mixer.c +++ b/drivers/sb16/mixer/sb16_mixer.c @@ -42,12 +42,14 @@ PRIVATE int mixer_avail = 0; /* Mixer exists? */ /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main *===========================================================================*/ PUBLIC void main() { message mess; + int ipc_status; int err, caller, proc_nr; /* SEF local startup. */ @@ -57,7 +59,7 @@ PUBLIC void main() { * it out, and sends a reply. */ while (TRUE) { - sef_receive(ANY, &mess); + driver_receive(ANY, &mess, &ipc_status); caller = mess.m_source; proc_nr = mess.IO_ENDPT; @@ -98,6 +100,11 @@ PUBLIC void main() { *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -106,6 +113,18 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the sb16 mixer driver. */ + /* Announce we are up! */ + driver_announce(); + + return(OK); +} + /*=========================================================================* * mixer_open *=========================================================================*/ diff --git a/drivers/ti1225/Makefile b/drivers/ti1225/Makefile index 6ad5d59c6..e95f48afd 100644 --- a/drivers/ti1225/Makefile +++ b/drivers/ti1225/Makefile @@ -2,8 +2,8 @@ PROG= ti1225 SRCS= ti1225.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -ldriver -lsys -ltimers MAN= diff --git a/drivers/ti1225/ti1225.c b/drivers/ti1225/ti1225.c index 8c94a925d..65ba4a5e3 100644 --- a/drivers/ti1225/ti1225.c +++ b/drivers/ti1225/ti1225.c @@ -5,6 +5,7 @@ Created: Dec 2005 by Philip Homburg */ #include +#include #include #include @@ -69,6 +70,7 @@ int main(int argc, char *argv[]) { int r; message m; + int ipc_status; /* SEF local startup. */ env_setargs(argc, argv); @@ -76,9 +78,9 @@ int main(int argc, char *argv[]) for (;;) { - r= sef_receive(ANY, &m); + r= driver_receive(ANY, &m, &ipc_status); if (r != OK) - panic("sef_receive failed: %d", r); + panic("driver_receive failed: %d", r); printf("ti1225: got message %u from %d\n", m.m_type, m.m_source); } @@ -177,6 +179,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) hw_init(&ports[i]); } + /* Announce we are up! */ + driver_announce(); + return(OK); } diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 78ebca49e..916d1a059 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -5,8 +5,8 @@ PROG= tty SRCS= tty.c console.c keyboard.c pty.c rs232.c -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +DPADD+= ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS} +LDADD+= -ldriver -lsys -ltimers MAN= diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 324b56c82..826803b48 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -58,6 +58,7 @@ */ #include +#include #include #include #include @@ -153,6 +154,7 @@ PUBLIC int main(void) /* Main routine of the terminal task. */ message tty_mess; /* buffer for all incoming messages */ + int ipc_status; unsigned line; int r; register tty_t *tp; @@ -167,9 +169,9 @@ PUBLIC int main(void) } /* Get a request message. */ - r= sef_receive(ANY, &tty_mess); + r= driver_receive(ANY, &tty_mess, &ipc_status); if (r != 0) - panic("sef_receive failed with: %d", r); + panic("driver_receive failed with: %d", r); /* First handle all kernel notification types that the TTY supports. * - An alarm went off, expire all timers and handle the events. @@ -181,7 +183,7 @@ PUBLIC int main(void) * do not operate on a device, in constrast to the driver requests. */ - if (is_notify(tty_mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(tty_mess.m_source)) { case CLOCK: /* run watchdogs of expired timers */ diff --git a/etc/usr/rc b/etc/usr/rc index 1db0489f5..52f8d4518 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -136,7 +136,7 @@ start) echo -n "Starting networking:" if grep -s 'psip0.*default' /etc/inet.conf then ifconfig -h 10.0.0.1 - else sleep 5 + else daemonize dhcpd fi daemonize nonamed -L diff --git a/include/Makefile b/include/Makefile index a50426d6c..c1cfd8fcb 100644 --- a/include/Makefile +++ b/include/Makefile @@ -16,8 +16,9 @@ INCS+= minix/a.out.h minix/bitmap.h minix/callnr.h minix/cdrom.h \ minix/dir.h minix/dl_eth.h minix/dmap.h minix/driver.h \ minix/drivers.h minix/drvlib.h minix/ds.h minix/endpoint.h \ minix/fslib.h minix/ioctl.h minix/ipc.h minix/ipcconst.h \ - minix/keymap.h minix/minlib.h minix/mq.h minix/partition.h \ - minix/paths.h minix/portio.h minix/profile.h minix/queryparam.h \ + minix/keymap.h minix/minlib.h minix/mq.h \ + minix/netdriver.h minix/partition.h minix/paths.h \ + minix/portio.h minix/profile.h minix/queryparam.h \ minix/rs.h minix/safecopies.h minix/sef.h minix/sound.h \ minix/sys_config.h minix/sysinfo.h minix/syslib.h \ minix/sysutil.h minix/tty.h minix/type.h minix/types.h \ diff --git a/include/minix/com.h b/include/minix/com.h index 65b1481fb..d97f12162 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -98,8 +98,10 @@ */ #define NOTIFY_MESSAGE 0x1000 /* FIXME the old is_notify(a) should be replaced by is_ipc_notify(status). */ -#define is_ipc_notify(status) (IPC_STATUS_CALL(status) == NOTIFY) -#define is_notify(a) ((unsigned) ((a) - NOTIFY_MESSAGE) < 0x100) +#define is_ipc_notify(ipc_status) (IPC_STATUS_CALL(ipc_status) == NOTIFY) +#define is_notify(a) ((unsigned) ((a) - NOTIFY_MESSAGE) < 0x100) +#define is_ipc_asynch(ipc_status) \ + (is_ipc_notify(ipc_status) || IPC_STATUS_CALL(ipc_status) == SENDA) #define NOTIFY_FROM(p_nr) (NOTIFY_MESSAGE | ((p_nr) + NR_TASKS)) /* Shorthands for message parameters passed with notifications. */ @@ -199,6 +201,8 @@ #define DEV_IOCTL_S (DEV_RQ_BASE + 24) /* (safecopy) I/O control code */ #define DEV_MMAP_S (DEV_RQ_BASE + 25) /* (safecopy) mmap interface */ +#define IS_DEV_RQ(type) (((type) & ~0xff) == DEV_RQ_BASE) + #define DEV_REPLY (DEV_RS_BASE + 0) /* general task reply */ #define DEV_CLONED (DEV_RS_BASE + 1) /* return cloned minor */ #define DEV_REVIVE (DEV_RS_BASE + 2) /* driver revives process */ @@ -209,6 +213,8 @@ #define DEV_SEL_REPL1 (DEV_RS_BASE + 7) /* first reply to DEV_SELECT */ #define DEV_SEL_REPL2 (DEV_RS_BASE + 8) /* (opt) second reply to DEV_SELECT */ +#define IS_DEV_RS(type) (((type) & ~0xff) == DEV_RS_BASE) + /* Field names for messages to block and character device drivers. */ #define DEVICE m2_i1 /* major-minor device */ #define IO_ENDPT m2_i2 /* which (proc/endpoint) wants I/O? */ @@ -365,9 +371,10 @@ # define SYS_EXIT (KERNEL_CALL + 53) /* sys_exit() */ # define SYS_SCHEDCTL (KERNEL_CALL + 54) /* sys_schedctl() */ +# define SYS_STATECTL (KERNEL_CALL + 55) /* sys_statectl() */ /* Total */ -#define NR_SYS_CALLS 55 /* number of system calls */ +#define NR_SYS_CALLS 56 /* number of kernel calls */ #define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS) @@ -375,7 +382,7 @@ #define SYS_BASIC_CALLS \ SYS_EXIT, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, SYS_VSAFECOPY, SYS_GETINFO, \ SYS_TIMES, SYS_SETALARM, SYS_SETGRANT, SYS_SAFEMAP, SYS_SAFEREVMAP, \ - SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL + SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL, SYS_STATECTL /* Field names for SYS_MEMSET. */ #define MEM_PTR m2_p1 /* base */ @@ -495,7 +502,7 @@ #define T_BOOTTIME m4_l3 /* Boottime in seconds (also for SYS_STIME) */ #define T_BOOT_TICKS m4_l5 /* number of clock ticks since boot time */ -/* Field names for SYS_TRACE, SYS_PRIVCTL. */ +/* Field names for SYS_TRACE, SYS_PRIVCTL, SYS_STATECTL. */ #define CTL_ENDPT m2_i1 /* process number of the caller */ #define CTL_REQUEST m2_i2 /* server control request */ #define CTL_ARG_PTR m2_p1 /* pointer to argument */ @@ -651,6 +658,9 @@ #define SYS_UPD_SRC_ENDPT m1_i1 /* source endpoint */ #define SYS_UPD_DST_ENDPT m1_i2 /* destination endpoint */ +/* Subfunctions for SYS_STATECTL */ +#define SYS_STATE_CLEAR_IPC_REFS 1 /* clear IPC references */ + /*===========================================================================* * Messages for the Reincarnation Server * *===========================================================================*/ @@ -709,6 +719,7 @@ # define DS_VAL m2_l1 /* data (u32, char *, etc.) */ # define DS_VAL_LEN m2_l2 /* data length */ # define DS_NR_SNAPSHOT m2_i3 /* number of snapshot */ +# define DS_OWNER m2_i3 /* owner */ /*===========================================================================* * Miscellaneous messages used by TTY * diff --git a/include/minix/driver.h b/include/minix/driver.h index f2956929f..d523ced35 100644 --- a/include/minix/driver.h +++ b/include/minix/driver.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -55,8 +56,18 @@ struct device { #define DRIVER_STD 0 /* Use the standard reply protocol */ #define DRIVER_ASYN 1 /* Use the new asynchronous protocol */ +#define MAX_NR_OPEN_DEVICES 16 + +#define IS_DEV_MINOR_RQ(type) (IS_DEV_RQ(type) && (type) != DEV_STATUS) + /* Functions defined by driver.c: */ +_PROTOTYPE( void driver_announce, (void) ); +_PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr, + int *status_ptr) ); +_PROTOTYPE( int driver_receive_mq, (message *m_ptr, int *status_ptr) ); _PROTOTYPE( void driver_task, (struct driver *dr, int type) ); +_PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) ); +_PROTOTYPE( void driver_init_buffer, (void) ); _PROTOTYPE( char *no_name, (void) ); _PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( struct device *nop_prepare, (int device) ); @@ -67,8 +78,6 @@ _PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) ); -_PROTOTYPE( int mq_queue, (message *m_ptr) ); -_PROTOTYPE( void init_buffer, (void) ); /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ diff --git a/include/minix/ds.h b/include/minix/ds.h index e33743a00..e803900d4 100644 --- a/include/minix/ds.h +++ b/include/minix/ds.h @@ -4,6 +4,7 @@ #define _MINIX_DS_H #include +#include /* Flags. */ #define DSF_IN_USE 0x001 /* entry is in use */ @@ -30,6 +31,9 @@ /* DS constants. */ #define DS_MAX_KEYLEN 80 /* Max length of a key, including '\0'. */ +/* DS events. */ +#define DS_DRIVER_UP 1 + /* ds.c */ /* U32 */ @@ -58,14 +62,16 @@ _PROTOTYPE( int ds_retrieve_map, (const char *ds_name, char *vaddr, _PROTOTYPE( int ds_delete_map, (const char *ds_name)); /* LABEL */ -_PROTOTYPE( int ds_publish_label, (const char *ds_name, u32_t value,int flags)); -_PROTOTYPE( int ds_retrieve_label_name, (char *ds_name, u32_t num)); -_PROTOTYPE( int ds_retrieve_label_num, (const char *ds_name, u32_t *value)); +_PROTOTYPE( int ds_publish_label, (const char *ds_name, endpoint_t endpoint, + int flags)); +_PROTOTYPE( int ds_retrieve_label_name, (char *ds_name, endpoint_t endpoint)); +_PROTOTYPE( int ds_retrieve_label_endpt, (const char *ds_name, + endpoint_t *endpoint)); _PROTOTYPE( int ds_delete_label, (const char *ds_name)); /* Subscribe and check. */ _PROTOTYPE( int ds_subscribe, (const char *regex, int flags)); -_PROTOTYPE( int ds_check, (char *ds_name, int *type)); +_PROTOTYPE( int ds_check, (char *ds_name, int *type, endpoint_t *owner_e)); #endif /* _MINIX_DS_H */ diff --git a/include/minix/mq.h b/include/minix/mq.h index 28423688b..65f1e9a36 100644 --- a/include/minix/mq.h +++ b/include/minix/mq.h @@ -12,6 +12,7 @@ Copyright 1995 Philip Homburg typedef struct mq { message mq_mess; + int mq_mess_status; struct mq *mq_next; int mq_allocated; } mq_t; diff --git a/include/minix/netdriver.h b/include/minix/netdriver.h new file mode 100644 index 000000000..82957b1ff --- /dev/null +++ b/include/minix/netdriver.h @@ -0,0 +1,14 @@ +/* Prototypes and definitions for network drivers. */ + +#ifndef _MINIX_NETDRIVER_H +#define _MINIX_NETDRIVER_H + +#include +#include + +/* Functions defined by netdriver.c: */ +_PROTOTYPE( void netdriver_announce, (void) ); +_PROTOTYPE( int netdriver_receive, (endpoint_t src, message *m_ptr, + int *status_ptr) ); + +#endif /* _MINIX_NETDRIVER_H */ diff --git a/include/minix/sef.h b/include/minix/sef.h index 85ae34b9f..6420fdb42 100644 --- a/include/minix/sef.h +++ b/include/minix/sef.h @@ -138,6 +138,7 @@ _PROTOTYPE( int sef_cb_lu_prepare_always_ready, (int state) ); _PROTOTYPE( int sef_cb_lu_prepare_never_ready, (int state) ); _PROTOTYPE( int sef_cb_lu_prepare_crash, (int state) ); _PROTOTYPE( int sef_cb_lu_state_isvalid_standard, (int state) ); +_PROTOTYPE( int sef_cb_lu_state_isvalid_workfree, (int state) ); /* Macros for predefined callback implementations. */ #define SEF_CB_LU_PREPARE_NULL sef_cb_lu_prepare_null diff --git a/include/minix/syslib.h b/include/minix/syslib.h index 1a3d07476..0ec32dc32 100644 --- a/include/minix/syslib.h +++ b/include/minix/syslib.h @@ -54,6 +54,7 @@ _PROTOTYPE( int sys_schedctl, (endpoint_t proc_ep)); _PROTOTYPE( int sys_runctl, (endpoint_t proc_ep, int action, int flags)); _PROTOTYPE( int sys_update, (endpoint_t src_ep, endpoint_t dst_ep)); +_PROTOTYPE( int sys_statectl, (int request)); _PROTOTYPE( int sys_privctl, (endpoint_t proc_ep, int req, void *p)); _PROTOTYPE( int sys_privquery_mem, (endpoint_t proc_ep, phys_bytes physstart, phys_bytes physlen)); diff --git a/kernel/config.h b/kernel/config.h index e17465aa1..63d59f25c 100644 --- a/kernel/config.h +++ b/kernel/config.h @@ -44,6 +44,7 @@ #define USE_RUNCTL 1 /* control stop flags of a process */ #define USE_UPDATE 1 /* update a process into another */ #define USE_MCONTEXT 1 /* enable getting and setting of mach context*/ +#define USE_STATECTL 1 /* let a process control its state */ /* Length of program names stored in the process table. This is only used * for the debugging dumps that can be generated with the IS server. The PM diff --git a/kernel/proto.h b/kernel/proto.h index 8be84262e..b8ff91a2c 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -69,6 +69,8 @@ _PROTOTYPE( void system_init, (void) ); umap_local(proc_addr(proc_nr), D, (vir_addr), (bytes)) _PROTOTYPE( phys_bytes umap_grant, (struct proc *, cp_grant_id_t, vir_bytes)); _PROTOTYPE( void clear_endpoint, (struct proc *rc) ); +_PROTOTYPE( void clear_ipc, (struct proc *rc) ); +_PROTOTYPE( void clear_ipc_refs, (struct proc *rc, int caller_ret) ); _PROTOTYPE( phys_bytes umap_bios, (vir_bytes vir_addr, vir_bytes bytes)); _PROTOTYPE( void kernel_call_resume, (struct proc *p)); diff --git a/kernel/system.c b/kernel/system.c index e0344bd75..a7f068504 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -184,6 +184,7 @@ PUBLIC void system_init(void) map(SYS_SETGRANT, do_setgrant); /* get/set own parameters */ map(SYS_RUNCTL, do_runctl); /* set/clear stop flag of a process */ map(SYS_UPDATE, do_update); /* update a process into another */ + map(SYS_STATECTL, do_statectl); /* let a process control its state */ /* Signal handling. */ map(SYS_KILL, do_kill); /* cause a process to be signaled */ @@ -476,39 +477,37 @@ vir_bytes bytes; /* size */ PUBLIC void clear_endpoint(rc) register struct proc *rc; /* slot of process to clean up */ { - register struct proc *rp; /* iterate over process table */ - register struct proc **xpp; /* iterate over caller queue */ - if(isemptyp(rc)) panic("clear_proc: empty process: %d", rc->p_endpoint); - if(rc->p_endpoint == PM_PROC_NR || rc->p_endpoint == VFS_PROC_NR || - rc->p_endpoint == VM_PROC_NR) - { - /* This test is great for debugging system processes dying, - * but as this happens normally on reboot, not good permanent code. - */ - printf("died: "); - proc_stacktrace(rc); - panic("system process died: %d", rc->p_endpoint); - } - /* Make sure that the exiting process is no longer scheduled. */ RTS_SET(rc, RTS_NO_ENDPOINT); if (priv(rc)->s_flags & SYS_PROC) { - if (priv(rc)->s_asynsize) { -#if 0 - printf("clear_endpoint: clearing s_asynsize of %s / %d\n", - rc->p_name, rc->p_endpoint); - proc_stacktrace(rc); -#endif - } priv(rc)->s_asynsize= 0; } /* If the process happens to be queued trying to send a * message, then it must be removed from the message queues. */ + clear_ipc(rc); + + /* Likewise, if another process was sending or receive a message to or from + * the exiting process, it must be alerted that process no longer is alive. + * Check all processes. + */ + clear_ipc_refs(rc, EDEADSRCDST); + +} + +/*===========================================================================* + * clear_ipc * + *===========================================================================*/ +PUBLIC void clear_ipc(rc) +register struct proc *rc; /* slot of process to clean up */ +{ +/* Clear IPC data for a given process slot. */ + struct proc **xpp; /* iterate over caller queue */ + if (RTS_ISSET(rc, RTS_SENDING)) { int target_proc; @@ -528,11 +527,18 @@ register struct proc *rc; /* slot of process to clean up */ rc->p_rts_flags &= ~RTS_SENDING; } rc->p_rts_flags &= ~RTS_RECEIVING; +} + +/*===========================================================================* + * clear_ipc_refs * + *===========================================================================*/ +PUBLIC void clear_ipc_refs(rc, caller_ret) +register struct proc *rc; /* slot of process to clean up */ +int caller_ret; /* code to return on callers */ +{ +/* Clear IPC references for a given process slot. */ + struct proc *rp; /* iterate over process table */ - /* Likewise, if another process was sending or receive a message to or from - * the exiting process, it must be alerted that process no longer is alive. - * Check all processes. - */ for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) { if(isemptyp(rp)) continue; @@ -540,13 +546,18 @@ register struct proc *rc; /* slot of process to clean up */ /* Unset pending notification bits. */ unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id); - /* Check if process is depends on exiting process. */ + /* XXX FIXME: Cleanup should be done for senda() as well. For this to be + * done in a realistic way, we need a better implementation of senda + * with a bitmap similar to s_notify_pending for notify() rather than + * a single global MF_ASYNMSG flag. The current arrangement exposes + * several performance issues. + */ + + /* Check if process depends on given process. */ if (P_BLOCKEDON(rp) == rc->p_endpoint) { - rp->p_reg.retreg = EDEADSRCDST; /* report source died */ + rp->p_reg.retreg = caller_ret; /* return requested code */ RTS_UNSET(rp, (RTS_RECEIVING|RTS_SENDING)); /* no longer blocking */ - printf("endpoint %d / %s blocked on dead src ep %d / %s\n", - rp->p_endpoint, rp->p_name, rc->p_endpoint, rc->p_name); - } + } } } diff --git a/kernel/system.h b/kernel/system.h index c85420e6c..832d3303d 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -208,5 +208,10 @@ _PROTOTYPE( int do_setmcontext, (struct proc * caller, message *m_ptr) ); _PROTOTYPE( int do_schedule, (struct proc * caller, message *m_ptr) ); _PROTOTYPE( int do_schedctl, (struct proc * caller, message *m_ptr) ); +_PROTOTYPE( int do_statectl, (struct proc * caller, message *m_ptr) ); +#if ! USE_STATECTL +#define do_statectl do_unused +#endif + #endif /* SYSTEM_H */ diff --git a/kernel/system/Makefile.inc b/kernel/system/Makefile.inc index 5addba866..3a9445353 100644 --- a/kernel/system/Makefile.inc +++ b/kernel/system/Makefile.inc @@ -41,4 +41,6 @@ SRCS+= \ do_vmctl.c \ do_mcontext.c \ do_schedule.c \ - do_schedctl.c + do_schedctl.c \ + do_statectl.c + diff --git a/kernel/system/do_statectl.c b/kernel/system/do_statectl.c new file mode 100644 index 000000000..54b257171 --- /dev/null +++ b/kernel/system/do_statectl.c @@ -0,0 +1,33 @@ +/* The kernel call implemented in this file: + * m_type: SYS_STATECTL + * + * The parameters for this kernel call are: + * m2_i2: CTL_REQUEST (state control request) + */ + +#include "kernel/system.h" + +#if USE_STATECTL + +/*===========================================================================* + * do_statectl * + *===========================================================================*/ +PUBLIC int do_statectl(struct proc * caller, message * m_ptr) +{ +/* Handle sys_statectl(). A process has issued a state control request. */ + + switch(m_ptr->CTL_REQUEST) + { + case SYS_STATE_CLEAR_IPC_REFS: + /* Clear IPC references for all the processes communicating + * with the caller. + */ + clear_ipc_refs(caller, EDEADSRCDST); + return(OK); + default: + printf("do_statectl: bad request %d\n", m_ptr->CTL_REQUEST); + return EINVAL; + } +} + +#endif /* USE_STATECTL */ diff --git a/kernel/system/do_update.c b/kernel/system/do_update.c index 2e52ef460..5a80222a1 100644 --- a/kernel/system/do_update.c +++ b/kernel/system/do_update.c @@ -124,11 +124,13 @@ PUBLIC int do_update(struct proc * caller, message * m_ptr) *===========================================================================*/ PRIVATE void adjust_proc_slot(struct proc *rp, struct proc *from_rp) { - /* Preserve endpoints, slot numbers, priv structure. */ + /* Preserve endpoints, slot numbers, priv structure, and IPC. */ rp->p_endpoint = from_rp->p_endpoint; rp->p_nr = from_rp->p_nr; rp->p_priv = from_rp->p_priv; priv(rp)->s_proc_nr = from_rp->p_nr; + rp->p_misc_flags |= (from_rp->p_misc_flags & MF_ASYNMSG); + rp->p_caller_q = from_rp->p_caller_q; } /*===========================================================================* diff --git a/lib/Makefile b/lib/Makefile index 2b3f8b1ef..18681aa78 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,6 +1,6 @@ .include -SUBDIR= csu libc libcurses libdriver libend libedit libm libsys \ +SUBDIR= csu libc libcurses libdriver libnetdriver libend libedit libm libsys \ libtimers libutil .if ${COMPILER_TYPE} == "ack" diff --git a/lib/libdriver/driver.c b/lib/libdriver/driver.c index 483c3cadc..295413db6 100644 --- a/lib/libdriver/driver.c +++ b/lib/libdriver/driver.c @@ -30,28 +30,79 @@ * * The file contains the following entry points: * + * driver_announce: called by a device driver to announce it is up + * driver_receive: receive() interface for drivers + * driver_receive_mq: receive() interface for drivers with message queueing * driver_task: called by the device dependent task entry - * init_buffer: initialize a DMA buffer - * mq_queue: queue an incoming message for later processing + * driver_init_buffer: initialize a DMA buffer + * driver_mq_queue: queue an incoming message for later processing */ - #include #include #include #include #include +#include /* Claim space for variables. */ u8_t *tmp_buf = NULL; /* the DMA buffer eventually */ phys_bytes tmp_phys; /* phys address of DMA buffer */ +FORWARD _PROTOTYPE( void clear_open_devs, (void) ); +FORWARD _PROTOTYPE( int is_open_dev, (int device) ); +FORWARD _PROTOTYPE( void set_open_dev, (int device) ); + FORWARD _PROTOTYPE( void asyn_reply, (message *mess, int proc_nr, int r) ); +FORWARD _PROTOTYPE( int driver_reply, (endpoint_t caller_e, int caller_status, + message *m_ptr) ); +FORWARD _PROTOTYPE( int driver_spurious_reply, (endpoint_t caller_e, + int caller_status, message *m_ptr) ); FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp) ); FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp) ); int device_caller; PRIVATE mq_t *queue_head = NULL; +PRIVATE int open_devs[MAX_NR_OPEN_DEVICES]; +PRIVATE int next_open_devs_slot = 0; + +/*===========================================================================* + * clear_open_devs * + *===========================================================================*/ +PRIVATE void clear_open_devs() +{ + next_open_devs_slot = 0; +} + +/*===========================================================================* + * is_open_dev * + *===========================================================================*/ +PRIVATE int is_open_dev(int device) +{ + int i, open_dev_found; + + open_dev_found = FALSE; + for(i=0;i= MAX_NR_OPEN_DEVICES) { + panic("out of slots for open devices"); + } + open_devs[next_open_devs_slot] = device; + next_open_devs_slot++; +} /*===========================================================================* * asyn_reply * @@ -115,6 +166,164 @@ int r; } } +/*===========================================================================* + * driver_reply * + *===========================================================================*/ +PRIVATE int driver_reply(caller_e, caller_status, m_ptr) +endpoint_t caller_e; +int caller_status; +message *m_ptr; +{ +/* Reply to a message sent to the driver. */ + int r; + + /* Use sendnb if caller is guaranteed to be blocked, asynsend otherwise. */ + if(IPC_STATUS_CALL(caller_status) == SENDREC) { + r = sendnb(caller_e, m_ptr); + } + else { + r = asynsend(caller_e, m_ptr); + } + + return r; +} + +/*===========================================================================* + * driver_spurious_reply * + *===========================================================================*/ +PRIVATE int driver_spurious_reply(caller_e, caller_status, m_ptr) +endpoint_t caller_e; +int caller_status; +message *m_ptr; +{ +/* Reply to a spurious message pretending to be dead. */ + int r; + + m_ptr->m_type = TASK_REPLY; + m_ptr->REP_ENDPT = m_ptr->IO_ENDPT; + m_ptr->REP_STATUS = ERESTART; + + r = driver_reply(caller_e, caller_status, m_ptr); + if(r != OK) { + printf("unable to reply to spurious message from %d\n", + caller_e); + } + + return r; +} + +/*===========================================================================* + * driver_announce * + *===========================================================================*/ +PUBLIC void driver_announce() +{ +/* Announce we are up after a fresh start or restart. */ + int r; + char key[DS_MAX_KEYLEN]; + char label[DS_MAX_KEYLEN]; + char *driver_prefix = "drv.vfs."; + + /* Callers are allowed to use sendrec to communicate with drivers. + * For this reason, there may blocked callers when a driver restarts. + * Ask the kernel to unblock them (if any). + */ + r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS); + if (r != OK) { + panic("driver_announce: sys_statectl failed: %d\n", r); + } + + /* Publish a driver up event. */ + r = ds_retrieve_label_name(label, getprocnr()); + if (r != OK) { + panic("driver_announce: unable to get own label: %d\n", r); + } + snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label); + r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE); + if (r != OK) { + panic("driver_announce: unable to publish driver up event: %d\n", r); + } + + /* Expect a DEV_OPEN for any device before serving regular driver requests. */ + clear_open_devs(); +} + +/*===========================================================================* + * driver_receive * + *===========================================================================*/ +PUBLIC int driver_receive(src, m_ptr, status_ptr) +endpoint_t src; +message *m_ptr; +int *status_ptr; +{ +/* receive() interface for drivers. */ + int r; + int ipc_status; + + while (TRUE) { + /* Wait for a request. */ + r = sef_receive_status(src, m_ptr, &ipc_status); + *status_ptr = ipc_status; + if (r != OK) { + return r; + } + + /* See if only DEV_OPEN is to be expected for this device. */ + if(IS_DEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) { + if(m_ptr->m_type != DEV_OPEN) { + if(!is_ipc_asynch(ipc_status)) { + driver_spurious_reply(m_ptr->m_source, + ipc_status, m_ptr); + } + continue; + } + set_open_dev(m_ptr->DEVICE); + } + + break; + } + + return OK; +} + +/*===========================================================================* + * driver_receive_mq * + *===========================================================================*/ +PUBLIC int driver_receive_mq(m_ptr, status_ptr) +message *m_ptr; +int *status_ptr; +{ +/* receive() interface for drivers with message queueing. */ + int ipc_status; + + /* Any queued messages? Oldest are at the head. */ + while(queue_head) { + mq_t *mq; + mq = queue_head; + memcpy(m_ptr, &mq->mq_mess, sizeof(mq->mq_mess)); + ipc_status = mq->mq_mess_status; + *status_ptr = ipc_status; + queue_head = queue_head->mq_next; + mq_free(mq); + + /* See if only DEV_OPEN is to be expected for this device. */ + if(IS_DEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) { + if(m_ptr->m_type != DEV_OPEN) { + if(!is_ipc_asynch(ipc_status)) { + driver_spurious_reply(m_ptr->m_source, + ipc_status, m_ptr); + } + continue; + } + set_open_dev(m_ptr->DEVICE); + } + + return OK; + } + + /* Fall back to standard receive() interface for drivers. */ + return driver_receive(ANY, m_ptr, status_ptr); +} + /*===========================================================================* * driver_task * *===========================================================================*/ @@ -124,35 +333,21 @@ int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */ { /* Main program of any device driver task. */ - int r, proc_nr; + int r, proc_nr, ipc_status; message mess; - /* Init MQ library. */ - mq_init(); - /* Here is the main loop of the disk task. It waits for a message, carries * it out, and sends a reply. */ while (TRUE) { - /* Any queued messages? Oldest are at the head. */ - if(queue_head) { - mq_t *mq; - mq = queue_head; - memcpy(&mess, &mq->mq_mess, sizeof(mess)); - queue_head = queue_head->mq_next; - mq_free(mq); - } else { - int s; - /* Wait for a request to read or write a disk block. */ - if ((s=sef_receive(ANY, &mess)) != OK) - panic("sef_receive() failed: %d", s); - } + if ((r=driver_receive_mq(&mess, &ipc_status)) != OK) + panic("driver_receive_mq failed: %d", r); device_caller = mess.m_source; proc_nr = mess.IO_ENDPT; /* Now carry out the work. */ - if (is_notify(mess.m_type)) { + if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(mess.m_source)) { case HARDWARE: /* leftover interrupt or expired timer. */ @@ -174,6 +369,7 @@ int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */ /* done, get a new message */ continue; } + switch(mess.m_type) { case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break; case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break; @@ -208,14 +404,7 @@ send_reply: /* Status is # of bytes transferred or error code. */ mess.REP_STATUS = r; - /* Changed from sendnb() to asynsend() by dcvmoole on 20091129. - * This introduces a potential overflow if a single process is - * flooding us with requests, but we need reliable delivery of - * reply messages for the 'filter' driver. A possible solution - * would be to allow only one pending asynchronous reply to a - * single process at any time. FIXME. - */ - r= asynsend(device_caller, &mess); + r= driver_reply(device_caller, ipc_status, &mess); if (r != OK) { printf("driver_task: unable to send reply to %d: %d\n", @@ -237,9 +426,9 @@ send_reply: /*===========================================================================* - * init_buffer * + * driver_init_buffer * *===========================================================================*/ -PUBLIC void init_buffer(void) +PUBLIC void driver_init_buffer(void) { /* Select a buffer that can safely be used for DMA transfers. It may also * be used to read partition tables and such. Its absolute address is @@ -459,15 +648,23 @@ message *mp; /* pointer to ioctl request */ } /*===========================================================================* - * mq_queue * + * driver_mq_queue * *===========================================================================*/ -PUBLIC int mq_queue(message *m) +PUBLIC int driver_mq_queue(message *m, int status) { mq_t *mq, *mi; + static int mq_initialized = FALSE; + + if(!mq_initialized) { + /* Init MQ library. */ + mq_init(); + mq_initialized = TRUE; + } if(!(mq = mq_get())) - panic("mq_queue: mq_get failed"); + panic("driver_mq_queue: mq_get failed"); memcpy(&mq->mq_mess, m, sizeof(mq->mq_mess)); + mq->mq_mess_status = status; mq->mq_next = NULL; if(!queue_head) { queue_head = mq; diff --git a/lib/libnetdriver/Makefile b/lib/libnetdriver/Makefile new file mode 100644 index 000000000..a1dbf4518 --- /dev/null +++ b/lib/libnetdriver/Makefile @@ -0,0 +1,7 @@ +# Makefile for libnetdriver + +LIB= netdriver + +SRCS= netdriver.c + +.include diff --git a/lib/libnetdriver/netdriver.c b/lib/libnetdriver/netdriver.c new file mode 100644 index 000000000..defc302cd --- /dev/null +++ b/lib/libnetdriver/netdriver.c @@ -0,0 +1,77 @@ +/* This file contains device independent network device driver interface. + * + * Changes: + * Apr 01, 2010 Created (Cristiano Giuffrida) + * + * The file contains the following entry points: + * + * netdriver_announce: called by a network driver to announce it is up + * netdriver_receive: receive() interface for network drivers + */ + +#include +#include +#include +#include + +PRIVATE int conf_expected = TRUE; + +/*===========================================================================* + * netdriver_announce * + *===========================================================================*/ +PUBLIC void netdriver_announce() +{ +/* Announce we are up after a fresh start or restart. */ + int r; + char key[DS_MAX_KEYLEN]; + char label[DS_MAX_KEYLEN]; + char *driver_prefix = "drv.net."; + + /* Publish a driver up event. */ + r = ds_retrieve_label_name(label, getprocnr()); + if (r != OK) { + panic("driver_announce: unable to get own label: %d\n", r); + } + snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label); + r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE); + if (r != OK) { + panic("driver_announce: unable to publish driver up event: %d\n", r); + } + + conf_expected = TRUE; +} + +/*===========================================================================* + * netdriver_receive * + *===========================================================================*/ +PUBLIC int netdriver_receive(src, m_ptr, status_ptr) +endpoint_t src; +message *m_ptr; +int *status_ptr; +{ +/* receive() interface for drivers. */ + int r; + + while (TRUE) { + /* Wait for a request. */ + r = sef_receive_status(src, m_ptr, status_ptr); + if (r != OK) { + return r; + } + + /* See if only DL_CONF is to be expected. */ + if(conf_expected) { + if(m_ptr->m_type == DL_CONF) { + conf_expected = FALSE; + } + else if(m_ptr->m_type != DL_GETNAME) { + continue; + } + } + + break; + } + + return OK; +} + diff --git a/lib/libsys/Makefile b/lib/libsys/Makefile index 321d433bb..126bdbca2 100644 --- a/lib/libsys/Makefile +++ b/lib/libsys/Makefile @@ -71,6 +71,7 @@ SRCS= \ sys_stime.c \ sys_schedule.c \ sys_schedctl.c \ + sys_statectl.c \ sys_times.c \ sys_trace.c \ sys_umap.c \ diff --git a/lib/libsys/ds.c b/lib/libsys/ds.c index 948579a87..753c8f8a3 100644 --- a/lib/libsys/ds.c +++ b/lib/libsys/ds.c @@ -35,9 +35,9 @@ PRIVATE int do_invoke_ds(int type, const char *ds_name) return r; } -int ds_publish_label(const char *ds_name, u32_t value, int flags) +int ds_publish_label(const char *ds_name, endpoint_t endpoint, int flags) { - m.DS_VAL = value; + m.DS_VAL = (u32_t) endpoint; m.DS_FLAGS = DSF_TYPE_LABEL | flags; return do_invoke_ds(DS_PUBLISH, ds_name); } @@ -114,20 +114,20 @@ int ds_snapshot_map(const char *ds_name, int *nr_snapshot) return r; } -int ds_retrieve_label_name(char *ds_name, u32_t num) +int ds_retrieve_label_name(char *ds_name, endpoint_t endpoint) { int r; - m.DS_VAL = num; + m.DS_VAL = (u32_t) endpoint; r = do_invoke_ds(DS_RETRIEVE_LABEL, ds_name); return r; } -int ds_retrieve_label_num(const char *ds_name, u32_t *value) +int ds_retrieve_label_endpt(const char *ds_name, endpoint_t *endpoint) { int r; m.DS_FLAGS = DSF_TYPE_LABEL; r = do_invoke_ds(DS_RETRIEVE, ds_name); - *value = m.DS_VAL; + *endpoint = (endpoint_t) m.DS_VAL; return r; } @@ -260,10 +260,11 @@ int ds_subscribe(const char *regexp, int flags) return do_invoke_ds(DS_SUBSCRIBE, regexp); } -int ds_check(char *ds_key, int *type) +int ds_check(char *ds_key, int *type, endpoint_t *owner_e) { int r; r = do_invoke_ds(DS_CHECK, ds_key); - *type = m.DS_FLAGS; + if(type) *type = m.DS_FLAGS; + if(owner_e) *owner_e = m.DS_OWNER; return r; } diff --git a/lib/libsys/pci_del_acl.c b/lib/libsys/pci_del_acl.c index 6b4184f15..8ac893594 100644 --- a/lib/libsys/pci_del_acl.c +++ b/lib/libsys/pci_del_acl.c @@ -17,16 +17,16 @@ endpoint_t proc_ep; { int r; message m; - u32_t u32; + endpoint_t endpoint; if (pci_procnr == ANY) { - r= ds_retrieve_label_num("pci", &u32); + r= ds_retrieve_label_endpt("pci", &endpoint); if (r != 0) { - panic("pci_del_acl: _pm_findproc failed for 'pci': %d", r); + panic("pci_del_acl: ds_retrieve_label_endpt failed for 'pci': %d", r); } - pci_procnr = u32; + pci_procnr = endpoint; } diff --git a/lib/libsys/pci_init1.c b/lib/libsys/pci_init1.c index be929d9b8..2838a8eea 100644 --- a/lib/libsys/pci_init1.c +++ b/lib/libsys/pci_init1.c @@ -18,14 +18,14 @@ PUBLIC void pci_init1(name) char *name; { int r; - u32_t u32; + endpoint_t endpoint; size_t len; message m; - r= ds_retrieve_label_num("pci", &u32); + r= ds_retrieve_label_endpt("pci", &endpoint); if (r != 0) - panic("pci_init1: ds_retrieve_label_num failed for 'pci': %d", r); - pci_procnr= u32; + panic("pci_init1: ds_retrieve_label_endpt failed for 'pci': %d", r); + pci_procnr= endpoint; m.m_type= BUSC_PCI_INIT; len= strlen(name); diff --git a/lib/libsys/pci_set_acl.c b/lib/libsys/pci_set_acl.c index d81e4e4a6..ab84553fb 100644 --- a/lib/libsys/pci_set_acl.c +++ b/lib/libsys/pci_set_acl.c @@ -18,16 +18,16 @@ struct rs_pci *rs_pci; int r; cp_grant_id_t gid; message m; - u32_t u32; + endpoint_t endpoint; if (pci_procnr == ANY) { - r= ds_retrieve_label_num("pci", &u32); + r= ds_retrieve_label_endpt("pci", &endpoint); if (r != 0) { - panic("pci_set_acl: ds_retrieve_label_num failed for 'pci': %d", r); + panic("pci_set_acl: ds_retrieve_label_endpt failed for 'pci': %d", r); } - pci_procnr = u32; + pci_procnr = endpoint; } diff --git a/lib/libsys/sef_liveupdate.c b/lib/libsys/sef_liveupdate.c index 553447f61..cf2a312de 100644 --- a/lib/libsys/sef_liveupdate.c +++ b/lib/libsys/sef_liveupdate.c @@ -289,3 +289,11 @@ PUBLIC int sef_cb_lu_state_isvalid_standard(int state) return SEF_LU_STATE_IS_STANDARD(state); } +/*===========================================================================* + * sef_cb_lu_state_isvalid_workfree * + *===========================================================================*/ +PUBLIC int sef_cb_lu_state_isvalid_workfree(int state) +{ + return (state == SEF_LU_STATE_WORK_FREE); +} + diff --git a/lib/libsys/sys_statectl.c b/lib/libsys/sys_statectl.c new file mode 100644 index 000000000..38b8ca869 --- /dev/null +++ b/lib/libsys/sys_statectl.c @@ -0,0 +1,10 @@ +#include "syslib.h" + +PUBLIC int sys_statectl(int request) +{ + message m; + + m.CTL_REQUEST = request; + + return _kernel_call(SYS_STATECTL, &m); +} diff --git a/servers/ds/store.c b/servers/ds/store.c index e37088f7b..4ee08693e 100644 --- a/servers/ds/store.c +++ b/servers/ds/store.c @@ -299,6 +299,10 @@ PUBLIC int do_publish(message *m_ptr) if(source == NULL) return EPERM; + /* Only RS can publish labels. */ + if((flags & DSF_TYPE_LABEL) && m_ptr->m_source != RS_PROC_NR) + return EPERM; + /* MAP should not be overwritten. */ if((flags & DSF_TYPE_MAP) && (flags & DSF_OVERWRITE)) return EINVAL; @@ -594,9 +598,10 @@ PUBLIC int do_check(message *m_ptr) { struct subscription *subp; char *owner; + endpoint_t entry_owner_e; int r, i; - /* Find the owner. */ + /* Find the subscription owner. */ owner = ds_getprocname(m_ptr->m_source); if(owner == NULL) return ESRCH; @@ -616,14 +621,19 @@ PUBLIC int do_check(message *m_ptr) /* Copy the key name. */ r = sys_safecopyto(m_ptr->m_source, (cp_grant_id_t) m_ptr->DS_KEY_GRANT, (vir_bytes) 0, - (vir_bytes) ds_store[i].key, strlen(ds_store[i].key), D); + (vir_bytes) ds_store[i].key, strlen(ds_store[i].key) + 1, D); if(r != OK) { printf("DS: check: copy failed from %d: %d\n", m_ptr->m_source, r); return r; } - /* Copy the type. */ + /* Copy the type and the owner of the original entry. */ + entry_owner_e = ds_getprocep(ds_store[i].owner); + if(entry_owner_e == -1) { + panic("ds_getprocep failed"); + } m_ptr->DS_FLAGS = ds_store[i].flags & DSF_MASK_TYPE; + m_ptr->DS_OWNER = entry_owner_e; /* Mark the entry as no longer updated for the subscriber. */ UNSET_BIT(subp->old_subs, i); @@ -639,6 +649,7 @@ PUBLIC int do_delete(message *m_ptr) struct data_store *dsp; char key_name[DS_MAX_KEYLEN]; char *source; + char *label; int type = m_ptr->DS_FLAGS & DSF_MASK_TYPE; int top, i, r; @@ -661,7 +672,25 @@ PUBLIC int do_delete(message *m_ptr) switch(type) { case DSF_TYPE_U32: + break; case DSF_TYPE_LABEL: + label = dsp->key; + + /* Clean up subscriptions. */ + for (i = 0; i < NR_DS_SUBS; i++) { + if ((ds_subs[i].flags & DSF_IN_USE) + && !strcmp(ds_subs[i].owner, label)) { + ds_subs[i].flags = 0; + } + } + + /* Clean up data entries. */ + for (i = 0; i < NR_DS_KEYS; i++) { + if ((ds_store[i].flags & DSF_IN_USE) + && !strcmp(ds_store[i].owner, label)) { + ds_store[i].flags = 0; + } + } break; case DSF_TYPE_STR: case DSF_TYPE_MEM: diff --git a/servers/inet/inet.c b/servers/inet/inet.c index 4628bd298..469e40232 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -91,6 +91,7 @@ _PROTOTYPE( void main, (void) ); FORWARD _PROTOTYPE( void nw_conf, (void) ); FORWARD _PROTOTYPE( void nw_init, (void) ); +FORWARD _PROTOTYPE( void ds_event, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); @@ -99,6 +100,7 @@ FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); PUBLIC void main() { mq_t *mq; + int ipc_status; int r; endpoint_t source; int m_type; @@ -135,7 +137,7 @@ PUBLIC void main() if (!mq) ip_panic(("out of messages")); - r= sef_receive(ANY, &mq->mq_mess); + r= sef_receive_status(ANY, &mq->mq_mess, &ipc_status); if (r<0) { ip_panic(("unable to receive: %d", r)); @@ -147,23 +149,29 @@ PUBLIC void main() { sr_rec(mq); } - else if (is_notify(m_type)) + else if (is_ipc_notify(ipc_status)) { - if (_ENDPOINT_P(source) == CLOCK) + if (source == CLOCK) { clck_tick(&mq->mq_mess); mq_free(mq); } - else if (_ENDPOINT_P(source) == PM_PROC_NR) + else if (source == PM_PROC_NR) { /* signaled */ /* probably SIGTERM */ mq_free(mq); } + else if (source == DS_PROC_NR) + { + /* DS notifies us of an event. */ + ds_event(); + mq_free(mq); + } else { - /* A driver is (re)started. */ - eth_check_drivers(&mq->mq_mess); + printf("inet: got unexpected notify from %d\n", + mq->mq_mess.m_source); mq_free(mq); } } @@ -291,6 +299,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) nw_init(); + /* Subscribe to driver events for network drivers. */ + r = ds_subscribe("drv\.net\..*", DSF_INITIAL | DSF_OVERWRITE); + if(r != OK) { + ip_panic(("inet: can't subscribe to driver events")); + } + return(OK); } @@ -320,6 +334,41 @@ PRIVATE void nw_init() udp_init(); } +/*===========================================================================* + * ds_event * + *===========================================================================*/ +PRIVATE void ds_event() +{ + char key[DS_MAX_KEYLEN]; + char *driver_prefix = "drv.net."; + u32_t value; + int type; + endpoint_t owner_endpoint; + int r; + + /* Get the event and the owner from DS. */ + r = ds_check(key, &type, &owner_endpoint); + if(r != OK) { + if(r != ENOENT) + printf("inet: ds_event: ds_check failed: %d\n", r); + return; + } + r = ds_retrieve_u32(key, &value); + if(r != OK) { + printf("inet: ds_event: ds_retrieve_u32 failed\n"); + return; + } + + /* Only check for network driver up events. */ + if(strncmp(key, driver_prefix, sizeof(driver_prefix)) + || value != DS_DRIVER_UP) { + return; + } + + /* A driver is (re)started. */ + eth_check_driver(owner_endpoint); +} + PUBLIC void panic0(file, line) char *file; int line; diff --git a/servers/inet/mnx_eth.c b/servers/inet/mnx_eth.c index e1cb788bc..a04253ebb 100644 --- a/servers/inet/mnx_eth.c +++ b/servers/inet/mnx_eth.c @@ -31,16 +31,15 @@ FORWARD _PROTOTYPE( void write_int, (eth_port_t *eth_port) ); FORWARD _PROTOTYPE( void eth_recvev, (event_t *ev, ev_arg_t ev_arg) ); FORWARD _PROTOTYPE( void eth_sendev, (event_t *ev, ev_arg_t ev_arg) ); FORWARD _PROTOTYPE( eth_port_t *find_port, (message *m) ); -FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port, endpoint_t tasknr) ); +FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port, + endpoint_t endpoint) ); FORWARD _PROTOTYPE( void send_getstat, (eth_port_t *eth_port) ); PUBLIC void osdep_eth_init() { int i, j, r, rport; - u32_t tasknr; struct eth_conf *ecp; eth_port_t *eth_port, *rep; - message mess; cp_grant_id_t gid; /* First initialize normal ethernet interfaces */ @@ -99,52 +98,12 @@ PUBLIC void osdep_eth_init() } eth_port->etp_osdep.etp_rd_vec_grant= gid; - r= ds_retrieve_label_num(ecp->ec_task, &tasknr); - if (r != OK && r != ESRCH) - { - printf("inet: ds_retrieve_label_num failed for '%s': %d\n", - ecp->ec_task, r); - } - if (r != OK) - { - /* Eventually, we expect ethernet drivers to be - * started after INET. So we always end up here. And - * the findproc can be removed. - */ -#if 0 - printf("eth%d: unable to find task %s: %d\n", - i, ecp->ec_task, r); -#endif - tasknr= ANY; - } - eth_port->etp_osdep.etp_port= ecp->ec_port; - eth_port->etp_osdep.etp_task= tasknr; + eth_port->etp_osdep.etp_task= ANY; eth_port->etp_osdep.etp_recvconf= 0; eth_port->etp_osdep.etp_send_ev= 0; ev_init(ð_port->etp_osdep.etp_recvev); - mess.m_type= DL_CONF; - mess.DL_PORT= eth_port->etp_osdep.etp_port; - mess.DL_PROC= this_proc; - mess.DL_MODE= DL_NOMODE; - - if (tasknr == ANY) - r= ENXIO; - else - { - assert(eth_port->etp_osdep.etp_state == OEPS_INIT); - r= asynsend(eth_port->etp_osdep.etp_task, &mess); - if (r == OK) - eth_port->etp_osdep.etp_state= OEPS_CONF_SENT; - else - { - printf( - "osdep_eth_init: unable to send to ethernet task, error= %d\n", - r); - } - } - sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF), i, eth_open, eth_close, eth_read, eth_write, eth_ioctl, eth_cancel, eth_select); @@ -473,25 +432,17 @@ PUBLIC void eth_rec(message *m) } } -PUBLIC void eth_check_drivers(message *m) +PUBLIC void eth_check_driver(endpoint_t endpoint) { int r; - endpoint_t tasknr= m->m_source; -#if 0 - if (notification_count < 100) - { - notification_count++; - printf("eth_check_drivers: got a notification #%d from %d\n", - notification_count, tasknr); - } -#endif - - m->m_type= DL_GETNAME; - r= asynsend(tasknr, m); + message m; + + m.m_type = DL_GETNAME; + r= asynsend(endpoint, &m); if (r != OK) { - printf("eth_check_drivers: asynsend to %d failed: %d\n", - tasknr, r); + printf("eth_check_driver: asynsend to %d failed: %d\n", + endpoint, r); return; } } @@ -884,20 +835,14 @@ message *m; return loc_port; } -static void eth_restart(eth_port_t *eth_port, endpoint_t tasknr) +static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint) { int r; unsigned flags, dl_flags; cp_grant_id_t gid; message mess; - if (eth_port->etp_osdep.etp_state != OEPS_INIT) { - printf("eth_restart: restarting eth%d, task %d, port %d\n", - eth_port-eth_port_table, tasknr, - eth_port->etp_osdep.etp_port); - } - - eth_port->etp_osdep.etp_task= tasknr; + eth_port->etp_osdep.etp_task= endpoint; switch(eth_port->etp_osdep.etp_state) { diff --git a/servers/inet/proto.h b/servers/inet/proto.h index cfbecca51..4a8b425ff 100644 --- a/servers/inet/proto.h +++ b/servers/inet/proto.h @@ -13,7 +13,7 @@ _PROTOTYPE( void clck_tick, (message *mess) ); /* mnx_eth.c */ _PROTOTYPE( void eth_rec, (message *m) ); -_PROTOTYPE( void eth_check_drivers, (message *m) ); +_PROTOTYPE( void eth_check_driver, (endpoint_t endpoint) ); /* sr.c */ diff --git a/servers/is/dmp_ds.c b/servers/is/dmp_ds.c index 89802e9ab..38cc18335 100644 --- a/servers/is/dmp_ds.c +++ b/servers/is/dmp_ds.c @@ -17,13 +17,13 @@ PUBLIC void data_store_dmp() } printf("Data store contents:\n"); - printf("-slot- ------key------ -----owner----- ---type--- ----value---\n"); + printf("-slot- -----------key----------- -----owner----- ---type--- ----value---\n"); for(i = prev_i; i < NR_DS_KEYS && n < LINES; i++) { p = &ds_store[i]; if(!(p->flags & DSF_IN_USE)) continue; - printf("%6d %-15s %-15s ", i, p->key, p->owner); + printf("%6d %-25s %-15s ", i, p->key, p->owner); switch(p->flags & DSF_MASK_TYPE) { case DSF_TYPE_U32: printf("%-10s %12u\n", "U32", p->u.u32); diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index 05ddbec82..004e577e6 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -61,8 +61,6 @@ PRIVATE char * dmap_flags(int flags) static char fl[10]; strcpy(fl, "---"); if(flags & DMAP_MUTABLE) fl[0] = 'M'; - if(flags & DMAP_BUSY) fl[1] = 'S'; - if(flags & DMAP_BABY) fl[2] = 'B'; return fl; } diff --git a/servers/iso9660fs/device.c b/servers/iso9660fs/device.c index 647560103..3c86e71f2 100644 --- a/servers/iso9660fs/device.c +++ b/servers/iso9660fs/device.c @@ -212,6 +212,7 @@ int flags; /* special flags, like O_NONBLOCK */ /* Call the task. */ r = sendrec(driver_e, &m); + if(r == OK && m.REP_STATUS == ERESTART) r = EDEADSRCDST; /* As block I/O never SUSPENDs, safe cleanup must be done whether * the I/O succeeded or not. */ @@ -295,6 +296,7 @@ message *mess_ptr; /* pointer to message for task */ proc_e = mess_ptr->IO_ENDPT; r = sendrec(task_nr, mess_ptr); + if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADSRCDST; if (r != OK) { if (r == EDEADSRCDST) { printf("fs: dead driver %d\n", task_nr); diff --git a/servers/iso9660fs/mount.c b/servers/iso9660fs/mount.c index eb5cd4b98..7df01b784 100644 --- a/servers/iso9660fs/mount.c +++ b/servers/iso9660fs/mount.c @@ -13,7 +13,6 @@ PUBLIC int fs_readsuper() { cp_grant_id_t label_gid; size_t label_len; int r = OK; - unsigned long tasknr; endpoint_t driver_e; int readonly; @@ -32,15 +31,13 @@ PUBLIC int fs_readsuper() { return(EINVAL); } - r = ds_retrieve_label_num(fs_dev_label, &tasknr); + r = ds_retrieve_label_endpt(fs_dev_label, &driver_e); if (r != OK) { - printf("ISOFS %s:%d ds_retrieve_label_num failed for '%s': %d\n", + printf("ISOFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n", __FILE__, __LINE__, fs_dev_label, r); return(EINVAL); } - driver_e = tasknr; - /* Map the driver endpoint for this major */ driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e; diff --git a/servers/mfs/device.c b/servers/mfs/device.c index f81aea977..1a8e7dd59 100644 --- a/servers/mfs/device.c +++ b/servers/mfs/device.c @@ -205,6 +205,7 @@ int flags; /* special flags, like O_NONBLOCK */ /* Call the task. */ r = sendrec(driver_e, &m); + if(r == OK && m.REP_STATUS == ERESTART) r = EDEADSRCDST; /* As block I/O never SUSPENDs, safe cleanup must be done whether * the I/O succeeded or not. */ @@ -325,6 +326,7 @@ PRIVATE int gen_io( proc_e = mess_ptr->IO_ENDPT; r = sendrec(task_nr, mess_ptr); + if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADSRCDST; if (r != OK) { if (r == EDEADSRCDST) { printf("fs: dead driver %d\n", task_nr); diff --git a/servers/mfs/mount.c b/servers/mfs/mount.c index 12d893309..8a84497cd 100644 --- a/servers/mfs/mount.c +++ b/servers/mfs/mount.c @@ -27,7 +27,6 @@ PUBLIC int fs_readsuper() cp_grant_id_t label_gid; size_t label_len; int r = OK; - unsigned long tasknr; endpoint_t driver_e; int readonly, isroot; @@ -48,16 +47,14 @@ PUBLIC int fs_readsuper() return(EINVAL); } - r= ds_retrieve_label_num(fs_dev_label, &tasknr); + r= ds_retrieve_label_endpt(fs_dev_label, &driver_e); if (r != OK) { - printf("mfs:fs_readsuper: ds_retrieve_label_num failed for '%s': %d\n", + printf("mfs:fs_readsuper: ds_retrieve_label_endpt failed for '%s': %d\n", fs_dev_label, r); return EINVAL; } - driver_e = tasknr; - /* Map the driver endpoint for this major */ driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e; use_getuptime2 = TRUE; /* Should be removed with old getuptime call. */ diff --git a/servers/pm/main.c b/servers/pm/main.c index 47d3ee5ea..0751c62dc 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -73,7 +73,7 @@ PUBLIC int main() /* Wait for the next message and extract useful information from it. */ if (sef_receive_status(ANY, &m_in, &ipc_status) != OK) - panic("PM sef_receive error"); + panic("PM sef_receive_status error"); who_e = m_in.m_source; /* who sent the message */ if(pm_isokendpt(who_e, &who_p) != OK) panic("PM got message from invalid endpoint: %d", who_e); diff --git a/servers/rs/main.c b/servers/rs/main.c index 69a9dff53..d94d453a5 100644 --- a/servers/rs/main.c +++ b/servers/rs/main.c @@ -50,7 +50,7 @@ PUBLIC int main(void) * sending the reply. The loop never terminates, unless a panic occurs. */ message m; /* request message */ - int status; /* status code */ + int ipc_status; /* status code */ int call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ @@ -61,7 +61,7 @@ PUBLIC int main(void) while (TRUE) { /* Wait for request message. */ - get_work(&m, &status); + get_work(&m, &ipc_status); who_e = m.m_source; if(rs_isokendpt(who_e, &who_p) != OK) { panic("message from bogus source: %d", who_e); @@ -79,7 +79,7 @@ PUBLIC int main(void) /* Notification messages are control messages and do not need a reply. * These include heartbeat messages and system notifications. */ - if (is_ipc_notify(status)) { + if (is_ipc_notify(ipc_status)) { switch (who_p) { case CLOCK: do_period(&m); /* check services status */ @@ -672,13 +672,13 @@ endpoint_t endpoint; { /* Block and catch an init ready message from the given source. */ int r; - int status; + int ipc_status; message m; struct rproc *rp; int result; /* Receive init ready message. */ - if ((r = sef_receive_status(endpoint, &m, &status)) != OK) { + if ((r = sef_receive_status(endpoint, &m, &ipc_status)) != OK) { panic("unable to receive init reply: %d", r); } if(m.m_type != RS_INIT) { diff --git a/servers/rs/manager.c b/servers/rs/manager.c index 37a40fd25..956004ea0 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -501,6 +501,13 @@ struct rproc *rp; /* pointer to service slot */ return kill_service(rp, "ds_publish_label call failed", r); } + /* If the service is a driver, map it. */ + if (rpub->dev_nr > 0) { + if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style, 1) != OK) { + return kill_service(rp, "couldn't map driver", errno); + } + } + if(rs_verbose) printf("RS: %s service-wide properties published\n", srv_to_string(rp)); @@ -889,7 +896,7 @@ PRIVATE int run_script(struct rproc *rp) reason= "restart"; else if (rp->r_flags & RS_NOPINGREPLY) reason= "no-heartbeat"; - else reason= "crashed"; + else reason= "terminated"; sprintf(incarnation_str, "%d", rp->r_restarts); if(rs_verbose) { @@ -906,7 +913,7 @@ PRIVATE int run_script(struct rproc *rp) return kill_service(rp, "unable to fork script", errno); case 0: execle(rp->r_script, rp->r_script, rpub->label, reason, - incarnation_str, NULL, envp); + incarnation_str, NULL, envp, (char*)NULL); printf("RS: run_script: execl '%s' failed: %s\n", rp->r_script, strerror(errno)); exit(1); @@ -1332,8 +1339,8 @@ endpoint_t source; rpub->pci_acl.rsp_class[i].mask= rs_start->rss_pci_class[i].mask; if(rs_verbose) printf("RS: init_slot: PCI class %06x mask %06x\n", - rpub->pci_acl.rsp_class[i].class, - rpub->pci_acl.rsp_class[i].mask); + (unsigned int) rpub->pci_acl.rsp_class[i].class, + (unsigned int) rpub->pci_acl.rsp_class[i].mask); } /* Copy kernel call mask. Inherit basic kernel calls. */ diff --git a/servers/rs/request.c b/servers/rs/request.c index 66ea117c3..4a9d3820d 100755 --- a/servers/rs/request.c +++ b/servers/rs/request.c @@ -71,7 +71,7 @@ PUBLIC int do_down(message *m_ptr) { register struct rproc *rp; register struct rprocpub *rpub; - int s, proc; + int s; char label[RS_MAX_LABEL_LEN]; /* Copy label. */ @@ -122,7 +122,7 @@ PUBLIC int do_down(message *m_ptr) PUBLIC int do_restart(message *m_ptr) { struct rproc *rp; - int s, proc, r; + int s, r; char label[RS_MAX_LABEL_LEN]; char script[MAX_SCRIPT_LEN]; @@ -242,7 +242,6 @@ PUBLIC int do_init_ready(message *m_ptr) int who_p; struct rproc *rp; struct rprocpub *rpub; - message m; int result; who_p = _ENDPOINT_P(m_ptr->m_source); @@ -269,19 +268,6 @@ PUBLIC int do_init_ready(message *m_ptr) return(EDONTREPLY); } - /* XXX If the service is a driver, map it. This should be part - * of publish_service() but the synchronous nature of mapdriver would - * cause a deadlock. The temporary hack is to map the driver here - * after initialization is complete. - */ - m.m_type = OK; - reply(rpub->endpoint, &m); - if (rpub->dev_nr > 0) { - if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style, 1) != OK) { - return kill_service(rp, "couldn't map driver", errno); - } - } - /* Mark the slot as no longer initializing. */ rp->r_flags &= ~RS_INITIALIZING; rp->r_check_tm = 0; @@ -313,7 +299,7 @@ PUBLIC int do_init_ready(message *m_ptr) printf("RS: %s completed restart\n", srv_to_string(rp)); } - return(EDONTREPLY); + return(OK); } /*===========================================================================* @@ -324,7 +310,6 @@ PUBLIC int do_update(message *m_ptr) struct rproc *rp; struct rproc *new_rp; struct rprocpub *rpub; - struct rprocpub *new_rpub; struct rs_start rs_start; int s; char label[RS_MAX_LABEL_LEN]; diff --git a/servers/rs/service/service.c b/servers/rs/service/service.c index baeeec82a..60383e47c 100644 --- a/servers/rs/service/service.c +++ b/servers/rs/service/service.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,7 @@ PRIVATE char *known_requests[] = { #define RUN_CMD "run" #define RUN_SCRIPT "/etc/rs.single" /* Default script for 'run' */ #define PATH_CONFIG _PATH_SYSTEM_CONF /* Default config file */ -#define DEFAULT_LU_STATE 3 /* Default live update state */ +#define DEFAULT_LU_STATE SEF_LU_STATE_WORK_FREE /* Default lu state */ #define DEFAULT_LU_MAXTIME 0 /* Default lu max time */ /* Define names for arguments provided to this utility. The first few diff --git a/servers/vfs/device.c b/servers/vfs/device.c index 2407a2ef3..5bf9d35c2 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -155,7 +155,9 @@ PUBLIC void dev_status(message *m) do { int r; st.m_type = DEV_STATUS; - if ((r = sendrec(m->m_source, &st)) != OK) { + r = sendrec(m->m_source, &st); + if(r == OK && st.REP_STATUS == ERESTART) r = EDEADSRCDST; + if (r != OK) { printf("DEV_STATUS failed to %d: %d\n", m->m_source, r); if (r == EDEADSRCDST) return; panic("couldn't sendrec for DEV_STATUS: %d", r); @@ -616,6 +618,7 @@ message *mess_ptr; /* pointer to message for task */ proc_e = mess_ptr->IO_ENDPT; r = sendrec(task_nr, mess_ptr); + if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADSRCDST; if (r != OK) { if (r == EDEADSRCDST) { printf("fs: dead driver %d\n", task_nr); diff --git a/servers/vfs/dmap.c b/servers/vfs/dmap.c index 39eca07ca..9c9d3bab6 100644 --- a/servers/vfs/dmap.c +++ b/servers/vfs/dmap.c @@ -63,7 +63,7 @@ PRIVATE struct dmap init_dmap[] = { PUBLIC int do_mapdriver() { int r, force, major, proc_nr_n; - unsigned long tasknr; + endpoint_t endpoint; vir_bytes label_vir; size_t label_len; char label[LABEL_MAX]; @@ -97,34 +97,23 @@ PUBLIC int do_mapdriver() label[label_len]= '\0'; - r= ds_retrieve_label_num(label, &tasknr); + r= ds_retrieve_label_endpt(label, &endpoint); if (r != OK) { printf("vfs:do_mapdriver: ds doesn't know '%s'\n", label); return EINVAL; } - if (isokendpt(tasknr, &proc_nr_n) != OK) + if (isokendpt(endpoint, &proc_nr_n) != OK) { - printf("vfs:do_mapdriver: bad endpoint %d\n", tasknr); + printf("vfs:do_mapdriver: bad endpoint %d\n", endpoint); return(EINVAL); } /* Try to update device mapping. */ major= m_in.md_major; force= m_in.md_force; - r= map_driver(label, major, tasknr, m_in.md_style, force); - if (r == OK) - { - /* If a driver has completed its exec(), it can be announced - * to be up. - */ - if(force || fproc[proc_nr_n].fp_execced) { - dev_up(major); - } else { - dmap[major].dmap_flags |= DMAP_BABY; - } - } + r= map_driver(label, major, endpoint, m_in.md_style, force); return(r); } @@ -169,7 +158,6 @@ int force; /* See if updating the entry is allowed. */ if (! (dp->dmap_flags & DMAP_MUTABLE)) return(EPERM); - if (dp->dmap_flags & DMAP_BUSY) return(EBUSY); if (!force) { @@ -274,9 +262,7 @@ PUBLIC void dmap_endpt_up(int proc_e) int i; for (i=0; ifp_execced = 1; - /* Check if this is a driver that can now be useful. */ - dmap_endpt_up(rfp->fp_endpoint); - return(OK); } diff --git a/servers/vfs/fs.h b/servers/vfs/fs.h index 13695de2d..25c7220c1 100644 --- a/servers/vfs/fs.h +++ b/servers/vfs/fs.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/servers/vfs/main.c b/servers/vfs/main.c index aab220f81..fcd8fff8e 100644 --- a/servers/vfs/main.c +++ b/servers/vfs/main.c @@ -106,13 +106,18 @@ PUBLIC int main(void) /* Check for special control messages first. */ if (is_notify(call_nr)) { - if (who_p == CLOCK) + if (who_e == CLOCK) { /* Alarm timer expired. Used only for select(). * Check it. */ fs_expire_timers(m_in.NOTIFY_TIMESTAMP); } + else if(who_e == DS_PROC_NR) + { + /* DS notifies us of an event. */ + ds_event(); + } else { /* Device notifies us of an event. */ @@ -283,6 +288,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) system_hz = sys_hz(); + /* Subscribe to driver events for VFS drivers. */ + s = ds_subscribe("drv\.vfs\..*", DSF_INITIAL | DSF_OVERWRITE); + if(s != OK) { + panic("vfs: can't subscribe to driver events"); + } + SANITYCHECK; #if DO_SANITYCHECKS diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index ae6701ff6..cf2088ce5 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -594,17 +594,9 @@ PUBLIC int do_svrctl() /* If a driver has completed its exec(), it can be announced * to be up. */ - if(fproc[proc_nr_n].fp_execced) { - /* Reply before calling dev_up */ -#if 0 - printf("do_svrctl: replying before dev_up\n"); -#endif - reply(who_e, r); - dev_up(major); - r= SUSPEND; - } else { - dmap[major].dmap_flags |= DMAP_BABY; - } + reply(who_e, r); + dev_up(major); + r= SUSPEND; } return(r); @@ -630,6 +622,38 @@ struct mem_map *seg_ptr; return OK; } +/*===========================================================================* + * ds_event * + *===========================================================================*/ +PUBLIC void ds_event() +{ + char key[DS_MAX_KEYLEN]; + char *driver_prefix = "drv.vfs."; + u32_t value; + int type; + endpoint_t owner_endpoint; + int r; + /* Get the event and the owner from DS. */ + r = ds_check(key, &type, &owner_endpoint); + if(r != OK) { + if(r != ENOENT) + printf("vfs: ds_event: ds_check failed: %d\n", r); + return; + } + r = ds_retrieve_u32(key, &value); + if(r != OK) { + printf("vfs: ds_event: ds_retrieve_u32 failed\n"); + return; + } + /* Only check for VFS driver up events. */ + if(strncmp(key, driver_prefix, sizeof(driver_prefix)) + || value != DS_DRIVER_UP) { + return; + } + + /* Perform up. */ + dmap_endpt_up(owner_endpoint); +} diff --git a/servers/vfs/mount.c b/servers/vfs/mount.c index 99ddc1c72..4a6dee940 100644 --- a/servers/vfs/mount.c +++ b/servers/vfs/mount.c @@ -81,7 +81,7 @@ PUBLIC int do_fslogin() *===========================================================================*/ PUBLIC int do_mount() { - u32_t fs_e; + endpoint_t fs_e; int r, proc_nr; /* Only the super-user may do MOUNT. */ @@ -96,13 +96,13 @@ PUBLIC int do_mount() mount_label[sizeof(mount_label)-1] = 0; - r = ds_retrieve_label_num(mount_label, &fs_e); + r = ds_retrieve_label_endpt(mount_label, &fs_e); if (r != OK) return(r); if (isokendpt(fs_e, &proc_nr) != OK) return(EINVAL); } else { /* Legacy support: get the endpoint from the request itself. */ - fs_e = (unsigned long) m_in.fs_label; + fs_e = (endpoint_t) m_in.fs_label; mount_label[0] = 0; } diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 9983ba149..be0820862 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -86,6 +86,7 @@ _PROTOTYPE( void pm_reboot, (void) ); _PROTOTYPE( int do_svrctl, (void) ); _PROTOTYPE( int do_getsysinfo, (void) ); _PROTOTYPE( int pm_dumpcore, (int proc_e, struct mem_map *seg_ptr) ); +_PROTOTYPE( void ds_event, (void) ); /* mount.c */ _PROTOTYPE( int do_fslogin, (void) ); diff --git a/test/ds/dstest.c b/test/ds/dstest.c index 5634e4593..5dcf97e36 100644 --- a/test/ds/dstest.c +++ b/test/ds/dstest.c @@ -124,23 +124,20 @@ void test_mem(void) void test_label(void) { int r; - char get_label[DS_MAX_KEYLEN]; - unsigned long num; + char label[DS_MAX_KEYLEN]; + endpoint_t endpoint; - /* Publish and retrieve. */ - r = ds_publish_label(key_label, 1234, 0); + /* Retrieve own label and endpoint. */ + r = ds_retrieve_label_name(label, getprocnr()); assert(r == OK); - r = ds_retrieve_label_num(key_label, &num); - assert(r == OK && num == 1234); + r = ds_retrieve_label_endpt(label, &endpoint); + assert(r == OK && endpoint == getprocnr()); - /* Here are the differences w.r.t. U32. */ - r = ds_publish_label("hello", 1234, 0); - assert(r == EEXIST); - r = ds_retrieve_label_name(get_label, 1234); - assert(r == OK && strcmp(key_label, get_label) == 0); - - r = ds_delete_label(key_label); - assert(r == OK); + /* Publish and delete. */ + r = ds_publish_label(label, endpoint, 0); + assert(r == EPERM); + r = ds_delete_label(label); + assert(r == EPERM); printf("DSTEST: LABEL test successful!\n"); } diff --git a/test/ds/subs.c b/test/ds/subs.c index f186b9f7a..2cd39bc3e 100644 --- a/test/ds/subs.c +++ b/test/ds/subs.c @@ -41,7 +41,7 @@ int main(void) continue; /* Check which one was changed. */ - r = ds_check(key, &type); + r = ds_check(key, &type, NULL); if(r == ENOENT) { printf("SUBSCRIBER: the key %s was deleted.\n", key);