patch-2.4.20 linux-2.4.20/drivers/char/eurotechwdt.c

Next file: linux-2.4.20/drivers/char/ftape/Config.in
Previous file: linux-2.4.20/drivers/char/efirtc.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/drivers/char/eurotechwdt.c linux-2.4.20/drivers/char/eurotechwdt.c
@@ -35,6 +35,9 @@
  *
  * 2001 - Rodolfo Giometti
  *	Initial release
+ *
+ * 2002.05.30 - Joel Becker <joel.becker@oracle.com>
+ * 	Added Matt Domsch's nowayout module option.
  */
 
 #include <linux/config.h>
@@ -68,6 +71,14 @@
  
 #define WDT_TIMEOUT		60                /* 1 minute */
 
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
+
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /*
  * Some symbolic names 
@@ -127,48 +138,48 @@
 
 static inline void eurwdt_write_reg(u8 index, u8 data)
 {
-   outb(index, io);
-   outb(data, io+1);
+	outb(index, io);
+	outb(data, io+1);
 }
 
 static inline void eurwdt_lock_chip(void)
 {
-   outb(0xaa, io);
+	outb(0xaa, io);
 }
 
 static inline void eurwdt_unlock_chip(void)
 {
-   outb(0x55, io);
-   eurwdt_write_reg(0x07, 0x08);   /* set the logical device */
+	outb(0x55, io);
+	eurwdt_write_reg(0x07, 0x08);   /* set the logical device */
 }
 
 static inline void eurwdt_set_timeout(int timeout)
 {
-   eurwdt_write_reg(WDT_TIMEOUT_VAL, (u8) timeout);
+	eurwdt_write_reg(WDT_TIMEOUT_VAL, (u8) timeout);
 }
 
 static inline void eurwdt_disable_timer(void)
 {
-   eurwdt_set_timeout(0);
+	eurwdt_set_timeout(0);
 }
  
 static void eurwdt_activate_timer(void)
 {
-   eurwdt_disable_timer();
-   eurwdt_write_reg(WDT_CTRL_REG, 0x01);      /* activate the WDT */
-   eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ?
+	eurwdt_disable_timer();
+	eurwdt_write_reg(WDT_CTRL_REG, 0x01);      /* activate the WDT */
+	eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ?
                                     WDT_EVENT_INT : WDT_EVENT_REBOOT);
-   /* Setting interrupt line */
-   if (irq == 2 || irq > 15 || irq < 0) {
-      printk(KERN_ERR ": invalid irq number\n");
-      irq = 0;   /* if invalid we disable interrupt */
-   }
-   if (irq == 0)
-      printk(KERN_INFO ": interrupt disabled\n");
-   eurwdt_write_reg(WDT_TIMER_CFG, irq<<4);
+	/* Setting interrupt line */
+	if (irq == 2 || irq > 15 || irq < 0) {
+		printk(KERN_ERR ": invalid irq number\n");
+		irq = 0;   /* if invalid we disable interrupt */
+	}
+	if (irq == 0)
+		printk(KERN_INFO ": interrupt disabled\n");
+	eurwdt_write_reg(WDT_TIMER_CFG, irq<<4);
 
-   eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS);   /* we use seconds */
-   eurwdt_set_timeout(0);                           /* the default timeout */ 
+	eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS);   /* we use seconds */
+	eurwdt_set_timeout(0);                           /* the default timeout */ 
 }
 
 
@@ -178,13 +189,13 @@
  
 void eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-   printk(KERN_CRIT "timeout WDT timeout\n");
+	printk(KERN_CRIT "timeout WDT timeout\n");
  
 #ifdef ONLY_TESTING
-   printk(KERN_CRIT "Would Reboot.\n");
+	printk(KERN_CRIT "Would Reboot.\n");
 #else
-   printk(KERN_CRIT "Initiating system reboot.\n");
-   machine_restart(NULL);
+	printk(KERN_CRIT "Initiating system reboot.\n");
+	machine_restart(NULL);
 #endif
 }
 
@@ -197,8 +208,8 @@
  
 static void eurwdt_ping(void)
 {
-   /* Write the watchdog default value */
-   eurwdt_set_timeout(eurwdt_timeout);
+	/* Write the watchdog default value */
+	eurwdt_set_timeout(eurwdt_timeout);
 }
  
 /**
@@ -212,28 +223,29 @@
  *      write of data will do, as we we don't define content meaning.
  */
  
-static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count,
-loff_t *ppos)
+static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-   /*  Can't seek (pwrite) on this device  */
-   if (ppos != &file->f_pos)
-      return -ESPIPE;
- 
-   if (count) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-      size_t i;
-
-      eur_expect_close = 0;
-
-      for (i = 0; i != count; i++) {
-         if (buf[i] == 'V')
-            eur_expect_close = 42;
-      }
-#endif
-      eurwdt_ping();   /* the default timeout */
-   }
-
-   return count;
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+ 
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			eur_expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if(get_user(c, buf+i))
+					return -EFAULT;
+				if (c == 'V')
+					eur_expect_close = 42;
+			}
+		}
+		eurwdt_ping();   /* the default timeout */
+	}
+	return count;
 }
 
 /**
@@ -250,66 +262,54 @@
 static int eurwdt_ioctl(struct inode *inode, struct file *file,
         unsigned int cmd, unsigned long arg)
 {
-   static struct watchdog_info ident = {
-      options		: WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
-      firmware_version	: 0,
-      identity		: "WDT Eurotech CPU-1220/1410"
-   };
-
-   int time;
- 
-   switch(cmd) {
-      default:
-         return -ENOTTY;
-
-      case WDIOC_GETSUPPORT:
-         return copy_to_user((struct watchdog_info *)arg, &ident,
-               sizeof(ident)) ? -EFAULT : 0;
- 
-      case WDIOC_GETSTATUS:
-      case WDIOC_GETBOOTSTATUS:
-         return put_user(0, (int *) arg);
-
-      case WDIOC_KEEPALIVE:
-         eurwdt_ping();
-         return 0;
-
-      case WDIOC_SETTIMEOUT:
-         if (copy_from_user(&time, (int *) arg, sizeof(int)))
-            return -EFAULT;
-
-         /* Sanity check */
-         if (time < 0 || time > 255)
-            return -EINVAL;
-
-         eurwdt_timeout = time; 
-         eurwdt_set_timeout(time); 
-	 /* Fall */
-
-      case WDIOC_GETTIMEOUT:
-	 return put_user(eurwdt_timeout, (int *)arg);
-
-      case WDIOC_SETOPTIONS:
-      {
-	 int options, retval = -EINVAL;
-
-	 if (get_user(options, (int *)arg))
-	    return -EFAULT;
-
-	 if (options & WDIOS_DISABLECARD) {
-	    eurwdt_disable_timer();
-	    retval = 0;
-	 }
-
-	 if (options & WDIOS_ENABLECARD) {
-	    eurwdt_activate_timer();
-	    eurwdt_ping();
-	    retval = 0;
-	 }
-
-	 return retval;
-      }
-   }
+	static struct watchdog_info ident = {
+		options		: WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+		firmware_version	: 0,
+		identity		: "WDT Eurotech CPU-1220/1410"
+	};
+	int time;
+ 
+	switch(cmd) {
+		default:
+			return -ENOTTY;
+		case WDIOC_GETSUPPORT:
+			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0;
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, (int *) arg);
+		case WDIOC_KEEPALIVE:
+			eurwdt_ping();
+			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (copy_from_user(&time, (int *) arg, sizeof(int)))
+				return -EFAULT;
+			/* Sanity check */
+			if (time < 0 || time > 255)
+				return -EINVAL;
+			eurwdt_timeout = time; 
+			eurwdt_set_timeout(time); 
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(eurwdt_timeout, (int *)arg);
+		case WDIOC_SETOPTIONS:
+		{
+			int options, retval = -EINVAL;
+
+			if (get_user(options, (int *)arg))
+				return -EFAULT;
+			if (options & WDIOS_DISABLECARD) {
+				eurwdt_disable_timer();
+				retval = 0;
+			}
+
+			if (options & WDIOS_ENABLECARD) {
+				eurwdt_activate_timer();
+				eurwdt_ping();
+				retval = 0;
+			}
+			return retval;
+		}
+	}
 }
 
 /**
@@ -323,15 +323,15 @@
  
 static int eurwdt_open(struct inode *inode, struct file *file)
 {
-   if (test_and_set_bit(0, &eurwdt_is_open))
-      return -EBUSY;
+	if (test_and_set_bit(0, &eurwdt_is_open))
+		return -EBUSY;
 
-   eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
+	eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
 
-   /* Activate the WDT */
-   eurwdt_activate_timer(); 
+	/* Activate the WDT */
+	eurwdt_activate_timer(); 
 
-   return 0;
+	return 0;
 }
  
 /**
@@ -348,16 +348,15 @@
  
 static int eurwdt_release(struct inode *inode, struct file *file)
 {
-   if (eur_expect_close == 42) {
-      eurwdt_disable_timer();
-   } else {
-      printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
-      eurwdt_ping();
-   }
-   clear_bit(0, &eurwdt_is_open);
-   eur_expect_close = 0;
-
-   return 0;
+	if (eur_expect_close == 42) {
+		eurwdt_disable_timer();
+	} else {
+		printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+		eurwdt_ping();
+	}
+	clear_bit(0, &eurwdt_is_open);
+	eur_expect_close = 0;
+	return 0;
 }
  
 /**
@@ -375,12 +374,11 @@
 static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
         void *unused)
 {
-   if (code == SYS_DOWN || code == SYS_HALT) {
-      /* Turn the card off */
-      eurwdt_disable_timer();
-   }
-
-   return NOTIFY_DONE;
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/* Turn the card off */
+		eurwdt_disable_timer();
+	}
+	return NOTIFY_DONE;
 }
  
 /*
@@ -428,13 +426,11 @@
  
 static void __exit eurwdt_exit(void)
 {
-   eurwdt_lock_chip();
-
-   misc_deregister(&eurwdt_miscdev);
-
-   unregister_reboot_notifier(&eurwdt_notifier);
-   release_region(io, 2);
-   free_irq(irq, NULL);
+	eurwdt_lock_chip();
+	misc_deregister(&eurwdt_miscdev);
+	unregister_reboot_notifier(&eurwdt_notifier);
+	release_region(io, 2);
+	free_irq(irq, NULL);
 }
  
 /**
@@ -447,52 +443,44 @@
  
 static int __init eurwdt_init(void)
 {
-   int ret;
- 
-   ret = misc_register(&eurwdt_miscdev);
-   if (ret) {
-      printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
-            WATCHDOG_MINOR);
-      goto out;
-   }
-
-   ret = request_irq(irq, eurwdt_interrupt, SA_INTERRUPT, "eurwdt", NULL);
-   if(ret) {
-      printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
-      goto outmisc;
-   }
-
-   if (!request_region(io, 2, "eurwdt")) {
-       printk(KERN_ERR "eurwdt: IO %X is not free.\n", io);
-       ret = -EBUSY;
-       goto outirq;
-   }
-
-   ret = register_reboot_notifier(&eurwdt_notifier);
-   if (ret) {
-      printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret);
-      goto outreg;
-   }
-
-   eurwdt_unlock_chip();
+	int ret;
  
-   ret = 0;
-   printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
-                    " - timeout event: %s\n", 
-         io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
-
-   out:
-      return ret;
- 
-   outreg:
-      release_region(io, 2);
-
-   outirq:
-      free_irq(irq, NULL);
-
-   outmisc:
-      misc_deregister(&eurwdt_miscdev);
-      goto out;
+	ret = misc_register(&eurwdt_miscdev);
+	if (ret) {
+		printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR);
+		goto out;
+	}
+	ret = request_irq(irq, eurwdt_interrupt, SA_INTERRUPT, "eurwdt", NULL);
+	if(ret) {
+		printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
+		goto outmisc;
+	}
+
+	if (!request_region(io, 2, "eurwdt")) {
+		printk(KERN_ERR "eurwdt: IO %X is not free.\n", io);
+		ret = -EBUSY;
+		goto outirq;
+	}
+
+	ret = register_reboot_notifier(&eurwdt_notifier);
+	if (ret) {
+		printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret);
+		goto outreg;
+	}
+	eurwdt_unlock_chip();
+ 
+	ret = 0;
+	printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
+                    " - timeout event: %s\n",  io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
+	return ret;
+outreg:
+	release_region(io, 2);
+outirq:
+	free_irq(irq, NULL);
+outmisc:
+	misc_deregister(&eurwdt_miscdev);
+out:
+	return ret;
 }
  
 module_init(eurwdt_init);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)