* Based on source code of the following authors:
* Ken Hollis <kenji@bitgate.com>,
* Lindsay Harris <lindsay@bluegum.com>,
- * Alan Cox <alan@redhat.com>,
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>,
* Matt Domsch <Matt_Domsch@dell.com>,
* Rob Radez <rob@osinvestor.com>
*
* A bells and whistles driver is available from:
* http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
*
- * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
+ * More info available at
+ * http://www.berkprod.com/ or http://www.pcwatchdog.com/
*/
/*
/* Module and version information */
#define WATCHDOG_VERSION "1.03"
-#define WATCHDOG_DATE "21 Jan 2007"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": "
-#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n"
+#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION "\n"
/* Stuff for the PCI ID's */
#ifndef PCI_VENDOR_ID_QUICKLOGIC
#define WD_PCI_TTRP 0x04 /* Temperature Trip status */
#define WD_PCI_RL2A 0x08 /* Relay 2 Active */
#define WD_PCI_RL1A 0x10 /* Relay 1 Active */
-#define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip/reset */
+#define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip /
+ reset */
#define WD_PCI_RLY2 0x80 /* Activate Relay 2 on the board */
/* Port 2 : Control Status #2 */
#define WD_PCI_WDIS 0x10 /* Watchdog Disable */
#define CMD_GET_CLEAR_RESET_COUNT 0x84
/* Watchdog's Dip Switch heartbeat values */
-static const int heartbeat_tbl [] = {
+static const int heartbeat_tbl[] = {
5, /* OFF-OFF-OFF = 5 Sec */
10, /* OFF-OFF-ON = 10 Sec */
30, /* OFF-ON-OFF = 30 Sec */
static int temp_panic;
static unsigned long is_active;
static char expect_release;
-static struct { /* this is private data for each PCI-PC watchdog card */
- int supports_temp; /* Wether or not the card has a temperature device */
- int boot_status; /* The card's boot status */
- unsigned long io_addr; /* The cards I/O address */
- spinlock_t io_lock; /* the lock for io operations */
- struct pci_dev *pdev; /* the PCI-device */
+/* this is private data for each PCI-PC watchdog card */
+static struct {
+ /* Wether or not the card has a temperature device */
+ int supports_temp;
+ /* The card's boot status */
+ int boot_status;
+ /* The cards I/O address */
+ unsigned long io_addr;
+ /* the lock for io operations */
+ spinlock_t io_lock;
+ /* the PCI-device */
+ struct pci_dev *pdev;
} pcipcwd_private;
/* module parameters */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
-#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
+#define WATCHDOG_HEARTBEAT 0 /* default heartbeat =
+ delay-time from dip-switches */
static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
+ "(0<heartbeat<65536 or 0=delay-time from dip-switches, default="
+ __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
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) ")");
/*
* Internal functions
int got_response, count;
if (debug >= DEBUG)
- printk(KERN_DEBUG PFX "sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n",
- cmd, *msb, *lsb);
+ printk(KERN_DEBUG PFX "sending following data "
+ "cmd=0x%02x msb=0x%02x lsb=0x%02x\n", cmd, *msb, *lsb);
spin_lock(&pcipcwd_private.io_lock);
/* If a command requires data it should be written first.
* the WRSP bit in port 2 and give it a max. timeout of
* PCI_COMMAND_TIMEOUT to process */
got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
- for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) {
+ for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response);
+ count++) {
mdelay(1);
got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
}
if (debug >= DEBUG) {
if (got_response) {
- printk(KERN_DEBUG PFX "time to process command was: %d ms\n",
+ printk(KERN_DEBUG PFX
+ "time to process command was: %d ms\n",
count);
} else {
- printk(KERN_DEBUG PFX "card did not respond on command!\n");
+ printk(KERN_DEBUG PFX
+ "card did not respond on command!\n");
}
}
inb_p(pcipcwd_private.io_addr + 6);
if (debug >= DEBUG)
- printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
+ printk(KERN_DEBUG PFX "received following data for "
+ "cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
cmd, *msb, *lsb);
}
char fw_ver_str[20]; /* The cards firmware version */
int option_switches;
- got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
- if (got_fw_rev) {
+ got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major,
+ &fw_rev_minor);
+ if (got_fw_rev)
sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
- } else {
+ else
sprintf(fw_ver_str, "<card no answer>");
- }
/* Get switch settings */
option_switches = pcipcwd_get_option_switches();
- printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
+ printk(KERN_INFO PFX "Found card at port "
+ "0x%04x (Firmware: %s) %s temp option\n",
(int) pcipcwd_private.io_addr, fw_ver_str,
(pcipcwd_private.supports_temp ? "with" : "without"));
- printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+ printk(KERN_INFO PFX "Option switches (0x%02x): "
+ "Temperature Reset Enable=%s, Power On Delay=%s\n",
option_switches,
((option_switches & 0x10) ? "ON" : "OFF"),
((option_switches & 0x08) ? "ON" : "OFF"));
if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
- printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
+ printk(KERN_INFO PFX
+ "Previous reset was caused by the Watchdog card\n");
if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
if (pcipcwd_private.boot_status == 0)
- printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+ printk(KERN_INFO PFX
+ "No previous trip detected - Cold boot or reset\n");
}
static int pcipcwd_start(void)
spin_unlock(&pcipcwd_private.io_lock);
if (!(stat_reg & WD_PCI_WDIS)) {
- printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n");
+ printk(KERN_ERR PFX
+ "Card did not acknowledge disable attempt\n");
return -1;
}
{
int control_status;
- *status=0;
+ *status = 0;
control_status = inb_p(pcipcwd_private.io_addr + 1);
if (control_status & WD_PCI_WTRP)
*status |= WDIOF_CARDRESET;
}
/* clear trip status & LED and keep mode of relay 2 */
- outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
+ outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP,
+ pcipcwd_private.io_addr + 1);
/* clear reset counter */
- msb=0;
- reset_counter=0xff;
+ msb = 0;
+ reset_counter = 0xff;
send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter);
if (debug >= DEBUG) {
* five months ago... */
expect_release = 0;
- /* scan to see whether or not we got the magic character */
+ /* scan to see whether or not we got the
+ * magic character */
for (i = 0; i != len; i++) {
char c;
- if(get_user(c, data+i))
+ if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
expect_release = 42;
return len;
}
-static int pcipcwd_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_OVERHEAT |
WDIOF_CARDRESET |
WDIOF_KEEPALIVEPING |
};
switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &ident,
- sizeof (ident)) ? -EFAULT : 0;
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ {
+ int status;
+ pcipcwd_get_status(&status);
+ return put_user(status, p);
+ }
- case WDIOC_GETSTATUS:
- {
- int status;
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(pcipcwd_private.boot_status, p);
- pcipcwd_get_status(&status);
+ case WDIOC_GETTEMP:
+ {
+ int temperature;
- return put_user(status, p);
- }
+ if (pcipcwd_get_temperature(&temperature))
+ return -EFAULT;
- case WDIOC_GETBOOTSTATUS:
- return put_user(pcipcwd_private.boot_status, p);
+ return put_user(temperature, p);
+ }
- case WDIOC_GETTEMP:
- {
- int temperature;
+ case WDIOC_SETOPTIONS:
+ {
+ int new_options, retval = -EINVAL;
- if (pcipcwd_get_temperature(&temperature))
- return -EFAULT;
+ if (get_user(new_options, p))
+ return -EFAULT;
- return put_user(temperature, p);
+ if (new_options & WDIOS_DISABLECARD) {
+ if (pcipcwd_stop())
+ return -EIO;
+ retval = 0;
}
- case WDIOC_KEEPALIVE:
- pcipcwd_keepalive();
- return 0;
-
- case WDIOC_SETOPTIONS:
- {
- int new_options, retval = -EINVAL;
-
- if (get_user (new_options, p))
- return -EFAULT;
-
- if (new_options & WDIOS_DISABLECARD) {
- if (pcipcwd_stop())
- return -EIO;
- retval = 0;
- }
+ if (new_options & WDIOS_ENABLECARD) {
+ if (pcipcwd_start())
+ return -EIO;
+ retval = 0;
+ }
- if (new_options & WDIOS_ENABLECARD) {
- if (pcipcwd_start())
- return -EIO;
- retval = 0;
- }
+ if (new_options & WDIOS_TEMPPANIC) {
+ temp_panic = 1;
+ retval = 0;
+ }
- if (new_options & WDIOS_TEMPPANIC) {
- temp_panic = 1;
- retval = 0;
- }
+ return retval;
+ }
- return retval;
- }
+ case WDIOC_KEEPALIVE:
+ pcipcwd_keepalive();
+ return 0;
- case WDIOC_SETTIMEOUT:
- {
- int new_heartbeat;
+ case WDIOC_SETTIMEOUT:
+ {
+ int new_heartbeat;
- if (get_user(new_heartbeat, p))
- return -EFAULT;
+ if (get_user(new_heartbeat, p))
+ return -EFAULT;
- if (pcipcwd_set_heartbeat(new_heartbeat))
- return -EINVAL;
+ if (pcipcwd_set_heartbeat(new_heartbeat))
+ return -EINVAL;
- pcipcwd_keepalive();
- /* Fall */
- }
+ pcipcwd_keepalive();
+ /* Fall */
+ }
- case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, p);
+ case WDIOC_GETTIMEOUT:
+ return put_user(heartbeat, p);
- case WDIOC_GETTIMELEFT:
- {
- int time_left;
+ case WDIOC_GETTIMELEFT:
+ {
+ int time_left;
- if (pcipcwd_get_timeleft(&time_left))
- return -EFAULT;
+ if (pcipcwd_get_timeleft(&time_left))
+ return -EFAULT;
- return put_user(time_left, p);
- }
+ return put_user(time_left, p);
+ }
- default:
- return -ENOTTY;
+ default:
+ return -ENOTTY;
}
}
/* /dev/watchdog can only be opened once */
if (test_and_set_bit(0, &is_active)) {
if (debug >= VERBOSE)
- printk(KERN_ERR PFX "Attempt to open already opened device.\n");
+ printk(KERN_ERR PFX
+ "Attempt to open already opened device.\n");
return -EBUSY;
}
if (expect_release == 42) {
pcipcwd_stop();
} else {
- printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+ printk(KERN_CRIT PFX
+ "Unexpected close, not stopping watchdog!\n");
pcipcwd_keepalive();
}
expect_release = 0;
if (pcipcwd_get_temperature(&temperature))
return -EFAULT;
- if (copy_to_user (data, &temperature, 1))
+ if (copy_to_user(data, &temperature, 1))
return -EFAULT;
return 1;
* Notify system
*/
-static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
{
- if (code==SYS_DOWN || code==SYS_HALT) {
- /* Turn the WDT off */
- pcipcwd_stop();
- }
+ if (code == SYS_DOWN || code == SYS_HALT)
+ pcipcwd_stop(); /* Turn the WDT off */
return NOTIFY_DONE;
}
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = pcipcwd_write,
- .ioctl = pcipcwd_ioctl,
+ .unlocked_ioctl = pcipcwd_ioctl,
.open = pcipcwd_open,
.release = pcipcwd_release,
};
/* If heartbeat = 0 then we use the heartbeat from the dip-switches */
if (heartbeat == 0)
- heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
+ heartbeat =
+ heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
- /* 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 (pcipcwd_set_heartbeat(heartbeat)) {
pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
- 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",
WATCHDOG_HEARTBEAT);
}
ret = register_reboot_notifier(&pcipcwd_notifier);
if (ret != 0) {
- 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 err_out_release_region;
}
if (pcipcwd_private.supports_temp) {
ret = misc_register(&pcipcwd_temp_miscdev);
if (ret != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
- TEMP_MINOR, ret);
+ printk(KERN_ERR PFX "cannot register miscdev on "
+ "minor=%d (err=%d)\n", TEMP_MINOR, ret);
goto err_out_unregister_reboot;
}
}
ret = misc_register(&pcipcwd_miscdev);
if (ret != 0) {
- 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 err_out_misc_deregister;
}