Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f2d1f0d authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

wdt: Cleanup and sort out locking and inb_p

parent 41dc8b72
Loading
Loading
Loading
Loading
+94 −82
Original line number Diff line number Diff line
@@ -24,9 +24,10 @@
 *					Matt Crocker).
 *		Alan Cox	:	Added wdt= boot option
 *		Alan Cox	:	Cleaned up copy/user stuff
 *		Tim Hockin	:	Added insmod parameters, comment cleanup
 *					Parameterized timeout
 *		Tigran Aivazian	:	Restructured wdt_init() to handle failures
 *		Tim Hockin	:	Added insmod parameters, comment
 *					cleanup, parameterized timeout
 *		Tigran Aivazian	:	Restructured wdt_init() to handle
 *					failures
 *		Joel Becker	:	Added WDIOC_GET/SETTIMEOUT
 *		Matt Domsch	:	Added nowayout module option
 */
@@ -42,9 +43,9 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include "wd501p.h"

@@ -60,11 +61,15 @@ static char expect_close;
static int heartbeat = WD_TIMO;
static int wd_heartbeat;
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
MODULE_PARM_DESC(heartbeat,
	"Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default="
				__MODULE_STRING(WD_TIMO) ")");

static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_PARM_DESC(nowayout,
	"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

/* You must set these - there is no sane way to probe for this board. */
static int io = 0x240;
@@ -82,7 +87,8 @@ MODULE_PARM_DESC(irq, "WDT irq (default=11)");
static int tachometer;

module_param(tachometer, int, 0);
MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)");
MODULE_PARM_DESC(tachometer,
		"WDT501-P Fan Tachometer support (0=disable, default=0)");
#endif /* CONFIG_WDT_501 */

/*
@@ -114,9 +120,12 @@ static int wdt_start(void)
	unsigned long flags;
	spin_lock_irqsave(&wdt_lock, flags);
	inb_p(WDT_DC);			/* Disable watchdog */
	wdt_ctr_mode(0,3);		/* Program CTR0 for Mode 3: Square Wave Generator */
	wdt_ctr_mode(1,2);		/* Program CTR1 for Mode 2: Rate Generator */
	wdt_ctr_mode(2,0);		/* Program CTR2 for Mode 0: Pulse on Terminal Count */
	wdt_ctr_mode(0, 3);		/* Program CTR0 for Mode 3:
						Square Wave Generator */
	wdt_ctr_mode(1, 2);		/* Program CTR1 for Mode 2:
						Rate Generator */
	wdt_ctr_mode(2, 0);		/* Program CTR2 for Mode 0:
						Pulse on Terminal Count */
	wdt_ctr_load(0, 8948);		/* Count at 100Hz */
	wdt_ctr_load(1, wd_heartbeat);	/* Heartbeat */
	wdt_ctr_load(2, 65535);		/* Length of reset pulse */
@@ -145,8 +154,8 @@ static int wdt_stop (void)
/**
 *	wdt_ping:
 *
 *	Reload counter one with the watchdog heartbeat. We don't bother reloading
 *	the cascade counter.
 *	Reload counter one with the watchdog heartbeat. We don't bother
 *	reloading the cascade counter.
 */

static int wdt_ping(void)
@@ -155,7 +164,8 @@ static int wdt_ping(void)
	spin_lock_irqsave(&wdt_lock, flags);
	/* Write a watchdog value */
	inb_p(WDT_DC);			/* Disable watchdog */
	wdt_ctr_mode(1,2);		/* Re-Program CTR1 for Mode 2: Rate Generator */
	wdt_ctr_mode(1, 2);		/* Re-Program CTR1 for Mode 2:
							Rate Generator */
	wdt_ctr_load(1, wd_heartbeat);	/* Heartbeat */
	outb_p(0, WDT_DC);		/* Enable watchdog */
	spin_unlock_irqrestore(&wdt_lock, flags);
@@ -166,13 +176,14 @@ static int wdt_ping(void)
 *	wdt_set_heartbeat:
 *	@t:		the new heartbeat value that needs to be set.
 *
 *	Set a new heartbeat value for the watchdog device. If the heartbeat value is
 *	incorrect we keep the old value and return -EINVAL. If successfull we
 *	return 0.
 *	Set a new heartbeat value for the watchdog device. If the heartbeat
 *	value is incorrect we keep the old value and return -EINVAL. If
 *	successful we return 0.
 */

static int wdt_set_heartbeat(int t)
{
	if ((t < 1) || (t > 65535))
	if (t < 1 || t > 65535)
		return -EINVAL;

	heartbeat = t;
@@ -304,7 +315,8 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id)
 *	write of data will do, as we we don't define content meaning.
 */

static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
static ssize_t wdt_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
{
	if (count) {
		if (!nowayout) {
@@ -328,7 +340,6 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count

/**
 *	wdt_ioctl:
 *	@inode: inode of the device
 *	@file: file handle to the device
 *	@cmd: watchdog command
 *	@arg: argument pointer
@@ -338,8 +349,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count
 *	querying capabilities and current status.
 */

static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	unsigned long arg)
static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
@@ -362,13 +372,11 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		ident.options |= WDIOF_FANFAULT;
#endif /* CONFIG_WDT_501 */

	switch(cmd)
	{
	switch (cmd) {
	default:
		return -ENOTTY;
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
		wdt_get_status(&status);
		return put_user(status, p);
@@ -380,10 +388,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	case WDIOC_SETTIMEOUT:
		if (get_user(new_heartbeat, p))
			return -EFAULT;

		if (wdt_set_heartbeat(new_heartbeat))
			return -EINVAL;

		wdt_ping();
		/* Fall */
	case WDIOC_GETTIMEOUT:
@@ -432,7 +438,8 @@ static int wdt_release(struct inode *inode, struct file *file)
		wdt_stop();
		clear_bit(0, &wdt_is_open);
	} else {
		printk(KERN_CRIT "wdt: WDT device closed unexpectedly.  WDT will not stop!\n");
		printk(KERN_CRIT
		 "wdt: WDT device closed unexpectedly.  WDT will not stop!\n");
		wdt_ping();
	}
	expect_close = 0;
@@ -451,7 +458,8 @@ static int wdt_release(struct inode *inode, struct file *file)
 *	farenheit. It was designed by an imperial measurement luddite.
 */

static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
static ssize_t wdt_temp_read(struct file *file, char __user *buf,
						size_t count, loff_t *ptr)
{
	int temperature;

@@ -506,10 +514,8 @@ static int wdt_temp_release(struct inode *inode, struct file *file)
static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
	void *unused)
{
	if(code==SYS_DOWN || code==SYS_HALT) {
		/* Turn the card off */
	if (code == SYS_DOWN || code == SYS_HALT)
		wdt_stop();
	}
	return NOTIFY_DONE;
}

@@ -522,7 +528,7 @@ static const struct file_operations wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= wdt_write,
	.ioctl		= wdt_ioctl,
	.unlocked_ioctl	= wdt_ioctl,
	.open		= wdt_open,
	.release	= wdt_release,
};
@@ -591,7 +597,8 @@ static int __init wdt_init(void)
{
	int ret;

	/* Check that the heartbeat value is within it's range ; if not reset to the default */
	/* Check that the heartbeat value is within it's range;
	   if not reset to the default */
	if (wdt_set_heartbeat(heartbeat)) {
		wdt_set_heartbeat(WD_TIMO);
		printk(KERN_INFO "wdt: heartbeat value must be 0 < heartbeat < 65536, using %d\n",
@@ -599,7 +606,8 @@ static int __init wdt_init(void)
	}

	if (!request_region(io, 8, "wdt501p")) {
		printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io);
		printk(KERN_ERR
			"wdt: I/O address 0x%04x already in use\n", io);
		ret = -EBUSY;
		goto out;
	}
@@ -612,14 +620,16 @@ static int __init wdt_init(void)

	ret = register_reboot_notifier(&wdt_notifier);
	if (ret) {
		printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret);
		printk(KERN_ERR
		      "wdt: cannot register reboot notifier (err=%d)\n", ret);
		goto outirq;
	}

#ifdef CONFIG_WDT_501
	ret = misc_register(&temp_miscdev);
	if (ret) {
		printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n",
		printk(KERN_ERR
			"wdt: cannot register miscdev on minor=%d (err=%d)\n",
							TEMP_MINOR, ret);
		goto outrbt;
	}
@@ -627,7 +637,8 @@ static int __init wdt_init(void)

	ret = misc_register(&wdt_miscdev);
	if (ret) {
		printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n",
		printk(KERN_ERR
			"wdt: cannot register miscdev on minor=%d (err=%d)\n",
							WATCHDOG_MINOR, ret);
		goto outmisc;
	}
@@ -636,7 +647,8 @@ static int __init wdt_init(void)
	printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n",
		io, irq, heartbeat, nowayout);
#ifdef CONFIG_WDT_501
	printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled"));
	printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
				(tachometer ? "Enabled" : "Disabled"));
#endif /* CONFIG_WDT_501 */

out:
+171 −129
Original line number Diff line number Diff line
@@ -29,9 +29,11 @@
 *		JP Nollmann	:	Added support for PCI wdt501p
 *		Alan Cox	:	Split ISA and PCI cards into two drivers
 *		Jeff Garzik	:	PCI cleanups
 *		Tigran Aivazian	:	Restructured wdtpci_init_one() to handle failures
 *		Tigran Aivazian	:	Restructured wdtpci_init_one() to handle
 *					failures
 *		Joel Becker 	:	Added WDIOC_GET/SETTIMEOUT
 *		Zwane Mwaikambo	:	Magic char closing, locking changes, cleanups
 *		Zwane Mwaikambo	:	Magic char closing, locking changes,
 *					cleanups
 *		Matt Domsch	:	nowayout module option
 */

@@ -47,9 +49,9 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>

#define WDT_IS_PCI
@@ -73,7 +75,7 @@
/* We can only use 1 card due to the /dev/watchdog restriction */
static int dev_count;

static struct semaphore open_sem;
static unsigned long open_lock;
static DEFINE_SPINLOCK(wdtpci_lock);
static char expect_close;

@@ -86,18 +88,23 @@ static int irq;
static int heartbeat = WD_TIMO;
static int wd_heartbeat;
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
MODULE_PARM_DESC(heartbeat,
		"Watchdog heartbeat in seconds. (0<heartbeat<65536, default="
				__MODULE_STRING(WD_TIMO) ")");

static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_PARM_DESC(nowayout,
		"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

#ifdef CONFIG_WDT_501_PCI
/* Support for the Fan Tachometer on the PCI-WDT501 */
static int tachometer;

module_param(tachometer, int, 0);
MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
MODULE_PARM_DESC(tachometer,
	"PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
#endif /* CONFIG_WDT_501_PCI */

/*
@@ -109,13 +116,16 @@ static void wdtpci_ctr_mode(int ctr, int mode)
	ctr <<= 6;
	ctr |= 0x30;
	ctr |= (mode << 1);
	outb_p(ctr, WDT_CR);
	outb(ctr, WDT_CR);
	udelay(8);
}

static void wdtpci_ctr_load(int ctr, int val)
{
	outb_p(val&0xFF, WDT_COUNT0+ctr);
	outb_p(val>>8, WDT_COUNT0+ctr);
	outb(val & 0xFF, WDT_COUNT0 + ctr);
	udelay(8);
	outb(val >> 8, WDT_COUNT0 + ctr);
	udelay(8);
}

/**
@@ -134,23 +144,35 @@ static int wdtpci_start(void)
	 * "pet" the watchdog, as Access says.
	 * This resets the clock outputs.
	 */
	inb_p(WDT_DC);			/* Disable watchdog */
	wdtpci_ctr_mode(2,0);		/* Program CTR2 for Mode 0: Pulse on Terminal Count */
	outb_p(0, WDT_DC);		/* Enable watchdog */

	inb_p(WDT_DC);			/* Disable watchdog */
	outb_p(0, WDT_CLOCK);		/* 2.0833MHz clock */
	inb_p(WDT_BUZZER);		/* disable */
	inb_p(WDT_OPTONOTRST);		/* disable */
	inb_p(WDT_OPTORST);		/* disable */
	inb_p(WDT_PROGOUT);		/* disable */
	wdtpci_ctr_mode(0,3);		/* Program CTR0 for Mode 3: Square Wave Generator */
	wdtpci_ctr_mode(1,2);		/* Program CTR1 for Mode 2: Rate Generator */
	wdtpci_ctr_mode(2,1);		/* Program CTR2 for Mode 1: Retriggerable One-Shot */
	inb(WDT_DC);			/* Disable watchdog */
	udelay(8);
	wdtpci_ctr_mode(2, 0);		/* Program CTR2 for Mode 0:
						Pulse on Terminal Count */
	outb(0, WDT_DC);		/* Enable watchdog */
	udelay(8);
	inb(WDT_DC);			/* Disable watchdog */
	udelay(8);
	outb(0, WDT_CLOCK);		/* 2.0833MHz clock */
	udelay(8);
	inb(WDT_BUZZER);		/* disable */
	udelay(8);
	inb(WDT_OPTONOTRST);		/* disable */
	udelay(8);
	inb(WDT_OPTORST);		/* disable */
	udelay(8);
	inb(WDT_PROGOUT);		/* disable */
	udelay(8);
	wdtpci_ctr_mode(0, 3);		/* Program CTR0 for Mode 3:
						Square Wave Generator */
	wdtpci_ctr_mode(1, 2);		/* Program CTR1 for Mode 2:
						Rate Generator */
	wdtpci_ctr_mode(2, 1);		/* Program CTR2 for Mode 1:
						Retriggerable One-Shot */
	wdtpci_ctr_load(0, 20833);	/* count at 100Hz */
	wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
	/* DO NOT LOAD CTR2 on PCI card! -- JPN */
	outb_p(0, WDT_DC);		/* Enable watchdog */
	outb(0, WDT_DC);		/* Enable watchdog */
	udelay(8);

	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
@@ -168,7 +190,8 @@ static int wdtpci_stop (void)

	/* Turn the card off */
	spin_lock_irqsave(&wdtpci_lock, flags);
	inb_p(WDT_DC);			/* Disable watchdog */
	inb(WDT_DC);			/* Disable watchdog */
	udelay(8);
	wdtpci_ctr_load(2, 0);		/* 0 length reset pulses now */
	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
@@ -177,20 +200,23 @@ static int wdtpci_stop (void)
/**
 *	wdtpci_ping:
 *
 *	Reload counter one with the watchdog heartbeat. We don't bother reloading
 *	the cascade counter.
 *	Reload counter one with the watchdog heartbeat. We don't bother
 *	reloading the cascade counter.
 */

static int wdtpci_ping(void)
{
	unsigned long flags;

	/* Write a watchdog value */
	spin_lock_irqsave(&wdtpci_lock, flags);
	inb_p(WDT_DC);			/* Disable watchdog */
	wdtpci_ctr_mode(1,2);		/* Re-Program CTR1 for Mode 2: Rate Generator */
	/* Write a watchdog value */
	inb(WDT_DC);			/* Disable watchdog */
	udelay(8);
	wdtpci_ctr_mode(1, 2);		/* Re-Program CTR1 for Mode 2:
							Rate Generator */
	wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
	outb_p(0, WDT_DC);		/* Enable watchdog */
	outb(0, WDT_DC);		/* Enable watchdog */
	udelay(8);
	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
}
@@ -199,14 +225,14 @@ static int wdtpci_ping(void)
 *	wdtpci_set_heartbeat:
 *	@t:		the new heartbeat value that needs to be set.
 *
 *	Set a new heartbeat value for the watchdog device. If the heartbeat value is
 *	incorrect we keep the old value and return -EINVAL. If successfull we
 *	return 0.
 *	Set a new heartbeat value for the watchdog device. If the heartbeat
 *	value is incorrect we keep the old value and return -EINVAL.
 *	If successful we return 0.
 */
static int wdtpci_set_heartbeat(int t)
{
	/* Arbitrary, can't find the card's limits */
	if ((t < 1) || (t > 65535))
	if (t < 1 || t > 65535)
		return -EINVAL;

	heartbeat = t;
@@ -227,7 +253,12 @@ static int wdtpci_set_heartbeat(int t)

static int wdtpci_get_status(int *status)
{
	unsigned char new_status=inb_p(WDT_SR);
	unsigned char new_status;
	unsigned long flags;

	spin_lock_irqsave(&wdtpci_lock, flags);
	new_status = inb(WDT_SR);
	spin_unlock_irqrestore(&wdtpci_lock, flags);

	*status = 0;
	if (new_status & WDC_SR_ISOI0)
@@ -259,8 +290,12 @@ static int wdtpci_get_status(int *status)

static int wdtpci_get_temperature(int *temperature)
{
	unsigned short c=inb_p(WDT_RT);

	unsigned short c;
	unsigned long flags;
	spin_lock_irqsave(&wdtpci_lock, flags);
	c = inb(WDT_RT);
	udelay(8);
	spin_unlock_irqrestore(&wdtpci_lock, flags);
	*temperature = (c * 11 / 15) + 7;
	return 0;
}
@@ -282,13 +317,21 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
	 *	Read the status register see what is up and
	 *	then printk it.
	 */
	unsigned char status=inb_p(WDT_SR);
	unsigned char status;

	spin_lock(&wdtpci_lock);

	status = inb(WDT_SR);
	udelay(8);

	printk(KERN_CRIT PFX "status %d\n", status);

#ifdef CONFIG_WDT_501_PCI
	if (!(status & WDC_SR_TGOOD))
 		printk(KERN_CRIT PFX "Overheat alarm.(%d)\n",inb_p(WDT_RT));
	if (!(status & WDC_SR_TGOOD)) {
		u8 alarm = inb(WDT_RT);
		printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm);
		udelay(8);
	}
	if (!(status & WDC_SR_PSUOVER))
		printk(KERN_CRIT PFX "PSU over voltage.\n");
	if (!(status & WDC_SR_PSUUNDR))
@@ -310,6 +353,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
		printk(KERN_CRIT PFX "Reset in 5ms.\n");
#endif
	}
	spin_unlock(&wdtpci_lock);
	return IRQ_HANDLED;
}

@@ -325,7 +369,8 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
 *	write of data will do, as we we don't define content meaning.
 */

static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
static ssize_t wdtpci_write(struct file *file, const char __user *buf,
					size_t count, loff_t *ppos)
{
	if (count) {
		if (!nowayout) {
@@ -343,13 +388,11 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co
		}
		wdtpci_ping();
	}

	return count;
}

/**
 *	wdtpci_ioctl:
 *	@inode: inode of the device
 *	@file: file handle to the device
 *	@cmd: watchdog command
 *	@arg: argument pointer
@@ -359,7 +402,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co
 *	querying capabilities and current status.
 */

static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static long wdtpci_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int new_heartbeat;
@@ -383,13 +426,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
		ident.options |= WDIOF_FANFAULT;
#endif /* CONFIG_WDT_501_PCI */

	switch(cmd)
	{
	switch (cmd) {
	default:
		return -ENOTTY;
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
		wdtpci_get_status(&status);
		return put_user(status, p);
@@ -401,10 +442,8 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
	case WDIOC_SETTIMEOUT:
		if (get_user(new_heartbeat, p))
			return -EFAULT;

		if (wdtpci_set_heartbeat(new_heartbeat))
			return -EINVAL;

		wdtpci_ping();
		/* Fall */
	case WDIOC_GETTIMEOUT:
@@ -426,12 +465,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd

static int wdtpci_open(struct inode *inode, struct file *file)
{
	if (down_trylock(&open_sem))
	if (test_and_set_bit(0, &open_lock))
		return -EBUSY;

	if (nowayout) {
	if (nowayout)
		__module_get(THIS_MODULE);
	}
	/*
	 *	Activate
	 */
@@ -460,7 +498,7 @@ static int wdtpci_release(struct inode *inode, struct file *file)
		wdtpci_ping();
	}
	expect_close = 0;
	up(&open_sem);
	clear_bit(0, &open_lock);
	return 0;
}

@@ -476,7 +514,8 @@ static int wdtpci_release(struct inode *inode, struct file *file)
 *	fahrenheit. It was designed by an imperial measurement luddite.
 */

static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
static ssize_t wdtpci_temp_read(struct file *file, char __user *buf,
						size_t count, loff_t *ptr)
{
	int temperature;

@@ -531,10 +570,8 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file)
static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
							void *unused)
{
	if (code==SYS_DOWN || code==SYS_HALT) {
		/* Turn the card off */
	if (code == SYS_DOWN || code == SYS_HALT)
		wdtpci_stop();
	}
	return NOTIFY_DONE;
}

@@ -547,7 +584,7 @@ static const struct file_operations wdtpci_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= wdtpci_write,
	.ioctl		= wdtpci_ioctl,
	.unlocked_ioctl	= wdtpci_ioctl,
	.open		= wdtpci_open,
	.release	= wdtpci_release,
};
@@ -591,7 +628,7 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev,

	dev_count++;
	if (dev_count > 1) {
		printk (KERN_ERR PFX "this driver only supports 1 device\n");
		printk(KERN_ERR PFX "This driver only supports one device\n");
		return -ENODEV;
	}

@@ -606,8 +643,6 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev,
		goto out_pci;
	}

	sema_init(&open_sem, 1);

	irq = dev->irq;
	io = pci_resource_start(dev, 2);

@@ -622,26 +657,31 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev,
		goto out_reg;
	}

	printk ("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n",
	printk(KERN_INFO
	 "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n",
								io, irq);

	/* Check that the heartbeat value is within it's range ; if not reset to the default */
	/* Check that the heartbeat value is within its range;
	   if not reset to the default */
	if (wdtpci_set_heartbeat(heartbeat)) {
		wdtpci_set_heartbeat(WD_TIMO);
		printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
		printk(KERN_INFO PFX
		  "heartbeat value must be 0 < heartbeat < 65536, using %d\n",
								WD_TIMO);
	}

	ret = register_reboot_notifier(&wdtpci_notifier);
	if (ret) {
		printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
		printk(KERN_ERR PFX
			"cannot register reboot notifier (err=%d)\n", ret);
		goto out_irq;
	}

#ifdef CONFIG_WDT_501_PCI
	ret = misc_register(&temp_miscdev);
	if (ret) {
		printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
		printk(KERN_ERR PFX
			"cannot register miscdev on minor=%d (err=%d)\n",
					TEMP_MINOR, ret);
		goto out_rbt;
	}
@@ -649,7 +689,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev,

	ret = misc_register(&wdtpci_miscdev);
	if (ret) {
		printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
		printk(KERN_ERR PFX
			"cannot register miscdev on minor=%d (err=%d)\n",
						WATCHDOG_MINOR, ret);
		goto out_misc;
	}
@@ -657,7 +698,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev,
	printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
		heartbeat, nowayout);
#ifdef CONFIG_WDT_501_PCI
	printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled"));
	printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
				(tachometer ? "Enabled" : "Disabled"));
#endif /* CONFIG_WDT_501_PCI */

	ret = 0;