static long usb_pcwd_ioctl()

in pcwd_usb.c [388:473]


static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
						unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static const struct watchdog_info ident = {
		.options =		WDIOF_KEEPALIVEPING |
					WDIOF_SETTIMEOUT |
					WDIOF_MAGICCLOSE,
		.firmware_version =	1,
		.identity =		DRIVER_NAME,
	};

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

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

	case WDIOC_GETTEMP:
	{
		int temperature;

		if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
			return -EFAULT;

		return put_user(temperature, p);
	}

	case WDIOC_SETOPTIONS:
	{
		int new_options, retval = -EINVAL;

		if (get_user(new_options, p))
			return -EFAULT;

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

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

		return retval;
	}

	case WDIOC_KEEPALIVE:
		usb_pcwd_keepalive(usb_pcwd_device);
		return 0;

	case WDIOC_SETTIMEOUT:
	{
		int new_heartbeat;

		if (get_user(new_heartbeat, p))
			return -EFAULT;

		if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
			return -EINVAL;

		usb_pcwd_keepalive(usb_pcwd_device);
	}
		fallthrough;

	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 -ENOTTY;
	}
}