Exemplo n.º 1
0
Arquivo: shwdt.c Projeto: wxlong/Test
/**
 * 	sh_wdt_ioctl - Query Device
 *
 * 	@inode: inode of device
 * 	@file: file handle of device
 * 	@cmd: watchdog command
 * 	@arg: argument
 *
 * 	Query basic information from the device or ping it, as outlined by the
 * 	watchdog API.
 */
static int sh_wdt_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	int new_heartbeat;
	int options, retval = -EINVAL;

	switch (cmd) {
		case WDIOC_GETSUPPORT:
			return copy_to_user((struct watchdog_info *)arg,
					  &sh_wdt_info,
					  sizeof(sh_wdt_info)) ? -EFAULT : 0;
		case WDIOC_GETSTATUS:
		case WDIOC_GETBOOTSTATUS:
			return put_user(0, (int *)arg);
		case WDIOC_KEEPALIVE:
			sh_wdt_keepalive();
			return 0;
		case WDIOC_SETTIMEOUT:
			if (get_user(new_heartbeat, (int *)arg))
				return -EFAULT;

			if (sh_wdt_set_heartbeat(new_heartbeat))
				return -EINVAL;

			sh_wdt_keepalive();
			/* Fall */
		case WDIOC_GETTIMEOUT:
			return put_user(heartbeat, (int *)arg);
		case WDIOC_SETOPTIONS:
			if (get_user(options, (int *)arg))
				return -EFAULT;

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

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

			return retval;
		default:
			return -ENOIOCTLCMD;
	}

	return 0;
}
Exemplo n.º 2
0
Arquivo: shwdt.c Projeto: wxlong/Test
/**
 * 	sh_wdt_write - Write to Device
 *
 * 	@file: file handle of device
 * 	@buf: buffer to write
 * 	@count: length of buffer
 * 	@ppos: offset
 *
 * 	Pings the watchdog on write.
 */
static ssize_t sh_wdt_write(struct file *file, const char *buf,
			    size_t count, loff_t *ppos)
{
	/* Can't seek (pwrite) on this device */
	if (ppos != &file->f_pos)
		return -ESPIPE;

	if (count) {
		if (!nowayout) {
			size_t i;

			shwdt_expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if (get_user(c, buf + i))
					return -EFAULT;
				if (c == 'V')
					shwdt_expect_close = 42;
			}
		}
		sh_wdt_keepalive();
	}

	return count;
}
Exemplo n.º 3
0
Arquivo: shwdt.c Projeto: wxlong/Test
/**
 * 	sh_wdt_close - Close the Device
 *
 * 	@inode: inode of device
 * 	@file: file handle of device
 *
 * 	Watchdog device is closed and stopped.
 */
static int sh_wdt_close(struct inode *inode, struct file *file)
{
	if (shwdt_expect_close == 42) {
		sh_wdt_stop();
	} else {
		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
		sh_wdt_keepalive();
	}

	clear_bit(0, &shwdt_is_open);
	shwdt_expect_close = 0;

	return 0;
}
Exemplo n.º 4
0
static int sh_wdt_close(struct inode *inode, struct file *file)
{
	struct sh_wdt *wdt = file->private_data;

	if (wdt->expect_close == 42) {
		sh_wdt_stop(wdt);
	} else {
		dev_crit(wdt->dev, "Unexpected close, not "
		         "stopping watchdog!\n");
		sh_wdt_keepalive(wdt);
	}

	clear_bit(0, &wdt->enabled);
	wdt->expect_close = 0;

	return 0;
}
Exemplo n.º 5
0
static ssize_t sh_wdt_write(struct file *file, const char *buf,
			    size_t count, loff_t *ppos)
{
	struct sh_wdt *wdt = file->private_data;

	if (count) {
		if (!nowayout) {
			size_t i;

			wdt->expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if (get_user(c, buf + i))
					return -EFAULT;
				if (c == 'V')
					wdt->expect_close = 42;
			}
		}
		sh_wdt_keepalive(wdt);
	}

	return count;
}