Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58b519f3 authored by Wim Van Sebroeck's avatar Wim Van Sebroeck
Browse files

[WATCHDOG] add WDIOC_GETTIMELEFT ioctl



Some watchdog drivers have the ability to report the remaining time
before the system will reboot. With the WDIOC_GETTIMELEFT ioctl
you can now read the time left before the watchdog would reboot
your system.

The following drivers support this new IOCTL:
i8xx_tco.c, pcwd_pci.c and pcwd_usb.c .

Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
parent e05b59fe
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -134,6 +134,15 @@ There is also a get function for getting the pretimeout:

Not all watchdog drivers will support a pretimeout.

Get the number of seconds before reboot:

Some watchdog drivers have the ability to report the remaining time
before the system will reboot. The WDIOC_GETTIMELEFT is the ioctl
that returns the number of seconds before reboot.

    ioctl(fd, WDIOC_GETTIMELEFT, &timeleft);
    printf("The timeout was is %d seconds\n", timeleft);

Environmental monitoring:

All watchdog drivers are required return more information about the system,
+27 −1
Original line number Diff line number Diff line
@@ -205,6 +205,23 @@ static int tco_timer_set_heartbeat (int t)
	return 0;
}

static int tco_timer_get_timeleft (int *time_left)
{
	unsigned char val;

	spin_lock(&tco_lock);

	/* read the TCO Timer */
	val = inb (TCO1_RLD);
	val &= 0x3f;

	spin_unlock(&tco_lock);

	*time_left = (int)((val * 6) / 10);

	return 0;
}

/*
 *	/dev/watchdog handling
 */
@@ -272,6 +289,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
{
	int new_options, retval = -EINVAL;
	int new_heartbeat;
	int time_left;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static struct watchdog_info ident = {
@@ -329,6 +347,14 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
		case WDIOC_GETTIMEOUT:
			return put_user(heartbeat, p);

		case WDIOC_GETTIMELEFT:
		{
			if (tco_timer_get_timeleft(&time_left))
				return -EINVAL;

			return put_user(time_left, p);
		}

		default:
			return -ENOIOCTLCMD;
	}
+29 −1
Original line number Diff line number Diff line
@@ -390,6 +390,24 @@ static int pcipcwd_get_temperature(int *temperature)
	return 0;
}

static int pcipcwd_get_timeleft(int *time_left)
{
	int msb;
	int lsb;

	/* Read the time that's left before rebooting */
	/* Note: if the board is not yet armed then we will read 0xFFFF */
	send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);

	*time_left = (msb << 8) + lsb;

	if (debug >= VERBOSE)
		printk(KERN_DEBUG PFX "Time left before next reboot: %d\n",
		       *time_left);

	return 0;
}

/*
 *	/dev/watchdog handling
 */
@@ -512,6 +530,16 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
		case WDIOC_GETTIMEOUT:
			return put_user(heartbeat, p);

		case WDIOC_GETTIMELEFT:
		{
			int time_left;

			if (pcipcwd_get_timeleft(&time_left))
				return -EFAULT;

			return put_user(time_left, p);
		}

		default:
			return -ENOIOCTLCMD;
	}
+23 −0
Original line number Diff line number Diff line
@@ -317,6 +317,19 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp
	return 0;
}

static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left)
{
	unsigned char msb, lsb;

	/* Read the time that's left before rebooting */
	/* Note: if the board is not yet armed then we will read 0xFFFF */
	usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);

	*time_left = (msb << 8) + lsb;

	return 0;
}

/*
 *	/dev/watchdog handling
 */
@@ -422,6 +435,16 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
		case WDIOC_GETTIMEOUT:
			return put_user(heartbeat, p);

		case WDIOC_GETTIMELEFT:
		{
			int time_left;

			if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))
				return -EFAULT;

			return put_user(time_left, p);
		}

		default:
			return -ENOIOCTLCMD;
	}
+4 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct watchdog_info {
#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define	WDIOC_SETPRETIMEOUT	_IOWR(WATCHDOG_IOCTL_BASE, 8, int)
#define	WDIOC_GETPRETIMEOUT	_IOR(WATCHDOG_IOCTL_BASE, 9, int)
#define	WDIOC_GETTIMELEFT	_IOR(WATCHDOG_IOCTL_BASE, 10, int)

#define	WDIOF_UNKNOWN		-1	/* Unknown flag error */
#define	WDIOS_UNKNOWN		-1	/* Unknown status error */