Пример #1
0
static int wdtpci_start(void)
{
	unsigned long flags;

	spin_lock_irqsave(&wdtpci_lock, flags);

	/*
	 * "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 */
	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 */

	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
}
Пример #2
0
static int wdtpci_stop (void)
{
	unsigned long flags;

	/* Turn the card off */
	spin_lock_irqsave(&wdtpci_lock, flags);
	inb_p(WDT_DC);			/* Disable watchdog */
	wdtpci_ctr_load(2,0);		/* 0 length reset pulses now */
	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
}
Пример #3
0
static void wdtpci_ping(void)
{
	unsigned long flags;

	/* Write a watchdog value */
	spin_lock_irqsave(&wdtpci_lock, flags);
	inb_p(WDT_DC);
	wdtpci_ctr_mode(1,2);
	wdtpci_ctr_load(1,wd_margin);		/* Timeout */
	outb_p(0, WDT_DC);
	spin_unlock_irqrestore(&wdtpci_lock, flags);
}
Пример #4
0
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 */
	wdtpci_ctr_load(1,wd_heartbeat);/* Heartbeat */
	outb_p(0, WDT_DC);		/* Enable watchdog */
	spin_unlock_irqrestore(&wdtpci_lock, flags);
	return 0;
}
Пример #5
0
static int wdtpci_release(struct inode *inode, struct file *file)
{

	if (iminor(inode)==WATCHDOG_MINOR) {
		unsigned long flags;
		if (expect_close) {
			spin_lock_irqsave(&wdtpci_lock, flags);
			inb_p(WDT_DC);		/* Disable counters */
			wdtpci_ctr_load(2,0);	/* 0 length reset pulses now */
			spin_unlock_irqrestore(&wdtpci_lock, flags);
		} else {
			printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
			wdtpci_ping();
		}
		up(&open_sem);
	}
	return 0;
}
Пример #6
0
static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	unsigned long arg)
{
	int new_margin;
	static struct watchdog_info ident = {
		.options	= WDIOF_OVERHEAT  | WDIOF_POWERUNDER |
				  WDIOF_POWEROVER | WDIOF_EXTERN1 |
				  WDIOF_EXTERN2   | WDIOF_FANFAULT |
				  WDIOF_SETTIMEOUT|WDIOF_MAGICCLOSE,
		.firmware_version = 1,
		.identity	  = "WDT500/501PCI",
	};
	
	ident.options&=WDT_OPTION_MASK;	/* Mask down to the card we have */
	switch(cmd)
	{
		default:
			return -ENOTTY;
		case WDIOC_GETSUPPORT:
			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;

		case WDIOC_GETSTATUS:
			return put_user(wdtpci_status(),(int *)arg);
		case WDIOC_GETBOOTSTATUS:
			return put_user(0, (int *)arg);
		case WDIOC_KEEPALIVE:
			wdtpci_ping();
			return 0;
		case WDIOC_SETTIMEOUT:
			if (get_user(new_margin, (int *)arg))
				return -EFAULT;
			/* Arbitrary, can't find the card's limits */
			new_margin *= 100;
			if ((new_margin < 0) || (new_margin > WD_TIMO_MAX))
				return -EINVAL;
			wd_margin = new_margin;
			wdtpci_ping();
			/* Fall */
		case WDIOC_GETTIMEOUT:
			return put_user(wd_margin / 100, (int *)arg);
	}
}

/**
 *	wdtpci_open:
 *	@inode: inode of device
 *	@file: file handle to device
 *
 *	One of our two misc devices has been opened. The watchdog device is
 *	single open and on opening we load the counters. Counter zero is a 
 *	100Hz cascade, into counter 1 which downcounts to reboot. When the
 *	counter triggers counter 2 downcounts the length of the reset pulse
 *	which set set to be as long as possible. 
 */
 
static int wdtpci_open(struct inode *inode, struct file *file)
{
	unsigned long flags;

	switch(iminor(inode))
	{
		case WATCHDOG_MINOR:
			if (down_trylock(&open_sem))
				return -EBUSY;

			if (nowayout) {
				__module_get(THIS_MODULE);
			}
			/*
			 *	Activate 
			 */
			spin_lock_irqsave(&wdtpci_lock, flags);
			
			inb_p(WDT_DC);		/* Disable */

			/*
			 * "pet" the watchdog, as Access says.
			 * This resets the clock outputs.
			 */
				
			wdtpci_ctr_mode(2,0);
			outb_p(0, WDT_DC);

			inb_p(WDT_DC);

			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);
			wdtpci_ctr_mode(1,2);
			wdtpci_ctr_mode(2,1);
			wdtpci_ctr_load(0,20833);	/* count at 100Hz */
			wdtpci_ctr_load(1,wd_margin);/* Timeout 60 seconds */
			/* DO NOT LOAD CTR2 on PCI card! -- JPN */
			outb_p(0, WDT_DC);	/* Enable */
			spin_unlock_irqrestore(&wdtpci_lock, flags);
			return 0;
		case TEMP_MINOR:
			return 0;
		default:
			return -ENODEV;
	}
}