X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fwatchdog%2Fscx200_wdt.c;h=fc0e0347f9d24b665711e21ca8d315567ea20e98;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=6f0657b2b7b682ab37ea1403183f149476cc9335;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index 6f0657b2b..fc0e0347f 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c @@ -4,7 +4,7 @@ Copyright (c) 2001,2002 Christer Weinigel - Som code taken from: + Some code taken from: National Semiconductor PC87307/PC97307 (ala SC1200) WDT driver (c) Copyright 2002 Zwane Mwaikambo @@ -17,7 +17,6 @@ of any nature resulting due to the use of this software. This software is provided AS-IS with no warranties. */ -#include #include #include #include @@ -39,15 +38,11 @@ MODULE_DESCRIPTION("NatSemi SCx200 Watchdog Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -#ifndef CONFIG_WATCHDOG_NOWAYOUT -#define CONFIG_WATCHDOG_NOWAYOUT 0 -#endif - static int margin = 60; /* in seconds */ module_param(margin, int, 0); MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); -static int nowayout = CONFIG_WATCHDOG_NOWAYOUT; +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); @@ -64,7 +59,7 @@ static char expect_close; static void scx200_wdt_ping(void) { - outw(wdto_restart, SCx200_CB_BASE + SCx200_WDT_WDTO); + outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); } static void scx200_wdt_update_margin(void) @@ -78,9 +73,9 @@ static void scx200_wdt_enable(void) printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", wdto_restart); - outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO); - outb(SCx200_WDT_WDSTS_WDOVF, SCx200_CB_BASE + SCx200_WDT_WDSTS); - outw(W_ENABLE, SCx200_CB_BASE + SCx200_WDT_WDCNFG); + outw(0, scx200_cb_base + SCx200_WDT_WDTO); + outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); + outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); scx200_wdt_ping(); } @@ -89,9 +84,9 @@ static void scx200_wdt_disable(void) { printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); - outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO); - outb(SCx200_WDT_WDSTS_WDOVF, SCx200_CB_BASE + SCx200_WDT_WDSTS); - outw(W_DISABLE, SCx200_CB_BASE + SCx200_WDT_WDCNFG); + outw(0, scx200_cb_base + SCx200_WDT_WDTO); + outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); + outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); } static int scx200_wdt_open(struct inode *inode, struct file *file) @@ -101,7 +96,7 @@ static int scx200_wdt_open(struct inode *inode, struct file *file) return -EBUSY; scx200_wdt_enable(); - return 0; + return nonseekable_open(inode, file); } static int scx200_wdt_release(struct inode *inode, struct file *file) @@ -132,12 +127,9 @@ static struct notifier_block scx200_wdt_notifier = .notifier_call = scx200_wdt_notify_sys, }; -static ssize_t scx200_wdt_write(struct file *file, const char *data, +static ssize_t scx200_wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { - if (ppos != &file->f_pos) - return -ESPIPE; - /* check for a magic close character */ if (len) { @@ -163,6 +155,8 @@ static ssize_t scx200_wdt_write(struct file *file, const char *data, static int scx200_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .identity = "NatSemi SCx200 Watchdog", .firmware_version = 1, @@ -172,22 +166,21 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, switch (cmd) { default: - return -ENOIOCTLCMD; + return -ENOTTY; case WDIOC_GETSUPPORT: - if(copy_to_user((struct watchdog_info *)arg, &ident, - sizeof(ident))) + if(copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - if (put_user(0, (int *)arg)) + if (put_user(0, p)) return -EFAULT; return 0; case WDIOC_KEEPALIVE: scx200_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int *)arg)) + if (get_user(new_margin, p)) return -EFAULT; if (new_margin < 1) return -EINVAL; @@ -195,14 +188,15 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, scx200_wdt_update_margin(); scx200_wdt_ping(); case WDIOC_GETTIMEOUT: - if (put_user(margin, (int *)arg)) + if (put_user(margin, p)) return -EFAULT; return 0; } } -static struct file_operations scx200_wdt_fops = { +static const struct file_operations scx200_wdt_fops = { .owner = THIS_MODULE, + .llseek = no_llseek, .write = scx200_wdt_write, .ioctl = scx200_wdt_ioctl, .open = scx200_wdt_open, @@ -211,7 +205,7 @@ static struct file_operations scx200_wdt_fops = { static struct miscdevice scx200_wdt_miscdev = { .minor = WATCHDOG_MINOR, - .name = NAME, + .name = "watchdog", .fops = &scx200_wdt_fops, }; @@ -221,25 +215,11 @@ static int __init scx200_wdt_init(void) printk(KERN_DEBUG NAME ": NatSemi SCx200 Watchdog Driver\n"); - /* - * First check that this really is a NatSemi SCx200 CPU or a Geode - * SC1100 processor - */ - if ((pci_find_device(PCI_VENDOR_ID_NS, - PCI_DEVICE_ID_NS_SCx200_BRIDGE, - NULL)) == NULL - && (pci_find_device(PCI_VENDOR_ID_NS, - PCI_DEVICE_ID_NS_SC1100_BRIDGE, - NULL)) == NULL) + /* check that we have found the configuration block */ + if (!scx200_cb_present()) return -ENODEV; - /* More sanity checks, verify that the configuration block is there */ - if (!scx200_cb_probe(SCx200_CB_BASE)) { - printk(KERN_WARNING NAME ": no configuration block found\n"); - return -ENODEV; - } - - if (!request_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, + if (!request_region(scx200_cb_base + SCx200_WDT_OFFSET, SCx200_WDT_SIZE, "NatSemi SCx200 Watchdog")) { printk(KERN_WARNING NAME ": watchdog I/O region busy\n"); @@ -253,7 +233,7 @@ static int __init scx200_wdt_init(void) r = misc_register(&scx200_wdt_miscdev); if (r) { - release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, + release_region(scx200_cb_base + SCx200_WDT_OFFSET, SCx200_WDT_SIZE); return r; } @@ -262,7 +242,7 @@ static int __init scx200_wdt_init(void) if (r) { printk(KERN_ERR NAME ": unable to register reboot notifier"); misc_deregister(&scx200_wdt_miscdev); - release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, + release_region(scx200_cb_base + SCx200_WDT_OFFSET, SCx200_WDT_SIZE); return r; } @@ -274,7 +254,7 @@ static void __exit scx200_wdt_cleanup(void) { unregister_reboot_notifier(&scx200_wdt_notifier); misc_deregister(&scx200_wdt_miscdev); - release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, + release_region(scx200_cb_base + SCx200_WDT_OFFSET, SCx200_WDT_SIZE); }