From: Guenter Roeck <linux@roeck-us.net>
To: Kyle Roeschley <kyle.roeschley@ni.com>
Cc: wim@iguana.be, linux-watchdog@vger.kernel.org
Subject: Re: [2/2] niwatchdog: add support for custom ioctls
Date: Sat, 16 Jan 2016 20:29:41 -0800 [thread overview]
Message-ID: <20160117042941.GA16822@roeck-us.net> (raw)
In-Reply-To: <1452558181-19511-2-git-send-email-kyle.roeschley@ni.com>
On Mon, Jan 11, 2016 at 06:23:01PM -0600, Kyle Roeschley wrote:
> Add custom ioctls for features specific to the NI watchdog, including
> disabling the watchdog, changing timeout behavior, and setting timeouts
> with sub-second resolution.
>
I don't really agree with any of the added functionality.
Most of the added ioctls duplicate standard functionality.
> Signed-off-by: Kyle Roeschley <kyle.roeschley@ni.com>
> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> ---
> drivers/watchdog/niwatchdog.c | 115 +++++++++++++++++++++++++++++++++++++++-
> include/uapi/linux/niwatchdog.h | 10 ++++
> 2 files changed, 123 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/watchdog/niwatchdog.c b/drivers/watchdog/niwatchdog.c
> index 3908846..fe637a3 100644
> --- a/drivers/watchdog/niwatchdog.c
> +++ b/drivers/watchdog/niwatchdog.c
> @@ -131,6 +131,35 @@ out_unlock:
> return ret;
> }
>
> +static int niwatchdog_check_action(u32 action)
> +{
> + int err = 0;
> +
> + switch (action) {
> + case NIWD_CONTROL_PROC_INTERRUPT:
> + case NIWD_CONTROL_PROC_RESET:
> + break;
> + default:
> + err = -ENOTSUPP;
> + }
> +
> + return err;
> +}
> +
> +static void niwatchdog_get_actions(struct niwatchdog *niwatchdog, u8 *actions)
> +{
> + u8 control;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&niwatchdog->lock, flags);
> +
> + control = inb(niwatchdog->io_base + NIWD_CONTROL);
> + *actions = control & (NIWD_CONTROL_PROC_INTERRUPT +
> + NIWD_CONTROL_PROC_RESET);
> +
> + spin_unlock_irqrestore(&niwatchdog->lock, flags);
> +}
> +
> static int niwatchdog_add_action(struct niwatchdog *niwatchdog, u32 action)
> {
> u8 action_mask;
> @@ -233,12 +262,20 @@ static int niwatchdog_wdd_set_timeout(struct watchdog_device *wdd,
> {
> struct niwatchdog *niwatchdog = to_niwatchdog(wdd);
> u32 counter = timeout * (1000000000 / NIWD_PERIOD_NS);
> + u8 actions;
>
> + niwatchdog_get_actions(niwatchdog, &actions);
> niwatchdog_reset(niwatchdog);
> niwatchdog_counter_set(niwatchdog, counter);
> - niwatchdog_add_action(niwatchdog, NIWATCHDOG_ACTION_RESET);
>
> - return niwatchdog_start(niwatchdog);
> + if (actions & NIWD_CONTROL_PROC_RESET)
> + niwatchdog_add_action(niwatchdog, NIWATCHDOG_ACTION_RESET);
> + if (actions & NIWD_CONTROL_PROC_INTERRUPT)
> + niwatchdog_add_action(niwatchdog, NIWATCHDOG_ACTION_INTERRUPT);
> +
> + niwatchdog_start(niwatchdog);
> +
> + return 0;
> }
>
> static unsigned int niwatchdog_wdd_get_timeleft(struct watchdog_device *wdd)
> @@ -319,6 +356,79 @@ static int niwatchdog_wdd_release(struct watchdog_device *wdd)
> return 0;
> }
>
> +static long niwatchdog_wdd_ioctl(struct watchdog_device *wdd, unsigned int cmd,
> + unsigned long arg)
> +{
> + struct niwatchdog *niwatchdog = to_niwatchdog(wdd);
> + int err = 0;
> +
> + switch (cmd) {
> + case NIWATCHDOG_IOCTL_PERIOD_NS: {
> + __u32 period = NIWD_PERIOD_NS;
> +
> + err = copy_to_user((__u32 *)arg, &period, sizeof(__u32));
> + break;
> + }
> + case NIWATCHDOG_IOCTL_MAX_COUNTER: {
> + __u32 counter = NIWD_MAX_COUNTER;
> +
> + err = copy_to_user((__u32 *)arg, &counter, sizeof(__u32));
> + break;
> + }
Those are constants and can as well be defined in some documentation.
> + case NIWATCHDOG_IOCTL_COUNTER_SET: {
> + __u32 counter;
> +
> + err = copy_from_user(&counter, (__u32 *)arg, sizeof(__u32));
> + if (!err)
> + err = niwatchdog_counter_set(niwatchdog, counter);
> + break;
> + }
Duplicates standard functionality
> + case NIWATCHDOG_IOCTL_CHECK_ACTION: {
> + __u32 action;
> +
> + err = copy_from_user(&action, (__u32 *)arg, sizeof(__u32));
> + if (!err)
> + err = niwatchdog_check_action(action);
> + break;
> + }
> + case NIWATCHDOG_IOCTL_ADD_ACTION: {
> + __u32 action;
> +
> + err = copy_from_user(&action, (__u32 *)arg, sizeof(__u32));
> + if (!err)
> + err = niwatchdog_add_action(niwatchdog, action);
> + break;
> + }
Use a module parameter or sysfs attribute for those.
> + case NIWATCHDOG_IOCTL_START: {
> + niwatchdog_start(niwatchdog);
> + break;
> + }
Duplicates standard functionality.
> + case NIWATCHDOG_IOCTL_PET: {
> + __u32 state;
> +
> + niwatchdog_pet(niwatchdog, &state);
> + err = copy_to_user((__u32 *)arg, &state, sizeof(__u32));
> + break;
> + }
Duplicates standard functionality.
> + case NIWATCHDOG_IOCTL_RESET: {
> + niwatchdog_reset(niwatchdog);
> + break;
> + }
Duplicates standard functionality.
> + case NIWATCHDOG_IOCTL_COUNTER_GET: {
> + __u32 counter;
> +
> + niwatchdog_counter_get(niwatchdog, &counter);
> + err = copy_to_user((__u32 *)arg, &counter, sizeof(__u32));
> + break;
> + }
Duplicates standard functionality.
> + default:
> + err = -ENOIOCTLCMD;
> + break;
> + };
> +
> + return err;
> +}
> +
> static int niwatchdog_ping(struct watchdog_device *wdd)
> {
> struct niwatchdog *niwatchdog = to_niwatchdog(wdd);
> @@ -403,6 +513,7 @@ static const struct watchdog_ops niwatchdog_wdd_ops = {
> .start = niwatchdog_wdd_open,
> .stop = niwatchdog_wdd_release,
> .ping = niwatchdog_ping,
> + .ioctl = niwatchdog_wdd_ioctl,
> .set_timeout = niwatchdog_wdd_set_timeout,
> .get_timeleft = niwatchdog_wdd_get_timeleft,
> };
> diff --git a/include/uapi/linux/niwatchdog.h b/include/uapi/linux/niwatchdog.h
> index 9d3613d..4fb8d47 100644
> --- a/include/uapi/linux/niwatchdog.h
> +++ b/include/uapi/linux/niwatchdog.h
> @@ -25,6 +25,16 @@
> #define NIWATCHDOG_STATE_EXPIRED 1
> #define NIWATCHDOG_STATE_DISABLED 2
>
> +#define NIWATCHDOG_IOCTL_PERIOD_NS _IOR('W', 60, __u32)
> +#define NIWATCHDOG_IOCTL_MAX_COUNTER _IOR('W', 61, __u32)
> +#define NIWATCHDOG_IOCTL_COUNTER_SET _IOW('W', 62, __u32)
> +#define NIWATCHDOG_IOCTL_CHECK_ACTION _IOW('W', 63, __u32)
> +#define NIWATCHDOG_IOCTL_ADD_ACTION _IOW('W', 64, __u32)
> +#define NIWATCHDOG_IOCTL_START _IO('W', 65)
> +#define NIWATCHDOG_IOCTL_PET _IOR('W', 66, __u32)
> +#define NIWATCHDOG_IOCTL_RESET _IO('W', 67)
> +#define NIWATCHDOG_IOCTL_COUNTER_GET _IOR('W', 68, __u32)
> +
> #define NIWATCHDOG_NAME "niwatchdog"
>
> #endif /* _LINUX_NIWATCHDOG_H_ */
next prev parent reply other threads:[~2016-01-17 4:29 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-12 0:23 [PATCH 1/2] watchdog: add NI 903x/913x watchdog support Kyle Roeschley
2016-01-12 0:23 ` [PATCH 2/2] niwatchdog: add support for custom ioctls Kyle Roeschley
2016-01-17 4:29 ` Guenter Roeck [this message]
2016-01-25 23:31 ` [2/2] " Kyle Roeschley
2016-01-26 1:00 ` Guenter Roeck
2016-02-03 0:44 ` Kyle Roeschley
2016-02-04 16:38 ` Guenter Roeck
2016-02-04 18:38 ` Josh Cartwright
2016-02-04 20:47 ` Kyle Roeschley
2016-01-17 4:25 ` [1/2] watchdog: add NI 903x/913x watchdog support Guenter Roeck
2016-01-25 23:21 ` Kyle Roeschley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160117042941.GA16822@roeck-us.net \
--to=linux@roeck-us.net \
--cc=kyle.roeschley@ni.com \
--cc=linux-watchdog@vger.kernel.org \
--cc=wim@iguana.be \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.