⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wdt.c

📁 linux2.6.13下2440看门狗驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	int new_heartbeat;	int status;	static struct watchdog_info ident = {		.options =		WDIOF_SETTIMEOUT|					WDIOF_MAGICCLOSE|					WDIOF_KEEPALIVEPING,		.firmware_version =	1,		.identity =		"WDT500/501",	};	/* Add options according to the card we have */	ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2);#ifdef CONFIG_WDT_501	ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER);	if (tachometer)		ident.options |= WDIOF_FANFAULT;#endif /* CONFIG_WDT_501 */	switch(cmd)	{		default:			return -ENOIOCTLCMD;		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);		case WDIOC_GETBOOTSTATUS:			return put_user(0, p);		case WDIOC_KEEPALIVE:			wdt_ping();			return 0;		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:			return put_user(heartbeat, p);	}}/** *	wdt_open: *	@inode: inode of device *	@file: file handle to device * *	The watchdog device 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 wdt_open(struct inode *inode, struct file *file){	if(test_and_set_bit(0, &wdt_is_open))		return -EBUSY;	/*	 *	Activate	 */	wdt_start();	return nonseekable_open(inode, file);}/** *	wdt_release: *	@inode: inode to board *	@file: file handle to board * *	The watchdog has a configurable API. There is a religious dispute *	between people who want their watchdog to be able to shut down and *	those who want to be sure if the watchdog manager dies the machine *	reboots. In the former case we disable the counters, in the latter *	case you have to open it again very soon. */static int wdt_release(struct inode *inode, struct file *file){	if (expect_close == 42) {		wdt_stop();		clear_bit(0, &wdt_is_open);	} else {		printk(KERN_CRIT "wdt: WDT device closed unexpectedly.  WDT will not stop!\n");		wdt_ping();	}	expect_close = 0;	return 0;}#ifdef CONFIG_WDT_501/** *	wdt_temp_read: *	@file: file handle to the watchdog board *	@buf: buffer to write 1 byte into *	@count: length of buffer *	@ptr: offset (no seek allowed) * *	Temp_read reports the temperature in degrees Fahrenheit. The API is in *	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){	int temperature;	if (wdt_get_temperature(&temperature))		return -EFAULT;	if (copy_to_user (buf, &temperature, 1))		return -EFAULT;	return 1;}/** *	wdt_temp_open: *	@inode: inode of device *	@file: file handle to device * *	The temperature device has been opened. */static int wdt_temp_open(struct inode *inode, struct file *file){	return nonseekable_open(inode, file);}/** *	wdt_temp_release: *	@inode: inode to board *	@file: file handle to board * *	The temperature device has been closed. */static int wdt_temp_release(struct inode *inode, struct file *file){	return 0;}#endif /* CONFIG_WDT_501 *//** *	notify_sys: *	@this: our notifier block *	@code: the event being reported *	@unused: unused * *	Our notifier is called on system shutdowns. We want to turn the card *	off at reboot otherwise the machine will reboot again during memory *	test or worse yet during the following fsck. This would suck, in fact *	trust me - if it happens it does suck. */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 */		wdt_stop();	}	return NOTIFY_DONE;}/* *	Kernel Interfaces */static struct file_operations wdt_fops = {	.owner		= THIS_MODULE,	.llseek		= no_llseek,	.write		= wdt_write,	.ioctl		= wdt_ioctl,	.open		= wdt_open,	.release	= wdt_release,};static struct miscdevice wdt_miscdev = {	.minor	= WATCHDOG_MINOR,	.name	= "watchdog",	.fops	= &wdt_fops,};#ifdef CONFIG_WDT_501static struct file_operations wdt_temp_fops = {	.owner		= THIS_MODULE,	.llseek		= no_llseek,	.read		= wdt_temp_read,	.open		= wdt_temp_open,	.release	= wdt_temp_release,};static struct miscdevice temp_miscdev = {	.minor	= TEMP_MINOR,	.name	= "temperature",	.fops	= &wdt_temp_fops,};#endif /* CONFIG_WDT_501 *//* *	The WDT card needs to learn about soft shutdowns in order to *	turn the timebomb registers off. */static struct notifier_block wdt_notifier = {	.notifier_call = wdt_notify_sys,};/** *	cleanup_module: * *	Unload the watchdog. You cannot do this with any file handles open. *	If your watchdog is set to continue ticking on close and you unload *	it, well it keeps ticking. We won't get the interrupt but the board *	will not touch PC memory so all is fine. You just have to load a new *	module in 60 seconds or reboot. */static void __exit wdt_exit(void){	misc_deregister(&wdt_miscdev);#ifdef CONFIG_WDT_501	misc_deregister(&temp_miscdev);#endif /* CONFIG_WDT_501 */	unregister_reboot_notifier(&wdt_notifier);	free_irq(irq, NULL);	release_region(io,8);}/** * 	wdt_init: * *	Set up the WDT watchdog board. All we have to do is grab the *	resources we require and bitch if anyone beat us to them. *	The open() function will actually kick the board off. */static int __init wdt_init(void){	int ret;	/* 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",			WD_TIMO);	}	if (!request_region(io, 8, "wdt501p")) {		printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io);		ret = -EBUSY;		goto out;	}	ret = request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL);	if(ret) {		printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq);		goto outreg;	}	ret = register_reboot_notifier(&wdt_notifier);	if(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",			TEMP_MINOR, ret);		goto outrbt;	}#endif /* CONFIG_WDT_501 */	ret = misc_register(&wdt_miscdev);	if (ret) {		printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n",			WATCHDOG_MINOR, ret);		goto outmisc;	}	ret = 0;	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"));#endif /* CONFIG_WDT_501 */out:	return ret;outmisc:#ifdef CONFIG_WDT_501	misc_deregister(&temp_miscdev);outrbt:#endif /* CONFIG_WDT_501 */	unregister_reboot_notifier(&wdt_notifier);outirq:	free_irq(irq, NULL);outreg:	release_region(io,8);	goto out;}module_init(wdt_init);module_exit(wdt_exit);MODULE_AUTHOR("Alan Cox");MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)");MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);MODULE_ALIAS_MISCDEV(TEMP_MINOR);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -