Patch for Berkshire PC Watchdog

Richard Gooch (rgooch@atnf.CSIRO.AU)
Tue, 19 Aug 1997 18:33:27 +1000


Hi, all. I just had some fun getting the driver for the Berkshire
Products PC Watchdog working under 2.0.30. This patch fixes a few bugs
(like tickling the port never worked) and also the board is enabled on
open and disabled on close.

Regards,

Richard....

--- pcwd.c-orig Fri Aug 30 02:15:14 1996
+++ pcwd.c Tue Aug 19 18:18:56 1997
@@ -15,6 +15,9 @@
* check_region command due to Alan's suggestion.
* 960821 Made changes to compile in newer 2.0.x kernels. Added
* "cold reboot sense" entry.
+ * 970819 Fixed use of is_open flag so pcwd_write does not always return
+ * -EIO; this prevented tickling. Enabled board on open and
+ * disabled on close.
*/

#include <linux/module.h>
@@ -46,7 +49,11 @@
#define WD_TIMERRESET_PORT2 0x370 /* Reset port - second choice */
#define WD_CTLSTAT_PORT1 0x271 /* Control port - first choice */
#define WD_CTLSTAT_PORT2 0x371 /* Control port - second choice */
-#define WD_PORT_EXTENT 2 /* Takes up two addresses */
+#define WD_CTLSTAT2_PORT1 0x272 /* Control port#2 - first choice */
+#define WD_CTLSTAT2_PORT2 0x372 /* Control port#2 - second choice */
+#define WD_DISABLE_PORT1 0x273 /* Disable port - first choice */
+#define WD_DISABLE_PORT2 0x373 /* Disable port - second choice */
+#define WD_PORT_EXTENT 4 /* Takes up four addresses */

#define WD_WDRST 0x01 /* Previously reset state */
#define WD_T110 0x02 /* Temperature overheat sense */
@@ -54,7 +61,9 @@
#define WD_RLY2 0x08 /* External relay triggered */
#define WD_SRLY2 0x80 /* Software external relay triggered */

+
static int current_ctlport, current_readport;
+static int current_ctlport2, current_disport;
static int is_open, is_eof;

int pcwd_checkcard(void)
@@ -193,7 +202,7 @@

outb_p(wdrst_stat, current_ctlport);

- return(1);
+ return(len);
}

static int pcwd_ioctl(struct inode *inode, struct file *file,
@@ -235,10 +244,22 @@
static int pcwd_open(struct inode *ino, struct file *filep)
{
#ifdef DEBUG
- printk("pcwd: open request\n");
+ int before, after;
+
+ before = inb_p (current_ctlport2);
+#endif
+ if (is_open)
+ return -EIO;
+
+ /* Enable the port */
+ outb_p (0, current_disport);
+#ifdef DEBUG
+ after = inb_p (current_ctlport2);
+ printk ("pcwd: open: control status #2 (b,a): %x, %x\n", before,after);
#endif

MOD_INC_USE_COUNT;
+ is_open = 1;
is_eof = 0;
return(0);
}
@@ -249,6 +270,10 @@
printk("pcwd: close request\n");
#endif

+ is_open = 0;
+ /* Disable the board */
+ outb_p (0xa5, current_disport);
+ outb_p (0xa5, current_disport);
MOD_DEC_USE_COUNT;
}

@@ -290,6 +315,8 @@

current_ctlport = WD_TIMERRESET_PORT1;
current_readport = WD_CTLSTAT_PORT1;
+ current_ctlport2 = WD_CTLSTAT2_PORT1;
+ current_disport = WD_DISABLE_PORT1;

if (!pcwd_checkcard()) {
#ifdef DEBUG
@@ -298,6 +325,8 @@

current_ctlport = WD_TIMERRESET_PORT2;
current_readport = WD_CTLSTAT_PORT2;
+ current_ctlport2 = WD_CTLSTAT2_PORT2;
+ current_disport = WD_DISABLE_PORT2;

if (!pcwd_checkcard()) {
printk("pcwd: No card detected, or wrong port assigned.\n");
@@ -327,8 +356,11 @@
#ifdef MODULE
void cleanup_module(void)
{
+ /* Disable the board */
+ outb_p (0xa5, current_disport);
+ outb_p (0xa5, current_disport);
misc_deregister(&pcwd_miscdev);
- release_region(current_ctlport, 2);
+ release_region(current_ctlport, WD_PORT_EXTENT);
#ifdef DEBUG
printk("pcwd: Cleanup successful.\n");
#endif