Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 *	watchdog_dev.c
  3 *
  4 *	(c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>,
  5 *						All Rights Reserved.
  6 *
  7 *	(c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>.
  8 *
  9 *
 10 *	This source code is part of the generic code that can be used
 11 *	by all the watchdog timer drivers.
 12 *
 13 *	This part of the generic code takes care of the following
 14 *	misc device: /dev/watchdog.
 15 *
 16 *	Based on source code of the following authors:
 17 *	  Matt Domsch <Matt_Domsch@dell.com>,
 18 *	  Rob Radez <rob@osinvestor.com>,
 19 *	  Rusty Lynch <rusty@linux.co.intel.com>
 20 *	  Satyam Sharma <satyam@infradead.org>
 21 *	  Randy Dunlap <randy.dunlap@oracle.com>
 22 *
 23 *	This program is free software; you can redistribute it and/or
 24 *	modify it under the terms of the GNU General Public License
 25 *	as published by the Free Software Foundation; either version
 26 *	2 of the License, or (at your option) any later version.
 27 *
 28 *	Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
 29 *	admit liability nor provide warranty for any of this software.
 30 *	This material is provided "AS-IS" and at no charge.
 31 */
 32
 33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 34
 35#include <linux/module.h>	/* For module stuff/... */
 36#include <linux/types.h>	/* For standard types (like size_t) */
 37#include <linux/errno.h>	/* For the -ENODEV/... values */
 38#include <linux/kernel.h>	/* For printk/panic/... */
 39#include <linux/fs.h>		/* For file operations */
 40#include <linux/watchdog.h>	/* For watchdog specific items */
 41#include <linux/miscdevice.h>	/* For handling misc devices */
 42#include <linux/init.h>		/* For __init/__exit/... */
 43#include <linux/uaccess.h>	/* For copy_to_user/put_user/... */
 44
 45/* make sure we only register one /dev/watchdog device */
 46static unsigned long watchdog_dev_busy;
 
 
 47/* the watchdog device behind /dev/watchdog */
 48static struct watchdog_device *wdd;
 49
 50/*
 51 *	watchdog_ping: ping the watchdog.
 52 *	@wddev: the watchdog device to ping
 53 *
 54 *	If the watchdog has no own ping operation then it needs to be
 55 *	restarted via the start operation. This wrapper function does
 56 *	exactly that.
 57 *	We only ping when the watchdog device is running.
 58 */
 59
 60static int watchdog_ping(struct watchdog_device *wddev)
 61{
 62	if (test_bit(WDOG_ACTIVE, &wddev->status)) {
 63		if (wddev->ops->ping)
 64			return wddev->ops->ping(wddev);  /* ping the watchdog */
 65		else
 66			return wddev->ops->start(wddev); /* restart watchdog */
 
 
 67	}
 68	return 0;
 
 
 
 
 
 
 
 
 
 
 
 69}
 70
 71/*
 72 *	watchdog_start: wrapper to start the watchdog.
 73 *	@wddev: the watchdog device to start
 74 *
 75 *	Start the watchdog if it is not active and mark it active.
 76 *	This function returns zero on success or a negative errno code for
 77 *	failure.
 78 */
 79
 80static int watchdog_start(struct watchdog_device *wddev)
 81{
 82	int err;
 83
 84	if (!test_bit(WDOG_ACTIVE, &wddev->status)) {
 85		err = wddev->ops->start(wddev);
 86		if (err < 0)
 87			return err;
 88
 89		set_bit(WDOG_ACTIVE, &wddev->status);
 
 
 90	}
 91	return 0;
 
 
 
 
 
 
 
 
 
 
 92}
 93
 94/*
 95 *	watchdog_stop: wrapper to stop the watchdog.
 96 *	@wddev: the watchdog device to stop
 97 *
 98 *	Stop the watchdog if it is still active and unmark it active.
 99 *	This function returns zero on success or a negative errno code for
100 *	failure.
101 *	If the 'nowayout' feature was set, the watchdog cannot be stopped.
102 */
103
104static int watchdog_stop(struct watchdog_device *wddev)
105{
106	int err = -EBUSY;
107
108	if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) {
109		pr_info("%s: nowayout prevents watchdog to be stopped!\n",
110							wddev->info->identity);
111		return err;
 
112	}
113
114	if (test_bit(WDOG_ACTIVE, &wddev->status)) {
115		err = wddev->ops->stop(wddev);
116		if (err < 0)
117			return err;
 
 
 
 
118
 
 
119		clear_bit(WDOG_ACTIVE, &wddev->status);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120	}
121	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122}
123
124/*
125 *	watchdog_write: writes to the watchdog.
126 *	@file: file from VFS
127 *	@data: user address of data
128 *	@len: length of data
129 *	@ppos: pointer to the file offset
130 *
131 *	A write to a watchdog device is defined as a keepalive ping.
132 *	Writing the magic 'V' sequence allows the next close to turn
133 *	off the watchdog (if 'nowayout' is not set).
134 */
135
136static ssize_t watchdog_write(struct file *file, const char __user *data,
137						size_t len, loff_t *ppos)
138{
 
139	size_t i;
140	char c;
141
142	if (len == 0)
143		return 0;
144
145	/*
146	 * Note: just in case someone wrote the magic character
147	 * five months ago...
148	 */
149	clear_bit(WDOG_ALLOW_RELEASE, &wdd->status);
150
151	/* scan to see whether or not we got the magic character */
152	for (i = 0; i != len; i++) {
153		if (get_user(c, data + i))
154			return -EFAULT;
155		if (c == 'V')
156			set_bit(WDOG_ALLOW_RELEASE, &wdd->status);
157	}
158
159	/* someone wrote to us, so we send the watchdog a keepalive ping */
160	watchdog_ping(wdd);
161
162	return len;
163}
164
165/*
166 *	watchdog_ioctl: handle the different ioctl's for the watchdog device.
167 *	@file: file handle to the device
168 *	@cmd: watchdog command
169 *	@arg: argument pointer
170 *
171 *	The watchdog API defines a common set of functions for all watchdogs
172 *	according to their available features.
173 */
174
175static long watchdog_ioctl(struct file *file, unsigned int cmd,
176							unsigned long arg)
177{
 
178	void __user *argp = (void __user *)arg;
179	int __user *p = argp;
180	unsigned int val;
181	int err;
182
183	if (wdd->ops->ioctl) {
184		err = wdd->ops->ioctl(wdd, cmd, arg);
185		if (err != -ENOIOCTLCMD)
186			return err;
187	}
188
189	switch (cmd) {
190	case WDIOC_GETSUPPORT:
191		return copy_to_user(argp, wdd->info,
192			sizeof(struct watchdog_info)) ? -EFAULT : 0;
193	case WDIOC_GETSTATUS:
194		val = wdd->ops->status ? wdd->ops->status(wdd) : 0;
 
 
195		return put_user(val, p);
196	case WDIOC_GETBOOTSTATUS:
197		return put_user(wdd->bootstatus, p);
198	case WDIOC_SETOPTIONS:
199		if (get_user(val, p))
200			return -EFAULT;
201		if (val & WDIOS_DISABLECARD) {
202			err = watchdog_stop(wdd);
203			if (err < 0)
204				return err;
205		}
206		if (val & WDIOS_ENABLECARD) {
207			err = watchdog_start(wdd);
208			if (err < 0)
209				return err;
210		}
211		return 0;
212	case WDIOC_KEEPALIVE:
213		if (!(wdd->info->options & WDIOF_KEEPALIVEPING))
214			return -EOPNOTSUPP;
215		watchdog_ping(wdd);
216		return 0;
217	case WDIOC_SETTIMEOUT:
218		if ((wdd->ops->set_timeout == NULL) ||
219		    !(wdd->info->options & WDIOF_SETTIMEOUT))
220			return -EOPNOTSUPP;
221		if (get_user(val, p))
222			return -EFAULT;
223		if ((wdd->max_timeout != 0) &&
224		    (val < wdd->min_timeout || val > wdd->max_timeout))
225				return -EINVAL;
226		err = wdd->ops->set_timeout(wdd, val);
227		if (err < 0)
228			return err;
229		wdd->timeout = val;
230		/* If the watchdog is active then we send a keepalive ping
231		 * to make sure that the watchdog keep's running (and if
232		 * possible that it takes the new timeout) */
233		watchdog_ping(wdd);
234		/* Fall */
235	case WDIOC_GETTIMEOUT:
236		/* timeout == 0 means that we don't know the timeout */
237		if (wdd->timeout == 0)
238			return -EOPNOTSUPP;
239		return put_user(wdd->timeout, p);
 
 
 
 
 
240	default:
241		return -ENOTTY;
242	}
243}
244
245/*
246 *	watchdog_open: open the /dev/watchdog device.
247 *	@inode: inode of device
248 *	@file: file handle to device
249 *
250 *	When the /dev/watchdog device gets opened, we start the watchdog.
251 *	Watch out: the /dev/watchdog device is single open, so we make sure
252 *	it can only be opened once.
253 */
254
255static int watchdog_open(struct inode *inode, struct file *file)
256{
257	int err = -EBUSY;
 
 
 
 
 
 
 
258
259	/* the watchdog is single open! */
260	if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status))
261		return -EBUSY;
262
263	/*
264	 * If the /dev/watchdog device is open, we don't want the module
265	 * to be unloaded.
266	 */
267	if (!try_module_get(wdd->ops->owner))
268		goto out;
269
270	err = watchdog_start(wdd);
271	if (err < 0)
272		goto out_mod;
273
 
 
 
 
 
274	/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
275	return nonseekable_open(inode, file);
276
277out_mod:
278	module_put(wdd->ops->owner);
279out:
280	clear_bit(WDOG_DEV_OPEN, &wdd->status);
281	return err;
282}
283
284/*
285 *      watchdog_release: release the /dev/watchdog device.
286 *      @inode: inode of device
287 *      @file: file handle to device
288 *
289 *	This is the code for when /dev/watchdog gets closed. We will only
290 *	stop the watchdog when we have received the magic char (and nowayout
291 *	was not set), else the watchdog will keep running.
292 */
293
294static int watchdog_release(struct inode *inode, struct file *file)
295{
 
296	int err = -EBUSY;
297
298	/*
299	 * We only stop the watchdog if we received the magic character
300	 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
301	 * watchdog_stop will fail.
302	 */
303	if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
304	    !(wdd->info->options & WDIOF_MAGICCLOSE))
305		err = watchdog_stop(wdd);
306
307	/* If the watchdog was not stopped, send a keepalive ping */
308	if (err < 0) {
309		pr_crit("%s: watchdog did not stop!\n", wdd->info->identity);
 
 
 
310		watchdog_ping(wdd);
311	}
312
313	/* Allow the owner module to be unloaded again */
314	module_put(wdd->ops->owner);
315
316	/* make sure that /dev/watchdog can be re-opened */
317	clear_bit(WDOG_DEV_OPEN, &wdd->status);
318
 
 
 
 
319	return 0;
320}
321
322static const struct file_operations watchdog_fops = {
323	.owner		= THIS_MODULE,
324	.write		= watchdog_write,
325	.unlocked_ioctl	= watchdog_ioctl,
326	.open		= watchdog_open,
327	.release	= watchdog_release,
328};
329
330static struct miscdevice watchdog_miscdev = {
331	.minor		= WATCHDOG_MINOR,
332	.name		= "watchdog",
333	.fops		= &watchdog_fops,
334};
335
336/*
337 *	watchdog_dev_register:
338 *	@watchdog: watchdog device
339 *
340 *	Register a watchdog device as /dev/watchdog. /dev/watchdog
341 *	is actually a miscdevice and thus we set it up like that.
 
342 */
343
344int watchdog_dev_register(struct watchdog_device *watchdog)
345{
346	int err;
347
348	/* Only one device can register for /dev/watchdog */
349	if (test_and_set_bit(0, &watchdog_dev_busy)) {
350		pr_err("only one watchdog can use /dev/watchdog.\n");
351		return -EBUSY;
 
 
 
 
 
 
 
 
352	}
353
354	wdd = watchdog;
355
356	err = misc_register(&watchdog_miscdev);
357	if (err != 0) {
358		pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
359			watchdog->info->identity, WATCHDOG_MINOR, err);
360		goto out;
 
 
 
 
 
 
 
361	}
362
363	return 0;
364
365out:
366	wdd = NULL;
367	clear_bit(0, &watchdog_dev_busy);
368	return err;
369}
370
371/*
372 *	watchdog_dev_unregister:
373 *	@watchdog: watchdog device
374 *
375 *	Deregister the /dev/watchdog device.
376 */
377
378int watchdog_dev_unregister(struct watchdog_device *watchdog)
379{
380	/* Check that a watchdog device was registered in the past */
381	if (!test_bit(0, &watchdog_dev_busy) || !wdd)
382		return -ENODEV;
383
384	/* We can only unregister the watchdog device that was registered */
385	if (watchdog != wdd) {
386		pr_err("%s: watchdog was not registered as /dev/watchdog.\n",
387			watchdog->info->identity);
388		return -ENODEV;
389	}
390
391	misc_deregister(&watchdog_miscdev);
392	wdd = NULL;
393	clear_bit(0, &watchdog_dev_busy);
394	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395}
v3.5.6
  1/*
  2 *	watchdog_dev.c
  3 *
  4 *	(c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>,
  5 *						All Rights Reserved.
  6 *
  7 *	(c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>.
  8 *
  9 *
 10 *	This source code is part of the generic code that can be used
 11 *	by all the watchdog timer drivers.
 12 *
 13 *	This part of the generic code takes care of the following
 14 *	misc device: /dev/watchdog.
 15 *
 16 *	Based on source code of the following authors:
 17 *	  Matt Domsch <Matt_Domsch@dell.com>,
 18 *	  Rob Radez <rob@osinvestor.com>,
 19 *	  Rusty Lynch <rusty@linux.co.intel.com>
 20 *	  Satyam Sharma <satyam@infradead.org>
 21 *	  Randy Dunlap <randy.dunlap@oracle.com>
 22 *
 23 *	This program is free software; you can redistribute it and/or
 24 *	modify it under the terms of the GNU General Public License
 25 *	as published by the Free Software Foundation; either version
 26 *	2 of the License, or (at your option) any later version.
 27 *
 28 *	Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
 29 *	admit liability nor provide warranty for any of this software.
 30 *	This material is provided "AS-IS" and at no charge.
 31 */
 32
 33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 34
 35#include <linux/module.h>	/* For module stuff/... */
 36#include <linux/types.h>	/* For standard types (like size_t) */
 37#include <linux/errno.h>	/* For the -ENODEV/... values */
 38#include <linux/kernel.h>	/* For printk/panic/... */
 39#include <linux/fs.h>		/* For file operations */
 40#include <linux/watchdog.h>	/* For watchdog specific items */
 41#include <linux/miscdevice.h>	/* For handling misc devices */
 42#include <linux/init.h>		/* For __init/__exit/... */
 43#include <linux/uaccess.h>	/* For copy_to_user/put_user/... */
 44
 45#include "watchdog_core.h"
 46
 47/* the dev_t structure to store the dynamically allocated watchdog devices */
 48static dev_t watchdog_devt;
 49/* the watchdog device behind /dev/watchdog */
 50static struct watchdog_device *old_wdd;
 51
 52/*
 53 *	watchdog_ping: ping the watchdog.
 54 *	@wddev: the watchdog device to ping
 55 *
 56 *	If the watchdog has no own ping operation then it needs to be
 57 *	restarted via the start operation. This wrapper function does
 58 *	exactly that.
 59 *	We only ping when the watchdog device is running.
 60 */
 61
 62static int watchdog_ping(struct watchdog_device *wddev)
 63{
 64	int err = 0;
 65
 66	mutex_lock(&wddev->lock);
 67
 68	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
 69		err = -ENODEV;
 70		goto out_ping;
 71	}
 72
 73	if (!watchdog_active(wddev))
 74		goto out_ping;
 75
 76	if (wddev->ops->ping)
 77		err = wddev->ops->ping(wddev);  /* ping the watchdog */
 78	else
 79		err = wddev->ops->start(wddev); /* restart watchdog */
 80
 81out_ping:
 82	mutex_unlock(&wddev->lock);
 83	return err;
 84}
 85
 86/*
 87 *	watchdog_start: wrapper to start the watchdog.
 88 *	@wddev: the watchdog device to start
 89 *
 90 *	Start the watchdog if it is not active and mark it active.
 91 *	This function returns zero on success or a negative errno code for
 92 *	failure.
 93 */
 94
 95static int watchdog_start(struct watchdog_device *wddev)
 96{
 97	int err = 0;
 98
 99	mutex_lock(&wddev->lock);
 
 
 
100
101	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
102		err = -ENODEV;
103		goto out_start;
104	}
105
106	if (watchdog_active(wddev))
107		goto out_start;
108
109	err = wddev->ops->start(wddev);
110	if (err == 0)
111		set_bit(WDOG_ACTIVE, &wddev->status);
112
113out_start:
114	mutex_unlock(&wddev->lock);
115	return err;
116}
117
118/*
119 *	watchdog_stop: wrapper to stop the watchdog.
120 *	@wddev: the watchdog device to stop
121 *
122 *	Stop the watchdog if it is still active and unmark it active.
123 *	This function returns zero on success or a negative errno code for
124 *	failure.
125 *	If the 'nowayout' feature was set, the watchdog cannot be stopped.
126 */
127
128static int watchdog_stop(struct watchdog_device *wddev)
129{
130	int err = 0;
131
132	mutex_lock(&wddev->lock);
133
134	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
135		err = -ENODEV;
136		goto out_stop;
137	}
138
139	if (!watchdog_active(wddev))
140		goto out_stop;
141
142	if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) {
143		dev_info(wddev->dev, "nowayout prevents watchdog being stopped!\n");
144		err = -EBUSY;
145		goto out_stop;
146	}
147
148	err = wddev->ops->stop(wddev);
149	if (err == 0)
150		clear_bit(WDOG_ACTIVE, &wddev->status);
151
152out_stop:
153	mutex_unlock(&wddev->lock);
154	return err;
155}
156
157/*
158 *	watchdog_get_status: wrapper to get the watchdog status
159 *	@wddev: the watchdog device to get the status from
160 *	@status: the status of the watchdog device
161 *
162 *	Get the watchdog's status flags.
163 */
164
165static int watchdog_get_status(struct watchdog_device *wddev,
166							unsigned int *status)
167{
168	int err = 0;
169
170	*status = 0;
171	if (!wddev->ops->status)
172		return -EOPNOTSUPP;
173
174	mutex_lock(&wddev->lock);
175
176	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
177		err = -ENODEV;
178		goto out_status;
179	}
180
181	*status = wddev->ops->status(wddev);
182
183out_status:
184	mutex_unlock(&wddev->lock);
185	return err;
186}
187
188/*
189 *	watchdog_set_timeout: set the watchdog timer timeout
190 *	@wddev: the watchdog device to set the timeout for
191 *	@timeout: timeout to set in seconds
192 */
193
194static int watchdog_set_timeout(struct watchdog_device *wddev,
195							unsigned int timeout)
196{
197	int err;
198
199	if ((wddev->ops->set_timeout == NULL) ||
200	    !(wddev->info->options & WDIOF_SETTIMEOUT))
201		return -EOPNOTSUPP;
202
203	if ((wddev->max_timeout != 0) &&
204	    (timeout < wddev->min_timeout || timeout > wddev->max_timeout))
205		return -EINVAL;
206
207	mutex_lock(&wddev->lock);
208
209	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
210		err = -ENODEV;
211		goto out_timeout;
212	}
213
214	err = wddev->ops->set_timeout(wddev, timeout);
215
216out_timeout:
217	mutex_unlock(&wddev->lock);
218	return err;
219}
220
221/*
222 *	watchdog_get_timeleft: wrapper to get the time left before a reboot
223 *	@wddev: the watchdog device to get the remaining time from
224 *	@timeleft: the time that's left
225 *
226 *	Get the time before a watchdog will reboot (if not pinged).
227 */
228
229static int watchdog_get_timeleft(struct watchdog_device *wddev,
230							unsigned int *timeleft)
231{
232	int err = 0;
233
234	*timeleft = 0;
235	if (!wddev->ops->get_timeleft)
236		return -EOPNOTSUPP;
237
238	mutex_lock(&wddev->lock);
239
240	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
241		err = -ENODEV;
242		goto out_timeleft;
243	}
244
245	*timeleft = wddev->ops->get_timeleft(wddev);
246
247out_timeleft:
248	mutex_unlock(&wddev->lock);
249	return err;
250}
251
252/*
253 *	watchdog_ioctl_op: call the watchdog drivers ioctl op if defined
254 *	@wddev: the watchdog device to do the ioctl on
255 *	@cmd: watchdog command
256 *	@arg: argument pointer
257 */
258
259static int watchdog_ioctl_op(struct watchdog_device *wddev, unsigned int cmd,
260							unsigned long arg)
261{
262	int err;
263
264	if (!wddev->ops->ioctl)
265		return -ENOIOCTLCMD;
266
267	mutex_lock(&wddev->lock);
268
269	if (test_bit(WDOG_UNREGISTERED, &wddev->status)) {
270		err = -ENODEV;
271		goto out_ioctl;
272	}
273
274	err = wddev->ops->ioctl(wddev, cmd, arg);
275
276out_ioctl:
277	mutex_unlock(&wddev->lock);
278	return err;
279}
280
281/*
282 *	watchdog_write: writes to the watchdog.
283 *	@file: file from VFS
284 *	@data: user address of data
285 *	@len: length of data
286 *	@ppos: pointer to the file offset
287 *
288 *	A write to a watchdog device is defined as a keepalive ping.
289 *	Writing the magic 'V' sequence allows the next close to turn
290 *	off the watchdog (if 'nowayout' is not set).
291 */
292
293static ssize_t watchdog_write(struct file *file, const char __user *data,
294						size_t len, loff_t *ppos)
295{
296	struct watchdog_device *wdd = file->private_data;
297	size_t i;
298	char c;
299
300	if (len == 0)
301		return 0;
302
303	/*
304	 * Note: just in case someone wrote the magic character
305	 * five months ago...
306	 */
307	clear_bit(WDOG_ALLOW_RELEASE, &wdd->status);
308
309	/* scan to see whether or not we got the magic character */
310	for (i = 0; i != len; i++) {
311		if (get_user(c, data + i))
312			return -EFAULT;
313		if (c == 'V')
314			set_bit(WDOG_ALLOW_RELEASE, &wdd->status);
315	}
316
317	/* someone wrote to us, so we send the watchdog a keepalive ping */
318	watchdog_ping(wdd);
319
320	return len;
321}
322
323/*
324 *	watchdog_ioctl: handle the different ioctl's for the watchdog device.
325 *	@file: file handle to the device
326 *	@cmd: watchdog command
327 *	@arg: argument pointer
328 *
329 *	The watchdog API defines a common set of functions for all watchdogs
330 *	according to their available features.
331 */
332
333static long watchdog_ioctl(struct file *file, unsigned int cmd,
334							unsigned long arg)
335{
336	struct watchdog_device *wdd = file->private_data;
337	void __user *argp = (void __user *)arg;
338	int __user *p = argp;
339	unsigned int val;
340	int err;
341
342	err = watchdog_ioctl_op(wdd, cmd, arg);
343	if (err != -ENOIOCTLCMD)
344		return err;
 
 
345
346	switch (cmd) {
347	case WDIOC_GETSUPPORT:
348		return copy_to_user(argp, wdd->info,
349			sizeof(struct watchdog_info)) ? -EFAULT : 0;
350	case WDIOC_GETSTATUS:
351		err = watchdog_get_status(wdd, &val);
352		if (err == -ENODEV)
353			return err;
354		return put_user(val, p);
355	case WDIOC_GETBOOTSTATUS:
356		return put_user(wdd->bootstatus, p);
357	case WDIOC_SETOPTIONS:
358		if (get_user(val, p))
359			return -EFAULT;
360		if (val & WDIOS_DISABLECARD) {
361			err = watchdog_stop(wdd);
362			if (err < 0)
363				return err;
364		}
365		if (val & WDIOS_ENABLECARD) {
366			err = watchdog_start(wdd);
367			if (err < 0)
368				return err;
369		}
370		return 0;
371	case WDIOC_KEEPALIVE:
372		if (!(wdd->info->options & WDIOF_KEEPALIVEPING))
373			return -EOPNOTSUPP;
374		watchdog_ping(wdd);
375		return 0;
376	case WDIOC_SETTIMEOUT:
 
 
 
377		if (get_user(val, p))
378			return -EFAULT;
379		err = watchdog_set_timeout(wdd, val);
 
 
 
380		if (err < 0)
381			return err;
 
382		/* If the watchdog is active then we send a keepalive ping
383		 * to make sure that the watchdog keep's running (and if
384		 * possible that it takes the new timeout) */
385		watchdog_ping(wdd);
386		/* Fall */
387	case WDIOC_GETTIMEOUT:
388		/* timeout == 0 means that we don't know the timeout */
389		if (wdd->timeout == 0)
390			return -EOPNOTSUPP;
391		return put_user(wdd->timeout, p);
392	case WDIOC_GETTIMELEFT:
393		err = watchdog_get_timeleft(wdd, &val);
394		if (err)
395			return err;
396		return put_user(val, p);
397	default:
398		return -ENOTTY;
399	}
400}
401
402/*
403 *	watchdog_open: open the /dev/watchdog* devices.
404 *	@inode: inode of device
405 *	@file: file handle to device
406 *
407 *	When the /dev/watchdog* device gets opened, we start the watchdog.
408 *	Watch out: the /dev/watchdog device is single open, so we make sure
409 *	it can only be opened once.
410 */
411
412static int watchdog_open(struct inode *inode, struct file *file)
413{
414	int err = -EBUSY;
415	struct watchdog_device *wdd;
416
417	/* Get the corresponding watchdog device */
418	if (imajor(inode) == MISC_MAJOR)
419		wdd = old_wdd;
420	else
421		wdd = container_of(inode->i_cdev, struct watchdog_device, cdev);
422
423	/* the watchdog is single open! */
424	if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status))
425		return -EBUSY;
426
427	/*
428	 * If the /dev/watchdog device is open, we don't want the module
429	 * to be unloaded.
430	 */
431	if (!try_module_get(wdd->ops->owner))
432		goto out;
433
434	err = watchdog_start(wdd);
435	if (err < 0)
436		goto out_mod;
437
438	file->private_data = wdd;
439
440	if (wdd->ops->ref)
441		wdd->ops->ref(wdd);
442
443	/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
444	return nonseekable_open(inode, file);
445
446out_mod:
447	module_put(wdd->ops->owner);
448out:
449	clear_bit(WDOG_DEV_OPEN, &wdd->status);
450	return err;
451}
452
453/*
454 *	watchdog_release: release the watchdog device.
455 *	@inode: inode of device
456 *	@file: file handle to device
457 *
458 *	This is the code for when /dev/watchdog gets closed. We will only
459 *	stop the watchdog when we have received the magic char (and nowayout
460 *	was not set), else the watchdog will keep running.
461 */
462
463static int watchdog_release(struct inode *inode, struct file *file)
464{
465	struct watchdog_device *wdd = file->private_data;
466	int err = -EBUSY;
467
468	/*
469	 * We only stop the watchdog if we received the magic character
470	 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
471	 * watchdog_stop will fail.
472	 */
473	if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
474	    !(wdd->info->options & WDIOF_MAGICCLOSE))
475		err = watchdog_stop(wdd);
476
477	/* If the watchdog was not stopped, send a keepalive ping */
478	if (err < 0) {
479		mutex_lock(&wdd->lock);
480		if (!test_bit(WDOG_UNREGISTERED, &wdd->status))
481			dev_crit(wdd->dev, "watchdog did not stop!\n");
482		mutex_unlock(&wdd->lock);
483		watchdog_ping(wdd);
484	}
485
486	/* Allow the owner module to be unloaded again */
487	module_put(wdd->ops->owner);
488
489	/* make sure that /dev/watchdog can be re-opened */
490	clear_bit(WDOG_DEV_OPEN, &wdd->status);
491
492	/* Note wdd may be gone after this, do not use after this! */
493	if (wdd->ops->unref)
494		wdd->ops->unref(wdd);
495
496	return 0;
497}
498
499static const struct file_operations watchdog_fops = {
500	.owner		= THIS_MODULE,
501	.write		= watchdog_write,
502	.unlocked_ioctl	= watchdog_ioctl,
503	.open		= watchdog_open,
504	.release	= watchdog_release,
505};
506
507static struct miscdevice watchdog_miscdev = {
508	.minor		= WATCHDOG_MINOR,
509	.name		= "watchdog",
510	.fops		= &watchdog_fops,
511};
512
513/*
514 *	watchdog_dev_register: register a watchdog device
515 *	@watchdog: watchdog device
516 *
517 *	Register a watchdog device including handling the legacy
518 *	/dev/watchdog node. /dev/watchdog is actually a miscdevice and
519 *	thus we set it up like that.
520 */
521
522int watchdog_dev_register(struct watchdog_device *watchdog)
523{
524	int err, devno;
525
526	if (watchdog->id == 0) {
527		watchdog_miscdev.parent = watchdog->parent;
528		err = misc_register(&watchdog_miscdev);
529		if (err != 0) {
530			pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
531				watchdog->info->identity, WATCHDOG_MINOR, err);
532			if (err == -EBUSY)
533				pr_err("%s: a legacy watchdog module is probably present.\n",
534					watchdog->info->identity);
535			return err;
536		}
537		old_wdd = watchdog;
538	}
539
540	/* Fill in the data structures */
541	devno = MKDEV(MAJOR(watchdog_devt), watchdog->id);
542	cdev_init(&watchdog->cdev, &watchdog_fops);
543	watchdog->cdev.owner = watchdog->ops->owner;
544
545	/* Add the device */
546	err  = cdev_add(&watchdog->cdev, devno, 1);
547	if (err) {
548		pr_err("watchdog%d unable to add device %d:%d\n",
549			watchdog->id,  MAJOR(watchdog_devt), watchdog->id);
550		if (watchdog->id == 0) {
551			misc_deregister(&watchdog_miscdev);
552			old_wdd = NULL;
553		}
554	}
 
 
 
 
 
 
555	return err;
556}
557
558/*
559 *	watchdog_dev_unregister: unregister a watchdog device
560 *	@watchdog: watchdog device
561 *
562 *	Unregister the watchdog and if needed the legacy /dev/watchdog device.
563 */
564
565int watchdog_dev_unregister(struct watchdog_device *watchdog)
566{
567	mutex_lock(&watchdog->lock);
568	set_bit(WDOG_UNREGISTERED, &watchdog->status);
569	mutex_unlock(&watchdog->lock);
570
571	cdev_del(&watchdog->cdev);
572	if (watchdog->id == 0) {
573		misc_deregister(&watchdog_miscdev);
574		old_wdd = NULL;
 
575	}
 
 
 
 
576	return 0;
577}
578
579/*
580 *	watchdog_dev_init: init dev part of watchdog core
581 *
582 *	Allocate a range of chardev nodes to use for watchdog devices
583 */
584
585int __init watchdog_dev_init(void)
586{
587	int err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
588	if (err < 0)
589		pr_err("watchdog: unable to allocate char dev region\n");
590	return err;
591}
592
593/*
594 *	watchdog_dev_exit: exit dev part of watchdog core
595 *
596 *	Release the range of chardev nodes used for watchdog devices
597 */
598
599void __exit watchdog_dev_exit(void)
600{
601	unregister_chrdev_region(watchdog_devt, MAX_DOGS);
602}