changeset 1:0b9854adb86c

Remove tedious messages and daemonize vd_watchdog.
author Thinker K.F. Li <thinker@branda.to>
date Tue, 08 Jul 2008 11:07:31 +0800
parents 71475f5afa92
children 89e9d591748d
files vd_watchdog/vd_watchdog.c vordog.c
diffstat 2 files changed, 110 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/vd_watchdog/vd_watchdog.c	Tue Jul 08 09:57:54 2008 +0800
+++ b/vd_watchdog/vd_watchdog.c	Tue Jul 08 11:07:31 2008 +0800
@@ -3,13 +3,16 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include "vordog.h"
 
 #define DEVNAME "/dev/vordog0"
 #define PROG "vd_watchdog"
 
+static int unit_factors[] = {0, 1, 60, 3600};
+
 static void
-watchdog(int min) {
+watchdog(int timeout, int unit) {
     struct vordog_cfg cfg;
     int intval;
     int r;
@@ -20,15 +23,17 @@
 	perror(PROG);
 	exit(1);
     }
-    cfg.init_val = min;
-    cfg.unit = VDT_1M;
+
+    cfg.init_val = timeout;
+    cfg.unit = unit;
     r = ioctl(fd, VDCTL_ENABLE, &cfg);
     if(r == -1) {
 	perror(PROG);
 	exit(1);
     }
-    
-    intval = min * 60 * 3 / 4;
+
+    /* reset timer periodically */
+    intval = timeout * unit_factors[unit];
     while(1) {
 	sleep(intval);
 	r = ioctl(fd, VDCTL_RESET);
@@ -36,13 +41,100 @@
 	    perror(PROG);
 	    exit(1);
 	}
-	printf("reset\n");
+    }
+}
+
+static void
+daemonize(void) {
+    pid_t pid;
+
+    pid = fork();
+    if(pid == -1) {
+	perror("fork");
+	exit(1);
     }
+
+    if(pid != 0)
+	exit(0);		/* parent */
+
+    /* child process */
+    pid = setsid();
+    if(pid == -1) {
+	perror("setsid");
+	exit(1);
+    }
+
+    close(STDOUT_FILENO);
+    close(STDOUT_FILENO);
+    /* close(STDERR_FILENO); */
+}
+
+static void
+usage(const char *prog) {
+    fprintf(stderr, "Usage: %s [-msMH] <timeout>\n");
+    fprintf(stderr, "\t-s\tcount in seconds.\n");
+    fprintf(stderr, "\t-M\tcount in minutes.\n");
+    fprintf(stderr, "\t-m\tcount in hours.\n");
+    fprintf(stderr,
+	    "\t<timeout> is interval between periodically reset of\n"
+	    "\t\twatchdog timer, or the system would be reseted without\n"
+	    "\t\treseting timer for 4 times. (default: 30s)\n"
+	    "\t\t(note: 1~255)\n");
 }
 
 
+static char *unit_names[] = {
+    "* 4ms",
+    "seconds",
+    "minutes",
+    "hours"
+};
+
 int
-main(int argc, const char *argv[]) {
-    watchdog(1);
+main(int argc, char * const argv[]) {
+    int timeout, unit;
+    int ch;
+    const char *prog = argv[0];
+    
+    timeout = 30;		/* default: 30s */
+    unit = VDT_1S;
+    
+    while((ch = getopt(argc, argv, "")) != -1) {
+	switch(ch) {
+	case 's':
+	    unit = VDT_1S;
+	    break;
+	case 'M':
+	    unit = VDT_1M;
+	    break;
+	case 'H':
+	    unit = VDT_1H;
+	    break;
+	case '?':
+	default:
+	    usage(prog);
+	    exit(1);
+	}
+    }
+    argc -= optind;
+    argv += optind;
+
+    if(argc != 1 && argc != 0) {
+	usage(prog);
+	return 1;
+    }
+
+    if(argc == 1)
+	timeout = atoi(argv[0]);
+    if(timeout < 1 || timeout > 255) {
+	usage(prog);
+	return 1;
+    }
+    
+    printf("Reset watchdog timer every %d %s\n",
+	   timeout, unit_names[unit]);
+
+    daemonize();
+    watchdog(timeout, unit);
     return 0;
 }
--- a/vordog.c	Tue Jul 08 09:57:54 2008 +0800
+++ b/vordog.c	Tue Jul 08 11:07:31 2008 +0800
@@ -81,36 +81,15 @@
     int val;
 #define VD_TIMER_RST 0xc
 
-#if 0
-    outb(VD_STATUS, 0xc0);	/* Clear events or it would be reset
-				 * immediately, since it is setted
-				 * by last timeout before PCIRST.
-				 */
-#endif
     val = cfg->init_val & 0xff;
-    printf("setup_timer 1 (%x)\n", val);
-    pause("vordog setup", hz);
     outb(VD_INITVAL, val);
-    printf("setup_timer 2\n");
     val = 0x80 | ((cfg->unit & 0x3) << 4) | VD_TIMER_RST;
-    printf("setup_timer 3 (%x)\n", val);
-    pause("vordog setup", hz);
     outb(VD_CTR, val);
-    printf("setup_timer 4\n");
 }
 
 static void
 reset_timer(int init_val) {
-#if 0
-    printf("reset_timer 1\n");
-    pause("vordog setup", hz);
-    outb(VD_INITVAL, init_val);
-#endif
-    printf("reset_timer 2\n");
-    pause("vordog setup", hz);
     outb(VD_STATUS, 0xc0);
-    printf("reset_timer 3\n");
-    pause("vordog setup", hz);
 }
 
 static void
@@ -129,17 +108,14 @@
     sc = CDEV_2_SOFTC(dev);
     switch(cmd) {
     case VDCTL_ENABLE:
-	printf("VDCTL_ENABLE\n");
 	cfg = (vordog_cfg_t)data;
 	sc->init_val = cfg->init_val & 0xff;
 	setup_timer(cfg);
 	break;
     case VDCTL_RESET:
-	printf("VDCTL_RESET\n");
 	reset_timer(sc->init_val);
 	break;
     case VDCTL_DISABLE:
-	printf("VDCTL_DISABLE\n");
 	disable_timer();
 	break;
     default:
@@ -161,24 +137,23 @@
     
     /* make sure vordog device is not in the bus. */
     vordog = device_find_child(parent, "vordog", 0);
-    if(vordog != NULL) {
-	printf("vordog is still existing!");
+    if(vordog != NULL)
 	return;
-    }
     vordog = BUS_ADD_CHILD(parent, 10, "vordog", 0);
-    printf("vordog_identify\n");
 }
 
 static int vordog_probe(device_t dev) {
     int b;
 
-    printf("vordog_probe\n");
     b = inb(VD_INITVAL);
-    printf("init val: %x\n", b);
+    if(b != 0)
+	return EINVAL;
     b = inb(VD_CTR);
-    printf("ctr: %x\n", b);
+    if(b != 0)
+	return EINVAL;
     b = inb(VD_STATUS);
-    printf("status: %x\n", b);
+    if(b != 0)
+	return EINVAL;
     return 0;
 }
 
@@ -186,13 +161,10 @@
     vd_softc_t sc;
     struct cdev *_cdev;
 
-    printf("vordog_attach 1\n");
-
     sc = (vd_softc_t)malloc(sizeof(struct vd_softc), M_TEMP, M_WAITOK);
     if(sc == NULL)
 	return ENOMEM;
 
-    printf("vordog_attach 2\n");
     _cdev = make_dev(&vordog_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "vordog0");
     if(_cdev == NULL) {
 	free(sc, M_TEMP);
@@ -202,13 +174,15 @@
     sc->_cdev = _cdev;
     sc->dev = dev;
 
-    printf("vordog_attach 3\n");
     device_set_softc(dev, sc);
     CDEV_2_SOFTC(_cdev) = sc;
 
     sc->open_cnt = 0;
     sc->init_val = 0;
 
+    device_set_desc(dev, "Watchdog of Vortex86 SoC");
+    device_printf(dev, "<Vortex86 SoC watchdog> at port 0x%x\n", VD_STATUS);
+
     return 0;
 }
 
@@ -216,17 +190,13 @@
     vd_softc_t sc;
     struct cdev *_cdev;
 
-    printf("vordog_detach 1\n");
     sc = device_get_softc(dev);
     if(sc->open_cnt != 0)
 	return EBUSY;
 
-    printf("vordog_detach 2\n");
     _cdev = sc->_cdev;
 
-    printf("vordog_detach 3\n");
     destroy_dev(_cdev);
-    printf("vordog_detach 4\n");
 
     free(sc, M_TEMP);
 
@@ -253,14 +223,11 @@
 
     switch(cmd) {
     case MOD_LOAD:
-	printf("MOD_LOAD\n");
 	break;
     case MOD_UNLOAD:
-	printf("MOD_UNLOAD\n");
 	vordog_go_detach();	/* remove device from parent */
 	break;
     case MOD_SHUTDOWN:
-	printf("MOD_SHUTDOWN\n");
 	break;
     default:
 	r = EINVAL;