提交 7a879824 编写于 作者: H Hans de Goede 提交者: Wim Van Sebroeck

watchdog: watchdog_dev: Rewrite wrapper code

Rewrite and extend the wrapper code so that we can easily introduce
locking (this to be able to prevent potential multithreading issues).
Signed-off-by: NHans de Goede <hdegoede@redhat.com>
Signed-off-by: NWim Van Sebroeck <wim@iguana.be>
上级 3dfd6218
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -61,13 +61,18 @@ static struct watchdog_device *old_wdd;
static int watchdog_ping(struct watchdog_device *wddev)
{
if (watchdog_active(wddev)) {
if (wddev->ops->ping)
return wddev->ops->ping(wddev); /* ping the watchdog */
else
return wddev->ops->start(wddev); /* restart watchdog */
}
return 0;
int err = 0;
if (!watchdog_active(wddev))
goto out_ping;
if (wddev->ops->ping)
err = wddev->ops->ping(wddev); /* ping the watchdog */
else
err = wddev->ops->start(wddev); /* restart watchdog */
out_ping:
return err;
}
/*
......@@ -81,16 +86,17 @@ static int watchdog_ping(struct watchdog_device *wddev)
static int watchdog_start(struct watchdog_device *wddev)
{
int err;
int err = 0;
if (!watchdog_active(wddev)) {
err = wddev->ops->start(wddev);
if (err < 0)
return err;
if (watchdog_active(wddev))
goto out_start;
err = wddev->ops->start(wddev);
if (err == 0)
set_bit(WDOG_ACTIVE, &wddev->status);
}
return 0;
out_start:
return err;
}
/*
......@@ -105,21 +111,111 @@ static int watchdog_start(struct watchdog_device *wddev)
static int watchdog_stop(struct watchdog_device *wddev)
{
int err = -EBUSY;
int err = 0;
if (!watchdog_active(wddev))
goto out_stop;
if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) {
dev_info(wddev->dev, "nowayout prevents watchdog being stopped!\n");
return err;
err = -EBUSY;
goto out_stop;
}
if (watchdog_active(wddev)) {
err = wddev->ops->stop(wddev);
if (err < 0)
return err;
err = wddev->ops->stop(wddev);
if (err == 0)
clear_bit(WDOG_ACTIVE, &wddev->status);
}
return 0;
out_stop:
return err;
}
/*
* watchdog_get_status: wrapper to get the watchdog status
* @wddev: the watchdog device to get the status from
* @status: the status of the watchdog device
*
* Get the watchdog's status flags.
*/
static int watchdog_get_status(struct watchdog_device *wddev,
unsigned int *status)
{
int err = 0;
*status = 0;
if (!wddev->ops->status)
return -EOPNOTSUPP;
*status = wddev->ops->status(wddev);
return err;
}
/*
* watchdog_set_timeout: set the watchdog timer timeout
* @wddev: the watchdog device to set the timeout for
* @timeout: timeout to set in seconds
*/
static int watchdog_set_timeout(struct watchdog_device *wddev,
unsigned int timeout)
{
int err;
if ((wddev->ops->set_timeout == NULL) ||
!(wddev->info->options & WDIOF_SETTIMEOUT))
return -EOPNOTSUPP;
if ((wddev->max_timeout != 0) &&
(timeout < wddev->min_timeout || timeout > wddev->max_timeout))
return -EINVAL;
err = wddev->ops->set_timeout(wddev, timeout);
return err;
}
/*
* watchdog_get_timeleft: wrapper to get the time left before a reboot
* @wddev: the watchdog device to get the remaining time from
* @timeleft: the time that's left
*
* Get the time before a watchdog will reboot (if not pinged).
*/
static int watchdog_get_timeleft(struct watchdog_device *wddev,
unsigned int *timeleft)
{
int err = 0;
*timeleft = 0;
if (!wddev->ops->get_timeleft)
return -EOPNOTSUPP;
*timeleft = wddev->ops->get_timeleft(wddev);
return err;
}
/*
* watchdog_ioctl_op: call the watchdog drivers ioctl op if defined
* @wddev: the watchdog device to do the ioctl on
* @cmd: watchdog command
* @arg: argument pointer
*/
static int watchdog_ioctl_op(struct watchdog_device *wddev, unsigned int cmd,
unsigned long arg)
{
int err;
if (!wddev->ops->ioctl)
return -ENOIOCTLCMD;
err = wddev->ops->ioctl(wddev, cmd, arg);
return err;
}
/*
......@@ -183,18 +279,18 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
unsigned int val;
int err;
if (wdd->ops->ioctl) {
err = wdd->ops->ioctl(wdd, cmd, arg);
if (err != -ENOIOCTLCMD)
return err;
}
err = watchdog_ioctl_op(wdd, cmd, arg);
if (err != -ENOIOCTLCMD)
return err;
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, wdd->info,
sizeof(struct watchdog_info)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
val = wdd->ops->status ? wdd->ops->status(wdd) : 0;
err = watchdog_get_status(wdd, &val);
if (err)
return err;
return put_user(val, p);
case WDIOC_GETBOOTSTATUS:
return put_user(wdd->bootstatus, p);
......@@ -218,15 +314,9 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
watchdog_ping(wdd);
return 0;
case WDIOC_SETTIMEOUT:
if ((wdd->ops->set_timeout == NULL) ||
!(wdd->info->options & WDIOF_SETTIMEOUT))
return -EOPNOTSUPP;
if (get_user(val, p))
return -EFAULT;
if ((wdd->max_timeout != 0) &&
(val < wdd->min_timeout || val > wdd->max_timeout))
return -EINVAL;
err = wdd->ops->set_timeout(wdd, val);
err = watchdog_set_timeout(wdd, val);
if (err < 0)
return err;
/* If the watchdog is active then we send a keepalive ping
......@@ -240,10 +330,10 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
return -EOPNOTSUPP;
return put_user(wdd->timeout, p);
case WDIOC_GETTIMELEFT:
if (!wdd->ops->get_timeleft)
return -EOPNOTSUPP;
return put_user(wdd->ops->get_timeleft(wdd), p);
err = watchdog_get_timeleft(wdd, &val);
if (err)
return err;
return put_user(val, p);
default:
return -ENOTTY;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部