Basic System Event Framework (SEF) with ping and live update.

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.
This commit is contained in:
Cristiano Giuffrida 2009-12-21 14:12:21 +00:00
parent 48ef79f78d
commit 1f5841c8ed
76 changed files with 2654 additions and 649 deletions

View 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;

View 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

View file

@ -24,180 +24,7 @@
#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);
}

View 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"

View file

@ -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)));
}

View 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

View 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

View 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

View 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;
}

View file

@ -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));
}

View 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

View 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;
}

View 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 *

View 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 **/

View 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 *
*===========================================================================*/

View 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)) {

View 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();
}

View 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)

View 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;
}

View file

@ -4,3 +4,4 @@
_PROTOTYPE(void main, (void));

View file

@ -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)));
}

View 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 *
*===========================================================================*/

View 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 *
*===========================================================================*/

View 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);

View 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)

101
drivers/log/liveupdate.c Normal file
View file

@ -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));
}

View 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);
}

View 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;
}

View 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

View 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 *
* *

View 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;
{

View 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)

View file

@ -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));
}

View 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 */
}

View 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 *
*===========================================================================*/

View 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: ";

View 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)

View file

@ -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));
}

View file

@ -55,57 +55,8 @@
*
*/
#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 *
*===========================================================================*/

View 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 $
*/

View 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;

View 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)

View 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 */

View 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 */

View file

@ -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));
}

View 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

View 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;

View 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 *
*===========================================================================*/

View file

@ -355,9 +355,6 @@
#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 */
@ -677,9 +674,12 @@
#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 */
@ -690,6 +690,10 @@
# 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 *
*===========================================================================*/

120
include/minix/sef.h Normal file
View file

@ -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 */

View file

@ -18,6 +18,7 @@
#endif
#include <minix/safecopies.h>
#include <minix/sef.h>
/* Forward declaration */
struct reg86u;

View 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 \

153
lib/syslib/sef.c Normal file
View file

@ -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;
}

245
lib/syslib/sef_liveupdate.c Normal file
View file

@ -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);
}

63
lib/syslib/sef_ping.c Normal file
View file

@ -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);
}

View 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 */

View 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();

View 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();
}

View 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);

View 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);
}

View 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);
}
/*===========================================================================*

View 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) {

View 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) {

View 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);

View 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)

View 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
@ -47,6 +48,10 @@
#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 */

View 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;

View 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);
}
/*===========================================================================*

View 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,6 +1180,22 @@ endpoint_t *endpoint;
if (s != OK) {
printf("RS: warning: publish_service failed: %d\n", s);
}
/* 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 = 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) {
@ -976,17 +1203,6 @@ endpoint_t *endpoint;
}
}
/* 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.
*/
if ((s = set_privs(child_proc_nr_e, &rp->r_priv, SYS_PRIV_SET_SYS)) != OK) {
report("RS","set_privs failed", s);
kill(child_pid, SIGKILL); /* kill the service */
rp->r_flags |= RS_EXITING; /* expect exit */
return(s); /* return error */
}
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 *
*===========================================================================*/

View file

@ -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)

View 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));

View 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;

View 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 */

View 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);

View 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);

View 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;
/*===========================================================================*