Browse Source

Plan 9 from Bell Labs 2005-09-13

David du Colombier 18 years ago
parent
commit
3c06e13123

+ 2 - 0
dist/replica/_plan9.db

@@ -14962,3 +14962,5 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+sys/src/9/port/portdat.h - 664 sys sys 1126582287 22484
+sys/src/9/port/portfns.h - 664 sys sys 1126582287 11006

+ 2 - 2
dist/replica/plan9.db

@@ -8098,8 +8098,8 @@ sys/src/9/port/page.c - 664 sys sys 1102133425 8281
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1072704671 3940
 sys/src/9/port/portclock.c - 664 sys sys 1102093397 4556
-sys/src/9/port/portdat.h - 664 sys sys 1109541435 22233
-sys/src/9/port/portfns.h - 664 sys sys 1123647283 10976
+sys/src/9/port/portdat.h - 664 sys sys 1126582287 22484
+sys/src/9/port/portfns.h - 664 sys sys 1126582287 11006
 sys/src/9/port/portmkfile - 664 sys sys 1124708650 2052
 sys/src/9/port/print.c - 664 sys sys 1014931178 227
 sys/src/9/port/proc.c - 664 sys sys 1099760501 28207

+ 2 - 0
dist/replica/plan9.log

@@ -21267,3 +21267,5 @@
 1126355461 0 c sys/lib/dist/pc/sub/termrc - 664 sys sys 1126355274 2209
 1126362662 0 c sys/src/cmd/dd.c - 664 sys sys 1126360951 11753
 1126409473 0 c 386/bin/dd - 775 sys sys 1126408183 45398
+1126582261 0 c sys/src/9/port/portdat.h - 664 sys sys 1126582287 22484
+1126582261 1 c sys/src/9/port/portfns.h - 664 sys sys 1126582287 11006

+ 172 - 0
sys/src/9/port/devwd.c

@@ -0,0 +1,172 @@
+#include	"u.h"
+#include	"../port/lib.h"
+#include	"mem.h"
+#include	"dat.h"
+#include	"fns.h"
+#include	"io.h"
+#include	"../port/error.h"
+
+enum {
+	Qdir,
+	Qwdctl,
+};
+
+static Watchdog *wd;
+static Dirtab wddir[] = {
+	".",		{ Qdir, 0, QTDIR },	0,		0550,
+	"wdctl",	{ Qwdctl, 0 },		0,		0660,
+};
+
+
+void
+addwatchdog(Watchdog *watchdog)
+{
+	if(wd){
+		print("addwatchdog: watchdog already installed\n");
+		return;
+	}
+	wd = watchdog;
+	if(wd)
+		wd->disable();
+}
+
+static Chan*
+wdattach(char *spec)
+{
+	return devattach('w', spec);
+}
+
+static Walkqid*
+wdwalk(Chan *c, Chan *nc, char **name, int nname)
+{
+	return devwalk(c, nc, name, nname, wddir, nelem(wddir), devgen);
+}
+
+static int
+wdstat(Chan *c, uchar *dp, int n)
+{
+	return devstat(c, dp, n, wddir, nelem(wddir), devgen);
+}
+
+static Chan*
+wdopen(Chan* c, int omode)
+{
+	return devopen(c, omode, wddir, nelem(wddir), devgen);
+}
+
+static void
+wdclose(Chan*)
+{
+}
+
+static long
+wdread(Chan* c, void* a, long n, vlong off)
+{
+	char *p;
+	ulong offset = off;
+
+	switch((ulong)c->qid.path){
+	case Qdir:
+		return devdirread(c, a, n, wddir, nelem(wddir), devgen);
+
+	case Qwdctl:
+		if(wd == nil || wd->stat == nil)
+			return 0;
+
+		p = malloc(READSTR);
+		if(waserror()){
+			free(p);
+			nexterror();
+		}
+
+		wd->stat(p, p + READSTR);
+		n = readstr(offset, a, n, p);
+		poperror();
+		free(p);
+		return n;
+
+	default:
+		error(Egreg);
+		break;
+	}
+	return 0;
+}
+
+static void
+wdctl(char *a)
+{
+	int n;
+	char *field[6];
+
+	n = tokenize(a, field, nelem(field));
+	if(n < 1)
+		error(Ebadarg);
+
+	if(!strcmp(field[0], "enable"))
+		wd->enable();
+	else if(!strcmp(field[0], "disable"))
+		wd->disable();
+	else if(!strcmp(field[0], "restart"))
+		wd->restart();
+	else
+		error(Ebadarg);
+}
+
+static long
+wdwrite(Chan* c, void* a, long n, vlong off)
+{
+	char *p;
+	ulong offset = off;
+
+	switch((ulong)c->qid.path){
+	case Qdir:
+		error(Eperm);
+
+	case Qwdctl:
+		if(wd == nil)
+			return n;
+
+		if(offset || n >= READSTR)
+			error(Ebadarg);
+
+		p = malloc(READSTR);
+		if(waserror()){
+			free(p);
+			nexterror();
+		}
+		memmove(p, a, n);
+		p[n] = 0;
+		wdctl(p);
+		poperror();
+		free(p);
+		return n;
+
+	default:
+		error(Egreg);
+		break;
+	}
+
+	return 0;
+}
+
+Dev wddevtab = {
+	'w',
+	"watchdog",
+
+	devreset,
+	devinit,
+	devshutdown,
+	wdattach,
+	wdwalk,
+	wdstat,
+	wdopen,
+	devcreate,
+	wdclose,
+	wdread,
+	devbread,
+	wdwrite,
+	devbwrite,
+	devremove,
+	devwstat,
+	devpower,
+};

+ 10 - 0
sys/src/9/port/portdat.h

@@ -44,6 +44,7 @@ typedef struct Timers	Timers;
 typedef struct Uart	Uart;
 typedef struct Waitq	Waitq;
 typedef struct Walkqid	Walkqid;
+typedef struct Watchdog	Watchdog;
 typedef int    Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
 
 #pragma incomplete DevConf
@@ -912,6 +913,15 @@ struct Perf
 	ulong	period;		/* perfticks() per clock tick */
 };
 
+struct Watchdog
+{
+	void	(*enable)(void);	/* watchdog enable */
+	void	(*disable)(void);	/* watchdog disable */
+	void	(*restart)(void);	/* watchdog restart */
+	void	(*stat)(char*, char*);	/* watchdog statistics */
+};
+
+
 /* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
 enum
 {

+ 1 - 0
sys/src/9/port/portfns.h

@@ -2,6 +2,7 @@ void		accounttime(void);
 Timer*		addclock0link(void (*)(void), int);
 int		addphysseg(Physseg*);
 void		addbootfile(char*, uchar*, ulong);
+void		addwatchdog(Watchdog*);
 Block*		adjustblock(Block*, int);
 void		alarmkproc(void*);
 Block*		allocb(int);