]> Zhao Yanbai Git Server - minix.git/commitdiff
Basic System Event Framework (SEF) with ping and live update.
authorCristiano Giuffrida <cristiano@minix3.org>
Mon, 21 Dec 2009 14:12:21 +0000 (14:12 +0000)
committerCristiano Giuffrida <cristiano@minix3.org>
Mon, 21 Dec 2009 14:12:21 +0000 (14:12 +0000)
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
  1. SEF Ping. The event occurs every time RS sends a ping to figure out
  whether a system process is still alive. The default callback implementation
  provided by SEF is to notify RS back to let it know the process is alive
  and kicking.
  2. SEF Live update. The event occurs every time RS sends a prepare to update
  message to let a system process know an update is available and to prepare
  for it. The live update support is very basic for now. SEF only deals with
  verifying if the prepare state can be supported by the process, dumping the
  state for debugging purposes, and providing an event-driven programming
  model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
  * PM notify messages primarily used at shutdown.
  * SYSTEM notify messages primarily used for signals.
  * CLOCK notify messages used for system alarms.
  * Debug messages. IS could still be in charge of fkey handling but would
  forward the debug message to the target process (e.g. PM, if the user
  requested debug information about PM). SEF would then catch the message and
  do nothing unless the process has registered an appropriate callback to
  deal with the event. This simplifies the programming model to print debug
  information, avoids duplicating code, and reduces the effort to print
  debug information.

SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.

RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
  * When an update command is issued (via "service update *"), RS notifies the
  target system process to prepare for a specific update state.
  * If the process doesn't respond back in time, the update is aborted.
  * When the process responds back, RS kills it and marks it for refreshing.
  * The process is then automatically restarted as for a buggy process and can
  start running again.
  * Live update is currently prototyped as a controlled failure.

76 files changed:
drivers/amddev/amddev.c
drivers/at_wini/Makefile
drivers/at_wini/at_wini.c
drivers/at_wini/at_wini.h
drivers/at_wini/liveupdate.c [new file with mode: 0644]
drivers/audio/es1370/Makefile
drivers/audio/es1371/Makefile
drivers/audio/framework/Makefile
drivers/audio/framework/audio_fw.c
drivers/audio/framework/liveupdate.c [new file with mode: 0644]
drivers/audio/sb16/Makefile
drivers/bios_wini/bios_wini.c
drivers/dp8390/dp8390.c
drivers/dpeth/dp.c
drivers/e1000/e1000.c
drivers/filter/driver.c
drivers/filter/main.c
drivers/floppy/Makefile
drivers/floppy/floppy.c
drivers/floppy/floppy.h
drivers/floppy/liveupdate.c [new file with mode: 0644]
drivers/fxp/fxp.c
drivers/lance/lance.c
drivers/libdriver/driver.c
drivers/log/Makefile
drivers/log/liveupdate.c [new file with mode: 0644]
drivers/log/log.c
drivers/memory/memory.c
drivers/memory/ramdisk/proto
drivers/orinoco/orinoco.c
drivers/pci/main.c
drivers/printer/Makefile
drivers/printer/liveupdate.c [new file with mode: 0644]
drivers/printer/printer.c
drivers/random/main.c
drivers/readclock/readclock.c
drivers/rtl8139/Makefile
drivers/rtl8139/liveupdate.c [new file with mode: 0644]
drivers/rtl8139/rtl8139.c
drivers/rtl8139/rtl8139.h
drivers/rtl8169/rtl8169.c
drivers/sb16/Makefile
drivers/sb16/sb16.h
drivers/sb16/sb16_dsp.c
drivers/sb16/sb16_dsp_liveupdate.c [new file with mode: 0644]
drivers/sb16/sb16_mixer.c
drivers/ti1225/ti1225.c
drivers/tty/tty.c
include/minix/com.h
include/minix/sef.h [new file with mode: 0644]
include/minix/syslib.h
lib/syslib/Makefile.in
lib/syslib/sef.c [new file with mode: 0644]
lib/syslib/sef_liveupdate.c [new file with mode: 0644]
lib/syslib/sef_ping.c [new file with mode: 0644]
servers/ds/main.c
servers/inet/inet.c
servers/ipc/main.c
servers/is/dmp_rs.c
servers/is/main.c
servers/iso9660fs/main.c
servers/mfs/main.c
servers/pfs/main.c
servers/pm/main.c
servers/rs/Makefile
servers/rs/const.h
servers/rs/glo.h
servers/rs/main.c
servers/rs/manager.c
servers/rs/manager.h [deleted file]
servers/rs/proto.h
servers/rs/service.c
servers/rs/type.h
servers/vfs/main.c
servers/vfs/request.c
servers/vm/main.c

index e476551f4f699a55bbe8357981a562a48e3850dd..86267550e7a161f7cecec351f3bc0e3697878dbe 100644 (file)
@@ -63,11 +63,17 @@ static void del_range(u32_t busaddr, u32_t size);
 static int do_pm_notify(message *m);
 static void report_exceptions(void);
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 int main(void)
 {
        int r;
        message m;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        printf("amddev: starting\n");
 
        init();
@@ -76,9 +82,9 @@ int main(void)
        {
                report_exceptions();
 
-               r= receive(ANY, &m);
+               r= sef_receive(ANY, &m);
                if (r != OK)
-                       panic(__FILE__, "receive failed", r);
+                       panic(__FILE__, "sef_receive failed", r);
                if (is_notify(m.m_type)) {
                        if (_ENDPOINT_P(m.m_source) == PM_PROC_NR) {
                                do_pm_notify(&m);
@@ -95,6 +101,19 @@ int main(void)
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 static int init()
 {
        int r, n_maps, n_domains, revision;
index 70f93f9ef9ad6c665554292c9c8157aa73f427ff..333a9459e6c5eedd6dfd77cfbab228b92505a040 100644 (file)
@@ -17,7 +17,7 @@ CFLAGS = -I$i $(CPROFILE)
 LDFLAGS = -i -L../libdriver
 LIBS = -ldriver -lsys -ltimers 
 
-OBJ = at_wini.o 
+OBJ = at_wini.o liveupdate.o
 
 
 # build local binary
index 0179074621e922f622e6fd8f49ba31ed152957f7..23c69b6fc5db0a564e08d9049159711f03f53e90 100644 (file)
 #include <ibm/pci.h>
 #include <sys/mman.h>
 
-#define ATAPI_DEBUG        0   /* To debug ATAPI code. */
-
-/* I/O Ports used by winchester disk controllers. */
-
-/* Read and write registers */
-#define REG_CMD_BASE0  0x1F0   /* command base register of controller 0 */
-#define REG_CMD_BASE1  0x170   /* command base register of controller 1 */
-#define REG_CTL_BASE0  0x3F6   /* control base register of controller 0 */
-#define REG_CTL_BASE1  0x376   /* control base register of controller 1 */
-
-#define PCI_CTL_OFF        2   /* Offset of control registers from BAR2 */
-#define PCI_DMA_2ND_OFF            8   /* Offset of DMA registers from BAR4 for 
-                                * secondary channel
-                                */
-
-#define REG_DATA           0   /* data register (offset from the base reg.) */
-#define REG_PRECOMP        1   /* start of write precompensation */
-#define REG_COUNT          2   /* sectors to transfer */
-#define REG_SECTOR         3   /* sector number */
-#define REG_CYL_LO         4   /* low byte of cylinder number */
-#define REG_CYL_HI         5   /* high byte of cylinder number */
-#define REG_LDH                    6   /* lba, drive and head */
-#define   LDH_DEFAULT          0xA0    /* ECC enable, 512 bytes per sector */
-#define   LDH_LBA              0x40    /* Use LBA addressing */
-#define          LDH_DEV               0x10    /* Drive 1 iff set */
-#define   ldh_init(drive)      (LDH_DEFAULT | ((drive) << 4))
-
-/* Read only registers */
-#define REG_STATUS         7   /* status */
-#define   STATUS_BSY           0x80    /* controller busy */
-#define          STATUS_RDY            0x40    /* drive ready */
-#define          STATUS_WF             0x20    /* write fault */
-#define          STATUS_SC             0x10    /* seek complete (obsolete) */
-#define          STATUS_DRQ            0x08    /* data transfer request */
-#define          STATUS_CRD            0x04    /* corrected data */
-#define          STATUS_IDX            0x02    /* index pulse */
-#define          STATUS_ERR            0x01    /* error */
-#define          STATUS_ADMBSY        0x100    /* administratively busy (software) */
-#define REG_ERROR          1   /* error code */
-#define          ERROR_BB              0x80    /* bad block */
-#define          ERROR_ECC             0x40    /* bad ecc bytes */
-#define          ERROR_ID              0x10    /* id not found */
-#define          ERROR_AC              0x04    /* aborted command */
-#define          ERROR_TK              0x02    /* track zero error */
-#define          ERROR_DM              0x01    /* no data address mark */
-
-/* Write only registers */
-#define REG_COMMAND        7   /* command */
-#define   CMD_IDLE             0x00    /* for w_command: drive idle */
-#define   CMD_RECALIBRATE      0x10    /* recalibrate drive */
-#define   CMD_READ             0x20    /* read data */
-#define   CMD_READ_EXT         0x24    /* read data (LBA48 addressed) */
-#define   CMD_READ_DMA_EXT     0x25    /* read data using DMA (w/ LBA48) */
-#define   CMD_WRITE            0x30    /* write data */
-#define          CMD_WRITE_EXT         0x34    /* write data (LBA48 addressed) */
-#define   CMD_WRITE_DMA_EXT    0x35    /* write data using DMA (w/ LBA48) */
-#define   CMD_READVERIFY       0x40    /* read verify */
-#define   CMD_FORMAT           0x50    /* format track */
-#define   CMD_SEEK             0x70    /* seek cylinder */
-#define   CMD_DIAG             0x90    /* execute device diagnostics */
-#define   CMD_SPECIFY          0x91    /* specify parameters */
-#define   CMD_READ_DMA         0xC8    /* read data using DMA */
-#define   CMD_WRITE_DMA                0xCA    /* write data using DMA */
-#define   ATA_IDENTIFY         0xEC    /* identify drive */
-/* #define REG_CTL             0x206   */ /* control register */
-#define REG_CTL                0       /* control register */
-#define   CTL_NORETRY          0x80    /* disable access retry */
-#define   CTL_NOECC            0x40    /* disable ecc retry */
-#define   CTL_EIGHTHEADS       0x08    /* more than eight heads */
-#define   CTL_RESET            0x04    /* reset controller */
-#define   CTL_INTDISABLE       0x02    /* disable interrupts */
-#define REG_CTL_ALTSTAT 0      /* alternate status register */
-
-/* Identify words */
-#define ID_GENERAL             0x00    /* General configuration information */
-#define                ID_GEN_NOT_ATA          0x8000  /* Not an ATA device */
-#define ID_CAPABILITIES                0x31    /* Capabilities (49)*/
-#define                ID_CAP_LBA              0x0200  /* LBA supported */
-#define                ID_CAP_DMA              0x0100  /* DMA supported */
-#define ID_FIELD_VALIDITY      0x35    /* Field Validity (53) */
-#define                ID_FV_88                0x04    /* Word 88 is valid (UDMA) */
-#define ID_MULTIWORD_DMA       0x3f    /* Multiword DMA (63) */
-#define                ID_MWDMA_2_SEL          0x0400  /* Mode 2 is selected */
-#define                ID_MWDMA_1_SEL          0x0200  /* Mode 1 is selected */
-#define                ID_MWDMA_0_SEL          0x0100  /* Mode 0 is selected */
-#define                ID_MWDMA_2_SUP          0x0004  /* Mode 2 is supported */
-#define                ID_MWDMA_1_SUP          0x0002  /* Mode 1 is supported */
-#define                ID_MWDMA_0_SUP          0x0001  /* Mode 0 is supported */
-#define ID_CSS                 0x53    /* Command Sets Supported (83) */
-#define                ID_CSS_LBA48            0x0400
-#define ID_ULTRA_DMA           0x58    /* Ultra DMA (88) */
-#define                ID_UDMA_5_SEL           0x2000  /* Mode 5 is selected */
-#define                ID_UDMA_4_SEL           0x1000  /* Mode 4 is selected */
-#define                ID_UDMA_3_SEL           0x0800  /* Mode 3 is selected */
-#define                ID_UDMA_2_SEL           0x0400  /* Mode 2 is selected */
-#define                ID_UDMA_1_SEL           0x0200  /* Mode 1 is selected */
-#define                ID_UDMA_0_SEL           0x0100  /* Mode 0 is selected */
-#define                ID_UDMA_5_SUP           0x0020  /* Mode 5 is supported */
-#define                ID_UDMA_4_SUP           0x0010  /* Mode 4 is supported */
-#define                ID_UDMA_3_SUP           0x0008  /* Mode 3 is supported */
-#define                ID_UDMA_2_SUP           0x0004  /* Mode 2 is supported */
-#define                ID_UDMA_1_SUP           0x0002  /* Mode 1 is supported */
-#define                ID_UDMA_0_SUP           0x0001  /* Mode 0 is supported */
-
-/* DMA registers */
-#define DMA_COMMAND            0               /* Command register */
-#define                DMA_CMD_WRITE           0x08    /* PCI bus master writes */
-#define                DMA_CMD_START           0x01    /* Start Bus Master */
-#define DMA_STATUS             2               /* Status register */
-#define                DMA_ST_D1_DMACAP        0x40    /* Drive 1 is DMA capable */
-#define                DMA_ST_D0_DMACAP        0x20    /* Drive 0 is DMA capable */
-#define                DMA_ST_INT              0x04    /* Interrupt */
-#define                DMA_ST_ERROR            0x02    /* Error */
-#define                DMA_ST_BM_ACTIVE        0x01    /* Bus Master IDE Active */
-#define DMA_PRDTP              4               /* PRD Table Pointer */
-
-/* Check for the presence of LBA48 only on drives that are 'big'. */
-#define LBA48_CHECK_SIZE       0x0f000000
-#define LBA_MAX_SIZE           0x0fffffff      /* Highest sector size for
-                                                * regular LBA.
-                                                */
-
-#if ENABLE_ATAPI
-#define   ERROR_SENSE           0xF0    /* sense key mask */
-#define     SENSE_NONE          0x00    /* no sense key */
-#define     SENSE_RECERR        0x10    /* recovered error */
-#define     SENSE_NOTRDY        0x20    /* not ready */
-#define     SENSE_MEDERR        0x30    /* medium error */
-#define     SENSE_HRDERR        0x40    /* hardware error */
-#define     SENSE_ILRQST        0x50    /* illegal request */
-#define     SENSE_UATTN         0x60    /* unit attention */
-#define     SENSE_DPROT         0x70    /* data protect */
-#define     SENSE_ABRT          0xb0    /* aborted command */
-#define     SENSE_MISCOM        0xe0    /* miscompare */
-#define   ERROR_MCR             0x08    /* media change requested */
-#define   ERROR_ABRT            0x04    /* aborted command */
-#define   ERROR_EOM             0x02    /* end of media detected */
-#define   ERROR_ILI             0x01    /* illegal length indication */
-#define REG_FEAT            1   /* features */
-#define   FEAT_OVERLAP          0x02    /* overlap */
-#define   FEAT_DMA              0x01    /* dma */
-#define REG_IRR             2   /* interrupt reason register */
-#define   IRR_REL               0x04    /* release */
-#define   IRR_IO                0x02    /* direction for xfer */
-#define   IRR_COD               0x01    /* command or data */
-#define REG_SAMTAG          3
-#define REG_CNT_LO          4   /* low byte of cylinder number */
-#define REG_CNT_HI          5   /* high byte of cylinder number */
-#define REG_DRIVE           6   /* drive select */
-#endif
-
-#define REG_STATUS          7   /* status */
-#define   STATUS_BSY            0x80    /* controller busy */
-#define   STATUS_DRDY           0x40    /* drive ready */
-#define   STATUS_DMADF          0x20    /* dma ready/drive fault */
-#define   STATUS_SRVCDSC        0x10    /* service or dsc */
-#define   STATUS_DRQ            0x08    /* data transfer request */
-#define   STATUS_CORR           0x04    /* correctable error occurred */
-#define   STATUS_CHECK          0x01    /* check error */
-
-#ifdef ENABLE_ATAPI
-#define   ATAPI_PACKETCMD       0xA0    /* packet command */
-#define   ATAPI_IDENTIFY        0xA1    /* identify drive */
-#define   SCSI_READ10           0x28    /* read from disk */
-#define   SCSI_SENSE            0x03    /* sense request */
-
-#define CD_SECTOR_SIZE         2048    /* sector size of a CD-ROM */
-#endif /* ATAPI */
-
-/* Interrupt request lines. */
-#define NO_IRQ          0      /* no IRQ set yet */
-
-#define ATAPI_PACKETSIZE       12
-#define SENSE_PACKETSIZE       18
+/* Variables. */
 
 /* Common command block */
 struct command {
@@ -216,44 +43,6 @@ struct command {
   u8_t cyl_hi_prev;
 };
 
-/* Error codes */
-#define ERR             (-1)   /* general error */
-#define ERR_BAD_SECTOR  (-2)   /* block marked bad detected */
-
-/* Some controllers don't interrupt, the clock will wake us up. */
-#define WAKEUP_SECS    32                      /* drive may be out for 31 seconds max */
-#define WAKEUP_TICKS   (WAKEUP_SECS*system_hz)
-
-/* Miscellaneous. */
-#define MAX_DRIVES         8
-#define COMPAT_DRIVES      4
-#if _WORD_SIZE > 2
-#define MAX_SECS        256    /* controller can transfer this many sectors */
-#else
-#define MAX_SECS        127    /* but not to a 16 bit process */
-#endif
-#define MAX_ERRORS         4   /* how often to try rd/wt before quitting */
-#define NR_MINORS       (MAX_DRIVES * DEV_PER_DRIVE)
-#define SUB_PER_DRIVE  (NR_PARTITIONS * NR_PARTITIONS)
-#define NR_SUBDEVS     (MAX_DRIVES * SUB_PER_DRIVE)
-#define DELAY_USECS     1000   /* controller timeout in microseconds */
-#define DELAY_TICKS       1    /* controller timeout in ticks */
-#define DEF_TIMEOUT_TICKS      300     /* controller timeout in ticks */
-#define RECOVERY_USECS 500000  /* controller recovery time in microseconds */
-#define RECOVERY_TICKS    30   /* controller recovery time in ticks */
-#define INITIALIZED    0x01    /* drive is initialized */
-#define DEAF           0x02    /* controller must be reset */
-#define SMART          0x04    /* drive supports ATA commands */
-#if ENABLE_ATAPI
-#define ATAPI          0x08    /* it is an ATAPI device */
-#else
-#define ATAPI             0    /* don't bother with ATAPI; optimise out */
-#endif
-#define IDENTIFIED     0x10    /* w_identify done successfully */
-#define IGNORING       0x20    /* w_identify failed once */
-
-#define NO_DMA_VAR     "ata_no_dma"
-
 /* Timeouts and max retries. */
 int timeout_ticks = DEF_TIMEOUT_TICKS, max_errors = MAX_ERRORS;
 long w_standard_timeouts = 0, w_pci_debug = 0, w_instance = 0,
@@ -266,8 +55,6 @@ int w_next_drive = 0;
 
 u32_t system_hz;
 
-/* Variables. */
-
 /* The struct wini is indexed by controller first, then drive (0-3).
  * Controller 0 is always the 'compatability' ide controller, at
  * the fixed locations, whether present or not.
@@ -303,7 +90,7 @@ PRIVATE int w_controller = -1;
 PRIVATE int w_major = -1;
 
 PRIVATE int win_tasknr;                        /* my task number */
-PRIVATE int w_command;                 /* current command in execution */
+PUBLIC int w_command;                  /* current command in execution */
 PRIVATE u8_t w_byteval;                        /* used for SYS_IRQCTL */
 PRIVATE int w_drive;                   /* selected drive */
 PRIVATE int w_controller;              /* selected controller */
@@ -428,14 +215,23 @@ PRIVATE struct driver w_dtab = {
   w_hw_int             /* leftover hardware interrupts */
 };
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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) );
+
 /*===========================================================================*
  *                             at_winchester_task                           *
  *===========================================================================*/
 PUBLIC int main(int argc, char *argv[])
 {
-/* Install signal handlers. Ask PM to transform signal into message. */
   struct sigaction sa;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
+  /* Install signal handlers. Ask PM to transform signal into message. */
   system_hz = sys_hz();
 
   init_buffer();
@@ -456,6 +252,20 @@ PUBLIC int main(int argc, char *argv[])
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             init_params                                  *
  *===========================================================================*/
@@ -2070,8 +1880,8 @@ PRIVATE void w_intr_wait()
         */
        while (w_wn->w_status & (STATUS_ADMBSY|STATUS_BSY)) {
                int rr;
-               if((rr=receive(ANY, &m)) != OK)
-                       panic("at_wini", "receive(ANY) failed", rr);
+               if((rr=sef_receive(ANY, &m)) != OK)
+                       panic("at_wini", "sef_receive(ANY) failed", rr);
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
                                case CLOCK:
@@ -2088,10 +1898,6 @@ PRIVATE void w_intr_wait()
                                        w_wn->w_status= w_status;
                                        ack_irqs(m.NOTIFY_ARG);
                                        break;
-                               case RS_PROC_NR:
-                                       /* RS monitor ping. */
-                                       notify(m.m_source);
-                                       break;
                                default:
                                        /* 
                                         * unhandled message.  queue it and
@@ -2792,3 +2598,4 @@ PRIVATE int at_in(int line, u32_t port, u32_t *value,
         panic(w_name(), "sys_in failed", NO_NUM);
 }
 
+
index 3b0b8d0c4044fce60f54dd0018ddfbb09a3aee97..258f023e633ecb2f273d4a4aa5b467fdb1de0f3e 100644 (file)
@@ -6,3 +6,217 @@ _PROTOTYPE(int main, (int argc, char *argv[]));
 
 #define VERBOSE                   0    /* display identify messages during boot */
 #define ENABLE_ATAPI      1    /* add ATAPI cd-rom support to driver */
+
+#define ATAPI_DEBUG        0   /* To debug ATAPI code. */
+
+/* I/O Ports used by winchester disk controllers. */
+
+/* Read and write registers */
+#define REG_CMD_BASE0  0x1F0   /* command base register of controller 0 */
+#define REG_CMD_BASE1  0x170   /* command base register of controller 1 */
+#define REG_CTL_BASE0  0x3F6   /* control base register of controller 0 */
+#define REG_CTL_BASE1  0x376   /* control base register of controller 1 */
+
+#define PCI_CTL_OFF        2   /* Offset of control registers from BAR2 */
+#define PCI_DMA_2ND_OFF            8   /* Offset of DMA registers from BAR4 for 
+                                * secondary channel
+                                */
+
+#define REG_DATA           0   /* data register (offset from the base reg.) */
+#define REG_PRECOMP        1   /* start of write precompensation */
+#define REG_COUNT          2   /* sectors to transfer */
+#define REG_SECTOR         3   /* sector number */
+#define REG_CYL_LO         4   /* low byte of cylinder number */
+#define REG_CYL_HI         5   /* high byte of cylinder number */
+#define REG_LDH                    6   /* lba, drive and head */
+#define   LDH_DEFAULT          0xA0    /* ECC enable, 512 bytes per sector */
+#define   LDH_LBA              0x40    /* Use LBA addressing */
+#define          LDH_DEV               0x10    /* Drive 1 iff set */
+#define   ldh_init(drive)      (LDH_DEFAULT | ((drive) << 4))
+
+/* Read only registers */
+#define REG_STATUS         7   /* status */
+#define   STATUS_BSY           0x80    /* controller busy */
+#define          STATUS_RDY            0x40    /* drive ready */
+#define          STATUS_WF             0x20    /* write fault */
+#define          STATUS_SC             0x10    /* seek complete (obsolete) */
+#define          STATUS_DRQ            0x08    /* data transfer request */
+#define          STATUS_CRD            0x04    /* corrected data */
+#define          STATUS_IDX            0x02    /* index pulse */
+#define          STATUS_ERR            0x01    /* error */
+#define          STATUS_ADMBSY        0x100    /* administratively busy (software) */
+#define REG_ERROR          1   /* error code */
+#define          ERROR_BB              0x80    /* bad block */
+#define          ERROR_ECC             0x40    /* bad ecc bytes */
+#define          ERROR_ID              0x10    /* id not found */
+#define          ERROR_AC              0x04    /* aborted command */
+#define          ERROR_TK              0x02    /* track zero error */
+#define          ERROR_DM              0x01    /* no data address mark */
+
+/* Write only registers */
+#define REG_COMMAND        7   /* command */
+#define   CMD_IDLE             0x00    /* for w_command: drive idle */
+#define   CMD_RECALIBRATE      0x10    /* recalibrate drive */
+#define   CMD_READ             0x20    /* read data */
+#define   CMD_READ_EXT         0x24    /* read data (LBA48 addressed) */
+#define   CMD_READ_DMA_EXT     0x25    /* read data using DMA (w/ LBA48) */
+#define   CMD_WRITE            0x30    /* write data */
+#define          CMD_WRITE_EXT         0x34    /* write data (LBA48 addressed) */
+#define   CMD_WRITE_DMA_EXT    0x35    /* write data using DMA (w/ LBA48) */
+#define   CMD_READVERIFY       0x40    /* read verify */
+#define   CMD_FORMAT           0x50    /* format track */
+#define   CMD_SEEK             0x70    /* seek cylinder */
+#define   CMD_DIAG             0x90    /* execute device diagnostics */
+#define   CMD_SPECIFY          0x91    /* specify parameters */
+#define   CMD_READ_DMA         0xC8    /* read data using DMA */
+#define   CMD_WRITE_DMA                0xCA    /* write data using DMA */
+#define   ATA_IDENTIFY         0xEC    /* identify drive */
+/* #define REG_CTL             0x206   */ /* control register */
+#define REG_CTL                0       /* control register */
+#define   CTL_NORETRY          0x80    /* disable access retry */
+#define   CTL_NOECC            0x40    /* disable ecc retry */
+#define   CTL_EIGHTHEADS       0x08    /* more than eight heads */
+#define   CTL_RESET            0x04    /* reset controller */
+#define   CTL_INTDISABLE       0x02    /* disable interrupts */
+#define REG_CTL_ALTSTAT 0      /* alternate status register */
+
+/* Identify words */
+#define ID_GENERAL             0x00    /* General configuration information */
+#define                ID_GEN_NOT_ATA          0x8000  /* Not an ATA device */
+#define ID_CAPABILITIES                0x31    /* Capabilities (49)*/
+#define                ID_CAP_LBA              0x0200  /* LBA supported */
+#define                ID_CAP_DMA              0x0100  /* DMA supported */
+#define ID_FIELD_VALIDITY      0x35    /* Field Validity (53) */
+#define                ID_FV_88                0x04    /* Word 88 is valid (UDMA) */
+#define ID_MULTIWORD_DMA       0x3f    /* Multiword DMA (63) */
+#define                ID_MWDMA_2_SEL          0x0400  /* Mode 2 is selected */
+#define                ID_MWDMA_1_SEL          0x0200  /* Mode 1 is selected */
+#define                ID_MWDMA_0_SEL          0x0100  /* Mode 0 is selected */
+#define                ID_MWDMA_2_SUP          0x0004  /* Mode 2 is supported */
+#define                ID_MWDMA_1_SUP          0x0002  /* Mode 1 is supported */
+#define                ID_MWDMA_0_SUP          0x0001  /* Mode 0 is supported */
+#define ID_CSS                 0x53    /* Command Sets Supported (83) */
+#define                ID_CSS_LBA48            0x0400
+#define ID_ULTRA_DMA           0x58    /* Ultra DMA (88) */
+#define                ID_UDMA_5_SEL           0x2000  /* Mode 5 is selected */
+#define                ID_UDMA_4_SEL           0x1000  /* Mode 4 is selected */
+#define                ID_UDMA_3_SEL           0x0800  /* Mode 3 is selected */
+#define                ID_UDMA_2_SEL           0x0400  /* Mode 2 is selected */
+#define                ID_UDMA_1_SEL           0x0200  /* Mode 1 is selected */
+#define                ID_UDMA_0_SEL           0x0100  /* Mode 0 is selected */
+#define                ID_UDMA_5_SUP           0x0020  /* Mode 5 is supported */
+#define                ID_UDMA_4_SUP           0x0010  /* Mode 4 is supported */
+#define                ID_UDMA_3_SUP           0x0008  /* Mode 3 is supported */
+#define                ID_UDMA_2_SUP           0x0004  /* Mode 2 is supported */
+#define                ID_UDMA_1_SUP           0x0002  /* Mode 1 is supported */
+#define                ID_UDMA_0_SUP           0x0001  /* Mode 0 is supported */
+
+/* DMA registers */
+#define DMA_COMMAND            0               /* Command register */
+#define                DMA_CMD_WRITE           0x08    /* PCI bus master writes */
+#define                DMA_CMD_START           0x01    /* Start Bus Master */
+#define DMA_STATUS             2               /* Status register */
+#define                DMA_ST_D1_DMACAP        0x40    /* Drive 1 is DMA capable */
+#define                DMA_ST_D0_DMACAP        0x20    /* Drive 0 is DMA capable */
+#define                DMA_ST_INT              0x04    /* Interrupt */
+#define                DMA_ST_ERROR            0x02    /* Error */
+#define                DMA_ST_BM_ACTIVE        0x01    /* Bus Master IDE Active */
+#define DMA_PRDTP              4               /* PRD Table Pointer */
+
+/* Check for the presence of LBA48 only on drives that are 'big'. */
+#define LBA48_CHECK_SIZE       0x0f000000
+#define LBA_MAX_SIZE           0x0fffffff      /* Highest sector size for
+                                                * regular LBA.
+                                                */
+
+#if ENABLE_ATAPI
+#define   ERROR_SENSE           0xF0    /* sense key mask */
+#define     SENSE_NONE          0x00    /* no sense key */
+#define     SENSE_RECERR        0x10    /* recovered error */
+#define     SENSE_NOTRDY        0x20    /* not ready */
+#define     SENSE_MEDERR        0x30    /* medium error */
+#define     SENSE_HRDERR        0x40    /* hardware error */
+#define     SENSE_ILRQST        0x50    /* illegal request */
+#define     SENSE_UATTN         0x60    /* unit attention */
+#define     SENSE_DPROT         0x70    /* data protect */
+#define     SENSE_ABRT          0xb0    /* aborted command */
+#define     SENSE_MISCOM        0xe0    /* miscompare */
+#define   ERROR_MCR             0x08    /* media change requested */
+#define   ERROR_ABRT            0x04    /* aborted command */
+#define   ERROR_EOM             0x02    /* end of media detected */
+#define   ERROR_ILI             0x01    /* illegal length indication */
+#define REG_FEAT            1   /* features */
+#define   FEAT_OVERLAP          0x02    /* overlap */
+#define   FEAT_DMA              0x01    /* dma */
+#define REG_IRR             2   /* interrupt reason register */
+#define   IRR_REL               0x04    /* release */
+#define   IRR_IO                0x02    /* direction for xfer */
+#define   IRR_COD               0x01    /* command or data */
+#define REG_SAMTAG          3
+#define REG_CNT_LO          4   /* low byte of cylinder number */
+#define REG_CNT_HI          5   /* high byte of cylinder number */
+#define REG_DRIVE           6   /* drive select */
+#endif
+
+#define REG_STATUS          7   /* status */
+#define   STATUS_BSY            0x80    /* controller busy */
+#define   STATUS_DRDY           0x40    /* drive ready */
+#define   STATUS_DMADF          0x20    /* dma ready/drive fault */
+#define   STATUS_SRVCDSC        0x10    /* service or dsc */
+#define   STATUS_DRQ            0x08    /* data transfer request */
+#define   STATUS_CORR           0x04    /* correctable error occurred */
+#define   STATUS_CHECK          0x01    /* check error */
+
+#if ENABLE_ATAPI
+#define   ATAPI_PACKETCMD       0xA0    /* packet command */
+#define   ATAPI_IDENTIFY        0xA1    /* identify drive */
+#define   SCSI_READ10           0x28    /* read from disk */
+#define   SCSI_SENSE            0x03    /* sense request */
+
+#define CD_SECTOR_SIZE         2048    /* sector size of a CD-ROM */
+#endif /* ATAPI */
+
+/* Interrupt request lines. */
+#define NO_IRQ          0      /* no IRQ set yet */
+
+#define ATAPI_PACKETSIZE       12
+#define SENSE_PACKETSIZE       18
+
+/* Error codes */
+#define ERR             (-1)   /* general error */
+#define ERR_BAD_SECTOR  (-2)   /* block marked bad detected */
+
+/* Some controllers don't interrupt, the clock will wake us up. */
+#define WAKEUP_SECS    32                      /* drive may be out for 31 seconds max */
+#define WAKEUP_TICKS   (WAKEUP_SECS*system_hz)
+
+/* Miscellaneous. */
+#define MAX_DRIVES         8
+#define COMPAT_DRIVES      4
+#if _WORD_SIZE > 2
+#define MAX_SECS        256    /* controller can transfer this many sectors */
+#else
+#define MAX_SECS        127    /* but not to a 16 bit process */
+#endif
+#define MAX_ERRORS         4   /* how often to try rd/wt before quitting */
+#define NR_MINORS       (MAX_DRIVES * DEV_PER_DRIVE)
+#define SUB_PER_DRIVE  (NR_PARTITIONS * NR_PARTITIONS)
+#define NR_SUBDEVS     (MAX_DRIVES * SUB_PER_DRIVE)
+#define DELAY_USECS     1000   /* controller timeout in microseconds */
+#define DELAY_TICKS       1    /* controller timeout in ticks */
+#define DEF_TIMEOUT_TICKS      300     /* controller timeout in ticks */
+#define RECOVERY_USECS 500000  /* controller recovery time in microseconds */
+#define RECOVERY_TICKS    30   /* controller recovery time in ticks */
+#define INITIALIZED    0x01    /* drive is initialized */
+#define DEAF           0x02    /* controller must be reset */
+#define SMART          0x04    /* drive supports ATA commands */
+#if ENABLE_ATAPI
+#define ATAPI          0x08    /* it is an ATAPI device */
+#else
+#define ATAPI             0    /* don't bother with ATAPI; optimise out */
+#endif
+#define IDENTIFIED     0x10    /* w_identify done successfully */
+#define IGNORING       0x20    /* w_identify failed once */
+
+#define NO_DMA_VAR     "ata_no_dma"
+
diff --git a/drivers/at_wini/liveupdate.c b/drivers/at_wini/liveupdate.c
new file mode 100644 (file)
index 0000000..1887368
--- /dev/null
@@ -0,0 +1,78 @@
+#include "at_wini.h"
+
+/* State management variables. */
+EXTERN int w_command;
+
+/* State management helpers. */
+#define IS_REQUEST_PENDING(c)           ((c) != CMD_IDLE)
+#define IS_READ_PENDING(c)              ((c) == CMD_READ \
+    || (c) == CMD_READ_EXT || (c) == CMD_READ_DMA || (c) == CMD_READ_DMA_EXT)
+#define IS_WRITE_PENDING(c)             ((c) == CMD_WRITE \
+    || (c) == CMD_WRITE_EXT || (c) == CMD_WRITE_DMA || (c) == CMD_WRITE_DMA_EXT)
+
+/* Custom states definition. */
+#define AT_STATE_READ_REQUEST_FREE      (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define AT_STATE_WRITE_REQUEST_FREE     (SEF_LU_STATE_CUSTOM_BASE + 1)
+#define AT_STATE_IS_CUSTOM(s) \
+    ((s) >= AT_STATE_READ_REQUEST_FREE && (s) <= AT_STATE_WRITE_REQUEST_FREE)
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!IS_REQUEST_PENDING(w_command));
+      break;
+
+      /* Custom states. */
+      case AT_STATE_READ_REQUEST_FREE:
+          is_ready = (!IS_READ_PENDING(w_command));
+      break;
+
+      case AT_STATE_WRITE_REQUEST_FREE:
+          is_ready = (!IS_WRITE_PENDING(w_command));
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || AT_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  sef_lu_dprint("at_wini: live update state = %d\n", state);
+  sef_lu_dprint("at_wini: w_command = 0x%02X\n", w_command);
+
+  sef_lu_dprint("at_wini: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("at_wini: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, (!IS_REQUEST_PENDING(w_command)));
+  sef_lu_dprint("at_wini: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!IS_REQUEST_PENDING(w_command)));
+  sef_lu_dprint("at_wini: AT_STATE_READ_REQUEST_FREE(%d) reached = %d\n", 
+      AT_STATE_READ_REQUEST_FREE, (!IS_READ_PENDING(w_command)));
+  sef_lu_dprint("at_wini: AT_STATE_WRITE_REQUEST_FREE(%d) reached = %d\n", 
+      AT_STATE_WRITE_REQUEST_FREE, (!IS_WRITE_PENDING(w_command)));
+}
+
index d10121df6460ec69dee1ba57e1169f924a590221..828a415ca658ac037788eb136cb4159c7f16fdd7 100644 (file)
@@ -17,11 +17,11 @@ LIBS = -lsys
 # build local binary
 all:   es1370
 
-es1370:        es1370.o ak4531.o audio_fw.o pci_helper.o
-       $(CC) -o $@ $(LDFLAGS) es1370.o ak4531.o audio_fw.o pci_helper.o $(LIBS)
+es1370:        es1370.o ak4531.o audio_fw.o liveupdate.o pci_helper.o
+       $(CC) -o $@ $(LDFLAGS) es1370.o ak4531.o audio_fw.o liveupdate.o pci_helper.o $(LIBS)
 
-audio_fw.o: ../framework/audio_fw.c ../framework/audio_fw.h
-       $(CC) -c ../framework/audio_fw.c
+audio_fw.o liveupdate.o: ../framework/audio_fw.c ../framework/liveupdate.c ../framework/audio_fw.h
+       $(CC) -c ../framework/audio_fw.c ../framework/liveupdate.c
        
 install: /usr/sbin/es1370
 /usr/sbin/es1370:      es1370
index ae7d5faf155f4d67138c05afd761dd919079142e..db5df78a34d5155d3a385d93a24319892cece843 100644 (file)
@@ -15,7 +15,7 @@ LIBS  = -lsys
 
 PROGRAM_NAME   = es1371
 INSTALL_BIN            = /usr/sbin/$(PROGRAM_NAME)
-OBJ                            = es1371.o AC97.o audio_fw.o pci_helper.o wait.o sample_rate_converter.o
+OBJ                            = es1371.o AC97.o audio_fw.o liveupdate.o pci_helper.o wait.o sample_rate_converter.o
 
 
 
@@ -27,8 +27,8 @@ $(PROGRAM_NAME): $(OBJ)
        $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
 
 
-audio_fw.o: ../framework/audio_fw.c ../framework/audio_fw.h
-       $(CC) -c ../framework/audio_fw.c
+audio_fw.o liveupdate.o: ../framework/audio_fw.c ../framework/liveupdate.c ../framework/audio_fw.h
+       $(CC) -c ../framework/audio_fw.c ../framework/liveupdate.c
        
 
 %.o: %.c
index 4273ada8c7988c1e8f60f23623400a458f83283d..c210c8d134aecea943fdfef8b6a51a453af7da76 100644 (file)
@@ -1,9 +1,9 @@
 CC =   exec cc
 
-all:   audio_fw.o
+all:   audio_fw.o liveupdate.o
 
-audio_fw.o:
-       $(CC) -c audio_fw.c
+audio_fw.o liveupdate.o:
+       $(CC) -c audio_fw.c liveupdate.c
 
 clean:
-       rm -f a.out *.bak core errs audio_fw.o
+       rm -f a.out *.bak core errs audio_fw.o liveupdate.o
index 70c7c1bf83ae76dc11439020e0865dd3ad073f7d..84951eb7ce84bcf03e92ca2e762002fe7756df7f 100644 (file)
@@ -77,19 +77,28 @@ PRIVATE int irq_hook_id = 0;        /* id of irq hook at the kernel */
 PRIVATE int irq_hook_set = FALSE;
 PRIVATE device_available = 0;/*todo*/
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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) );
+PUBLIC int is_status_msg_expected = FALSE;
 
 PUBLIC void main(void) 
 {      
        int r, caller, proc_nr, chan;
        message mess, repl_mess;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        drv_init();
 
        /* Here is the main loop of the dma driver.  It waits for a message, 
           carries it out, and sends a reply. */
 
        while(1) {
-               receive(ANY, &mess);
+               sef_receive(ANY, &mess);
                caller = mess.m_source;
                proc_nr = mess.IO_ENDPT;
 
@@ -102,10 +111,6 @@ PUBLIC void main(void)
                                case PM_PROC_NR:
                                        msg_sig_stop();
                                        break;
-                               case RS_PROC_NR:
-                                       /* Got ping from RS. Just notify RS */
-                                       notify(RS_PROC_NR);
-                                       break;
                                default:
                                        dprint("%s: %d uncaught notify!\n",
                                                drv.DriverName, mess.m_type);
@@ -175,6 +180,19 @@ PUBLIC void main(void)
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
 
 PRIVATE int init_driver(void) {
        u32_t i; char irq;
@@ -589,6 +607,7 @@ PRIVATE void msg_status(message *m_ptr)
                        sub_dev[i].ReadyToRevive = FALSE;
                        sub_dev[i].RevivePending = 0;
 
+                       is_status_msg_expected = TRUE;
                        return; /* stop after one mess, 
                                           file system will get back for other processes */
                }
@@ -596,6 +615,7 @@ PRIVATE void msg_status(message *m_ptr)
        m_ptr->m_type = DEV_NO_STATUS;
        m_ptr->REP_STATUS = 0;
        send(m_ptr->m_source, m_ptr);                   /* send DEV_NO_STATUS message */
+       is_status_msg_expected = FALSE;
 }
 
 
diff --git a/drivers/audio/framework/liveupdate.c b/drivers/audio/framework/liveupdate.c
new file mode 100644 (file)
index 0000000..dc85467
--- /dev/null
@@ -0,0 +1,117 @@
+#include "audio_fw.h"
+
+/* State management variables. */
+EXTERN int is_status_msg_expected;
+/*
+ * - From audio_fw.h:
+ * EXTERN drv_t drv;
+ * EXTERN sub_dev_t sub_dev[];
+*/
+
+/* State management helpers */
+PRIVATE int is_read_pending;
+PRIVATE int is_write_pending;
+PRIVATE void load_state_info(void)
+{
+  int i, dma_mode, found_pending;
+
+  /* Check if reads or writes are pending. */
+  is_read_pending = FALSE;
+  is_write_pending = FALSE;
+  found_pending = FALSE;
+  for (i = 0; i < drv.NrOfSubDevices && !found_pending; i++) {
+      if(sub_dev[i].RevivePending) {
+          dma_mode = sub_dev[i].DmaMode;
+
+          if(dma_mode = DEV_READ_S) {
+              is_read_pending = TRUE;
+          }
+          else if (dma_mode = DEV_WRITE_S){
+              is_write_pending = TRUE;
+          }
+      }
+
+      found_pending = (is_read_pending && is_write_pending);
+  }
+}
+
+/* Custom states definition. */
+#define AUDIO_STATE_READ_REQUEST_FREE   (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define AUDIO_STATE_WRITE_REQUEST_FREE  (SEF_LU_STATE_CUSTOM_BASE + 1)
+#define AUDIO_STATE_IS_CUSTOM(s) \
+  ((s) >= AUDIO_STATE_READ_REQUEST_FREE && (s) <=AUDIO_STATE_WRITE_REQUEST_FREE)
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Load state information. */
+  load_state_info();
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+          is_ready = (!is_read_pending && !is_write_pending);
+      break;
+
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!is_read_pending && !is_write_pending
+              && !is_status_msg_expected);
+      break;
+
+      /* Custom states. */
+      case AUDIO_STATE_READ_REQUEST_FREE:
+          is_ready = (!is_read_pending);
+      break;
+
+      case AUDIO_STATE_WRITE_REQUEST_FREE:
+          is_ready = (!is_write_pending);
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || AUDIO_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  /* Load state information. */
+  load_state_info();
+
+  sef_lu_dprint("audio: live update state = %d\n", state);
+  sef_lu_dprint("audio: is_status_msg_expected = %d\n",
+      is_status_msg_expected);
+  sef_lu_dprint("audio: is_read_pending = %d\n", is_read_pending);
+  sef_lu_dprint("audio: is_write_pending = %d\n", is_write_pending);
+
+  sef_lu_dprint("audio: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("audio: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, (!is_read_pending && !is_write_pending));
+  sef_lu_dprint("audio: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!is_read_pending && !is_write_pending
+      && !is_status_msg_expected));
+  sef_lu_dprint("audio: AUDIO_STATE_READ_REQUEST_FREE(%d) reached = %d\n", 
+      AUDIO_STATE_READ_REQUEST_FREE, (!is_read_pending));
+  sef_lu_dprint("audio: AUDIO_STATE_WRITE_REQUEST_FREE(%d) reached = %d\n", 
+      AUDIO_STATE_WRITE_REQUEST_FREE, (!is_write_pending));
+}
+
index 2b2591f333aa9030353b6c47c50bcf598693222a..ae892173d5e2051e6d523f954714bfe7fd0bc7d8 100644 (file)
@@ -18,11 +18,11 @@ LIBS = -lsys
 # build local binary
 all build:     sb16    
 
-sb16:  sb16.o mixer.o audio_fw.o
-       $(CC) -o $@ $(LDFLAGS) sb16.o mixer.o audio_fw.o $(LIBS)
+sb16:  sb16.o mixer.o audio_fw.o liveupdate.o
+       $(CC) -o $@ $(LDFLAGS) sb16.o mixer.o audio_fw.o liveupdate.o $(LIBS)
 
-audio_fw.o:    ../framework/audio_fw.c ../framework/audio_fw.h
-       $(CC) -c ../framework/audio_fw.c
+audio_fw.o liveupdate.o: ../framework/audio_fw.c ../framework/liveupdate.c ../framework/audio_fw.h
+       $(CC) -c ../framework/audio_fw.c ../framework/liveupdate.c
 
 # install with other drivers
 install:       /usr/sbin/sb16
index b8e4cce40471c4d5b4280ac5fa8083d5be9cf597..c14ce12dacf82d5bb0a1706083a9385d8865c105 100644 (file)
@@ -94,6 +94,9 @@ PRIVATE struct driver w_dtab = {
   NULL                 /* leftover hardware interrupts */
 };
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             bios_winchester_task                         *
  *===========================================================================*/
@@ -101,6 +104,9 @@ PUBLIC int main()
 {
   long v;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   v= 0;
   env_parse("bios_remap_first", "d", 0, &v, 0, 1);
   remap_first= v;
@@ -110,6 +116,19 @@ PUBLIC int main()
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             w_prepare                                    *
  *===========================================================================*/
@@ -512,3 +531,4 @@ message *m;
         return EINVAL;
 }
 
+
index cce2c0ab818850caf783de31c87cfab6fbda02c5..9dfac7d633db3d98b79452b4a0712087cb3f13f5 100644 (file)
@@ -232,6 +232,9 @@ PRIVATE int handle_hw_intr(void)
        return r;
 }
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             dpeth_task                                   *
  *===========================================================================*/
@@ -242,6 +245,9 @@ int main(int argc, char *argv[])
        dpeth_t *dep;
        long v;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        system_hz = sys_hz();
 
        if (argc < 1)
@@ -270,14 +276,11 @@ int main(int argc, char *argv[])
 
        while (TRUE)
        {
-               if ((r= receive(ANY, &m)) != OK)
-                       panic("", "dp8390: receive failed", r);
+               if ((r= sef_receive(ANY, &m)) != OK)
+                       panic("", "dp8390: sef_receive failed", r);
 
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
-                               case RS_PROC_NR:
-                                       notify(m.m_source);
-                                       break;
                                case HARDWARE:
                                        r = handle_hw_intr();
                                        break;
@@ -323,6 +326,17 @@ int main(int argc, char *argv[])
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 #if 0
 /*===========================================================================*
  *                             dp8390_dump                                  *
index afbb73861493eeea66497a7d0e99f25107c662fb..7de00b47403a65cc709180b731f51cced85424f2 100644 (file)
@@ -86,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[] = "receive failed";
+static char RecvErrMsg[] = "sef_receive failed";
 static char SendErrMsg[] = "send failed";
 static char SizeErrMsg[] = "illegal packet size";
 static char TypeErrMsg[] = "illegal message type";
@@ -577,6 +577,9 @@ PRIVATE void handle_hw_intr(void)
        }
 }
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*
 **  Name:      int dpeth_task(void)
 **  Function:  Main entry for dp task
@@ -587,6 +590,9 @@ PUBLIC int main(int argc, char **argv)
   dpeth_t *dep;
   int rc, fkeys, sfkeys, tasknr;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
 
   env_setargs(argc, argv);
@@ -612,7 +618,7 @@ PUBLIC int main(int argc, char **argv)
        notify(tasknr);
 
   while (TRUE) {
-       if ((rc = receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc);
+       if ((rc = sef_receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc);
 
        DEBUG(printf("eth: got message %d, ", m.m_type));
 
@@ -622,10 +628,6 @@ PUBLIC int main(int argc, char **argv)
                                /* to be defined */
                                do_watchdog(&m);
                                break;
-                       case RS_PROC_NR:        
-                               /* Status request from RS */
-                               notify(m.m_source);
-                               break;
                        case HARDWARE:
                                /* Interrupt from device */
                                handle_hw_intr();
@@ -673,4 +675,15 @@ PUBLIC int main(int argc, char **argv)
   return OK;                   /* Never reached, but keeps compiler happy */
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /** dp.c **/
index 3e9c887e2a9b64ada51a71ba44f8de3045866e35..22c5a4ebb35330a4a00a59039e66e84b38766bcd 100644 (file)
@@ -62,6 +62,9 @@ _PROTOTYPE( PRIVATE int eeprom_ich_cycle, (e1000_t *e, u32_t timeout)   );
 _PROTOTYPE( PRIVATE void reply, (e1000_t *e, int err, int may_block)   );
 _PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply)    );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -73,6 +76,9 @@ int main(int argc, char *argv[])
     e1000_t *e;
     long v;
 
+    /* SEF local startup. */
+    sef_local_startup();
+
     /* Verify command-line arguments. */
     if (argc < 1)
     {
@@ -104,18 +110,14 @@ int main(int argc, char *argv[])
      */
     while (TRUE)
     {
-       if ((r= receive(ANY, &m)) != OK)
+       if ((r= sef_receive(ANY, &m)) != OK)
        {
-           panic("e1000", "receive failed", r);
+           panic("e1000", "sef_receive failed", r);
        }
        if (is_notify(m.m_type))
        {
            switch (_ENDPOINT_P(m.m_source))
            {
-                case RS_PROC_NR:
-                    notify(m.m_source);
-                    break;
-               
                 case HARDWARE:
                    e1000_interrupt(&m);
                    break;
@@ -143,6 +145,17 @@ int main(int argc, char *argv[])
     }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             e1000_init                                   *
  *===========================================================================*/
index 97e095850b718bf3a8627e30714ba31f57e9ae61..e840308f2ae9c92238ba5d2afada6ea18fb35f22 100644 (file)
@@ -583,9 +583,9 @@ static int flt_receive(message *mess, int which)
        int r;
 
        for (;;) {
-               r = receive(ANY, mess);
+               r = sef_receive(ANY, mess);
                if(r != OK)
-                       panic(__FILE__, "receive returned error", r);
+                       panic(__FILE__, "sef_receive returned error", r);
 
                if(mess->m_source == CLOCK && is_notify(mess->m_type)) {
                        if (mess->NOTIFY_TIMESTAMP < flt_alarm(-1)) {
index 0813ecd84a462bc8e1ea1ee8c4cd0f802f32ecbf..a973f1a3b3b69ebb6b70e4a35960d1c1b8aee18e 100644 (file)
@@ -376,6 +376,9 @@ static void got_signal(void)
        exit(0);
 }
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -384,6 +387,9 @@ int main(int argc, char *argv[])
        message m_out;
        int r;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        r = parse_arguments(argc, argv);
        if(r != OK) {
                printf("Filter: wrong argument!\n");
@@ -399,8 +405,8 @@ int main(int argc, char *argv[])
 
        for (;;) {
                /* Wait for request. */
-               if(receive(ANY, &m_in) != OK) {
-                       panic(__FILE__, "receive failed", NO_NUM);
+               if(sef_receive(ANY, &m_in) != OK) {
+                       panic(__FILE__, "sef_receive failed", NO_NUM);
                }
 
 #if DEBUG2
@@ -444,3 +450,15 @@ int main(int argc, char *argv[])
 
        return 0;
 }
+
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
index 07dcf18fd42d8045ab5eb11b6e219a963276345f..e690291fdb09ff19618fbbd1ac251cf46732dda9 100644 (file)
@@ -16,7 +16,7 @@ CFLAGS = -I$i $(CPROFILE)
 LDFLAGS = -i -L../libdriver
 LIBS = -ldriver -lsys  -ltimers
 
-OBJ = floppy.o 
+OBJ = floppy.o liveupdate.o
 
 # build local binary
 all build:     $(DRIVER)
index 27c7215e017a3d878746a8531c90d686ec25b8b3..3788d8a3dd7d84ac8841a1b0268cac96576e301e 100644 (file)
@@ -29,6 +29,7 @@
 #include <minix/sysutil.h>
 #include <minix/syslib.h>
 #include <minix/endpoint.h>
+#include <stdio.h>
 
 /* I/O Ports used by floppy disk task. */
 #define DOR            0x3F2   /* motor drive control bits */
@@ -219,15 +220,15 @@ PRIVATE struct floppy {           /* main drive struct, one entry per drive */
 } floppy[NR_DRIVES];
 
 PRIVATE int irq_hook_id;       /* id of irq hook at the kernel */
-PRIVATE int motor_status;      /* bitmap of current motor status */
+PUBLIC int motor_status;       /* bitmap of current motor status */
 PRIVATE int need_reset;                /* set to 1 when controller must be reset */
-PRIVATE unsigned f_drive;      /* selected drive */
+PUBLIC unsigned f_drive;       /* selected drive */
 PRIVATE unsigned f_device;     /* selected minor device */
 PRIVATE struct floppy *f_fp;   /* current drive */
 PRIVATE struct density *f_dp;  /* current density parameters */
 PRIVATE struct density *prev_dp;/* previous density parameters */
 PRIVATE unsigned f_sectors;    /* equal to f_dp->secpt (needed a lot) */
-PRIVATE u16_t f_busy;          /* BSY_IDLE, BSY_IO, BSY_WAKEN */
+PUBLIC u16_t f_busy;           /* BSY_IDLE, BSY_IO, BSY_WAKEN */
 PRIVATE struct device *f_dv;   /* device's base and size */
 PRIVATE struct disk_parameter_s fmt_param; /* parameters for format */
 PRIVATE u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */
@@ -289,16 +290,25 @@ PRIVATE struct driver f_dtab = {
 static char *floppy_buf;
 static phys_bytes floppy_buf_phys;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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) );
+PUBLIC int last_transfer_opcode;
+
 /*===========================================================================*
  *                             floppy_task                                  *
  *===========================================================================*/
 PUBLIC void main()
 {
-/* Initialize the floppy structure and the timers. */
-
   struct floppy *fp;
   int s;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
+  /* Initialize the floppy structure and the timers. */
   system_hz = sys_hz();
 
   if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE,
@@ -330,6 +340,20 @@ PUBLIC void main()
   driver_task(&f_dtab, DRIVER_STD);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             f_expire_tmrs                                *
  *===========================================================================*/
@@ -469,6 +493,9 @@ unsigned nr_req;            /* length of request vector */
        return OK;      /* Way beyond EOF */
   position= cv64ul(pos64);
 
+  /* Record the opcode of the last transfer performed. */
+  last_transfer_opcode = opcode;
+
   /* Check disk address. */
   if ((position & SECTOR_MASK) != 0) return(EINVAL);
 
@@ -759,16 +786,13 @@ PRIVATE void start_motor()
   f_set_timer(&f_tmr_timeout, f_dp->start_ms * system_hz / 1000, f_timeout);
   f_busy = BSY_IO;
   do {
-       receive(ANY, &mess); 
+       sef_receive(ANY, &mess); 
 
        if (is_notify(mess.m_type)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
                                f_expire_tmrs(NULL, NULL);
                                break;
-                       case RS_PROC_NR:
-                               notify(mess.m_source);
-                               break;
                        default :
                                f_busy = BSY_IDLE;
                                break;
@@ -851,16 +875,13 @@ PRIVATE int seek()
        f_set_timer(&f_tmr_timeout, system_hz/30, f_timeout);
        f_busy = BSY_IO;
        do {
-               receive(ANY, &mess); 
+               sef_receive(ANY, &mess); 
        
                if (is_notify(mess.m_type)) {
                        switch (_ENDPOINT_P(mess.m_source)) {
                                case CLOCK:
                                        f_expire_tmrs(NULL, NULL);
                                        break;
-                               case RS_PROC_NR:
-                                       notify(mess.m_source);
-                                       break;
                                default :
                                        f_busy = BSY_IDLE;
                                        break;
@@ -1133,15 +1154,12 @@ PRIVATE void f_reset()
    * but be prepared to handle a timeout.
    */
   do {
-       receive(ANY, &mess); 
+       sef_receive(ANY, &mess); 
        if (is_notify(mess.m_type)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
                                f_expire_tmrs(NULL, NULL);
                                break;
-                       case RS_PROC_NR:
-                               notify(mess.m_source);
-                               break;
                        default :
                                f_busy = BSY_IDLE;
                                break;
@@ -1185,15 +1203,12 @@ PRIVATE int f_intr_wait()
 
   /* We expect an interrupt, but if a timeout, occurs, report an error. */
   do {
-       receive(ANY, &mess); 
+       sef_receive(ANY, &mess); 
        if (is_notify(mess.m_type)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
                                f_expire_tmrs(NULL, NULL);
                                break;
-                       case RS_PROC_NR:
-                               notify(mess.m_source);
-                               break;
                        default :
                                f_busy = BSY_IDLE;
                                break;
@@ -1365,3 +1380,4 @@ struct partition *entry;
   entry->sectors = f_sectors;
 }
 
+
index b1c64ccf1f55c3e5e62952adcf34ce11a9062c38..6d737ab7e8bbcb50296c0ec0c57a536415a4fd89 100644 (file)
@@ -4,3 +4,4 @@
 
 _PROTOTYPE(void main, (void));
 
+
diff --git a/drivers/floppy/liveupdate.c b/drivers/floppy/liveupdate.c
new file mode 100644 (file)
index 0000000..0d4d142
--- /dev/null
@@ -0,0 +1,81 @@
+#include "floppy.h"
+
+/* State management variables. */
+EXTERN u16_t f_busy;
+EXTERN int motor_status;
+EXTERN unsigned f_drive;
+EXTERN int last_transfer_opcode;
+#define BSY_IO      1   /* busy doing I/O */
+
+/* State management helpers. */
+#define IS_REQUEST_PENDING(b)           ((b) == BSY_IO)
+#define IS_READ_PENDING(b, c) \
+    (IS_REQUEST_PENDING((b)) && (c) == DEV_GATHER_S)
+#define IS_WRITE_PENDING(b, c) \
+    (IS_REQUEST_PENDING((b)) && (c) == DEV_SCATTER_S)
+#define IS_MOTOR_RUNNING(s, d)          ((s) & (1 << (d)))
+
+/* Custom states definition. */
+#define FL_STATE_MOTOR_OFF              (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define FL_STATE_IS_CUSTOM(s)   ((s) == FL_STATE_MOTOR_OFF)
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!IS_REQUEST_PENDING(f_busy));
+      break;
+
+      /* Custom states. */
+      case FL_STATE_MOTOR_OFF:
+          is_ready = (!IS_REQUEST_PENDING(f_busy)
+              && !IS_MOTOR_RUNNING(motor_status, f_drive));
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || FL_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  sef_lu_dprint("floppy: live update state = %d\n", state);
+  sef_lu_dprint("floppy: f_busy = %d\n", f_busy);
+  sef_lu_dprint("floppy: motor_status = 0x%02X\n", motor_status);
+  sef_lu_dprint("floppy: f_drive = %d\n", f_drive);
+  sef_lu_dprint("floppy: last_transfer_opcode = 0x%02X\n",
+      last_transfer_opcode);
+
+  sef_lu_dprint("floppy: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n",
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("floppy: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n",
+      SEF_LU_STATE_REQUEST_FREE, (!IS_REQUEST_PENDING(f_busy)));
+  sef_lu_dprint("floppy: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n",
+      SEF_LU_STATE_PROTOCOL_FREE, (!IS_REQUEST_PENDING(f_busy)));
+  sef_lu_dprint("floppy: FL_STATE_MOTOR_OFF(%d) reached = %d\n",
+      FL_STATE_MOTOR_OFF, (!IS_REQUEST_PENDING(f_busy)
+      && !IS_MOTOR_RUNNING(motor_status, f_drive)));
+}
+
index 78ff9fbbc0191c688b7583a45494d6a693c1d901..576f2f27be97461b19bba220b0f6e622496200c7 100644 (file)
@@ -301,6 +301,9 @@ PRIVATE void handle_hw_intr(void)
        }
 }
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -312,6 +315,9 @@ int main(int argc, char *argv[])
        long v;
        vir_bytes ft = sizeof(*fxp_table)*FXP_PORT_NR;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        system_hz = sys_hz();
 
        if (argc < 1)
@@ -342,14 +348,11 @@ int main(int argc, char *argv[])
 
        while (TRUE)
        {
-               if ((r= receive(ANY, &m)) != OK)
-                       panic("FXP","receive failed", r);
+               if ((r= sef_receive(ANY, &m)) != OK)
+                       panic("FXP","sef_receive failed", r);
 
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
-                               case RS_PROC_NR:
-                                       notify(m.m_source);
-                                       break;
                                case HARDWARE:
                                        handle_hw_intr();
                                        break;
@@ -393,6 +396,17 @@ int main(int argc, char *argv[])
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             fxp_init                                     *
  *===========================================================================*/
index 38c22f46caad3381cda4028683785036b9ae460e..5975f9a3d12f731c514bdc5ca16635f546f3c8fe 100644 (file)
@@ -264,7 +264,10 @@ static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
 static char *progname;
 
 phys_bytes lance_buf_phys;
+
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                              main                                         *
  *===========================================================================*/
@@ -279,6 +282,9 @@ void main( int argc, char **argv )
    int fkeys, sfkeys;
 #endif
 
+   /* SEF local startup. */
+   sef_local_startup();
+
    (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
 
    env_setargs( argc, argv );
@@ -310,9 +316,9 @@ void main( int argc, char **argv )
             sys_irqenable(&ec->ec_hook);
       }
 
-      if ((r= receive(ANY, &m)) != OK)
-         panic( "lance", "receive failed", r);
-
+      if ((r= sef_receive(ANY, &m)) != OK)
+        panic( "lance", "sef_receive failed", r);
+        
       for (i=0;i<EC_PORT_NR_MAX;++i)
       {
          ec= &ec_table[i];
@@ -322,9 +328,6 @@ void main( int argc, char **argv )
 
       if (is_notify(m.m_type)) {
              switch(_ENDPOINT_P(m.m_source)) {
-                     case RS_PROC_NR:
-                             notify(m.m_source);
-                             break;
                      case TTY_PROC_NR:
                              lance_dump();
                              break;
@@ -388,6 +391,17 @@ void main( int argc, char **argv )
    }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                              lance_dump                                   *
  *===========================================================================*/
index 5c394b445689c94a4ad4a694885e367698e9399f..770e6f6d3db14325d2229e955f3a5e7b5b609461 100644 (file)
@@ -145,8 +145,8 @@ int type;           /* Driver type (DRIVER_STD or DRIVER_ASYN) */
        } else {
                int s;
                /* Wait for a request to read or write a disk block. */
-               if ((s=receive(ANY, &mess)) != OK)
-                       panic((*dp->dr_name)(),"receive() failed", s);
+               if ((s=sef_receive(ANY, &mess)) != OK)
+                       panic((*dp->dr_name)(),"sef_receive() failed", s);
        }
 
        device_caller = mess.m_source;
@@ -172,9 +172,6 @@ int type;           /* Driver type (DRIVER_STD or DRIVER_ASYN) */
                        case CLOCK:
                                (*dp->dr_alarm)(dp, &mess);     
                                break;
-                       case RS_PROC_NR:
-                               notify(mess.m_source);
-                               break;
                        default:                
                                if(dp->dr_other)
                                        r = (*dp->dr_other)(dp, &mess);
index e7ebfb6c29a507fbfe2bcf266017ff17eae9ec29..eecdc5e69ea2c2cbf0522f1254840d8cb4561a2c 100644 (file)
@@ -16,7 +16,7 @@ LDFLAGS = -i -L../libdriver
 LIBS = -ldriver  -lsys 
 LIB_DEP = ../libdriver/libdriver.a
 
-OBJ = log.o diag.o
+OBJ = log.o diag.o liveupdate.o
 
 # build local binary
 all build:     $(DRIVER)
diff --git a/drivers/log/liveupdate.c b/drivers/log/liveupdate.c
new file mode 100644 (file)
index 0000000..793b415
--- /dev/null
@@ -0,0 +1,101 @@
+#include "log.h"
+
+/* State management variables. */
+#define NR_DEVS     1   /* number of minor devices */
+EXTERN struct logdevice logdevices[NR_DEVS];
+
+/* State management helpers. */
+PRIVATE int is_read_pending;
+PRIVATE int is_select_callback_pending;
+PRIVATE void load_state_info(void)
+{
+  int i, found_pending;
+  struct logdevice *log;
+
+  /* Check if reads or select callbacks are pending. */
+  is_read_pending = FALSE;
+  is_select_callback_pending = FALSE;
+  found_pending = FALSE;
+  for (i = 0; i < NR_DEVS && !found_pending; i++) {
+      log = &logdevices[i];
+      if(log->log_proc_nr) {
+          is_read_pending = TRUE;
+      }
+      if(log->log_selected) {
+          is_select_callback_pending = TRUE;
+      }
+
+      found_pending = (is_read_pending && is_select_callback_pending);
+  }
+}
+
+/* Custom states definition. */
+#define LOG_STATE_SELECT_PROTOCOL_FREE  (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define LOG_STATE_IS_CUSTOM(s)  ((s) == LOG_STATE_SELECT_PROTOCOL_FREE)
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Load state information. */
+  load_state_info();
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+          is_ready = (!is_read_pending);
+      break;
+
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!is_read_pending && !is_select_callback_pending);
+      break;
+
+      /* Custom states. */
+      case LOG_STATE_SELECT_PROTOCOL_FREE:
+          is_ready = (!is_select_callback_pending);
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || LOG_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  /* Load state information. */
+  load_state_info();
+
+  sef_lu_dprint("log: live update state = %d\n", state);
+  sef_lu_dprint("log: is_read_pending = %d\n", is_read_pending);
+  sef_lu_dprint("log: is_select_callback_pending = %d\n",
+      is_select_callback_pending);
+
+  sef_lu_dprint("log: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("log: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, (!is_read_pending));
+  sef_lu_dprint("log: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!is_read_pending
+      && !is_select_callback_pending));
+  sef_lu_dprint("log: LOG_STATE_SELECT_PROTOCOL_FREE(%d) reached = %d\n", 
+      LOG_STATE_SELECT_PROTOCOL_FREE, (!is_select_callback_pending));
+}
+
index 5edf5d4aa6ef44eccfa7bc970363973b7092cff5..7009526d5efb28036073c2425ce3a2d238988c6f 100644 (file)
@@ -54,12 +54,23 @@ PRIVATE struct driver log_dtab = {
 
 extern int device_caller;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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                                      *
  *===========================================================================*/
 PUBLIC int main(void)
 {
   int i;
+
+  /* SEF local startup. */
+  sef_local_startup();
+
+  /* Initialize log devices. */
   for(i = 0; i < NR_DEVS; i++) {
        log_geom[i].dv_size = cvul64(LOG_SIZE);
        log_geom[i].dv_base = cvul64((long)logdevices[i].log_buffer);
@@ -76,7 +87,21 @@ PUBLIC int main(void)
 }
 
 /*===========================================================================*
- *                              log_name                                            *
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
+/*===========================================================================*
+ *                              log_name                                    *
  *===========================================================================*/
 PRIVATE char *log_name()
 {
@@ -462,3 +487,4 @@ message *m_ptr;
 
   return(ready_ops);
 }
+
index 24896659b9e3f5ed40438a471a8ead38adab1062..0c33ed831bc0108ee1ba64d1d538d266bae34908 100644 (file)
@@ -83,6 +83,9 @@ PRIVATE char dev_zero[ZERO_BUF_SIZE];
 #define click_to_round_k(n) \
        ((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                                main                                      *
  *===========================================================================*/
@@ -91,6 +94,9 @@ PUBLIC int main(void)
 /* Main program. Initialize the memory driver and start the main loop. */
   struct sigaction sa;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   sa.sa_handler = SIG_MESS;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = 0;
@@ -101,6 +107,19 @@ PUBLIC int main(void)
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                              m_name                                      *
  *===========================================================================*/
@@ -469,3 +488,4 @@ struct partition *entry;
   entry->heads = 64;
   entry->sectors = 32;
 }
+
index bd21e6d88758dd523294085b6a1e7765cd3dcb7d..9547833cd008f11c1c736faf437e6dd3e131ba48 100644 (file)
@@ -1,5 +1,5 @@
 boot 
-175 400
+200 400
 d--755 0 0
        bin d--755 0 0
                at_wini ---755 0 0 at_wini
index 8d8268a1107501ec440600ac9e74f1e47c53387f..4b3105ce511a18701851a8e292187e3e5325fa61 100644 (file)
@@ -236,6 +236,9 @@ u32_t system_hz;
 static char *progname;
 extern int errno;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*****************************************************************************
  *            main                                                           *
  *                                                                           *
@@ -248,6 +251,9 @@ int main(int argc, char *argv[]) {
        long v = 0;
        t_or *orp;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        system_hz = sys_hz();
 
        (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
@@ -269,14 +275,11 @@ int main(int argc, char *argv[]) {
                printf("orinoco: ds_retrieve_u32 failed for 'inet': %d\n", r);
 
        while (TRUE) {
-               if ((r = receive (ANY, &m)) != OK)
-                       panic(__FILE__, "orinoco: receive failed", NO_NUM);
+               if ((r = sef_receive (ANY, &m)) != OK)
+                       panic(__FILE__, "orinoco: sef_receive failed", NO_NUM);
 
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
-                               case RS_PROC_NR: 
-                                       notify(m.m_source);     
-                                       break;
                                case CLOCK:
                                        or_watchdog_f(NULL);     
                                        break;           
@@ -346,6 +349,17 @@ int main(int argc, char *argv[]) {
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*****************************************************************************
  *                    check_int_events                                       *
  *                                                                           *
index 1cf529f481c5e00fa0ac650f919ea841c8d8dc6c..fecbef64499e4108e8825b9d89f9d059eaa233ba 100644 (file)
@@ -41,19 +41,25 @@ FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint)         );
 
 extern int debug;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 int main(void)
 {
        int i, r;
        message m;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        pci_init();
 
        for(;;)
        {
-               r= receive(ANY, &m);
+               r= sef_receive(ANY, &m);
                if (r < 0)
                {
-                       printf("PCI: receive from ANY failed: %d\n", r);
+                       printf("PCI: sef_receive from ANY failed: %d\n", r);
                        break;
                }
 
@@ -101,6 +107,19 @@ int main(void)
        return 0;
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 PRIVATE void do_init(mp)
 message *mp;
 {
index 7e3228fb4975acf3323f58f8a703fc5519020721..b3a9d8c7f0b0b0ad6fd35457039658e3f6cd8e5d 100644 (file)
@@ -13,9 +13,9 @@ d = ..
 CC =   exec cc
 CFLAGS = -I$i $(CPROFILE)
 LDFLAGS = -i
-LIBS =  -lsys   -lsys
+LIBS =  -lsys
 
-OBJ = printer.o
+OBJ = printer.o liveupdate.o
 
 # build local binary
 all build:     $(DRIVER)
diff --git a/drivers/printer/liveupdate.c b/drivers/printer/liveupdate.c
new file mode 100644 (file)
index 0000000..b65d61b
--- /dev/null
@@ -0,0 +1,69 @@
+#include "../drivers.h"
+
+/* State management variables. */
+EXTERN int writing;
+EXTERN int is_status_msg_expected;
+
+/* Custom states definition. */
+#define PR_STATE_WRITE_PROTOCOL_FREE    (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define PR_STATE_IS_CUSTOM(s)   ((s) == PR_STATE_WRITE_PROTOCOL_FREE)
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+          is_ready = TRUE;
+      break;
+
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!writing && !is_status_msg_expected);
+      break;
+
+      /* Custom states. */
+      case PR_STATE_WRITE_PROTOCOL_FREE:
+          is_ready = (!writing);
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || PR_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  sef_lu_dprint("printer: live update state = %d\n", state);
+  sef_lu_dprint("printer: writing = %d\n", writing);
+  sef_lu_dprint("printer: is_status_msg_expected = %d\n",
+      is_status_msg_expected);
+
+  sef_lu_dprint("printer: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("printer: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, TRUE);
+  sef_lu_dprint("printer: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!writing && !is_status_msg_expected));
+  sef_lu_dprint("printer: PR_STATE_WRITE_PROTOCOL_FREE(%d) reached = %d\n", 
+      PR_STATE_WRITE_PROTOCOL_FREE, (!writing));
+}
+
index 00ec2e469ed12b8ac252c237a6ebcba56798ff7a..e61153d5f2bb3adc71e62f52d8aebe28511c1af8 100644 (file)
@@ -100,7 +100,7 @@ PRIVATE int user_left;              /* bytes of output left in user buf */
 PRIVATE vir_bytes user_vir_g;  /* start of user buf (address or grant) */
 PRIVATE vir_bytes user_vir_d;  /* offset in user buf */
 PRIVATE int user_safe;         /* address or grant? */
-PRIVATE int writing;           /* nonzero while write is in progress */
+PUBLIC int writing;            /* nonzero while write is in progress */
 PRIVATE int irq_hook_id;       /* id of irq hook at kernel */
 
 extern int errno;              /* error number */
@@ -115,6 +115,12 @@ FORWARD _PROTOTYPE( void reply, (int code,int replyee,int proc,int status));
 FORWARD _PROTOTYPE( void do_printer_output, (void) );
 FORWARD _PROTOTYPE( void do_signal, (void) );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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) );
+PUBLIC int is_status_msg_expected = FALSE;
 
 /*===========================================================================*
  *                             printer_task                                 *
@@ -126,6 +132,9 @@ PUBLIC void main(void)
   struct sigaction sa;
   int s;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Install signal handlers. Ask PM to transform signal into message. */
   sa.sa_handler = SIG_MESS;
   sigemptyset(&sa.sa_mask);
@@ -133,16 +142,13 @@ PUBLIC void main(void)
   if (sigaction(SIGTERM,&sa,NULL)<0) panic("PRN","sigaction failed", errno);
   
   while (TRUE) {
-       receive(ANY, &pr_mess);
+       sef_receive(ANY, &pr_mess);
 
        if (is_notify(pr_mess.m_type)) {
                switch (_ENDPOINT_P(pr_mess.m_source)) {
                        case HARDWARE:
                                do_printer_output();
                                break;
-                       case RS_PROC_NR:
-                               notify(pr_mess.m_source);
-                               break;
                        case PM_PROC_NR:
                                do_signal();
                                break;
@@ -169,6 +175,19 @@ PUBLIC void main(void)
   }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
 
 /*===========================================================================*
  *                              do_signal                                   *
@@ -275,6 +294,7 @@ PRIVATE void output_done()
     else {                             /* done! report back to FS */
        status = orig_count;
     }
+    is_status_msg_expected = TRUE;
     revive_pending = TRUE;
     revive_status = status;
     notify(caller);
@@ -296,6 +316,8 @@ register message *m_ptr;    /* pointer to the newly arrived message */
        revive_pending = FALSE;                 /* unmark event */
   } else {
        m_ptr->m_type = DEV_NO_STATUS;
+       
+       is_status_msg_expected = FALSE;
   }
   send(m_ptr->m_source, m_ptr);                        /* send the message */
 }
index 13a4830fd3e23f8f83bb52c190a4eccde5e70dff..97024a80628163336463dbb0362875bd8878350c 100644 (file)
@@ -54,16 +54,35 @@ PRIVATE struct driver r_dtab = {
 #define RANDOM_BUF_SIZE                1024
 PRIVATE char random_buf[RANDOM_BUF_SIZE];
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                                main                                      *
  *===========================================================================*/
 PUBLIC int main(void)
 {
+  /* SEF local startup. */
+  sef_local_startup();
+
   r_init();                            /* initialize the memory driver */
   driver_task(&r_dtab, DRIVER_ASYN);   /* start driver's main loop */
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                              r_name                                      *
  *===========================================================================*/
index b2cb6b2dace8a5ae70bfc1e22756680a63538bbf..f52fb49386e150aef1f2ee1568833b915510b011 100644 (file)
@@ -49,6 +49,7 @@
 #include <time.h>
 #include <errno.h>
 #include <signal.h>
+#include <minix/const.h>
 #include <minix/type.h>
 #include <minix/syslib.h>
 #include <minix/com.h>
@@ -87,6 +88,9 @@ int bcd_to_dec(int n);
 int dec_to_bcd(int n);
 void usage(void);
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 int main(int argc, char **argv)
 {
   struct tm time1;
@@ -98,6 +102,9 @@ int main(int argc, char **argv)
   unsigned char mach_id, cmos_state;
   struct sysgetenv sysgetenv;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   if((s=sys_readbios(MACH_ID_ADDR, &mach_id, sizeof(mach_id))) != OK) {
        printf("readclock: sys_readbios failed: %d.\n", s);
        exit(1);
@@ -212,6 +219,15 @@ int main(int argc, char **argv)
   exit(0);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 void errmsg(char *s)
 {
   static char *prompt = "readclock: ";
index 0e6d2bb112a6b85a592f3bee2ed83b0abd488d6a..36c1faeee03f8e695e407c89fa5418aa1e51f604 100644 (file)
@@ -16,7 +16,7 @@ CFLAGS = -I$i $(CPROFILE)
 LDFLAGS = -i
 LIBS = -lsys   -ltimers 
 
-OBJ = rtl8139.o 
+OBJ = rtl8139.o liveupdate.o
 
 # build local binary
 all build:     $(DRIVER)
diff --git a/drivers/rtl8139/liveupdate.c b/drivers/rtl8139/liveupdate.c
new file mode 100644 (file)
index 0000000..19e0641
--- /dev/null
@@ -0,0 +1,108 @@
+#include "rtl8139.h"
+
+/* State management variables. */
+EXTERN re_t re_table[RE_PORT_NR];
+
+/* Custom states definition. */
+#define RL_STATE_READ_PROTOCOL_FREE     (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define RL_STATE_WRITE_PROTOCOL_FREE    (SEF_LU_STATE_CUSTOM_BASE + 1)
+#define RL_STATE_IS_CUSTOM(s) \
+    ((s) >= RL_STATE_READ_PROTOCOL_FREE && (s) <= RL_STATE_WRITE_PROTOCOL_FREE)
+
+/* State management helpers. */
+PRIVATE int is_reading;
+PRIVATE int is_writing;
+PRIVATE void load_state_info(void)
+{
+  int i, found_processing;
+  re_t *rep;
+
+  /* Check if we are reading or writing. */
+  is_reading = FALSE;
+  is_writing = FALSE;
+  found_processing = FALSE;
+  for (i= 0; i<RE_PORT_NR && !found_processing; i++) {
+      rep = &re_table[i];
+
+      if (rep->re_flags & REF_READING) {
+          is_reading = TRUE;
+      }
+
+      if (rep->re_flags & REF_SEND_AVAIL) {
+          is_writing = TRUE;
+      }
+
+      found_processing = (is_reading && is_writing);
+  }
+}
+
+/*===========================================================================*
+ *                              sef_cb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Load state information. */
+  load_state_info();
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+          is_ready = TRUE;
+      break;
+
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!is_reading && !is_writing);
+      break;
+
+      /* Custom states. */
+      case RL_STATE_READ_PROTOCOL_FREE:
+          is_ready = (!is_reading);
+      break;
+
+      case RL_STATE_WRITE_PROTOCOL_FREE:
+          is_ready = (!is_writing);
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || RL_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  /* Load state information. */
+  load_state_info();
+
+  sef_lu_dprint("rtl8139: live update state = %d\n", state);
+  sef_lu_dprint("rtl8139: is_reading = %d\n", is_reading);
+  sef_lu_dprint("rtl8139: is_writing = %d\n", is_writing);
+
+  sef_lu_dprint("rtl8139: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("rtl8139: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, TRUE);
+  sef_lu_dprint("rtl8139: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!is_reading && !is_writing));
+  sef_lu_dprint("rtl8139: RL_STATE_READ_PROTOCOL_FREE(%d) reached = %d\n", 
+      RL_STATE_READ_PROTOCOL_FREE, (!is_reading));
+  sef_lu_dprint("rtl8139: RL_STATE_WRITE_PROTOCOL_FREE(%d) reached = %d\n", 
+      RL_STATE_WRITE_PROTOCOL_FREE, (!is_writing));
+}
+
index e736972ea3e0034a0a6a8d13b8c7a1dbf6fe4d9e..d4b91d771a2f13fe5cc411c7a648e73281aee495 100644 (file)
  *
  */
 
-#include "../drivers.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <minix/com.h>
-#include <minix/ds.h>
-#include <minix/keymap.h>
-#include <minix/syslib.h>
-#include <minix/type.h>
-#include <minix/sysutil.h>
-#include <minix/endpoint.h>
-#include <timers.h>
-#include <net/hton.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-#include <ibm/pci.h>
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/ioc_memory.h>
-#include "../../kernel/const.h"
-#include "../../kernel/config.h"
-#include "../../kernel/type.h"
-
-#define tmra_ut                        timer_t
-#define tmra_inittimer(tp)     tmr_inittimer(tp)
-#define Proc_number(p)         proc_number(p)
-#define debug                  0
-#define printW()               ((void)0)
-#define vm_1phys2bus(p)                (p)
-
-#define VERBOSE                1       /* display message during init */
-
 #include "rtl8139.h"
 
-#define RX_BUFSIZE     RL_RCR_RBLEN_64K_SIZE
-#define RX_BUFBITS     RL_RCR_RBLEN_64K
-#define N_TX_BUF       RL_N_TX
-
-#define RE_PORT_NR     1               /* Minix */
-
-/* I/O vectors are handled IOVEC_NR entries at a time. */
-#define IOVEC_NR       16
-
-/* Configuration */
-#define RL_ENVVAR      "RTLETH"
-
 PRIVATE struct pcitab
 {
        u16_t vid;
@@ -136,70 +87,7 @@ PRIVATE struct pcitab
        { 0x0000, 0x0000, 0 }
 };
 
-typedef struct re
-{
-       port_t re_base_port;
-       int re_irq;
-       int re_mode;
-       int re_flags;
-       int re_client;
-       int re_link_up;
-       int re_got_int;
-       int re_send_int;
-       int re_report_link;
-       int re_clear_rx;
-       int re_need_reset;
-       int re_tx_alive;
-       char *re_model;
-
-       /* Rx */
-       phys_bytes re_rx_buf;
-       char  *v_re_rx_buf;
-       vir_bytes re_read_s;
-
-       /* Tx */
-       int re_tx_head;
-       int re_tx_tail;
-       struct
-       {
-               int ret_busy;
-               phys_bytes ret_buf;
-               char * v_ret_buf;
-       } re_tx[N_TX_BUF];
-       u32_t re_ertxth;        /* Early Tx Threshold */
-
-       /* PCI related */
-       int re_seen;                    /* TRUE iff device available */
-       u8_t re_pcibus; 
-       u8_t re_pcidev; 
-       u8_t re_pcifunc;        
-
-       /* 'large' items */
-       int re_hook_id;                 /* IRQ hook id at kernel */
-       eth_stat_t re_stat;
-       ether_addr_t re_address;
-       message re_rx_mess;
-       message re_tx_mess;
-       char re_name[sizeof("rtl8139#n")];
-       iovec_t re_iovec[IOVEC_NR];
-       iovec_s_t re_iovec_s[IOVEC_NR];
-}
-re_t;
-
-#define REM_DISABLED   0x0
-#define REM_ENABLED    0x1
-
-#define REF_PACK_SENT  0x001
-#define REF_PACK_RECV  0x002
-#define REF_SEND_AVAIL 0x004
-#define REF_READING    0x010
-#define REF_EMPTY      0x000
-#define REF_PROMISC    0x040
-#define REF_MULTI      0x080
-#define REF_BROAD      0x100
-#define REF_ENABLED    0x200
-
-static re_t re_table[RE_PORT_NR];
+PUBLIC re_t re_table[RE_PORT_NR];
 
 static u16_t eth_ign_proto;
 static tmra_ut rl_watchdog;
@@ -303,6 +191,12 @@ static char *progname;
 extern int errno;
 u32_t system_hz;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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                                 *
  *===========================================================================*/
@@ -314,6 +208,9 @@ int main(int argc, char *argv[])
        re_t *rep;
        long v;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        system_hz = sys_hz();
 
        (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
@@ -345,14 +242,11 @@ int main(int argc, char *argv[])
 
        while (TRUE)
        {
-               if ((r= receive(ANY, &m)) != OK)
-                       panic("rtl8139","receive failed", r);
+               if ((r= sef_receive(ANY, &m)) != OK)
+                       panic("rtl8139","sef_receive failed", r);
 
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
-                               case RS_PROC_NR:
-                                       notify(m.m_source);
-                                       break;
                                case CLOCK:
                                        /* 
                                         * Under MINIX, synchronous alarms are
@@ -418,6 +312,20 @@ int main(int argc, char *argv[])
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             check_int_events                             *
  *===========================================================================*/
index 7613ec6e1c6a46853c59a5ce422ed1ca8f21d499..218be4b5cb36383ba696fc9ff1b1f7039f23abc3 100644 (file)
@@ -4,6 +4,34 @@ ibm/rtl8139.h
 Created:       Aug 2003 by Philip Homburg <philip@cs.vu.nl>
 */
 
+#include "../drivers.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <minix/com.h>
+#include <minix/ds.h>
+#include <minix/keymap.h>
+#include <minix/syslib.h>
+#include <minix/type.h>
+#include <minix/sysutil.h>
+#include <minix/endpoint.h>
+#include <timers.h>
+#include <net/hton.h>
+#include <net/gen/ether.h>
+#include <net/gen/eth_io.h>
+#include <ibm/pci.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/ioc_memory.h>
+#include "../../kernel/const.h"
+#include "../../kernel/config.h"
+#include "../../kernel/type.h"
+
 #define        RL_IDR          0x00    /* Ethernet address
                                 * Note: RL_9346CR_EEM_CONFIG mode is
                                 * required the change the ethernet
@@ -424,6 +452,90 @@ d8 R/W     Config5         Configuration register 5
 d9-ff                          reserved
 #endif
 
+#define tmra_ut                        timer_t
+#define tmra_inittimer(tp)     tmr_inittimer(tp)
+#define Proc_number(p)         proc_number(p)
+#define debug                  0
+#define printW()               ((void)0)
+#define vm_1phys2bus(p)                (p)
+
+#define VERBOSE                1       /* display message during init */
+
+#define RX_BUFSIZE     RL_RCR_RBLEN_64K_SIZE
+#define RX_BUFBITS     RL_RCR_RBLEN_64K
+#define N_TX_BUF       RL_N_TX
+
+#define RE_PORT_NR     1               /* Minix */
+
+/* I/O vectors are handled IOVEC_NR entries at a time. */
+#define IOVEC_NR       16
+
+/* Configuration */
+#define RL_ENVVAR      "RTLETH"
+
+typedef struct re
+{
+       port_t re_base_port;
+       int re_irq;
+       int re_mode;
+       int re_flags;
+       int re_client;
+       int re_link_up;
+       int re_got_int;
+       int re_send_int;
+       int re_report_link;
+       int re_clear_rx;
+       int re_need_reset;
+       int re_tx_alive;
+       char *re_model;
+
+       /* Rx */
+       phys_bytes re_rx_buf;
+       char  *v_re_rx_buf;
+       vir_bytes re_read_s;
+
+       /* Tx */
+       int re_tx_head;
+       int re_tx_tail;
+       struct
+       {
+               int ret_busy;
+               phys_bytes ret_buf;
+               char * v_ret_buf;
+       } re_tx[N_TX_BUF];
+       u32_t re_ertxth;        /* Early Tx Threshold */
+
+       /* PCI related */
+       int re_seen;                    /* TRUE iff device available */
+       u8_t re_pcibus; 
+       u8_t re_pcidev; 
+       u8_t re_pcifunc;        
+
+       /* 'large' items */
+       int re_hook_id;                 /* IRQ hook id at kernel */
+       eth_stat_t re_stat;
+       ether_addr_t re_address;
+       message re_rx_mess;
+       message re_tx_mess;
+       char re_name[sizeof("rtl8139#n")];
+       iovec_t re_iovec[IOVEC_NR];
+       iovec_s_t re_iovec_s[IOVEC_NR];
+}
+re_t;
+
+#define REM_DISABLED   0x0
+#define REM_ENABLED    0x1
+
+#define REF_PACK_SENT  0x001
+#define REF_PACK_RECV  0x002
+#define REF_SEND_AVAIL 0x004
+#define REF_READING    0x010
+#define REF_EMPTY      0x000
+#define REF_PROMISC    0x040
+#define REF_MULTI      0x080
+#define REF_BROAD      0x100
+#define REF_ENABLED    0x200
+
 /*
  * $PchId: rtl8139.h,v 1.1 2003/09/05 10:58:50 philip Exp $
  */
index e3de8e3983f05e713be26e4c17f43de992e3336c..e5b46b3a37d21a5177d43b4aecb10b070c7f0bbb 100644 (file)
@@ -284,6 +284,9 @@ PRIVATE int int_event_check;                /* set to TRUE if events arrived */
 static char *progname;
 u32_t system_hz;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -294,6 +297,9 @@ int main(int argc, char *argv[])
        re_t *rep;
        long v;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        system_hz = sys_hz();
 
        (progname = strrchr(argv[0], '/')) ? progname++ : (progname = argv[0]);
@@ -321,14 +327,11 @@ int main(int argc, char *argv[])
                printf("rtl8169: ds_retrieve_u32 failed for 'inet': %d\n", r);
 #endif
        while (TRUE) {
-               if ((r = receive(ANY, &m)) != OK)
-                       panic("rtl8169", "receive failed", r);
+               if ((r = sef_receive(ANY, &m)) != OK)
+                       panic("rtl8169", "sef_receive failed", r);
 
                if (is_notify(m.m_type)) {
                        switch (_ENDPOINT_P(m.m_source)) {
-                       case RS_PROC_NR:
-                               notify(m.m_source);
-                               break;
                        case CLOCK:
                                /*
                                 * Under MINIX, synchronous alarms are used
@@ -383,6 +386,17 @@ int main(int argc, char *argv[])
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 static void mdio_write(U16_t port, int regaddr, int value)
 {
        int i;
@@ -1254,8 +1268,8 @@ void transmittest(re_t *rep)
                do {
                        message m;
                        int r;
-                       if ((r = receive(ANY, &m)) != OK)
-                               panic("rtl8169", "receive failed", r);
+                       if ((r = sef_receive(ANY, &m)) != OK)
+                               panic("rtl8169", "sef_receive failed", r);
                } while(m.m_source != HARDWARE);
                assert(!(rep->re_flags & REF_SEND_AVAIL));
                rep->re_flags |= REF_SEND_AVAIL;
index 3f159633a5da4892a16441ab3b3effa9b4fa128b..73c76a07a19ba4de9f3d8d60a4817ef74102bfa9 100644 (file)
@@ -17,8 +17,8 @@ LIBS = -lsys
 
 # build local binary
 all build:     sb16_dsp sb16_mixer
-sb16_dsp:      sb16.o sb16_dsp.o
-       $(CC) -o $@ $(LDFLAGS) sb16.o sb16_dsp.o $(LIBS)
+sb16_dsp:      sb16.o sb16_dsp.o sb16_dsp_liveupdate.o
+       $(CC) -o $@ $(LDFLAGS) sb16.o sb16_dsp.o sb16_dsp_liveupdate.o $(LIBS)
 sb16_mixer:    sb16.o sb16_mixer.o
        $(CC) -o $@ $(LDFLAGS) sb16.o sb16_mixer.o $(LIBS)
 
index 3396743c1b6611d5631257b856b5202283b2263c..0f0f80a47aa4d21b77090891bbfdc7c2da2e05be 100644 (file)
@@ -5,7 +5,6 @@
 #include <sys/ioc_sound.h>
 #include <minix/sound.h>
 
-
 #define SB_TIMEOUT             32000   /* timeout count */
 
 /* IRQ, base address and DMA channels */
index 8932481701b423d7c52a917117f58027990c2342..954e056891503f6415365017502399dbd5d2d806 100644 (file)
@@ -77,6 +77,13 @@ PRIVATE int reviveProcNr;
 
 #define dprint (void)
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+EXTERN _PROTOTYPE( void 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) );
+PUBLIC int is_processing = FALSE;
+PUBLIC int is_status_msg_expected = FALSE;
 
 /*===========================================================================*
  *                             main
@@ -86,6 +93,9 @@ PUBLIC void main()
        int r, caller, proc_nr, s;
        message mess;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        dprint("sb16_dsp.c: main()\n");
 
        /* Get a DMA buffer. */
@@ -93,7 +103,7 @@ PUBLIC void main()
 
        while(TRUE) {
                /* Wait for an incoming message */
-               receive(ANY, &mess);
+               sef_receive(ANY, &mess);
 
                caller = mess.m_source;
                proc_nr = mess.IO_ENDPT;
@@ -137,6 +147,19 @@ send_reply:
 
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* Register live update callbacks. */
+  sef_setcb_lu_prepare(sef_cb_lu_prepare);
+  sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+  sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
 
 /*===========================================================================*
  *                             dsp_open
@@ -242,6 +265,7 @@ message *m_ptr;
        }
        
        reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, SUSPEND);
+       is_processing = TRUE;
 
        if(DmaBusy < 0) { /* Dma tranfer not yet started */
 
@@ -269,7 +293,7 @@ message *m_ptr;
        } else { /* Dma buffer is full, filling second buffer */ 
 
                while(BufReadNext == BufFillNext) { /* Second buffer also full, wait for space to become available */ 
-                       receive(HARDWARE, &mess);
+                       sef_receive(HARDWARE, &mess);
                        dsp_hardware_msg();
                }
                sys_datacopy(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->ADDRESS, SELF, (vir_bytes)Buffer + BufFillNext * DspFragmentSize, (phys_bytes)DspFragmentSize);
@@ -278,6 +302,7 @@ message *m_ptr;
 
        } 
        
+       is_status_msg_expected = TRUE;
        revivePending = 1;
        reviveStatus = DspFragmentSize;
        reviveProcNr = m_ptr->IO_ENDPT;
@@ -338,8 +363,11 @@ message *m_ptr;    /* pointer to the newly arrived message */
                m_ptr->REP_STATUS = reviveStatus;
 
                revivePending = 0;                                      /* unmark event */
+               is_processing = FALSE;
        } else {
                m_ptr->m_type = DEV_NO_STATUS;
+
+               is_status_msg_expected = FALSE;
        }
 
        send(m_ptr->m_source, m_ptr);                   /* send the message */
diff --git a/drivers/sb16/sb16_dsp_liveupdate.c b/drivers/sb16/sb16_dsp_liveupdate.c
new file mode 100644 (file)
index 0000000..83f915c
--- /dev/null
@@ -0,0 +1,70 @@
+#include "sb16.h"
+
+/* State management variables. */
+EXTERN int is_processing;
+EXTERN int is_status_msg_expected;
+
+/* Custom states definition. */
+#define SB16_STATE_PROCESSING_PROTOCOL_FREE (SEF_LU_STATE_CUSTOM_BASE + 0)
+#define SB16_STATE_IS_CUSTOM(s) \
+    ((s) == SB16_STATE_PROCESSING_PROTOCOL_FREE)
+
+/*===========================================================================*
+ *                      sef_cb_lu_prepare                                   *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare(int state)
+{
+  int is_ready;
+
+  /* Check if we are ready for the target state. */
+  is_ready = FALSE;
+  switch(state) {
+      /* Standard states. */
+      case SEF_LU_STATE_REQUEST_FREE:
+          is_ready = TRUE;
+      break;
+
+      case SEF_LU_STATE_PROTOCOL_FREE:
+          is_ready = (!is_processing && !is_status_msg_expected);
+      break;
+
+      /* Custom states. */
+      case SB16_STATE_PROCESSING_PROTOCOL_FREE:
+          is_ready = (!is_processing);
+      break;
+  }
+
+  /* Tell SEF if we are ready. */
+  if(is_ready) {
+      sef_lu_ready(OK);
+  }
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_isvalid                            *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state) || SB16_STATE_IS_CUSTOM(state);
+}
+
+/*===========================================================================*
+ *                        sef_cb_lu_state_dump                              *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump(int state)
+{
+  sef_lu_dprint("sb16: live update state = %d\n", state);
+  sef_lu_dprint("sb16: is_processing = %d\n", is_processing);
+  sef_lu_dprint("sb16: is_status_msg_expected = %d\n",
+      is_status_msg_expected);
+
+  sef_lu_dprint("sb16: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_WORK_FREE, TRUE);
+  sef_lu_dprint("sb16: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_REQUEST_FREE, TRUE);
+  sef_lu_dprint("sb16: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n", 
+      SEF_LU_STATE_PROTOCOL_FREE, (!is_processing && !is_status_msg_expected));
+  sef_lu_dprint("sb16: SB16_STATE_PROCESSING_PROTOCOL_FREE(%d) reached = %d\n", 
+      SB16_STATE_PROCESSING_PROTOCOL_FREE, (!is_processing));
+}
+
index 6e4a9f1415d181e51e9b6e3dacb9e6034e341aa7..03b698022e595afa787a5551e3c66eec9d91654e 100644 (file)
@@ -40,6 +40,8 @@ PRIVATE int mixer_avail = 0;  /* Mixer exists? */
 
 #define dprint (void)
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 
 /*===========================================================================*
  *                             main
@@ -48,11 +50,14 @@ PUBLIC void main() {
 message mess;
        int err, caller, proc_nr;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        /* Here is the main loop of the mixer task. It waits for a message, carries
        * it out, and sends a reply.
        */
        while (TRUE) {
-               receive(ANY, &mess);
+               sef_receive(ANY, &mess);
 
                caller = mess.m_source;
                proc_nr = mess.IO_ENDPT;
@@ -88,6 +93,18 @@ message mess;
        }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
 
 /*=========================================================================*
  *                             mixer_open                                      
index eeed9b237079111fda1289da877c980864a3c7a7..dcb29779dd4a886f94cc05752b01a14e2368697a 100644 (file)
@@ -59,11 +59,17 @@ FORWARD _PROTOTYPE( u8_t read_exca, (struct port *pp, int socket, int reg) );
 FORWARD _PROTOTYPE( void do_outb, (port_t port, u8_t value)            );
 FORWARD _PROTOTYPE( u8_t do_inb, (port_t port)                         );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 int main(int argc, char *argv[])
 {
        int c, r;
        message m;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
 
        if((r=micro_delay_calibrate()) != OK)
@@ -84,15 +90,28 @@ int main(int argc, char *argv[])
 
        for (;;)
        {
-               r= receive(ANY, &m);
+               r= sef_receive(ANY, &m);
                if (r != OK)
-                       panic("ti1225", "receive failed", r);
+                       panic("ti1225", "sef_receive failed", r);
                printf("ti1225: got message %u from %d\n",
                        m.m_type, m.m_source);
        }
        return 0;
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 PRIVATE void init()
 {
        int i, r, first, devind, port;
index 784c77ca182a0091a8da1565a23bee8044ef79bf..8574bc62febac7455e6a983c4cdc99c5a9595a53 100644 (file)
@@ -146,6 +146,8 @@ extern PUBLIC unsigned info_location;
 extern PUBLIC phys_bytes vid_size;     /* 0x2000 for color or 0x0800 for mono */
 extern PUBLIC phys_bytes vid_base;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 
 /*===========================================================================*
  *                             tty_task                                     *
@@ -159,6 +161,9 @@ PUBLIC int main(void)
   int r, s;
   register tty_t *tp;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Get kernel environment (protected_mode, pc_at and ega are needed). */ 
   if (OK != (s=sys_getmachine(&machine))) {
     panic("TTY","Couldn't obtain kernel environment.", s);
@@ -179,9 +184,9 @@ PUBLIC int main(void)
        }
 
        /* Get a request message. */
-       r= receive(ANY, &tty_mess);
+       r= sef_receive(ANY, &tty_mess);
        if (r != 0)
-               panic("TTY", "receive failed with %d", r);
+               panic("TTY", "sef_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. 
@@ -199,9 +204,6 @@ PUBLIC int main(void)
                                /* run watchdogs of expired timers */
                                expire_timers();
                                break;
-                       case RS_PROC_NR:
-                               notify(tty_mess.m_source);
-                               break;
                        case HARDWARE: 
                                /* hardware interrupt notification */
                                
@@ -330,6 +332,17 @@ PUBLIC int main(void)
   return 0;
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             do_status                                    *
  *===========================================================================*/
index 2825d14f9ae8ed5d5fe8d16d261f0b9cecd9bbf2..b7419a970cc24d1858c349c1ddee7ca6ceb37716 100644 (file)
 
 #define NR_SYS_CALLS   47      /* number of system calls */ 
 
-/* Pseudo call for use in kernel/table.c. */
-#define SYS_ALL_CALLS (NR_SYS_CALLS)
-
 /* Subfunctions for SYS_PRIVCTL */
 #define SYS_PRIV_ALLOW         1       /* Allow process to run */
 #define SYS_PRIV_DISALLOW      2       /* Disallow process to run */
 #define RS_REFRESH     (RS_RQ_BASE + 2)        /* refresh system service */
 #define RS_RESTART     (RS_RQ_BASE + 3)        /* restart system service */
 #define RS_SHUTDOWN    (RS_RQ_BASE + 4)        /* alert about shutdown */
+#define RS_UPDATE      (RS_RQ_BASE + 5)        /* update system service */
 
 #define RS_LOOKUP      (RS_RQ_BASE + 8)        /* lookup server name */
 
+#define RS_LU_PREPARE  (RS_RQ_BASE + 21)       /* prepare to update message */
+
 #  define RS_CMD_ADDR          m1_p1           /* command string */
 #  define RS_CMD_LEN           m1_i1           /* length of command */
 #  define RS_PERIOD            m1_i2           /* heartbeat period */
 #  define RS_NAME              m1_p1           /* name */
 #  define RS_NAME_LEN          m1_i1           /* namelen */
 
+#  define RS_LU_RESULT          m1_i1           /* live update result */
+#  define RS_LU_STATE           m1_i2           /* state required to update */
+#  define RS_LU_PREPARE_MAXTIME m1_i3           /* the max time to prepare */
+
 /*===========================================================================*
  *                Messages for the Data Store Server                        *
  *===========================================================================*/
diff --git a/include/minix/sef.h b/include/minix/sef.h
new file mode 100644 (file)
index 0000000..26a5734
--- /dev/null
@@ -0,0 +1,120 @@
+/* Prototypes for System Event Framework (SEF) functions. */
+
+#ifndef _SEF_H
+#define _SEF_H
+
+/* SEF entry points for system processes. */
+_PROTOTYPE( void sef_startup, (void) );
+_PROTOTYPE( int sef_receive, (endpoint_t src, message *m_ptr) );
+
+/* SEF Debug. */
+#include <stdio.h>
+#define sef_dprint                      printf
+#define sef_debug_begin()               (void)(NULL)
+#define sef_debug_end()                 fflush(stdout)
+
+/*===========================================================================*
+ *                               SEF Ping                                   *
+ *===========================================================================*/
+/* What to intercept. */
+#define INTERCEPT_SEF_PING_REQUESTS 1
+#define IS_SEF_PING_REQUEST(mp) (is_notify((mp)->m_type) \
+    && (mp)->m_source == RS_PROC_NR)
+
+/* Callback type definitions. */
+typedef void(*sef_cb_ping_reply_t)(message *m_ptr);
+
+/* Callback registration helpers. */
+_PROTOTYPE( void sef_setcb_ping_reply, (sef_cb_ping_reply_t cb));
+
+/* Predefined callback implementations. */
+_PROTOTYPE( void sef_cb_ping_reply_null, (message *m_ptr) );
+
+_PROTOTYPE( void sef_cb_ping_reply_pong, (message *m_ptr) );
+
+/* Macros for predefined callback implementations. */
+#define SEF_CB_PING_REPLY_NULL          sef_cb_ping_reply_null
+
+#define SEF_CB_PING_REPLY_DEFAULT       sef_cb_ping_reply_pong
+
+/* Debug. */
+#define SEF_PING_DEBUG_DEFAULT 0
+
+#ifndef SEF_PING_DEBUG
+#define SEF_PING_DEBUG                  SEF_PING_DEBUG_DEFAULT
+#endif
+
+#define sef_ping_dprint                 sef_dprint
+#define sef_ping_debug_begin            sef_debug_begin
+#define sef_ping_debug_end              sef_debug_end
+
+/*===========================================================================*
+ *                             SEF Live update                              *
+ *===========================================================================*/
+/* What to intercept. */
+#define INTERCEPT_SEF_LU_REQUESTS 1
+#define IS_SEF_LU_REQUEST(mp) ((mp)->m_type == RS_LU_PREPARE \
+    && (mp)->m_source == RS_PROC_NR)
+
+/* Global helpers. */
+_PROTOTYPE( void sef_lu_ready, (int result) );
+
+/* Callback type definitions. */
+typedef void(*sef_cb_lu_prepare_t)(int);
+typedef  int(*sef_cb_lu_state_isvalid_t)(int);
+typedef void(*sef_cb_lu_state_changed_t)(int, int);
+typedef void(*sef_cb_lu_state_dump_t)(int);
+typedef  int(*sef_cb_lu_ready_pre_t)(int);
+
+/* Callback registration helpers. */
+_PROTOTYPE( void sef_setcb_lu_prepare, (sef_cb_lu_prepare_t cb) );
+_PROTOTYPE( void sef_setcb_lu_state_isvalid, (sef_cb_lu_state_isvalid_t cb) );
+_PROTOTYPE( void sef_setcb_lu_state_changed, (sef_cb_lu_state_changed_t cb) );
+_PROTOTYPE( void sef_setcb_lu_state_dump, (sef_cb_lu_state_dump_t cb) );
+_PROTOTYPE( void sef_setcb_lu_ready_pre, (sef_cb_lu_ready_pre_t cb) );
+
+/* Predefined callback implementations. */
+_PROTOTYPE( void sef_cb_lu_prepare_null, (int state) );
+_PROTOTYPE(  int sef_cb_lu_state_isvalid_null, (int state) );
+_PROTOTYPE( void sef_cb_lu_state_changed_null, (int old_state, int state) );
+_PROTOTYPE( void sef_cb_lu_state_dump_null, (int state) );
+_PROTOTYPE(  int sef_cb_lu_ready_pre_null, (int result) );
+
+_PROTOTYPE( void sef_cb_lu_prepare_always_ready, (int state) );
+_PROTOTYPE(  int sef_cb_lu_state_isvalid_standard, (int state) );
+
+/* Macros for predefined callback implementations. */
+#define SEF_CB_LU_PREPARE_NULL          sef_cb_lu_prepare_null
+#define SEF_CB_LU_STATE_ISVALID_NULL    sef_cb_lu_state_isvalid_null
+#define SEF_CB_LU_STATE_CHANGED_NULL    sef_cb_lu_state_changed_null
+#define SEF_CB_LU_STATE_DUMP_NULL       sef_cb_lu_state_dump_null
+#define SEF_CB_LU_READY_PRE_NULL        sef_cb_lu_ready_pre_null
+
+#define SEF_CB_LU_PREPARE_DEFAULT       sef_cb_lu_prepare_null
+#define SEF_CB_LU_STATE_ISVALID_DEFAULT sef_cb_lu_state_isvalid_null
+#define SEF_CB_LU_STATE_CHANGED_DEFAULT sef_cb_lu_state_changed_null
+#define SEF_CB_LU_STATE_DUMP_DEFAULT    sef_cb_lu_state_dump_null
+#define SEF_CB_LU_READY_PRE_DEFAULT     sef_cb_lu_ready_pre_null
+
+/* Standard live update states. */
+#define SEF_LU_STATE_NULL               0    /* null state */
+#define SEF_LU_STATE_WORK_FREE          1    /* no work in progress */
+#define SEF_LU_STATE_REQUEST_FREE       2    /* no request in progress */
+#define SEF_LU_STATE_PROTOCOL_FREE      3    /* no protocol in progress */
+#define SEF_LU_STATE_CUSTOM_BASE        (SEF_LU_STATE_PROTOCOL_FREE+1)
+#define SEF_LU_STATE_IS_STANDARD(s)     ((s) > SEF_LU_STATE_NULL \
+    && (s) < SEF_LU_STATE_CUSTOM_BASE)
+
+/* Debug. */
+#define SEF_LU_DEBUG_DEFAULT 1
+
+#ifndef SEF_LU_DEBUG
+#define SEF_LU_DEBUG            SEF_LU_DEBUG_DEFAULT
+#endif
+
+#define sef_lu_dprint           sef_dprint
+#define sef_lu_debug_begin      sef_debug_begin
+#define sef_lu_debug_end        sef_debug_end
+
+#endif /* _SEF_H */
+
index 60f8587da24218ae2588bea0d7c72fc1592d4bb8..d47c643dc907ac5c593585d328c8e2abd16f7a7d 100644 (file)
@@ -18,6 +18,7 @@
 #endif
 
 #include <minix/safecopies.h>
+#include <minix/sef.h>
 
 /* Forward declaration */
 struct reg86u;
index 3c27938567287da5ad01eb54ea75a05cf6a169b7..0bcad88851529d64644afbbf3900c31cd30ce360 100644 (file)
@@ -27,6 +27,9 @@ libsys_FILES=" \
        pci_set_acl.c \
        pci_slot_name.c \
        safecopies.c \
+       sef.c \
+       sef_liveupdate.c \
+       sef_ping.c \
        sys_abort.c \
        sys_cprof.c \
        sys_endsig.c \
diff --git a/lib/syslib/sef.c b/lib/syslib/sef.c
new file mode 100644 (file)
index 0000000..3f1d145
--- /dev/null
@@ -0,0 +1,153 @@
+#include "syslib.h"
+#include <assert.h>
+#include <minix/sysutil.h>
+#include <stdio.h>
+
+/* Self variables. */
+#define SEF_SELF_NAME_MAXLEN 20
+PRIVATE char sef_self_name[SEF_SELF_NAME_MAXLEN];
+PRIVATE endpoint_t sef_self_endpoint;
+
+/* Debug. */
+#define SEF_DEBUG_HEADER_MAXLEN 32
+PRIVATE time_t sef_debug_boottime = 0;
+PRIVATE u32_t sef_debug_system_hz = 0;
+PRIVATE time_t sef_debug_time_sec = 0;
+PRIVATE time_t sef_debug_time_us = 0;
+PRIVATE char sef_debug_header_buff[SEF_DEBUG_HEADER_MAXLEN];
+FORWARD _PROTOTYPE( void sef_debug_refresh_params, (void) );
+PUBLIC _PROTOTYPE( char* sef_debug_header, (void) );
+
+/* SEF Live update prototypes. */
+EXTERN _PROTOTYPE( void do_sef_lu_before_receive, (void) );
+EXTERN _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) );
+
+/* SEF Ping prototypes. */
+EXTERN _PROTOTYPE( int do_sef_ping_request, (message *m_ptr) );
+
+/*===========================================================================*
+ *                             sef_startup                                  *
+ *===========================================================================*/
+PUBLIC void sef_startup()
+{
+/* SEF startup interface for system processes. */
+  int r;
+
+  /* Get information about self. */
+  r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN);
+  if ( r != OK) {
+      sef_self_endpoint = SELF;
+      sprintf(sef_self_name, "%s", "Unknown");
+  }
+}
+
+/*===========================================================================*
+ *                             sef_receive                                  *
+ *===========================================================================*/
+PUBLIC int sef_receive(endpoint_t src, message *m_ptr)
+{
+/* SEF receive() interface for system processes. */
+  int r;
+
+  while(TRUE) {
+
+#if INTERCEPT_SEF_LU_REQUESTS
+      /* Handle SEF Live update before receive events. */
+      do_sef_lu_before_receive();
+#endif
+
+      /* Receive and return in case of error. */
+      r = receive(src, m_ptr);
+      if(r != OK) {
+          return r;
+      }
+
+#if INTERCEPT_SEF_PING_REQUESTS
+      /* Intercept SEF Ping requests. */
+      if(IS_SEF_PING_REQUEST(m_ptr)) {
+          if(do_sef_ping_request(m_ptr) == OK) {
+              continue;
+          }
+      }
+#endif
+
+#if INTERCEPT_SEF_LU_REQUESTS
+      /* Intercept SEF Live update requests. */
+      if(IS_SEF_LU_REQUEST(m_ptr)) {
+          if(do_sef_lu_request(m_ptr) == OK) {
+              continue;
+          }
+      }
+#endif
+
+      /* If we get this far, this is not a valid SEF request, return and
+       * let the caller deal with that.
+       */
+      break;
+  }
+
+  return r;
+}
+
+/*===========================================================================*
+ *                         sef_debug_refresh_params                         *
+ *===========================================================================*/
+PRIVATE void sef_debug_refresh_params(void)
+{
+/* Refresh SEF debug params. */
+  clock_t uptime;
+  endpoint_t endpoint;
+  int r;
+
+  /* Get boottime the first time. */
+  if(!sef_debug_boottime) {
+      r = sys_times(NONE, NULL, NULL, NULL, &sef_debug_boottime);
+      if ( r != OK) {
+          sef_debug_boottime = -1;
+      }
+  }
+
+  /* Get system hz the first time. */
+  if(!sef_debug_system_hz) {
+      r = sys_getinfo(GET_HZ, &sef_debug_system_hz,
+          sizeof(sef_debug_system_hz), 0, 0);
+      if ( r != OK) {
+          sef_debug_system_hz = -1;
+      }
+  }
+
+  /* Get uptime. */
+  uptime = -1;
+  if(sef_debug_boottime!=-1 && sef_debug_system_hz!=-1) {
+      r = sys_times(NONE, NULL, NULL, &uptime, NULL);
+      if ( r != OK) {
+            uptime = -1;
+      }
+  }
+
+  /* Compute current time. */
+  if(sef_debug_boottime==-1 || sef_debug_system_hz==-1 || uptime==-1) {
+      sef_debug_time_sec = 0;
+      sef_debug_time_us = 0;
+  }
+  else {
+      sef_debug_time_sec = (time_t) (sef_debug_boottime
+          + (uptime/sef_debug_system_hz));
+      sef_debug_time_us = (uptime%sef_debug_system_hz)
+          * 1000000/sef_debug_system_hz;
+  }
+}
+
+/*===========================================================================*
+ *                              sef_debug_header                            *
+ *===========================================================================*/
+PUBLIC char* sef_debug_header(void)
+{
+/* Build and return a SEF debug header. */
+  sef_debug_refresh_params();
+  sprintf(sef_debug_header_buff, "%s: time = %ds %06dus", 
+      sef_self_name, sef_debug_time_sec, sef_debug_time_us);
+
+  return sef_debug_header_buff;
+}
+
diff --git a/lib/syslib/sef_liveupdate.c b/lib/syslib/sef_liveupdate.c
new file mode 100644 (file)
index 0000000..862f113
--- /dev/null
@@ -0,0 +1,245 @@
+#include "syslib.h"
+#include <assert.h>
+#include <minix/sysutil.h>
+
+/* SEF Live update variables. */
+PRIVATE int sef_lu_state = SEF_LU_STATE_NULL;
+
+/* SEF Live update callbacks. */
+PRIVATE struct sef_cbs {
+    sef_cb_lu_prepare_t                 sef_cb_lu_prepare;
+    sef_cb_lu_state_isvalid_t           sef_cb_lu_state_isvalid;
+    sef_cb_lu_state_changed_t           sef_cb_lu_state_changed;
+    sef_cb_lu_state_dump_t              sef_cb_lu_state_dump;
+    sef_cb_lu_ready_pre_t               sef_cb_lu_ready_pre;
+} sef_cbs = {
+    SEF_CB_LU_PREPARE_DEFAULT,
+    SEF_CB_LU_STATE_ISVALID_DEFAULT,
+    SEF_CB_LU_STATE_CHANGED_DEFAULT,
+    SEF_CB_LU_STATE_DUMP_DEFAULT,
+    SEF_CB_LU_READY_PRE_DEFAULT,
+};
+
+/* SEF Live update prototypes for sef_receive(). */
+PUBLIC _PROTOTYPE( void do_sef_lu_before_receive, (void) );
+PUBLIC _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) );
+
+/* Debug. */
+EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
+PRIVATE int sef_lu_debug_cycle = 0;
+
+/*===========================================================================*
+ *                         do_sef_lu_before_receive                         *
+ *===========================================================================*/
+PUBLIC void do_sef_lu_before_receive()
+{
+/* Handle SEF Live update before receive events. */
+
+  /* Nothing to do if we are not preparing for a live update. */
+  if(sef_lu_state == SEF_LU_STATE_NULL) {
+      return;
+  }
+
+  /* Debug. */
+#if SEF_LU_DEBUG
+  sef_lu_debug_cycle++;
+  sef_lu_debug_begin();
+  sef_lu_dprint("%s, cycle=%d. Dumping state variables:\n",
+      sef_debug_header(), sef_lu_debug_cycle);
+  sef_cbs.sef_cb_lu_state_dump(sef_lu_state);
+  sef_lu_debug_end();
+#endif
+
+  /* Let the callback code handle the event.
+   * For SEF_LU_STATE_WORK_FREE, we're always ready, tell immediately.
+   */
+  if(sef_lu_state == SEF_LU_STATE_WORK_FREE) {
+      sef_lu_ready(OK);
+  }
+  else {
+      sef_cbs.sef_cb_lu_prepare(sef_lu_state);
+  }
+}
+
+/*===========================================================================*
+ *                               do_sef_lu_request                          *
+ *===========================================================================*/
+PUBLIC int do_sef_lu_request(message *m_ptr)
+{
+/* Handle a SEF Live update request. */
+  int old_state, is_valid_state;
+
+  sef_lu_debug_cycle = 0;
+  old_state = sef_lu_state;
+
+  /* Only accept live update requests with a valid state. */
+  is_valid_state = sef_cbs.sef_cb_lu_state_isvalid(m_ptr->RS_LU_STATE);
+  if(!is_valid_state) {
+      sef_lu_ready(EINVAL);
+  }
+  else {
+      /* Set the new live update state. */
+      sef_lu_state = m_ptr->RS_LU_STATE;
+
+      /* If the live update state changed, let the callback code
+       * handle the rest.
+       */
+      if(old_state != sef_lu_state) {
+          sef_cbs.sef_cb_lu_state_changed(old_state, sef_lu_state);
+      }
+  }
+
+  /* Return OK not to let anybody else intercept the request. */
+  return(OK);
+}
+
+/*===========================================================================*
+ *                               sef_lu_ready                               *
+ *===========================================================================*/
+PUBLIC void sef_lu_ready(int result)
+{
+  message m;
+  int old_state, r;
+
+#if SEF_LU_DEBUG
+  sef_lu_debug_begin();
+  sef_lu_dprint("%s, cycle=%d. Ready to update with result: %d%s\n",
+      sef_debug_header(), sef_lu_debug_cycle,
+      result, (result == OK ? "(OK)" : ""));
+  sef_lu_debug_end();
+#endif
+
+  /* Let the callback code perform any pre-ready operations. */
+  r = sef_cbs.sef_cb_lu_ready_pre(result);
+  if(r != OK) {
+      /* Abort update if callback returned error. */
+      result = r;
+  }
+  else {
+      /* Inform RS that we're ready with the given result. */
+      m.m_type = RS_LU_PREPARE;
+      m.RS_LU_STATE = sef_lu_state;
+      m.RS_LU_RESULT = result;
+      r = sendrec(RS_PROC_NR, &m);
+      if ( r != OK) {
+          panic("SEF", "sendrec failed", r);
+      }
+  }
+
+#if SEF_LU_DEBUG
+  sef_lu_debug_begin();
+  sef_lu_dprint("%s, cycle=%d. The %s aborted the update!\n",
+      sef_debug_header(), sef_lu_debug_cycle,
+      (result == OK ? "server" : "client"));
+  sef_lu_debug_end();
+#endif
+
+  /* Something went wrong. Update was aborted and we didn't get updated.
+   * Restore things back to normal and continue executing.
+   */
+  old_state = sef_lu_state;
+  sef_lu_state = SEF_LU_STATE_NULL;
+  if(old_state != sef_lu_state) {
+      sef_cbs.sef_cb_lu_state_changed(old_state, sef_lu_state);
+  }
+}
+
+/*===========================================================================*
+ *                            sef_setcb_lu_prepare                           *
+ *===========================================================================*/
+PUBLIC void sef_setcb_lu_prepare(sef_cb_lu_prepare_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_lu_prepare = cb;
+}
+
+/*===========================================================================*
+ *                         sef_setcb_lu_state_isvalid                        *
+ *===========================================================================*/
+PUBLIC void sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_lu_state_isvalid = cb;
+}
+
+/*===========================================================================*
+ *                         sef_setcb_lu_state_changed                        *
+ *===========================================================================*/
+PUBLIC void sef_setcb_lu_state_changed(sef_cb_lu_state_changed_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_lu_state_changed = cb;
+}
+
+/*===========================================================================*
+ *                          sef_setcb_lu_state_dump                          *
+ *===========================================================================*/
+PUBLIC void sef_setcb_lu_state_dump(sef_cb_lu_state_dump_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_lu_state_dump = cb;
+}
+
+/*===========================================================================*
+ *                          sef_setcb_lu_ready_pre                           *
+ *===========================================================================*/
+PUBLIC void sef_setcb_lu_ready_pre(sef_cb_lu_ready_pre_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_lu_ready_pre = cb;
+}
+
+/*===========================================================================*
+ *                         sef_cb_lu_prepare_null                           *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare_null(int state)
+{
+}
+
+/*===========================================================================*
+ *                      sef_cb_lu_state_isvalid_null                        *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid_null(int state)
+{
+  return FALSE;
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_changed_null                       *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_changed_null(int old_state, int state)
+{
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_state_dump_null                          *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_state_dump_null(int state)
+{
+  sef_lu_dprint("NULL\n");
+}
+
+/*===========================================================================*
+ *                       sef_cb_lu_ready_pre_null                           *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_ready_pre_null(int result)
+{
+  return(OK);
+}
+
+/*===========================================================================*
+ *                    sef_cb_lu_prepare_always_ready                        *
+ *===========================================================================*/
+PUBLIC void sef_cb_lu_prepare_always_ready(int state)
+{
+  sef_lu_ready(OK);
+}
+
+/*===========================================================================*
+ *                   sef_cb_lu_state_isvalid_standard                       *
+ *===========================================================================*/
+PUBLIC int sef_cb_lu_state_isvalid_standard(int state)
+{
+  return SEF_LU_STATE_IS_STANDARD(state);
+}
+
diff --git a/lib/syslib/sef_ping.c b/lib/syslib/sef_ping.c
new file mode 100644 (file)
index 0000000..60c6734
--- /dev/null
@@ -0,0 +1,63 @@
+#include "syslib.h"
+#include <assert.h>
+#include <minix/sysutil.h>
+
+/* SEF Ping callbacks. */
+PRIVATE struct sef_cbs {
+    sef_cb_ping_reply_t                 sef_cb_ping_reply;
+} sef_cbs = {
+    SEF_CB_PING_REPLY_DEFAULT
+};
+
+/* SEF Ping prototypes for sef_receive(). */
+PUBLIC _PROTOTYPE( int do_sef_ping_request, (message *m_ptr) );
+
+/* Debug. */
+EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
+
+/*===========================================================================*
+ *                            do_sef_ping_request                           *
+ *===========================================================================*/
+PUBLIC int do_sef_ping_request(message *m_ptr)
+{
+/* Handle a SEF Ping request. */
+
+  /* Debug. */
+#if SEF_PING_DEBUG
+  sef_ping_debug_begin();
+  sef_ping_dprint("%s. Got a SEF Ping request! About to reply.\n", 
+      sef_debug_header());
+  sef_ping_debug_end();
+#endif
+
+  /* Let the callback code handle the request. */
+  sef_cbs.sef_cb_ping_reply(m_ptr);
+
+  /* Return OK not to let anybody else intercept the request. */
+  return(OK);
+}
+
+/*===========================================================================*
+ *                          sef_setcb_ping_reply                             *
+ *===========================================================================*/
+PUBLIC void sef_setcb_ping_reply(sef_cb_ping_reply_t cb)
+{
+  assert(cb != NULL);
+  sef_cbs.sef_cb_ping_reply = cb;
+}
+
+/*===========================================================================*
+ *                        sef_cb_ping_reply_null                            *
+ *===========================================================================*/
+PUBLIC void sef_cb_ping_reply_null(message *m_ptr)
+{
+}
+
+/*===========================================================================*
+ *                        sef_cb_ping_reply_pong                            *
+ *===========================================================================*/
+PUBLIC void sef_cb_ping_reply_pong(message *m_ptr)
+{
+  notify(m_ptr->m_source);
+}
+
index d6edc50ce60af3198ddfbbb68d56a1f6b097c228..978da669b53d9a6e13f33ba66e4629b53d0a60f5 100644 (file)
@@ -25,6 +25,9 @@ FORWARD _PROTOTYPE(void sig_handler, (void)                           );
 FORWARD _PROTOTYPE(void get_work, (message *m_ptr)                     );
 FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr)              );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -38,6 +41,9 @@ PUBLIC int main(int argc, char **argv)
   int result;                 
   sigset_t sigset;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server(argc, argv);
 
@@ -93,6 +99,17 @@ send_reply:
   return(OK);                          /* shouldn't come here */
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                              init_server                                 *
  *===========================================================================*/
@@ -142,7 +159,7 @@ PRIVATE void get_work(m_ptr)
 message *m_ptr;                                /* message buffer */
 {
     int status = 0;
-    status = receive(ANY, m_ptr);   /* this blocks until message arrives */
+    status = sef_receive(ANY, m_ptr);   /* this blocks until message arrives */
     if (OK != status)
         panic("DS","failed to receive message!", status);
     who_e = m_ptr->m_source;        /* message arrived! set sender */
index a6a59e2c4eefc08a232343def7af73166474ed38..ae20e10342da246d1609730b38a31aaba77d57ae 100644 (file)
@@ -97,6 +97,9 @@ _PROTOTYPE( void main, (void) );
 FORWARD _PROTOTYPE( void nw_conf, (void) );
 FORWARD _PROTOTYPE( void nw_init, (void) );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 PUBLIC void main()
 {
        mq_t *mq;
@@ -110,6 +113,9 @@ PUBLIC void main()
        u8_t randbits[32];
        struct timeval tv;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
 #if DEBUG
        printf("Starting inet...\n");
        printf("%s\n", version);
@@ -235,7 +241,7 @@ PUBLIC void main()
                if (!mq)
                        ip_panic(("out of messages"));
 
-               r= receive (ANY, &mq->mq_mess);
+               r= sef_receive(ANY, &mq->mq_mess);
                if (r<0)
                {
                        ip_panic(("unable to receive: %d", r));
@@ -291,6 +297,17 @@ PUBLIC void main()
        ip_panic(("task is not allowed to terminate"));
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 PRIVATE void nw_conf()
 {
        read_conf();
index f72ed7b78e8fa7f4a68bf9db371bf78fb9b2ff34..2310a245c79080557b2cc3ea550a8c86e1a5d50c 100644 (file)
@@ -23,10 +23,16 @@ struct {
 
 int verbose = 0;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 PUBLIC int main(int argc, char *argv[])
 {
        message m;
 
+       /* SEF local startup. */
+       sef_local_startup();
+
        SELF_E = getprocnr();
 
        if(verbose)
@@ -36,8 +42,8 @@ PUBLIC int main(int argc, char *argv[])
                int r;
                int i;
 
-               if ((r = receive(ANY, &m)) != OK)
-                       printf("IPC receive error %d.\n", r);
+               if ((r = sef_receive(ANY, &m)) != OK)
+                       printf("sef_receive failed %d.\n", r);
                who_e = m.m_source;
                call_type = m.m_type;
 
@@ -100,3 +106,14 @@ PUBLIC int main(int argc, char *argv[])
        return -1;
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
index da7b7cfba8e27e40cb914a76f9eb312eabe79386..709ffbd462790a11312df200e6eb03133fdb9638 100644 (file)
@@ -56,7 +56,7 @@ PRIVATE char *s_flags_str(int flags)
        str[1] = (flags & RS_EXITING)       ? 'E' : '-';
        str[2] = (flags & RS_REFRESHING)    ? 'R' : '-';
        str[3] = (flags & RS_NOPINGREPLY)   ? 'N' : '-';
-       str[4] = '-';
+       str[4] = (flags & RS_UPDATING)      ? 'u' : '-';
        str[5] = '\0';
 
        return(str);
index 15f2b5ee05d6e363c2dee0a11ebd9422c8aa0fdf..c2e88ab00fb30b2a991bde8c869d16370a65458d 100644 (file)
@@ -24,6 +24,9 @@ FORWARD _PROTOTYPE(void sig_handler, (void)                           );
 FORWARD _PROTOTYPE(void get_work, (void)                               );
 FORWARD _PROTOTYPE(void reply, (int whom, int result)                  );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -36,6 +39,9 @@ PUBLIC int main(int argc, char **argv)
   int result;                 
   sigset_t sigset;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server(argc, argv);
 
@@ -60,9 +66,6 @@ PUBLIC int main(int argc, char **argv)
                      case TTY_PROC_NR:
                              result = do_fkey_pressed(&m_in);
                              break;
-                     case RS_PROC_NR:
-                             notify(m_in.m_source);
-                             continue;
              }
       }
       else {
@@ -79,6 +82,19 @@ PUBLIC int main(int argc, char **argv)
   return(OK);                          /* shouldn't come here */
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* 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);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                              init_server                                 *
  *===========================================================================*/
@@ -123,9 +139,9 @@ PRIVATE void sig_handler()
 PRIVATE void get_work()
 {
     int status = 0;
-    status = receive(ANY, &m_in);   /* this blocks until message arrives */
+    status = sef_receive(ANY, &m_in);   /* this blocks until message arrives */
     if (OK != status)
-        panic("IS","failed to receive message!", status);
+        panic("IS","sef_receive failed!", status);
     who_e = m_in.m_source;        /* message arrived! set sender */
     callnr = m_in.m_type;       /* set function call number */
 }
@@ -144,3 +160,4 @@ int result;                                 /* report result to replyee */
         panic("IS", "unable to send reply!", send_status);
 }
 
+
index 38bbd7555931dc77094ed777f7951400d550a7d9..6bff616d764732941057fcfd9c8a8ddca7721ae3 100644 (file)
@@ -12,6 +12,9 @@
 FORWARD _PROTOTYPE(void init_server, (void)                            );
 FORWARD _PROTOTYPE(void get_work, (message *m_in)                      );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -19,9 +22,12 @@ PUBLIC int main(void) {
   int who_e, ind, error;
   message m;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server();
-  
+
   fs_m_in.m_type = FS_READY;
   
   if (send(FS_PROC_NR, &fs_m_in) != OK) {
@@ -65,6 +71,17 @@ PUBLIC int main(void) {
   }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             init_server                                  *
  *===========================================================================*/
@@ -87,9 +104,9 @@ PRIVATE void init_server(void)
 PRIVATE void get_work(m_in)
 message *m_in;                         /* pointer to message */
 {
-  int s;                               /* receive status */
-  if (OK != (s = receive(ANY, m_in)))  /* wait for message */
-    panic("ISOFS","receive failed", s);
+  int s;                                       /* receive status */
+  if (OK != (s = sef_receive(ANY, m_in)))      /* wait for message */
+    panic("ISOFS","sef_receive failed", s);
 }
 
 /*===========================================================================*
index 38a5c12bc051c60f370471fcab2bb009160ecbba..d946b4d03d0683ef6f6d5ae3dfb37aba6e310928 100644 (file)
@@ -14,6 +14,8 @@ FORWARD _PROTOTYPE(void init_server, (void)                           );
 FORWARD _PROTOTYPE(void get_work, (message *m_in)                      );
 FORWARD _PROTOTYPE(void cch_check, (void)                              );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 
 /*===========================================================================*
  *                             main                                         *
@@ -27,6 +29,9 @@ PUBLIC int main(int argc, char *argv[])
   int error, ind;
   message m;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server();       
 
@@ -84,6 +89,17 @@ PUBLIC int main(int argc, char *argv[])
 }
 
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             init_server                                  *
  *===========================================================================*/
@@ -119,8 +135,8 @@ message *m_in;                              /* pointer to message */
   endpoint_t src;
 
   do {
-       if ((r = receive(ANY, m_in)) != OK)     /* wait for message */
-               panic("MFS","receive failed", r);
+       if ((r = sef_receive(ANY, m_in)) != OK)         /* wait for message */
+               panic("MFS","sef_receive failed", r);
        src = fs_m_in.m_source;
 
        if (src != FS_PROC_NR) {
index 0040006cee1c3b99c52401b312456c3bd9d54c78..f386b07979ff8bbf55a55874ff16959842027c5b 100644 (file)
@@ -10,6 +10,9 @@
 FORWARD _PROTOTYPE(void init_server, (void)                            );
 FORWARD _PROTOTYPE(void get_work, (message *m_in)                      );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -22,6 +25,9 @@ PUBLIC int main(int argc, char *argv[])
   int error, ind;
   message m;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server();       
 
@@ -60,6 +66,16 @@ PUBLIC int main(int argc, char *argv[])
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
 
 /*===========================================================================*
  *                             init_server                                  *
@@ -99,8 +115,8 @@ message *m_in;                               /* pointer to message */
   endpoint_t src;
 
   do {
-       if ((r = receive(ANY, m_in)) != OK)     /* wait for message */
-               panic("PFS","receive failed", r);
+       if ((r = sef_receive(ANY, m_in)) != OK)         /* wait for message */
+               panic("PFS","sef_receive failed", r);
        src = fs_m_in.m_source;
 
        if (src != VFS_PROC_NR) {
index 4c56234484adc78b1e8d3c55f29f2f2eb3576a93..64f5f2f8dffa414884179b8634c4e29e09bbb340 100644 (file)
@@ -48,6 +48,9 @@ FORWARD _PROTOTYPE( void handle_fs_reply, (void)                      );
 #define click_to_round_k(n) \
        ((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -58,6 +61,9 @@ PUBLIC int main()
   struct mproc *rmp;
   sigset_t sigset;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   pm_init();                   /* initialize process manager tables */
 
   /* This is PM's main loop-  get work and do it, forever and forever. */
@@ -176,14 +182,25 @@ send_reply:
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             get_work                                     *
  *===========================================================================*/
 PRIVATE void get_work()
 {
 /* Wait for the next message and extract useful information from it. */
-  if (receive(ANY, &m_in) != OK)
-       panic(__FILE__,"PM receive error", NO_NUM);
+  if (sef_receive(ANY, &m_in) != OK)
+       panic(__FILE__,"PM sef_receive error", NO_NUM);
   who_e = m_in.m_source;       /* who sent the message */
   if(pm_isokendpt(who_e, &who_p) != OK)
        panic(__FILE__, "PM got message from invalid endpoint", who_e);
index 72cd9261b9fe96f896ed6d46225f2ed0089bf584..7c820a8fc052e0e5fd57c1773dbb567a731c603e 100644 (file)
@@ -27,7 +27,7 @@ $(UTIL):      $(UTIL_OBJ)
        $(CC) -o $@ $(LDFLAGS) $(UTIL_OBJ) $(UTIL_LIBS)
 $(SERVER):     $(OBJ)
        $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
-       install -S 350k $@
+       install -S 450k $@
 
 # install with other servers
 install:       /bin/$(UTIL) /usr/sbin/$(SERVER)
index c415ad45dbfdc05a9ccd32ca360b438a6e42686a..dff91414a47e24fda7f7572a789a0f46f7bcf7da 100644 (file)
@@ -26,6 +26,7 @@
 #define RS_CRASHED      0x040    /* service crashed */
 #define RS_LATEREPLY    0x080    /* no reply sent to RS_DOWN caller yet */
 #define RS_SIGNALED     0x100    /* service crashed */
+#define RS_UPDATING     0x200    /* set when update must be done */
 
 /* Sys flag values. */
 #define SF_CORE_PROC    0x001    /* set for core system processes
 #define END_RPROC_ADDR  (&rproc[NR_SYS_PROCS])
 #define NIL_RPROC ((struct mproc *) 0)
 
+/* Constants for live update. */
+#define RS_DEFAULT_PREPARE_MAXTIME 2*RS_DELTA_T   /* default prepare max time */
+#define RS_MAX_PREPARE_MAXTIME     20*RS_DELTA_T  /* max prepare max time */
+
 
 /* Definitions for boot info tables. */
 #define NULL_BOOT_NR    NR_BOOT_PROCS        /* marks a null boot entry */
index e1681b3424cb51325525f0ce674430bfc305fff2..9d9f4dd8aa6a896fdbeeb7c086a4828efcbdfafe 100644 (file)
@@ -37,6 +37,11 @@ EXTERN struct rproc *rproc_ptr[NR_PROCS];       /* mapping for fast access */
  */
 EXTERN int exec_pipe[2];
 
+/* Global update descriptor. This descriptor holds data when a live update
+ * is in progress.
+ */
+EXTERN struct rupdate rupdate;
+
 /* Enable/disable verbose output. */
 EXTERN long rs_verbose;
 
index 7243614c09e26bcddda94667098ca58c0e5b0b84..2b3a0a460b252c4afecde99988307b3fc8d97cc8 100644 (file)
@@ -44,6 +44,9 @@ PRIVATE char *boot_image_buffer;
 /* Flag set when memory unmapping can be done. */
 EXTERN int unmap_ok;
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -59,6 +62,9 @@ PUBLIC int main(void)
   sigset_t sigset;                             /* system signal set */
   int s;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   /* Initialize the server, then go to work. */
   init_server();       
 
@@ -74,9 +80,10 @@ PUBLIC int main(void)
 
       call_nr = m.m_type;
 
-      /* Now determine what to do.  Three types of requests are expected: 
+      /* Now determine what to do.  Four types of requests are expected:
        * - Heartbeat messages (notifications from registered system services)
        * - System notifications (POSIX signals or synchronous alarm)
+       * - Ready to update messages (reply messages from registered services)
        * - User requests (control messages to manage system services)
        */
 
@@ -87,10 +94,9 @@ PUBLIC int main(void)
           switch (who_p) {
           case CLOCK:
              do_period(&m);                    /* check services status */
-             continue;                         
-          case PM_PROC_NR:
-             sig_handler();
-              continue;                                
+             continue;
+          case PM_PROC_NR:                      /* signal or PM heartbeat */
+             sig_handler();                            
          default:                              /* heartbeat notification */
              if (rproc_ptr[who_p] != NULL) {   /* mark heartbeat time */ 
                  rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP;
@@ -101,7 +107,21 @@ PUBLIC int main(void)
          }
       }
 
-      /* If this is not a notification message, it is a normal request. 
+      /* See if this is a ready to update message.
+       * If the message was expected, update the originating process
+       */
+      else if(call_nr == RS_LU_PREPARE) {
+         result = do_upd_ready(&m);
+         
+         /* Send reply only if something went wrong. */
+          if (result != OK) {
+             m.m_type = result;
+              reply(who_e, &m);
+          }
+      }
+      
+      /* If this is neither a ready to update message nor a notification
+       * message, it is a normal request.
        * Handle the request and send a reply to the caller. 
        */
       else {
@@ -121,6 +141,7 @@ PUBLIC int main(void)
           case RS_REFRESH:     result = do_refresh(&m);        break;
           case RS_RESTART:     result = do_restart(&m);        break;
           case RS_SHUTDOWN:    result = do_shutdown(&m);       break;
+          case RS_UPDATE:      result = do_update(&m);         break;
           case GETSYSINFO:     result = do_getsysinfo(&m);     break;
          case RS_LOOKUP:       result = do_lookup(&m);         break;
           default: 
@@ -138,6 +159,17 @@ PUBLIC int main(void)
   }
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                         exec_image_copy                                  *
  *===========================================================================*/
@@ -322,6 +354,9 @@ PRIVATE void init_server(void)
   /* See if we run in verbose mode. */
   env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
 
+  /* Initialize the global update descriptor. */
+  rupdate.flags = 0;
+
   /* Get a copy of the boot image table. */
   if ((s = sys_getimage(image)) != OK) {
       panic("RS", "unable to get copy of boot image table", s);
@@ -495,7 +530,7 @@ PRIVATE void init_server(void)
       boot_image_info_lookup(boot_image_priv->endpoint, image,
           &ip, NULL, NULL, NULL);
 
-      /* Allow the process to run. */
+      /* Allow the service to run. */
       if ((s = sys_privctl(ip->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
           panic("RS", "unable to initialize privileges", s);
       }
@@ -618,8 +653,8 @@ PRIVATE void get_work(m_in)
 message *m_in;                         /* pointer to message */
 {
     int s;                             /* receive status */
-    if (OK != (s=receive(ANY, m_in)))  /* wait for message */
-        panic("RS","receive failed", s);
+    if (OK != (s=sef_receive(ANY, m_in)))      /* wait for message */
+        panic("RS", "sef_receive failed", s);
 }
 
 /*===========================================================================*
index c2fd0ca5c53b0eb0859926301123c2932e965671..0fc66b166720646610d1893467290a5f27277216 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Changes:
+ *   Nov 22, 2009:     added basic live update support  (Cristiano Giuffrida)
  *   Mar 02, 2009:     Extended isolation policies  (Jorrit N. Herder)
  *   Jul 22, 2005:     Created  (Jorrit N. Herder)
  */
@@ -38,9 +39,9 @@ FORWARD _PROTOTYPE( void add_forward_ipc, (struct rproc *rp,
 FORWARD _PROTOTYPE( void add_backward_ipc, (struct rproc *rp,
        struct priv *privp) );
 FORWARD _PROTOTYPE( void init_privs, (struct rproc *rp, struct priv *privp) );
-FORWARD _PROTOTYPE( int set_privs, (endpoint_t endpoint, struct priv *privp,
-    int req) );
 FORWARD _PROTOTYPE( void init_pci, (struct rproc *rp, int endpoint) );
+FORWARD _PROTOTYPE( void update_period, (message *m_ptr) );
+FORWARD _PROTOTYPE( void end_update, (clock_t now) );
 
 PRIVATE int shutting_down = FALSE;
 
@@ -590,6 +591,190 @@ PUBLIC int do_shutdown(message *m_ptr)
   return(OK);
 }
 
+/*===========================================================================*
+ *                             do_update                                    *
+ *===========================================================================*/
+PUBLIC int do_update(message *m_ptr)
+{
+  register struct rproc *rp;
+  size_t len;
+  int s;
+  char label[MAX_LABEL_LEN];
+  int lu_state;
+  int prepare_maxtime;
+
+  /* Retrieve label. */
+  len= m_ptr->RS_CMD_LEN;
+  if (len >= sizeof(label))
+      return EINVAL;           /* Too long */
+  s= sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR, 
+      SELF, (vir_bytes) label, len);
+  if (s != OK) return(s);
+  label[len]= '\0';
+
+  /* Retrieve live update state. */
+  lu_state = m_ptr->RS_LU_STATE;
+  if(lu_state == SEF_LU_STATE_NULL) {
+      return(EINVAL);
+  }
+
+  /* Retrieve prepare max time. */
+  prepare_maxtime = m_ptr->RS_LU_PREPARE_MAXTIME;
+  if(prepare_maxtime) {
+      if(prepare_maxtime < 0 || prepare_maxtime > RS_MAX_PREPARE_MAXTIME) {
+          return(EINVAL);
+      }
+  }
+  else {
+      prepare_maxtime = RS_DEFAULT_PREPARE_MAXTIME;
+  }
+
+  /* Make sure we are not already updating. */
+  if(rupdate.flags & RS_UPDATING) {
+      if(rs_verbose) {
+         printf("RS: do_update: an update is already in progress");
+      }
+      return(EBUSY);
+  }
+
+  /* Try to start the update process. */
+  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
+      if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
+          if(rs_verbose) {
+             printf("RS: updating %s (%d)\n", rp->r_label, rp->r_pid);
+         }
+         
+         rp->r_flags |= RS_UPDATING;
+         rupdate.flags |= RS_UPDATING;
+         getuptime(&rupdate.prepare_tm);
+          rupdate.prepare_maxtime = prepare_maxtime;
+         rupdate.rp = rp;
+         
+         m_ptr->m_type = RS_LU_PREPARE;
+         asynsend(rp->r_proc_nr_e, m_ptr);  /* request to prepare for update */
+         
+         return(OK);
+      }
+  }
+  if(rs_verbose) {
+      printf("RS: do_update: '%s' not found\n", label);
+  }
+
+  return(ESRCH);
+}
+
+/*===========================================================================*
+ *                             do_upd_ready                                 *
+ *===========================================================================*/
+PUBLIC int do_upd_ready(message *m_ptr)
+{
+  register struct rproc *rp;
+  int who_p;
+  clock_t now = m_ptr->NOTIFY_TIMESTAMP;
+  int result;
+
+  who_p = _ENDPOINT_P(m_ptr->m_source);
+  rp = rproc_ptr[who_p];
+  result = m_ptr->RS_LU_RESULT;
+
+  /* Make sure the originating process was requested to prepare for update. */
+  if(! (rp->r_flags & RS_UPDATING) ) {
+      if(rs_verbose) {
+          printf("RS: do_upd_ready: got unexpected update ready msg from %d\n",
+              m_ptr->m_source);
+      }
+      return(EINVAL);
+  }
+
+  /* Check if something went wrong and the process failed to prepare
+   * for the update. In that case, end the update process.
+   */
+  if(result != OK) {
+      end_update(now);
+      switch(result) {
+          case EACCES:
+              printf("RS: update failed: %s\n",
+                  "process does not support live update");
+          break;
+
+          case EINVAL:
+              printf("RS: update failed: %s\n",
+                  "process does not support the required state");
+          break;
+
+          case EBUSY:
+              printf("RS: update failed: %s\n",
+                  "process is not able to prepare for the update now");
+          break;
+
+          case EGENERIC:
+              printf("RS: update failed: %s\n",
+                  "a generic error occurred while preparing for the update");
+          break;
+
+          default:
+              printf("RS: update failed: %s (%d)\n",
+                  "an unknown error occurred while preparing for the update\n",
+                  result);
+          break;
+      }
+
+      return ENOTREADY;
+  }
+
+  /* Kill the process now and mark it for refresh, the new version will
+   * be automatically restarted.
+   */
+  rp->r_flags &= ~RS_EXITING;
+  rp->r_flags |= RS_REFRESHING;
+  kill(rp->r_pid, SIGKILL);
+
+  return(OK);
+}
+
+/*===========================================================================*
+ *                             update_period                                *
+ *===========================================================================*/
+PRIVATE void update_period(message *m_ptr)
+{
+  clock_t now = m_ptr->NOTIFY_TIMESTAMP;
+  short has_update_timed_out;
+  message m;
+
+  /* See if a timeout has occurred. */
+  has_update_timed_out = (now - rupdate.prepare_tm > rupdate.prepare_maxtime);
+
+  /* If an update timed out, end the update process and notify the service. */
+  if(has_update_timed_out) {
+      end_update(now);
+      printf("RS: update failed: maximum prepare time reached\n");
+
+      /* Prepare cancel request. */
+      m.m_type = RS_LU_PREPARE;
+      m.RS_LU_STATE = SEF_LU_STATE_NULL;
+      asynsend(rupdate.rp->r_proc_nr_e, &m);
+  }
+}
+
+/*===========================================================================*
+ *                             end_update                                   *
+ *===========================================================================*/
+PRIVATE void end_update(clock_t now)
+{
+  /* End the update process and mark the affected service as no longer under
+   * update. Eventual late ready to update message (if any) will simply be
+   * ignored and the service can continue executing.
+   * Also, if the service has a period, update the alive and check timestamps
+   * of the service to force a status request in the next period.
+   */
+  rupdate.flags &= ~RS_UPDATING;
+  rupdate.rp->r_flags &= ~RS_UPDATING;
+  if(rupdate.rp->r_period > 0 ) {
+      rupdate.rp->r_alive_tm = now;
+      rupdate.rp->r_check_tm = now - rupdate.rp->r_period - 1;
+  }
+}
+
 /*===========================================================================*
  *                             do_exit                                      *
  *===========================================================================*/
@@ -599,6 +784,7 @@ PUBLIC void do_exit(message *m_ptr)
   pid_t exit_pid;
   int exit_status, r, slot_nr;
   endpoint_t ep;
+  clock_t now = m_ptr->NOTIFY_TIMESTAMP;
 
   if(rs_verbose)
      printf("RS: got SIGCHLD signal, doing wait to get exited child.\n");
@@ -682,6 +868,9 @@ PUBLIC void do_exit(message *m_ptr)
                  }
              }
              else if(rp->r_flags & RS_REFRESHING) {
+                     short is_updating = rp->r_flags & RS_UPDATING;
+
+                     /* Refresh */
                      rp->r_restarts = -1;              /* reset counter */
                      if (rp->r_script[0] != '\0')
                        run_script(rp);
@@ -690,6 +879,12 @@ PUBLIC void do_exit(message *m_ptr)
                        if(m_ptr)
                                m_ptr->RS_ENDPOINT = ep;
                      }
+
+                     /* If updating, end the update process. */
+                     if(is_updating) {
+                          end_update(now);
+                          printf("RS: update succeeded\n");
+                     }
              }
              else {
                   /* Determine what to do. If this is the first unexpected 
@@ -749,9 +944,16 @@ message *m_ptr;
   int s;
   endpoint_t ep;
 
-  /* Search system services table. Only check slots that are in use. */
+  /* If an update is in progress, check its status. */
+  if(rupdate.flags & RS_UPDATING) {
+      update_period(m_ptr);
+  }
+
+  /* Search system services table. Only check slots that are in use and not
+   * updating.
+   */
   for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
-      if (rp->r_flags & RS_IN_USE) {
+      if ((rp->r_flags & RS_IN_USE) && !(rp->r_flags & RS_UPDATING)) {
 
           /* If the service is to be revived (because it repeatedly exited, 
           * and was not directly restarted), the binary backoff field is  
@@ -946,6 +1148,15 @@ endpoint_t *endpoint;
        }
   }
 
+  /* Set and synch the privilege structure for the new service. */
+  if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_SET_SYS, &rp->r_priv)) != OK
+      || (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) {
+      report("RS","unable to set privileges", s);
+      kill(child_pid, SIGKILL);                                /* kill the service */
+      rp->r_flags |= RS_EXITING;                       /* expect exit */
+      return(s);                                       /* return error */
+  }
+
   /* If PCI properties are set, inform the PCI driver about the new service. */
   if(rp->r_nr_pci_id || rp->r_nr_pci_class) {
       init_pci(rp, child_proc_nr_e);
@@ -969,24 +1180,29 @@ endpoint_t *endpoint;
   if (s != OK) {
        printf("RS: warning: publish_service failed: %d\n", s);
   }
-  if (rp->r_dev_nr > 0) {                              /* set driver map */
-      if ((s=mapdriver5(rp->r_label, strlen(rp->r_label),
-             rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
-          report("RS", "couldn't map driver (continuing)", errno);
-      }
-  }
 
-  /* Set the privilege structure for the child process.
-   * That will also cause the child process to start running.
-   * This call should succeed: we tested number in use above.
+  /* Allow the service to run.
+   * XXX FIXME: we should let the service run only after publishing information
+   * about the new system service, but this is not currently possible due to
+   * the blocking nature of mapdriver() that expects the service to be running.
+   * The current solution is not race-free. This hack can go once service
+   * publishing is made fully asynchronous in RS.
    */
-  if ((s = set_privs(child_proc_nr_e, &rp->r_priv, SYS_PRIV_SET_SYS)) != OK) {
-      report("RS","set_privs failed", s);
+  if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_ALLOW, NULL)) != OK) {
+      report("RS","unable to allow the service to run", s);
       kill(child_pid, SIGKILL);                                /* kill the service */
       rp->r_flags |= RS_EXITING;                       /* expect exit */
       return(s);                                       /* return error */
   }
 
+  /* Map the new service. */
+  if (rp->r_dev_nr > 0) {                              /* set driver map */
+      if ((s=mapdriver5(rp->r_label, strlen(rp->r_label),
+             rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
+          report("RS", "couldn't map driver (continuing)", errno);
+      }
+  }
+
   if(rs_verbose)
       printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n", 
           rp->r_cmd, rp->r_dev_nr, child_pid,
@@ -1171,12 +1387,15 @@ struct rproc *rp;
                        rp->r_script, strerror(errno));
                exit(1);
        default:
-               /* Set the privilege structure for the child process and let it
-                * run.
-                */
+               /* Set the privilege structure for the child process. */
                proc_nr_e = getnprocnr(pid);
-               if ((r= set_privs(proc_nr_e, NULL, SYS_PRIV_SET_USER)) != OK) {
-                       printf("RS: run_script: set_privs call failed: %d\n",r);
+               if ((r = sys_privctl(proc_nr_e, SYS_PRIV_SET_USER, NULL))
+                       != OK) {
+                       printf("RS: run_script: can't set privileges: %d\n",r);
+               }
+               /* Allow the process to run. */
+               if ((r = sys_privctl(proc_nr_e, SYS_PRIV_ALLOW, NULL)) != OK) {
+                       printf("RS: run_script: process can't run: %d\n",r);
                }
                /* Do not wait for the child */
                break;
@@ -1408,36 +1627,6 @@ struct priv *privp;
        }
 }
 
-/*===========================================================================*
- *                             set_privs                                    *
- *===========================================================================*/
-PRIVATE int set_privs(endpoint, privp, req)
-endpoint_t endpoint;
-struct priv *privp;
-int req;
-{
-  int r;
-
-  /* Set the privilege structure. */
-  if ((r = sys_privctl(endpoint, req, privp)) != OK) {
-      return r;
-  }
-
-  /* Synch the privilege structure with the kernel for system services. */
-  if(req == SYS_PRIV_SET_SYS) {
-      if ((r = sys_getpriv(privp, endpoint)) != OK) {
-          return r;
-      }
-  }
-
-  /* Allow the process to run. */
-  if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
-      return r;
-  }
-
-  return(OK);
-}
-
 /*===========================================================================*
  *                             init_pci                                     *
  *===========================================================================*/
diff --git a/servers/rs/manager.h b/servers/rs/manager.h
deleted file mode 100644 (file)
index 2c21e6e..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This table has one slot per system process.  It contains information for
- * servers and driver needed by the reincarnation server to keep track of 
- * each process' status. 
- */
-
-/* Space reserved for program and arguments. */
-#define MAX_COMMAND_LEN     512                /* maximum argument string length */
-#define MAX_LABEL_LEN       16         /* Unique name of (this instance of)
-                                        * the driver
-                                        */
-#define MAX_SCRIPT_LEN      256                /* maximum restart script name length */
-#define MAX_NR_ARGS          4         /* maximum number of arguments */
-#define MAX_RESCUE_DIR_LEN   64                /* maximum rescue dir length */
-
-#define MAX_IPC_LIST       256         /* Max size of list for IPC target
-                                        * process names
-                                        */
-#define MAX_VM_LIST        256
-
-/* Definition of the system process table. This table only has entries for
- * the servers and drivers, and thus is not directly indexed by slot number.
- */
-extern struct rproc {
-  int r_proc_nr_e;             /* process endpoint number */
-  pid_t r_pid;                 /* process id, -1 if the process is not there */
-  dev_t r_dev_nr;              /* major device number */
-  int r_dev_style;             /* device style */
-
-  int r_restarts;              /* number of restarts (initially zero) */
-  long r_backoff;              /* number of periods to wait before revive */
-  unsigned r_flags;            /* status and policy flags */
-
-  long r_period;               /* heartbeat period (or zero) */
-  clock_t r_check_tm;          /* timestamp of last check */
-  clock_t r_alive_tm;          /* timestamp of last heartbeat */
-  clock_t r_stop_tm;           /* timestamp of SIGTERM signal */
-  endpoint_t r_caller;         /* RS_LATEREPLY caller */
-
-  char *r_exec;                        /* Executable image */ 
-  size_t r_exec_len;           /* Length of image */
-
-  char r_label[MAX_LABEL_LEN]; /* unique name of this driver */
-  char r_cmd[MAX_COMMAND_LEN]; /* raw command plus arguments */
-  char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */
-  char *r_argv[MAX_NR_ARGS+2];  /* parsed arguments vector */
-  int r_argc;                          /* number of arguments */
-
-  /* Resources */
-  int r_set_resources;
-  struct priv r_priv;          /* Privilege structure to be passed to the
-                                * kernel.
-                                */
-  uid_t r_uid;
-  int r_nice;
-  int r_nr_pci_id;             /* Number of PCI devices IDs */
-  struct { u16_t vid; u16_t did; } r_pci_id[RSS_NR_PCI_ID];
-  int r_nr_pci_class;          /* Number of PCI class IDs */
-  struct { u32_t class; u32_t mask; } r_pci_class[RSS_NR_PCI_CLASS];
-
-  u32_t r_call_mask[RSS_NR_SYSTEM];
-  char r_ipc_list[MAX_IPC_LIST];
-  bitchunk_t r_vm[RSS_VM_CALL_SIZE];
-  int r_nr_control;
-  char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN];
-} rproc[NR_SYS_PROCS];
-
-/* Mapping for fast access to the system process table. */ 
-extern struct rproc *rproc_ptr[NR_PROCS];
-
-/* Pipe for detection of exec failures. The pipe is close-on-exec, and
- * no data will be written to the pipe if the exec succeeds. After an 
- * exec failure, the slot number is written to the pipe. After each exit,
- * a non-blocking read retrieves the slot number from the pipe.
- */
-int exec_pipe[2];
-
-/* Flag values. */
-#define RS_IN_USE       0x001  /* set when process slot is in use */
-#define RS_EXITING      0x004  /* set when exit is expected */
-#define RS_REFRESHING   0x008  /* set when refresh must be done */
-#define RS_NOPINGREPLY         0x010   /* driver failed to reply to a ping request */
-#define RS_KILLED      0x020   /* driver is killed */
-#define RS_CRASHED     0x040   /* driver crashed */
-#define RS_LATEREPLY   0x080   /* no reply sent to RS_DOWN caller yet */
-#define RS_SIGNALED    0x100   /* driver crashed */
-
-/* Constants determining RS period and binary exponential backoff. */
-#define RS_DELTA_T       60                    /* check every T ticks */
-#define BACKOFF_BITS   (sizeof(long)*8)        /* bits in backoff field */
-#define MAX_BACKOFF     30                     /* max backoff in RS_DELTA_T */
-
-/* Magic process table addresses. */
-#define BEG_RPROC_ADDR (&rproc[0])
-#define END_RPROC_ADDR (&rproc[NR_SYS_PROCS])
-#define NIL_RPROC ((struct mproc *) 0)
-
index 4372f0ed079938ce7f873cc5907a2ccbd61e8c76..7bccb85ae09a4c8ab2ee0fbc5da1d7f1c8f599a7 100644 (file)
@@ -18,6 +18,8 @@ _PROTOTYPE( int do_restart, (message *m));
 _PROTOTYPE( int do_lookup, (message *m));
 _PROTOTYPE( int do_shutdown, (message *m));
 _PROTOTYPE( void do_period, (message *m));
+_PROTOTYPE( int do_update, (message *m));
+_PROTOTYPE( int do_upd_ready, (message *m));
 _PROTOTYPE( void do_exit, (message *m));
 _PROTOTYPE( int do_getsysinfo, (message *m));
 
index f1ed0114de634c08b899e38667385776c8c22403..e8aa3f082a1912d58f1d784098450605948dd154 100644 (file)
@@ -2,7 +2,8 @@
  * reincarnation server that does the actual work. 
  *
  * Changes:
- *   Jul 22, 2005:     Created  (Jorrit N. Herder)
+ *   Nov 22, 2009: added basic live update support  (Cristiano Giuffrida)
+ *   Jul 22, 2005: Created  (Jorrit N. Herder)
  */
 
 #include <stdarg.h>
@@ -36,6 +37,7 @@ PRIVATE char *known_requests[] = {
   "refresh", 
   "restart",
   "shutdown", 
+  "update",
   "catch for illegal requests"
 };
 #define ILLEGAL_REQUEST  sizeof(known_requests)/sizeof(char *)
@@ -57,6 +59,8 @@ PRIVATE char *known_requests[] = {
 #define ARG_REQUEST    0               /* request to perform */
 #define ARG_PATH       1               /* rescue dir or system service */
 #define ARG_LABEL      1               /* name of system service */
+#define ARG_LU_STATE           2       /* the state required to update */
+#define ARG_PREPARE_MAXTIME    3       /* max time to prepare for the update */
 
 #define MIN_ARG_COUNT  1               /* require an action */
 
@@ -92,6 +96,8 @@ PRIVATE char *req_ipc;
 PRIVATE char *req_config = PATH_CONFIG;
 PRIVATE int req_printep;
 PRIVATE int class_recurs;      /* Nesting level of class statements */
+PRIVATE int req_lu_state;
+PRIVATE int req_prepare_maxtime;
 
 /* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
 PRIVATE char command[4096];    
@@ -111,6 +117,7 @@ PRIVATE void print_usage(char *app_name, char *problem)
   fprintf(stderr, "    %s down label\n", app_name);
   fprintf(stderr, "    %s refresh label\n", app_name);
   fprintf(stderr, "    %s restart label\n", app_name);
+  fprintf(stderr, "    %s update label state maxtime\n", app_name);
   fprintf(stderr, "    %s rescue <dir>\n", app_name);
   fprintf(stderr, "    %s shutdown\n", app_name);
   fprintf(stderr, "\n");
@@ -131,7 +138,7 @@ PRIVATE void failure(int num)
 PRIVATE int parse_arguments(int argc, char **argv)
 {
   struct stat stat_buf;
-  char *hz;
+  char *hz, *buff;
   int req_nr;
   int c, i;
   int c_flag, r_flag;
@@ -294,6 +301,43 @@ PRIVATE int parse_arguments(int argc, char **argv)
   else if (req_nr == RS_SHUTDOWN) {
         /* no extra arguments required */
   }
+  else if (req_nr == RS_UPDATE) {
+      /* Check for mandatory arguments */ 
+      if (argc - 1 < optind+ARG_LU_STATE) {
+          print_usage(argv[ARG_NAME],
+              "action requires at least a label and a live update state");
+          exit(EINVAL);
+      }
+      
+      /* Label. */
+      req_label= argv[optind+ARG_LABEL];
+      
+      /* Live update state. */
+      errno=0;
+      req_lu_state=strtol(argv[optind+ARG_LU_STATE], &buff, 10);
+      if(errno || strcmp(buff, "")) {
+          print_usage(argv[ARG_NAME],
+              "action requires a correct live update state");
+          exit(EINVAL);
+      }
+      if(req_lu_state == SEF_LU_STATE_NULL) {
+          print_usage(argv[ARG_NAME],
+              "action requires a non-null live update state.");
+          exit(EINVAL);
+      }
+      
+      /* Prepare max time. */
+      req_prepare_maxtime=0;
+      if (argc - 1 >= optind+ARG_PREPARE_MAXTIME) {
+          req_prepare_maxtime=strtol(argv[optind+ARG_PREPARE_MAXTIME],
+              &buff, 10);
+          if(errno || strcmp(buff, "") || req_prepare_maxtime<0) {
+              print_usage(argv[ARG_NAME],
+                "action requires a correct max time to prepare for the update");
+              exit(EINVAL);
+          }
+      }
+  }
 
   /* Return the request number if no error were found. */
   return(req_nr);
@@ -1115,6 +1159,14 @@ PUBLIC int main(int argc, char **argv)
       if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
           failure(-s);
       break;
+  case RS_UPDATE:
+      m.RS_CMD_ADDR = req_label;
+      m.RS_CMD_LEN = strlen(req_label);
+      m.RS_LU_STATE = req_lu_state;
+      m.RS_LU_PREPARE_MAXTIME = req_prepare_maxtime;
+      if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
+          failure(-s);
+      break;
   default:
       print_usage(argv[ARG_NAME], "request is not yet supported");
       result = EGENERIC;
index 4d1bd5ee093a8344960e2e371c1f2d8c5c5fb25a..473bd511b1e557754b9eda493b3bff76a394a64e 100644 (file)
@@ -75,4 +75,12 @@ struct rproc {
   char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN];
 };
 
+/* Definition of the global update descriptor. */
+struct rupdate {
+  int flags;               /* flags to keep track of the status of the update */
+  clock_t prepare_tm;      /* timestamp of when the update was scheduled */
+  clock_t prepare_maxtime; /* max time to wait for the process to be ready */
+  struct rproc *rp;        /* the process under update */
+};
+
 #endif /* RS_TYPE_H */
index ba47955b58ea334a1e885c1512bc35b73c7d1ba7..983019a6d3e9e6aa12459e98176edc0ca4073c71 100644 (file)
@@ -44,6 +44,8 @@ FORWARD _PROTOTYPE( void get_work, (void)                             );
 FORWARD _PROTOTYPE( void init_root, (void)                             );
 FORWARD _PROTOTYPE( void service_pm, (void)                            );
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 
 /*===========================================================================*
  *                             main                                         *
@@ -56,6 +58,9 @@ PUBLIC int main(void)
  */
   int error;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
   fs_init();
 
   SANITYCHECK;
@@ -223,6 +228,17 @@ PUBLIC int main(void)
   return(OK);                          /* shouldn't come here */
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 /*===========================================================================*
  *                             get_work                                     *
  *===========================================================================*/
@@ -282,8 +298,8 @@ PRIVATE void get_work()
   for(;;) {
     int r;
     /* Normal case.  No one to revive. */
-    if ((r=receive(ANY, &m_in)) != OK)
-       panic(__FILE__,"fs receive error", r);
+    if ((r=sef_receive(ANY, &m_in)) != OK)
+       panic(__FILE__,"fs sef_receive error", r);
     who_e = m_in.m_source;
     who_p = _ENDPOINT_P(who_e);
 
@@ -358,7 +374,7 @@ PRIVATE void fs_init()
    * Then, stop and synchronize with the PM.
    */
   do {
-       if (OK != (s=receive(PM_PROC_NR, &mess)))
+       if (OK != (s=sef_receive(PM_PROC_NR, &mess)))
                panic(__FILE__,"FS couldn't receive from PM", s);
        if (NONE == mess.PR_ENDPT) break; 
 
@@ -434,7 +450,7 @@ PRIVATE void init_root()
   /* Wait FS login message */
   if (last_login_fs_e != ROOT_FS_E) {
          /* Wait FS login message */
-         if (receive(ROOT_FS_E, &m) != OK) {
+         if (sef_receive(ROOT_FS_E, &m) != OK) {
                  printf("VFS: Error receiving login request from FS_e %d\n", 
                                  ROOT_FS_E);
                  panic(__FILE__, "Error receiving login request from root filesystem\n", ROOT_FS_E);
index c28e42d6e6997f928b590a71ec453af1fddbabc4..9b6882ffb93af295a32b63208b084b6c72eb33f4 100644 (file)
@@ -1097,7 +1097,7 @@ PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
           for (;;) {
               new_driver_e = 0;
               printf("VFSdead_driver: waiting for new driver\n");
-              r = receive(RS_PROC_NR, &m);
+              r = sef_receive(RS_PROC_NR, &m);
               if (r != OK) {
                   panic(__FILE__, "VFSdead_driver: unable to receive from RS", 
                                  r);
index d270a6b06fc80cecca018675b336dc84dab0ddc2..a568529da54fb5dd125fd21a0612c6670109b44b 100644 (file)
@@ -67,6 +67,8 @@ struct {
 FORWARD _PROTOTYPE(void vm_init, (void));
 FORWARD _PROTOTYPE(int vm_acl_ok, (endpoint_t caller, int call));
 
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 
 /*===========================================================================*
  *                             main                                         *
@@ -76,6 +78,9 @@ PUBLIC int main(void)
   message msg;
   int result, who_e;
 
+  /* SEF local startup. */
+  sef_local_startup();
+
 #if SANITYCHECKS
   incheck = nocheck = 0;
   FIXME("VM SANITYCHECKS are on");
@@ -99,8 +104,8 @@ PUBLIC int main(void)
        }
        SANITYCHECK(SCL_DETAIL);
 
-       if ((r=receive(ANY, &msg)) != OK)
-               vm_panic("receive() error", r);
+       if ((r=sef_receive(ANY, &msg)) != OK)
+               vm_panic("sef_receive() error", r);
 
        SANITYCHECK(SCL_DETAIL);
 
@@ -161,6 +166,17 @@ PUBLIC int main(void)
   return(OK);
 }
 
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+  /* No live update support for now. */
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
 extern int unmap_ok;
 
 /*===========================================================================*