. added cd-probe logic; tries to find the right root filesystem
if the boot monitor parameter is set. it also sets a boot monitor parameter (by talking to the PM) so userland knows it. . ramdisk copy code made slightly smarter . various select() prettifications (work in progress)
This commit is contained in:
parent
f73af8573a
commit
6e8f484b3b
7 changed files with 176 additions and 51 deletions
|
@ -16,7 +16,8 @@ LIBS = -lsys -lsysutil -ltimers
|
||||||
OBJ = main.o open.o read.o write.o pipe.o dmap.o \
|
OBJ = main.o open.o read.o write.o pipe.o dmap.o \
|
||||||
device.o path.o mount.o link.o super.o inode.o \
|
device.o path.o mount.o link.o super.o inode.o \
|
||||||
cache.o cache2.o filedes.o stadir.o protect.o time.o \
|
cache.o cache2.o filedes.o stadir.o protect.o time.o \
|
||||||
cmostime.o lock.o misc.o utility.o select.o timers.o table.o
|
cmostime.o lock.o misc.o utility.o select.o timers.o table.o \
|
||||||
|
cdprobe.o
|
||||||
|
|
||||||
# build local binary
|
# build local binary
|
||||||
all build: $(SERVER)
|
all build: $(SERVER)
|
||||||
|
|
87
servers/fs/cdprobe.c
Normal file
87
servers/fs/cdprobe.c
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/* This file contains some code to guess where we have to load the
|
||||||
|
* RAM image device from, if started from CD. (In this case it's hard
|
||||||
|
* to tell where this is without diving into BIOS heuristics.)
|
||||||
|
*
|
||||||
|
* There is some nasty hard-codery in here (e.g. AT minor device numbers,
|
||||||
|
* MINIX cd label) that can be improved on.
|
||||||
|
*
|
||||||
|
* Changes:
|
||||||
|
* Jul 14, 2005 Created (Ben Gras)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fs.h"
|
||||||
|
#include "super.h"
|
||||||
|
|
||||||
|
#include <minix/com.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* cdprobe *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC int cdprobe(void)
|
||||||
|
{
|
||||||
|
#define CD_SECTOR 2048
|
||||||
|
#define AT_MAJOR 3
|
||||||
|
#define AT_MINORS 4
|
||||||
|
int i, minors[AT_MINORS] = { 0, 5, 10, 15 }, dev = 0, found = 0;
|
||||||
|
char pvd[CD_SECTOR];
|
||||||
|
for(i = 0; i < AT_MINORS && !found; i++) {
|
||||||
|
struct super_block probe_super;
|
||||||
|
int r, minor;
|
||||||
|
|
||||||
|
dev = (AT_MAJOR << MAJOR) | minors[i];
|
||||||
|
|
||||||
|
/* 1. The drive should be a CD - which is not write-openable.
|
||||||
|
* Check for this.
|
||||||
|
*/
|
||||||
|
if((r = dev_open(dev, FS_PROC_NR, R_BIT|W_BIT)) == OK) {
|
||||||
|
dev_close(dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. The drive should be a CD. Open whole drive and
|
||||||
|
* check for the PVD.
|
||||||
|
*/
|
||||||
|
if((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if((r = dev_io(DEV_READ, dev, FS_PROC_NR, pvd,
|
||||||
|
16*CD_SECTOR, sizeof(pvd), 0)) != sizeof(pvd)) {
|
||||||
|
dev_close(dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dev_close(dev);
|
||||||
|
|
||||||
|
/* Check PVD ID. */
|
||||||
|
if(pvd[0] != 1 || pvd[1] != 'C' || pvd[2] != 'D' ||
|
||||||
|
pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' || pvd[6] != 1 ||
|
||||||
|
strncmp(pvd + 40, "MINIX", 5)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. Both c0dXp1 and p2 should have a superblock. */
|
||||||
|
for(minor = minors[i]+2; minor <= minors[i]+3; minor++) {
|
||||||
|
dev = (AT_MAJOR << MAJOR) | minor;
|
||||||
|
if((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK)
|
||||||
|
continue;
|
||||||
|
probe_super.s_dev = dev;
|
||||||
|
r = read_super(&probe_super);
|
||||||
|
dev_close(dev);
|
||||||
|
if(r != OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(minor > minors[i]+3) {
|
||||||
|
/* Success? Then set dev to p1. */
|
||||||
|
dev = (AT_MAJOR << MAJOR) | (minors[i]+2);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) return NO_DEV;
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct super_block; /* proto.h needs to know this */
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioc_memory.h>
|
#include <sys/ioc_memory.h>
|
||||||
|
@ -34,12 +35,11 @@ struct super_block; /* proto.h needs to know this */
|
||||||
|
|
||||||
|
|
||||||
FORWARD _PROTOTYPE( void fs_init, (void) );
|
FORWARD _PROTOTYPE( void fs_init, (void) );
|
||||||
FORWARD _PROTOTYPE( int igetenv, (char *var) );
|
FORWARD _PROTOTYPE( int igetenv, (char *var, int optional) );
|
||||||
FORWARD _PROTOTYPE( void get_work, (void) );
|
FORWARD _PROTOTYPE( void get_work, (void) );
|
||||||
FORWARD _PROTOTYPE( void load_ram, (void) );
|
FORWARD _PROTOTYPE( void load_ram, (void) );
|
||||||
FORWARD _PROTOTYPE( void load_super, (Dev_t super_dev) );
|
FORWARD _PROTOTYPE( void load_super, (Dev_t super_dev) );
|
||||||
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* main *
|
* main *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
@ -225,6 +225,7 @@ PRIVATE void fs_init()
|
||||||
map_controllers(); /* map controller devices to drivers */
|
map_controllers(); /* map controller devices to drivers */
|
||||||
load_ram(); /* init RAM disk, load if it is root */
|
load_ram(); /* init RAM disk, load if it is root */
|
||||||
load_super(root_dev); /* load super block for root device */
|
load_super(root_dev); /* load super block for root device */
|
||||||
|
init_select(); /* init select() structures */
|
||||||
|
|
||||||
|
|
||||||
/* The root device can now be accessed; set process directories. */
|
/* The root device can now be accessed; set process directories. */
|
||||||
|
@ -242,19 +243,22 @@ PRIVATE void fs_init()
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* igetenv *
|
* igetenv *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int igetenv(key)
|
PRIVATE int igetenv(key, optional)
|
||||||
char *key;
|
char *key;
|
||||||
|
int optional;
|
||||||
{
|
{
|
||||||
/* Ask kernel for an integer valued boot environment variable. */
|
/* Ask kernel for an integer valued boot environment variable. */
|
||||||
char value[64];
|
char value[64];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((i = get_mon_param(key, value, sizeof(value))) != OK)
|
if ((i = get_mon_param(key, value, sizeof(value))) != OK) {
|
||||||
|
if(!optional)
|
||||||
printf("FS: Warning, couldn't get monitor param: %d\n", i);
|
printf("FS: Warning, couldn't get monitor param: %d\n", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return(atoi(value));
|
return(atoi(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* load_ram *
|
* load_ram *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
@ -276,18 +280,38 @@ PRIVATE void load_ram(void)
|
||||||
int block_size_image, block_size_ram, ramfs_block_size;
|
int block_size_image, block_size_ram, ramfs_block_size;
|
||||||
|
|
||||||
/* Get some boot environment variables. */
|
/* Get some boot environment variables. */
|
||||||
root_dev = igetenv("rootdev");
|
root_dev = igetenv("rootdev", 0);
|
||||||
image_dev = igetenv("ramimagedev");
|
image_dev = igetenv("ramimagedev", 0);
|
||||||
ram_size_kb = igetenv("ramsize");
|
ram_size_kb = igetenv("ramsize", 0);
|
||||||
|
|
||||||
/* Open the root device. */
|
/* Open the root device. */
|
||||||
if (dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT) != OK) {
|
if (dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT) != OK)
|
||||||
panic(__FILE__,"Cannot open root device",NO_NUM);
|
panic(__FILE__,"Cannot open root device",NO_NUM);
|
||||||
}
|
|
||||||
|
|
||||||
/* If we must initialize a ram disk, get details from the image device. */
|
/* If we must initialize a ram disk, get details from the image device. */
|
||||||
if (root_dev == DEV_RAM || root_dev != image_dev) {
|
if (root_dev == DEV_RAM || root_dev != image_dev) {
|
||||||
u32_t fsmax;
|
u32_t fsmax, probedev;
|
||||||
|
|
||||||
|
/* If we are running from CD, see if we can find it. */
|
||||||
|
if(igetenv("cdproberoot", 1) && (probedev=cdprobe()) != NO_DEV) {
|
||||||
|
char devnum[10];
|
||||||
|
struct sysgetenv env;
|
||||||
|
|
||||||
|
/* If so, this is our new RAM image device. */
|
||||||
|
image_dev = probedev;
|
||||||
|
|
||||||
|
/* Tell PM about it, so userland can find out about it
|
||||||
|
* with sysenv interface.
|
||||||
|
*/
|
||||||
|
env.key = "cdproberoot";
|
||||||
|
env.keylen = strlen(env.key);
|
||||||
|
sprintf(devnum, "%d", probedev);
|
||||||
|
env.val = devnum;
|
||||||
|
env.vallen = strlen(devnum);
|
||||||
|
svrctl(MMSETPARAM, &env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open image device for RAM root. */
|
||||||
if (dev_open(image_dev, FS_PROC_NR, R_BIT) != OK)
|
if (dev_open(image_dev, FS_PROC_NR, R_BIT) != OK)
|
||||||
panic(__FILE__,"Cannot open RAM image device", NO_NUM);
|
panic(__FILE__,"Cannot open RAM image device", NO_NUM);
|
||||||
|
|
||||||
|
@ -349,21 +373,33 @@ PRIVATE void load_ram(void)
|
||||||
block_size_ram = get_block_size(DEV_RAM);
|
block_size_ram = get_block_size(DEV_RAM);
|
||||||
block_size_image = get_block_size(image_dev);
|
block_size_image = get_block_size(image_dev);
|
||||||
|
|
||||||
if(block_size_ram != block_size_image) {
|
/* RAM block size has to be a multiple of the root image block
|
||||||
printf("ram block size: %d image block size: %d\n",
|
* size to make copying easier.
|
||||||
|
*/
|
||||||
|
if(block_size_image % block_size_ram) {
|
||||||
|
printf("\nram block size: %d image block size: %d\n",
|
||||||
block_size_ram, block_size_image);
|
block_size_ram, block_size_image);
|
||||||
panic(__FILE__,"ram disk and image disk block sizes must match", NO_NUM);
|
panic(__FILE__, "ram disk block size must be a multiple of the image disk block size", NO_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loading blocks from image device. */
|
||||||
for (b = 0; b < (block_t) lcount; b++) {
|
for (b = 0; b < (block_t) lcount; b++) {
|
||||||
|
int rb, factor;
|
||||||
bp = rahead(&inode[0], b, (off_t)block_size_image * b, block_size_image);
|
bp = rahead(&inode[0], b, (off_t)block_size_image * b, block_size_image);
|
||||||
bp1 = get_block(root_dev, b, NO_READ);
|
factor = block_size_image/block_size_ram;
|
||||||
memcpy(bp1->b_data, bp->b_data, (size_t) block_size_image);
|
for(rb = 0; rb < factor; rb++) {
|
||||||
|
bp1 = get_block(root_dev, b * factor + rb, NO_READ);
|
||||||
|
memcpy(bp1->b_data, bp->b_data + rb * block_size_ram,
|
||||||
|
(size_t) block_size_ram);
|
||||||
bp1->b_dirt = DIRTY;
|
bp1->b_dirt = DIRTY;
|
||||||
put_block(bp, FULL_DATA_BLOCK);
|
|
||||||
put_block(bp1, FULL_DATA_BLOCK);
|
put_block(bp1, FULL_DATA_BLOCK);
|
||||||
printf("\b\b\b\b\b\b\b%5ldK ", ((long) b * block_size_image)/1024L);
|
|
||||||
}
|
}
|
||||||
|
put_block(bp, FULL_DATA_BLOCK);
|
||||||
|
printf("\b\b\b\b\b\b\b\b%6ldK ", ((long) b * block_size_image)/1024L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Commit changes to RAM so dev_io will see it. */
|
||||||
|
do_sync();
|
||||||
|
|
||||||
printf("\rRAM disk of %u kb loaded.\33[K", ram_size_kb);
|
printf("\rRAM disk of %u kb loaded.\33[K", ram_size_kb);
|
||||||
if (root_dev == DEV_RAM) printf(" RAM disk is used as root FS.");
|
if (root_dev == DEV_RAM) printf(" RAM disk is used as root FS.");
|
||||||
|
|
|
@ -184,9 +184,14 @@ _PROTOTYPE( int do_select, (void) );
|
||||||
_PROTOTYPE( int select_callback, (struct filp *, int ops) );
|
_PROTOTYPE( int select_callback, (struct filp *, int ops) );
|
||||||
_PROTOTYPE( void select_forget, (int fproc) );
|
_PROTOTYPE( void select_forget, (int fproc) );
|
||||||
_PROTOTYPE( void select_timeout_check, (timer_t *) );
|
_PROTOTYPE( void select_timeout_check, (timer_t *) );
|
||||||
|
_PROTOTYPE( void init_select, (void) );
|
||||||
_PROTOTYPE( int select_notified, (message *) );
|
_PROTOTYPE( int select_notified, (message *) );
|
||||||
|
|
||||||
/* timers.c */
|
/* timers.c */
|
||||||
_PROTOTYPE( void fs_set_timer, (timer_t *tp, int delta, tmr_func_t watchdog, int arg));
|
_PROTOTYPE( void fs_set_timer, (timer_t *tp, int delta, tmr_func_t watchdog, int arg));
|
||||||
_PROTOTYPE( void fs_expire_timers, (clock_t now));
|
_PROTOTYPE( void fs_expire_timers, (clock_t now));
|
||||||
_PROTOTYPE( void fs_cancel_timer, (timer_t *tp));
|
_PROTOTYPE( void fs_cancel_timer, (timer_t *tp));
|
||||||
|
_PROTOTYPE( void fs_init_timer, (timer_t *tp));
|
||||||
|
|
||||||
|
/* cdprobe.c */
|
||||||
|
_PROTOTYPE( int cdprobe, (void));
|
||||||
|
|
|
@ -58,9 +58,7 @@ FORWARD _PROTOTYPE(int select_reevaluate, (struct filp *fp));
|
||||||
FORWARD _PROTOTYPE(int select_request_file, (struct filp *f, int *ops, int block));
|
FORWARD _PROTOTYPE(int select_request_file, (struct filp *f, int *ops, int block));
|
||||||
FORWARD _PROTOTYPE(int select_match_file, (struct filp *f));
|
FORWARD _PROTOTYPE(int select_match_file, (struct filp *f));
|
||||||
|
|
||||||
FORWARD _PROTOTYPE(int select_request_tty, (struct filp *f, int *ops, int block));
|
FORWARD _PROTOTYPE(int select_request_general, (struct filp *f, int *ops, int block));
|
||||||
FORWARD _PROTOTYPE(int select_request_inet, (struct filp *f, int *ops, int block));
|
|
||||||
FORWARD _PROTOTYPE(int select_request_log, (struct filp *f, int *ops, int block));
|
|
||||||
FORWARD _PROTOTYPE(int select_major_match, (int match_major, struct filp *file));
|
FORWARD _PROTOTYPE(int select_major_match, (int match_major, struct filp *file));
|
||||||
|
|
||||||
FORWARD _PROTOTYPE(void select_cancel_all, (struct selectentry *e));
|
FORWARD _PROTOTYPE(void select_cancel_all, (struct selectentry *e));
|
||||||
|
@ -80,13 +78,13 @@ PRIVATE struct fdtype {
|
||||||
/* SELFD_FILE */
|
/* SELFD_FILE */
|
||||||
{ select_request_file, select_match_file, 0 },
|
{ select_request_file, select_match_file, 0 },
|
||||||
/* SELFD_TTY (also PTY) */
|
/* SELFD_TTY (also PTY) */
|
||||||
{ select_request_tty, NULL, TTY_MAJOR },
|
{ select_request_general, NULL, TTY_MAJOR },
|
||||||
/* SELFD_INET */
|
/* SELFD_INET */
|
||||||
{ select_request_inet, NULL, INET_MAJOR },
|
{ select_request_general, NULL, INET_MAJOR },
|
||||||
/* SELFD_PIPE (pipe(2) pipes and FS FIFOs) */
|
/* SELFD_PIPE (pipe(2) pipes and FS FIFOs) */
|
||||||
{ select_request_pipe, select_match_pipe, 0 },
|
{ select_request_pipe, select_match_pipe, 0 },
|
||||||
/* SELFD_LOG (/dev/klog) */
|
/* SELFD_LOG (/dev/klog) */
|
||||||
{ select_request_log, NULL, LOG_MAJOR },
|
{ select_request_general, NULL, LOG_MAJOR },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Open Group:
|
/* Open Group:
|
||||||
|
@ -128,25 +126,9 @@ PRIVATE int select_request_tty(struct filp *f, int *ops, int block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* select_request_inet *
|
* select_request_general *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int select_request_inet(struct filp *f, int *ops, int block)
|
PRIVATE int select_request_general(struct filp *f, int *ops, int block)
|
||||||
{
|
|
||||||
int r, rops;
|
|
||||||
rops = *ops;
|
|
||||||
if(block) rops |= SEL_NOTIFY;
|
|
||||||
*ops = dev_io(DEV_SELECT, f->filp_ino->i_zone[0], rops, NULL, 0, 0, 0);
|
|
||||||
printf("select_request_inet: got reply %d from inet for %d on %d\n",
|
|
||||||
*ops, rops, f->filp_ino->i_zone[0]);
|
|
||||||
if(*ops < 0)
|
|
||||||
return SEL_ERR;
|
|
||||||
return SEL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* select_request_log *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int select_request_log(struct filp *f, int *ops, int block)
|
|
||||||
{
|
{
|
||||||
int r, rops;
|
int r, rops;
|
||||||
rops = *ops;
|
rops = *ops;
|
||||||
|
@ -536,7 +518,6 @@ PUBLIC int select_callback(struct filp *fp, int ops)
|
||||||
* operations that we are still interested in, if any.
|
* operations that we are still interested in, if any.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
restart_callback:
|
|
||||||
want_ops = 0;
|
want_ops = 0;
|
||||||
type = -1;
|
type = -1;
|
||||||
for(s = 0; s < MAXSELECTS; s++) {
|
for(s = 0; s < MAXSELECTS; s++) {
|
||||||
|
@ -613,6 +594,16 @@ PUBLIC int select_notified(message *m)
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
/*===========================================================================*
|
||||||
|
* init_select *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC void init_select(void)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
|
||||||
|
for(s = 0; s < MAXSELECTS; s++)
|
||||||
|
fs_init_timer(&selecttab[s].timer);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* int select_forget *
|
* int select_forget *
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* This file manages the super block table and the related data structures,
|
/* This file manages the super block table and the related data structures, * namely, the bit maps that keep track of which zones and which inodes are
|
||||||
* namely, the bit maps that keep track of which zones and which inodes are
|
|
||||||
* allocated and which are free. When a new inode or zone is needed, the
|
* allocated and which are free. When a new inode or zone is needed, the
|
||||||
* appropriate bit map is searched for a free entry.
|
* appropriate bit map is searched for a free entry.
|
||||||
*
|
*
|
||||||
|
@ -174,9 +173,11 @@ PUBLIC int get_block_size(dev_t dev)
|
||||||
if(dev == NO_DEV)
|
if(dev == NO_DEV)
|
||||||
panic(__FILE__,"request for block size of NO_DEV", NO_NUM);
|
panic(__FILE__,"request for block size of NO_DEV", NO_NUM);
|
||||||
|
|
||||||
for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
|
for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++) {
|
||||||
if (sp->s_dev == dev)
|
if (sp->s_dev == dev) {
|
||||||
return(sp->s_block_size);
|
return(sp->s_block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* no mounted filesystem? use this block size then. */
|
/* no mounted filesystem? use this block size then. */
|
||||||
return MIN_BLOCK_SIZE;
|
return MIN_BLOCK_SIZE;
|
||||||
|
|
|
@ -19,7 +19,6 @@ PUBLIC void fs_set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
|
||||||
if((r = getuptime(&now)) != OK)
|
if((r = getuptime(&now)) != OK)
|
||||||
panic(__FILE__, "FS couldn't get uptime from system task.", NO_NUM);
|
panic(__FILE__, "FS couldn't get uptime from system task.", NO_NUM);
|
||||||
|
|
||||||
tmr_inittimer(tp);
|
|
||||||
tmr_arg(tp)->ta_int = arg;
|
tmr_arg(tp)->ta_int = arg;
|
||||||
|
|
||||||
old_head = tmrs_settimer(&fs_timers, tp, now+ticks, watchdog, &new_head);
|
old_head = tmrs_settimer(&fs_timers, tp, now+ticks, watchdog, &new_head);
|
||||||
|
@ -54,6 +53,11 @@ PUBLIC void fs_expire_timers(clock_t now)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUBLIC void fs_init_timer(timer_t *tp)
|
||||||
|
{
|
||||||
|
tmr_inittimer(tp);
|
||||||
|
}
|
||||||
|
|
||||||
PUBLIC void fs_cancel_timer(timer_t *tp)
|
PUBLIC void fs_cancel_timer(timer_t *tp)
|
||||||
{
|
{
|
||||||
clock_t new_head, old_head;
|
clock_t new_head, old_head;
|
||||||
|
|
Loading…
Reference in a new issue