From: Cristiano Giuffrida Date: Thu, 8 Apr 2010 13:41:35 +0000 (+0000) Subject: Driver refactory for live update and crash recovery. X-Git-Tag: v3.1.7~169 X-Git-Url: http://zhaoyanbai.com/repos/man.named-checkzone.html?a=commitdiff_plain;h=48c6bb79f4be940126eb319828ab6b25106ab0c1;p=minix.git Driver refactory for live update and crash recovery. SYSLIB CHANGES: - DS calls to publish / retrieve labels consider endpoints instead of u32_t. VFS CHANGES: - mapdriver() only adds an entry in the dmap table in VFS. - dev_up() is only executed upon reception of a driver up event. INET CHANGES: - INET no longer searches for existing drivers instances at startup. - A newtwork driver is (re)initialized upon reception of a driver up event. - Networking startup is now race-free by design. No need to waste 5 seconds at startup any more. DRIVER CHANGES: - Every driver publishes driver up events when starting for the first time or in case of restart when recovery actions must be taken in the upper layers. - Driver up events are published by drivers through DS. - For regular drivers, VFS is normally the only subscriber, but not necessarily. For instance, when the filter driver is in use, it must subscribe to driver up events to initiate recovery. - For network drivers, inet is the only subscriber for now. - Every VFS driver is statically linked with libdriver, every network driver is statically linked with libnetdriver. DRIVER LIBRARIES CHANGES: - Libdriver is extended to provide generic receive() and ds_publish() interfaces for VFS drivers. - driver_receive() is a wrapper for sef_receive() also used in driver_task() to discard spurious messages that were meant to be delivered to a previous version of the driver. - driver_receive_mq() is the same as driver_receive() but integrates support for queued messages. - driver_announce() publishes a driver up event for VFS drivers and marks the driver as initialized and expecting a DEV_OPEN message. - Libnetdriver is introduced to provide similar receive() and ds_publish() interfaces for network drivers (netdriver_announce() and netdriver_receive()). - Network drivers all support live update with no state transfer now. KERNEL CHANGES: - Added kernel call statectl for state management. Used by driver_announce() to unblock eventual callers sendrecing to the driver. --- 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; - - 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); + 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); - 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 == DS_PROC_NR && is_ipc_notify(ipc_status)) { + ds_event(); + continue; + } - if(mess->m_source == CLOCK && is_notify(mess->m_type)) { + 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); - assert(r == OK); - r = ds_retrieve_label_num(key_label, &num); - assert(r == OK && num == 1234); - - /* 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); + /* Retrieve own label and endpoint. */ + r = ds_retrieve_label_name(label, getprocnr()); assert(r == OK); + r = ds_retrieve_label_endpt(label, &endpoint); + assert(r == OK && endpoint == getprocnr()); + + /* 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);