static int xwdt_release(struct inode *inode, struct file *file) { if (expect_close == 42) { xwdt_stop(); } else { pr_crit("Unexpected close, not stopping watchdog!\n"); xwdt_keepalive(); } clear_bit(0, &driver_open); expect_close = 0; return 0; }
/* * xwdt_ioctl: * @file: file handle to the device * @cmd: watchdog command * @arg: argument pointer * * The watchdog API defines a common set of functions for all watchdogs * according to their available features. */ static long xwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int status; union { struct watchdog_info __user *ident; int __user *i; } uarg; uarg.i = (int __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETBOOTSTATUS: return put_user(xdev.boot_status, uarg.i); case WDIOC_GETSTATUS: xwdt_get_status(&status); return put_user(status, uarg.i); case WDIOC_KEEPALIVE: xwdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: printk(KERN_INFO "This feature is not implemented yet!\n"); case WDIOC_GETTIMEOUT: if (no_timeout) return -ENOTTY; else return put_user(timeout, uarg.i); default: return -ENOTTY; } }
/* * xwdt_write: * @file: file handle to the watchdog * @buf: buffer to write (unused as data does not matter here * @count: count of bytes * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any * write of data will do, as we don't define content meaning. */ static ssize_t xwdt_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { if (len) { if (!xdev.nowayout) { size_t i; /* In case it was set long ago */ expect_close = 0; for (i = 0; i != len; i++) { char c; if (get_user(c, buf + i)) return -EFAULT; if (c == 'V') expect_close = 42; } } xwdt_keepalive(); } return len; }