+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:
PROG= amddev
SRCS= amddev.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBDRIVER} ${LIBSYS}
+LDADD+= -ldriver -lsys
MAN=
Driver for the AMD Device Exclusion Vector (DEV)
*/
-#define _SYSTEM
-#define _MINIX
-
+#include <minix/driver.h>
#include <minix/config.h>
#include <minix/type.h>
{
int r;
message m;
+ int ipc_status;
/* SEF local startup. */
sef_local_startup();
{
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;
printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0));
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
#include <sys/ioc_disk.h>
#include <machine/pci.h>
#include <sys/mman.h>
+#include <sys/svrctl.h>
/* Variables. */
/* Initialize the at_wini driver. */
system_hz = sys_hz();
- init_buffer();
+ driver_init_buffer();
w_identify_wakeup_ticks = WAKEUP_TICKS;
wakeup_ticks = WAKEUP_TICKS;
/* Set special disk parameters. */
init_params();
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
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".
*/
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. */
* unhandled message. queue it and
* handle it in the libdriver loop.
*/
- mq_queue(&m);
+ driver_mq_queue(&m, ipc_status);
}
}
else {
* unhandled message. queue it and handle it in the
* libdriver loop.
*/
- mq_queue(&m);
+ driver_mq_queue(&m, ipc_status);
}
}
} else {
PROG= atl2
SRCS= atl2.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBNETDRIVER} ${LIBSYS}
+LDADD+= -lnetdriver -lsys
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <sys/mman.h>
#include <minix/ds.h>
{
/* Initialize the atl2 driver.
*/
- u32_t inet_endpt;
int r, devind;
#if ATL2_FKEY
int fkeys, sfkeys;
/* 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. */
*===========================================================================*/
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);
/* Driver task.
*/
message m;
+ int ipc_status;
int r;
/* Initialize SEF. */
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);
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"
{
int r, caller;
message mess, repl_mess;
+ int ipc_status;
/* SEF local startup. */
sef_local_startup();
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();
return EIO;
}
irq_hook_set = TRUE; /* now signal handler knows it must unregister policy*/
+
+ /* Announce we are up! */
+ driver_announce();
+
return OK;
}
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 */
}
{
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;
#define AUDIO_FW_H
#include <minix/drivers.h>
+#include <minix/driver.h>
#include <sys/ioc_sound.h>
MAN=
+LIBS += -ldriver
+
BINDIR?= /usr/sbin
.include <minix.prog.mk>
/* best viewed with tabsize=4 */
#include <sys/types.h>
-#include <minix/drivers.h>
#include <sys/ioc_sound.h>
#ifndef ES1371_H
#define ES1371_H
/* best viewed with tabsize=4 */
-
+
+#include "audio_fw.h"
#include <sys/types.h>
-#include <minix/drivers.h>
#include <sys/ioc_sound.h>
#include <minix/sound.h>
env_parse("bios_remap_first", "d", 0, &v, 0, 1);
remap_first = v;
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
PROG= dec21140A
SRCS= dec21140A.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBNETDRIVER} ${LIBSYS}
+LDADD+= -lnetdriver -lsys
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <assert.h>
#include <machine/pci.h>
{
dpeth_t *dep;
message m;
+ int ipc_status;
int r;
/* SEF local startup. */
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;
{
/* 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);
/* Initialize the DEC 21140A driver. */
int r;
int fkeys, sfkeys;
- endpoint_t tasknr;
(progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
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;
}
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=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <stdlib.h>
#include <minix/com.h>
#include <minix/endpoint.h>
+#include <minix/ds.h>
#include <net/hton.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
_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;
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. */
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();
{
/* 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);
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;
(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);
}
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=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <minix/endpoint.h>
+#include <minix/ds.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
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";
PUBLIC int main(int argc, char **argv)
{
message m;
+ int ipc_status;
int rc;
/* SEF local startup. */
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 */
{
/* 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);
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]);
}
#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);
}
PROG= e1000
SRCS= e1000.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lnetdriver -lsys -ltimers
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <stdlib.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
int main(int argc, char *argv[])
{
message m;
+ int ipc_status;
int r;
/* SEF local startup. */
*/
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))
{
{
/* 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);
{
/* Initialize the e1000 driver. */
int r;
- u32_t tasknr;
/* Verify command-line arguments. */
if (env_argc < 1)
{
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);
}
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=
#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;
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);
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);
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",
"threshold, restarting driver\n", which);
#endif
- *tell_rs = 1;
+ *tell_rs = (driver[which].up_event != UP_PENDING);
break;
case BD_DEAD:
/* Restart the given driver. Block until the new instance is up.
*/
message msg;
+ int ipc_status;
endpoint_t endpt;
int r, w = 0;
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();
+ }
}
/*===========================================================================*
* 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 "
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;
+}
+
#include <minix/partition.h>
#include <minix/ds.h>
#include <minix/callnr.h>
+#include <minix/driver.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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.
*/
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);
+
int main(int argc, char *argv[])
{
message m_out;
+ int ipc_status;
int r;
/* SEF local startup. */
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
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;
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);
}
/* 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);
-}
-
if ((s=sys_irqenable(&irq_hook_id)) != OK)
panic("Couldn't enable IRQs: %d", s);
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
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 */
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);
struct floppy *fp = f_fp;
int r;
message mess;
+ int ipc_status;
u8_t cmd[3];
/* Are we already on the correct cylinder? */
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);
pvb_pair_t byte_out[2];
int s,i;
message mess;
+ int ipc_status;
/* Disable interrupts and strobe reset bit low. */
need_reset = FALSE;
* 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);
* 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);
PROG= fxp
SRCS= fxp.c mii.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lnetdriver -lsys -ltimers
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <stdlib.h>
#include <net/hton.h>
int main(int argc, char *argv[])
{
message m;
+ int ipc_status;
int r;
/* 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 HARDWARE:
handle_hw_intr();
{
/* 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);
{
/* Initialize the fxp driver. */
int r;
- u32_t tasknr;
long v;
vir_bytes ft;
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);
}
{
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;
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) {
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;
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. */
PROG= lance
SRCS= lance.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBNETDRIVER} ${LIBSYS}
+LDADD+= -lnetdriver -lsys
MAN=
#define LANCE_FKEY 0 /* Use function key to dump Lance stats */
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <net/hton.h>
#include <net/gen/ether.h>
void main( int argc, char **argv )
{
message m;
+ int ipc_status;
int i,r;
ether_card_t *ec;
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;i<EC_PORT_NR_MAX;++i)
{
sys_irqdisable(&ec->ec_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();
{
/* 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);
{
/* Initialize the lance driver. */
int r;
- u32_t tasknr;
long v;
#if LANCE_FKEY
int fkeys, sfkeys;
(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;
}
PROG= orinoco
SRCS= orinoco.c hermes.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lnetdriver -lsys -ltimers
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <string.h>
#include <minix/syslib.h>
#include <minix/type.h>
*****************************************************************************/
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);
{
/* 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);
{
/* Initialize the orinoco driver. */
int fkeys, sfkeys, r;
- u32_t inet_proc_nr;
system_hz = sys_hz();
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);
}
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=
main.c
*/
-#include <minix/drivers.h>
-
-#include <minix/rs.h>
-#include <minix/endpoint.h>
-
#include "pci.h"
PUBLIC struct pci_acl pci_acl[NR_DRIVERS];
{
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 */
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
*/
-#include <minix/drivers.h>
#include <assert.h>
#include <machine/pci.h>
#include <machine/vm.h>
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
*/
+#include <minix/drivers.h>
+#include <minix/driver.h>
#include <minix/rs.h>
/* tempory functions: to be replaced later (see pci_intel.h) */
PROG= printer
SRCS= printer.c liveupdate.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBDRIVER} ${LIBSYS}
+LDADD+= -ldriver -lsys
MAN=
#include <minix/endpoint.h>
#include <minix/drivers.h>
+#include <minix/driver.h>
/* Control bits (in port_base + 2). "+" means positive logic and "-" means
* negative logic. Most of the signals are negative logic on the pins but
/* 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) );
{
/* 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();
*===========================================================================*/
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);
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 *
*===========================================================================*/
for(i = 0; i < RANDOM_SOURCES; i++)
r_updatebin(i, &krandom.bin[i]);
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
PROG= readclock.drv
SRCS= readclock.c
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBDRIVER} ${LIBSYS}
+LDADD+= -ldriver -lsys
MAN=
PROG= rtl8139
SRCS= rtl8139.c liveupdate.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lnetdriver -lsys -ltimers
MAN=
int main(int argc, char *argv[])
{
int r;
+ int ipc_status;
/* SEF local startup. */
env_setargs(argc, 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:
/*
#if RTL8139_FKEY
int fkeys, sfkeys;
#endif
- u32_t inet_proc_nr;
int r;
re_t *rep;
long v;
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);
}
{
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;
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <stdlib.h>
#include <stdio.h>
PROG= rtl8169
SRCS= rtl8169.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lnetdriver -lsys -ltimers
MAN=
*/
#include <minix/drivers.h>
+#include <minix/netdriver.h>
#include <stdlib.h>
#include <stdio.h>
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:
/*
{
/* 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);
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;
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);
}
void transmittest(re_t *rep)
{
int tx_head;
+ int ipc_status;
tx_head = rep->re_tx_head;
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;
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"
#define SB16_H
#include <minix/drivers.h>
+#include <minix/driver.h>
#include <sys/ioc_sound.h>
#include <minix/sound.h>
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();
panic("initialization failed: CHIP != INTEL: %d", 0);
#endif /* CHIP == INTEL */
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
PRIVATE void dsp_write(const message *m_ptr)
{
message mess;
+ int ipc_status;
dprint("sb16_dsp.c: dsp_write()\n");
} 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);
/* 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. */
* 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;
*===========================================================================*/
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);
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
*=========================================================================*/
PROG= ti1225
SRCS= ti1225.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -ldriver -lsys -ltimers
MAN=
*/
#include <minix/drivers.h>
+#include <minix/driver.h>
#include <machine/pci.h>
#include <machine/vm.h>
{
int r;
message m;
+ int ipc_status;
/* SEF local startup. */
env_setargs(argc, 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);
}
hw_init(&ports[i]);
}
+ /* Announce we are up! */
+ driver_announce();
+
return(OK);
}
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=
*/
#include <minix/drivers.h>
+#include <minix/driver.h>
#include <termios.h>
#include <sys/ioc_tty.h>
#include <signal.h>
/* 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;
}
/* 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.
* 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 */
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
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 \
*/
#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. */
#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 */
#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? */
# 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)
#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 */
#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 */
#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 *
*===========================================================================*/
# 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 *
#include <minix/const.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>
+#include <minix/endpoint.h>
#include <string.h>
#include <limits.h>
#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) );
_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 */
#define _MINIX_DS_H
#include <minix/types.h>
+#include <minix/endpoint.h>
/* Flags. */
#define DSF_IN_USE 0x001 /* entry is in use */
/* DS constants. */
#define DS_MAX_KEYLEN 80 /* Max length of a key, including '\0'. */
+/* DS events. */
+#define DS_DRIVER_UP 1
+
/* ds.c */
/* U32 */
_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 */
typedef struct mq
{
message mq_mess;
+ int mq_mess_status;
struct mq *mq_next;
int mq_allocated;
} mq_t;
--- /dev/null
+/* Prototypes and definitions for network drivers. */
+
+#ifndef _MINIX_NETDRIVER_H
+#define _MINIX_NETDRIVER_H
+
+#include <minix/endpoint.h>
+#include <minix/ipc.h>
+
+/* 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 */
_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
_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));
#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
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));
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 */
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;
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;
/* 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);
- }
+ }
}
}
_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 */
do_vmctl.c \
do_mcontext.c \
do_schedule.c \
- do_schedctl.c
+ do_schedctl.c \
+ do_statectl.c
+
--- /dev/null
+/* 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 */
*===========================================================================*/
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;
}
/*===========================================================================*
.include <minix.own.mk>
-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"
*
* 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 <minix/drivers.h>
#include <sys/ioc_disk.h>
#include <minix/mq.h>
#include <minix/endpoint.h>
#include <minix/driver.h>
+#include <minix/ds.h>
/* 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<next_open_devs_slot;i++) {
+ if(open_devs[i] == device) {
+ open_dev_found = TRUE;
+ break;
+ }
+ }
+
+ return open_dev_found;
+}
+
+/*===========================================================================*
+ * set_open_dev *
+ *===========================================================================*/
+PRIVATE void set_open_dev(int device)
+{
+ if(next_open_devs_slot >= MAX_NR_OPEN_DEVICES) {
+ panic("out of slots for open devices");
+ }
+ open_devs[next_open_devs_slot] = device;
+ next_open_devs_slot++;
+}
/*===========================================================================*
* asyn_reply *
}
}
+/*===========================================================================*
+ * 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 *
*===========================================================================*/
{
/* 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. */
/* 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;
/* 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",
/*===========================================================================*
- * 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
}
/*===========================================================================*
- * 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;
--- /dev/null
+# Makefile for libnetdriver
+
+LIB= netdriver
+
+SRCS= netdriver.c
+
+.include <minix.lib.mk>
--- /dev/null
+/* 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 <minix/drivers.h>
+#include <minix/endpoint.h>
+#include <minix/netdriver.h>
+#include <minix/ds.h>
+
+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;
+}
+
sys_stime.c \
sys_schedule.c \
sys_schedctl.c \
+ sys_statectl.c \
sys_times.c \
sys_trace.c \
sys_umap.c \
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);
}
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;
}
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;
}
{
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;
}
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);
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;
}
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);
+}
+
--- /dev/null
+#include "syslib.h"
+
+PUBLIC int sys_statectl(int request)
+{
+ message m;
+
+ m.CTL_REQUEST = request;
+
+ return _kernel_call(SYS_STATECTL, &m);
+}
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;
{
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;
/* 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);
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;
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:
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) );
PUBLIC void main()
{
mq_t *mq;
+ int ipc_status;
int r;
endpoint_t source;
int m_type;
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));
{
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);
}
}
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);
}
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;
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 */
}
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);
}
}
-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;
}
}
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)
{
/* 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 */
}
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);
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;
}
/* 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. */
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);
cp_grant_id_t label_gid;
size_t label_len;
int r = OK;
- unsigned long tasknr;
endpoint_t driver_e;
int readonly;
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;
/* 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. */
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);
cp_grant_id_t label_gid;
size_t label_len;
int r = OK;
- unsigned long tasknr;
endpoint_t driver_e;
int readonly, isroot;
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. */
/* 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);
* 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 */
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);
/* 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 */
{
/* 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) {
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));
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) {
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);
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. */
{
register struct rproc *rp;
register struct rprocpub *rpub;
- int s, proc;
+ int s;
char label[RS_MAX_LABEL_LEN];
/* Copy label. */
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];
int who_p;
struct rproc *rp;
struct rprocpub *rpub;
- message m;
int result;
who_p = _ENDPOINT_P(m_ptr->m_source);
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;
printf("RS: %s completed restart\n", srv_to_string(rp));
}
- return(EDONTREPLY);
+ return(OK);
}
/*===========================================================================*
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];
#include <minix/sysinfo.h>
#include <minix/bitmap.h>
#include <minix/paths.h>
+#include <minix/sef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <configfile.h>
#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
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);
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);
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];
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);
}
/* 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)
{
int i;
for (i=0; i<NR_DEVICES; i++) {
if(dmap[i].dmap_driver != NONE
- && dmap[i].dmap_driver == proc_e
- && (dmap[i].dmap_flags & DMAP_BABY)) {
- dmap[i].dmap_flags &= ~DMAP_BABY;
+ && dmap[i].dmap_driver == proc_e) {
dev_up(i);
}
}
* entry's current status and determines what control options are possible.
*/
#define DMAP_MUTABLE 0x01 /* mapping can be overtaken */
-#define DMAP_BUSY 0x02 /* driver busy with request */
-#define DMAP_BABY 0x04 /* driver exec() not done yet */
extern struct dmap {
int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
/* This child has now exec()ced. */
rfp->fp_execced = 1;
- /* Check if this is a driver that can now be useful. */
- dmap_endpt_up(rfp->fp_endpoint);
-
return(OK);
}
#include <minix/const.h>
#include <minix/type.h>
#include <minix/dmap.h>
+#include <minix/ds.h>
#include <limits.h>
#include <errno.h>
/* 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. */
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
/* 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);
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);
+}
*===========================================================================*/
PUBLIC int do_mount()
{
- u32_t fs_e;
+ endpoint_t fs_e;
int r, proc_nr;
/* Only the super-user may 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;
}
_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) );
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");
}
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);