# HG changeset patch # User Thinker K.F. Li # Date 1215486451 -28800 # Node ID 0b9854adb86cf91123109f8a3b6ea3bd0c11d6d5 # Parent 71475f5afa925d5de81f5eecb754f480ff3052f1 Remove tedious messages and daemonize vd_watchdog. diff -r 71475f5afa92 -r 0b9854adb86c vd_watchdog/vd_watchdog.c --- 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 #include #include +#include #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] \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 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; } diff -r 71475f5afa92 -r 0b9854adb86c vordog.c --- 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, " 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;