示例#1
0
void watchdog_init( void )
{
    wdt_init();
    wdt_config();
    wdt_set_timeout(((WATCHDOG_TIMEOUT/1000)*WATCHDOG_CLK_FREQ));
    watchdog_smphr = xSemaphoreCreateBinary();
    xTaskCreate( WatchdogTask, (const char *) "Watchdog Task", 60, (void * ) NULL, tskWATCHDOG_PRIORITY, ( TaskHandle_t * ) NULL);
}
示例#2
0
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd) {
    case WDIOC_GETSUPPORT:
        return copy_to_user((void __user *)arg, &ident, sizeof(ident))
               ? -EFAULT : 0;
    case WDIOC_GETSTATUS:
    case WDIOC_GETBOOTSTATUS:
        return put_user(0, (int __user *)arg);
    case WDIOC_SETOPTIONS:
    {
        int options;
        int retval = -EINVAL;

        if (get_user(options, (int __user *)arg))
            return -EFAULT;

        if (options & WDIOS_DISABLECARD) {
            wdt_disable();
            retval = 0;
        }

        if (options & WDIOS_ENABLECARD) {
            wdt_enable();
            retval = 0;
        }

        return retval;
    }
    case WDIOC_KEEPALIVE:
        wdt_keepalive();
        return 0;
    case WDIOC_SETTIMEOUT:
    {
        int new_timeout;

        if (get_user(new_timeout, (int __user *)arg))
            return -EFAULT;

        if (wdt_set_timeout(new_timeout))
            return -EINVAL;

        /* Fall through */
    }
    case WDIOC_GETTIMEOUT:
        return put_user(timeout, (int __user *)arg);
    default:
        return -ENOTTY;
    }
}
示例#3
0
static int wdt_open(struct inode *inode, struct file *file)
{
	/* Allow only one person to hold it open */
	if (access)
		return -EBUSY;

	if (nowayout)
		__module_get(THIS_MODULE);

	/* Activate timer */
	wdt_reset_counter();
	wdt_set_timeout();
	printk(KERN_INFO NAME ": enabling watchdog timer\n");
	access = 1;
	return 0;
}
示例#4
0
int wdt_exit(uev_ctx_t *ctx)
{
	/* Let plugins exit before we leave main loop */
	wdt_plugins_exit(ctx);

	/* Be nice, sync any buffered data to disk first. */
	sync();

	if (fd != -1) {
		INFO("Forced watchdog reboot.");
		wdt_set_timeout(1);
		close(fd);
	}

	/* Tell main() to loop until reboot ... */
	wait_reboot = 1;

	/* Leave main loop. */
	return uev_exit(ctx);
}
示例#5
0
static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int new_timeout;
	static struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT |
					WDIOF_KEEPALIVEPING |
					WDIOF_MAGICCLOSE,
		.firmware_version =	0,
		.identity =		"ADM5120_WDT Watchdog",
	};
	switch (cmd) {
	default:
		return -ENOTTY;
	case WDIOC_GETSUPPORT:
		if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
			return -EFAULT;
		return 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, (int *)arg);
	case WDIOC_KEEPALIVE:
		wdt_reset_counter();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_timeout, (int *)arg))
			return -EFAULT;
		if (new_timeout < 1)
			return -EINVAL;
		if (new_timeout > MAX_TIMEOUT)
			return -EINVAL;
		timeout = new_timeout;
		wdt_set_timeout();
		/* Fall */
	case WDIOC_GETTIMEOUT:
		return put_user(timeout, (int *)arg);
	}
}

static const struct file_operations wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= wdt_write,
	.unlocked_ioctl	= wdt_ioctl,
	.open		= wdt_open,
	.release	= wdt_release,
};

static struct miscdevice wdt_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &wdt_fops,
};

static char banner[] __initdata = KERN_INFO NAME ": Watchdog Timer version " VERSION "\n";

static int __init watchdog_init(void)
{
	int ret;

	ret = misc_register(&wdt_miscdev);

	if (ret)
		return ret;

	wdt_disable();
	printk(banner);

	return 0;
}

static void __exit watchdog_exit(void)
{
	misc_deregister(&wdt_miscdev);
}
示例#6
0
static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int status;
	int new_options, retval = -EINVAL;
	int new_timeout;
	union {
		struct watchdog_info __user *ident;
		int __user *i;
	} uarg;

	uarg.i = (int __user *)arg;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(uarg.ident, &ident,
						sizeof(ident)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
		wdt_get_status(&status);
		return put_user(status, uarg.i);

	case WDIOC_GETBOOTSTATUS:
		return put_user(0, uarg.i);

	case WDIOC_SETOPTIONS:
		if (get_user(new_options, uarg.i))
			return -EFAULT;

		if (new_options & WDIOS_DISABLECARD) {
			wdt_stop();
			retval = 0;
		}

		if (new_options & WDIOS_ENABLECARD) {
			wdt_start();
			retval = 0;
		}

		return retval;

	case WDIOC_KEEPALIVE:
		wdt_keepalive();
		return 0;

	case WDIOC_SETTIMEOUT:
		if (get_user(new_timeout, uarg.i))
			return -EFAULT;

		if (wdt_set_timeout(new_timeout))
			return -EINVAL;

		wdt_keepalive();
		/* Fall */

	case WDIOC_GETTIMEOUT:
		return put_user(timeout, uarg.i);

	default:
		return -ENOTTY;

	}
}
示例#7
0
文件: vmiwdt-7760.c 项目: jeisch/vme
/*============================================================================
 * Hook to the ioctl file operation
 */
int vmiwdt_ioctl(struct inode *inode, struct file *file_ptr, uint32_t cmd,
		 unsigned long arg)
{
	int timeout, status = 0;
	static struct watchdog_info wdt_info = {
		.options = WDIOF_SETTIMEOUT,
		.firmware_version = 0,
		.identity = MOD_NAME
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user((void *) arg, &wdt_info, sizeof (wdt_info)))
			return -EFAULT;
		break;
	case WDIOC_GETSTATUS:
		if (copy_to_user((void *) arg, &status, sizeof (int)))
			return -EFAULT;
		break;
	case WDIOC_KEEPALIVE:
		wdt_keepalive();
		break;
	case WDIOC_SETTIMEOUT:
		if (copy_from_user(&timeout, (void *) arg, sizeof (int)))
			return -EFAULT;
		/* The wdt_set_timeout function expects milliseconds */
		timeout *= 1000;
		wdt_set_timeout(&timeout);
		timeout /= 1000;
		if (copy_to_user((void *) arg, &timeout, sizeof (int)))
			return -EFAULT;
		break;
#ifdef WDIOC_SETTIMEOUT_MS
	case WDIOC_SETTIMEOUT_MS:
#endif
		if (copy_from_user(&timeout, (void *) arg, sizeof (int)))
			return -EFAULT;
		wdt_set_timeout(&timeout);
		if (copy_to_user((void *) arg, &timeout, sizeof (int)))
			return -EFAULT;
		break;
	case WDIOC_GETTIMEOUT:
		/* The wdt_set_timeout function returns milliseconds */
		timeout = wdt_get_timeout();
		timeout /= 1000;
		if (copy_to_user((void *) arg, &timeout, sizeof (timeout)))
			return -EFAULT;
		break;
#ifdef WDIOC_GETTIMEOUT_MS
	case WDIOC_GETTIMEOUT_MS:
#endif
		timeout = wdt_get_timeout();
		if (copy_to_user((void *) arg, &timeout, sizeof (timeout)))
			return -EFAULT;
		break;
	default:
		return -ENOTTY;
	}

	return 0;
}


/*============================================================================
 * Hook for the open file operation
 */
static int vmiwdt_open(struct inode *inode, struct file *file_ptr)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
	MOD_INC_USE_COUNT;
#endif
	if (1 == ++vmiwdt_count) {
		wdt_enable();
	}

	return 0;
}
示例#8
0
int main(int argc, char *argv[])
{
	int timeout = WDT_TIMEOUT_DEFAULT;
	int real_timeout = 0;
	int T;
	int background = 1;
	int use_syslog = 1;
	int c, status;
	int log_opts = LOG_NDELAY | LOG_NOWAIT | LOG_PID;
	struct option long_options[] = {
		{"load-average",  1, 0, 'a'},
		{"foreground",    0, 0, 'n'},
		{"help",          0, 0, 'h'},
		{"interval",      1, 0, 't'},
		{"loglevel",      1, 0, 'l'},
		{"meminfo",       1, 0, 'm'},
		{"filenr",        1, 0, 'f'},
		{"pmon",          2, 0, 'p'},
		{"safe-exit",     0, 0, 'e'},
		{"syslog",        0, 0, 's'},
#ifndef TESTMODE_DISABLED
		{"test-mode",     0, 0, 'S'}, /* Hidden test mode, not for public use. */
#endif
		{"version",       0, 0, 'v'},
		{"timeout",       1, 0, 'T'},
		{NULL, 0, 0, 0}
	};
	uev_ctx_t ctx;

	while ((c = getopt_long(argc, argv, "a:f:Fhl:Lm:np::sSt:T:Vvx?", long_options, NULL)) != EOF) {
		switch (c) {
		case 'a':
			if (loadavg_set(optarg))
			    return usage(1);
			break;

		case 'f':
			if (filenr_set(optarg))
				return usage(1);
			break;

		case 'h':
			return usage(0);

		case 'l':
			loglevel = __wdog_loglevel(optarg);
			if (-1 == loglevel)
				return usage(1);
			break;

		case 'm':
			if (meminfo_set(optarg))
				return usage(1);
			break;

		case 'F':	/* BusyBox watchdogd compat. */
		case 'n':	/* Run in foreground */
			background = 0;
			use_syslog--;
			break;

		case 'p':
			if (pmon_set(optarg))
				return usage(1);
			break;

		case 's':
			use_syslog++;
			break;

#ifndef TESTMODE_DISABLED
		case 'S':	/* Simulate: no interaction with kernel, for testing pmon */
			__wdt_testmode = 1;
			break;
#endif

		case 't':	/* Watchdog kick interval */
			if (!optarg) {
				ERROR("Missing interval argument.");
				return usage(1);
			}
			period = atoi(optarg);
			break;

		case 'T':	/* Watchdog timeout */
			if (!optarg) {
				ERROR("Missing timeout argument.");
				return usage(1);
			}
			timeout = atoi(optarg);
			break;

		case 'v':
			printf("v%s\n", VERSION);
			return 0;

		case 'x':	/* Safe exit, i.e., don't reboot if we exit and close device */
			magic = 1;
			break;

		default:
			printf("Unrecognized option \"-%c\".\n", c);
			return usage(1);
		}
	}

	/* BusyBox watchdogd compat. */
	if (optind < argc) {
		char *dev = argv[optind];

		if (!strncmp(dev, "/dev", 4))
			strlcpy(devnode, dev, sizeof(devnode));
	}

	if (background) {
		DEBUG("Daemonizing ...");

		if (-1 == daemon(0, 0)) {
			PERROR("Failed daemonizing");
			return 1;
		}
	}

	if (!background && use_syslog < 1)
		log_opts |= LOG_PERROR;

	setlogmask(LOG_UPTO(loglevel));
	openlog(NULL, log_opts, LOG_DAEMON);

	INFO("watchdogd v%s %s ...", PACKAGE_VERSION, wdt_testmode() ? "test mode" : "starting");
	uev_init(&ctx);

	/* Setup callbacks for SIGUSR1 and, optionally, exit magic on SIGINT/SIGTERM */
	setup_signals(&ctx);

	if (wdt_init()) {
		PERROR("Failed connecting to kernel watchdog driver");
		return 1;
	}

	/* Set requested WDT timeout right before we enter the event loop. */
	if (wdt_set_timeout(timeout))
		PERROR("Failed setting HW watchdog timeout: %d", timeout);

	/* Sanity check with driver that setting actually took. */
	real_timeout = wdt_get_timeout();
	if (real_timeout < 0) {
		PERROR("Failed reading current watchdog timeout");
	} else {
		if (real_timeout <= period) {
			ERROR("Warning, watchdog timeout <= kick interval: %d <= %d",
			      real_timeout, period);
		}
	}

	/* If user did not provide '-k' argument, set to half actual timeout */
	if (-1 == period) {
		if (real_timeout < 0)
			period = WDT_KICK_DEFAULT;
		else
			period = real_timeout / 2;

		if (!period)
			period = 1;
	}

	/* Calculate period (T) in milliseconds for libuEv */
	T = period * 1000;
	DEBUG("Watchdog kick interval set to %d sec.", period);

	/* Read boot cause from watchdog and save in /var/run/watchdogd.status */
	create_bootstatus(real_timeout, period);

	/* Every period (T) seconds we kick the wdt */
	uev_timer_init(&ctx, &period_watcher, period_cb, NULL, T, T);

	/* Start all enabled plugins */
	wdt_plugins_init(&ctx, T);

	/* Only create pidfile when we're done with all set up. */
	if (pidfile(NULL) && !wdt_testmode())
		PERROR("Cannot create pidfile");

	status = uev_run(&ctx, 0);
	if (wdt_testmode())
		return status;

	while (wait_reboot) {
		int reboot_in = 3 * real_timeout;

		INFO("Waiting for HW WDT reboot ...");
		while (reboot_in > 0) {
			unsigned int rest = sleep(real_timeout);

			while (rest)
				rest = sleep(rest);

			reboot_in -= real_timeout;
		}

		INFO("HW WDT dit not reboot, forcing reboot now ...");
		reboot(RB_AUTOBOOT);
	}

	return status;
}