欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

wdrtas.c

linux-2.6.15.6
C
第 1 页 / 共 2 页
字号:
		return put_user(i, argp);	case WDIOC_SETOPTIONS:		if (get_user(i, argp))			return -EFAULT;		if (i & WDIOS_DISABLECARD)			wdrtas_timer_stop();		if (i & WDIOS_ENABLECARD) {			wdrtas_timer_keepalive();			wdrtas_timer_start();		}		if (i & WDIOS_TEMPPANIC) {			/* not implemented. Done by H8 */		}		return 0;	case WDIOC_KEEPALIVE:		wdrtas_timer_keepalive();		return 0;	case WDIOC_SETTIMEOUT:		if (get_user(i, argp))			return -EFAULT;		if (wdrtas_set_interval(i))			return -EINVAL;		wdrtas_timer_keepalive();		if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)			wdrtas_interval = i;		else			wdrtas_interval = wdrtas_get_interval(i);		/* fallthrough */	case WDIOC_GETTIMEOUT:		return put_user(wdrtas_interval, argp);	default:		return -ENOIOCTLCMD;	}}/** * wdrtas_open - open function of watchdog device * @inode: inode structure * @file: file structure * * returns 0 on success, -EBUSY if the file has been opened already, <0 on * other failures * * function called when watchdog device is opened */static intwdrtas_open(struct inode *inode, struct file *file){	/* only open once */	if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {		atomic_dec(&wdrtas_miscdev_open);		return -EBUSY;	}	wdrtas_timer_start();	wdrtas_timer_keepalive();	return nonseekable_open(inode, file);}/** * wdrtas_close - close function of watchdog device * @inode: inode structure * @file: file structure * * returns 0 on success * * close function. Always succeeds */static intwdrtas_close(struct inode *inode, struct file *file){	/* only stop watchdog, if this was announced using 'V' before */	if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)		wdrtas_timer_stop();	else {		printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "		       "not stopped.\n");		wdrtas_timer_keepalive();	}	wdrtas_expect_close = 0;	atomic_dec(&wdrtas_miscdev_open);	return 0;}/** * wdrtas_temp_read - gives back the temperature in fahrenheit * @file: file structure * @buf: user buffer * @count: number of bytes to be read * @ppos: position in file * * returns always 1 or -EFAULT in case of user space copy failures, <0 on * other failures * * wdrtas_temp_read gives the temperature to the users by copying this * value as one byte into the user space buffer. The unit is Fahrenheit... */static ssize_twdrtas_temp_read(struct file *file, char __user *buf,		 size_t count, loff_t *ppos){	int temperature = 0;	temperature = wdrtas_get_temperature();	if (temperature < 0)		return temperature;	if (copy_to_user(buf, &temperature, 1))		return -EFAULT;	return 1;}/** * wdrtas_temp_open - open function of temperature device * @inode: inode structure * @file: file structure * * returns 0 on success, <0 on failure * * function called when temperature device is opened */static intwdrtas_temp_open(struct inode *inode, struct file *file){	return nonseekable_open(inode, file);}/** * wdrtas_temp_close - close function of temperature device * @inode: inode structure * @file: file structure * * returns 0 on success * * close function. Always succeeds */static intwdrtas_temp_close(struct inode *inode, struct file *file){	return 0;}/** * wdrtas_reboot - reboot notifier function * @nb: notifier block structure * @code: reboot code * @ptr: unused * * returns NOTIFY_DONE * * wdrtas_reboot stops the watchdog in case of a reboot */static intwdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr){	if ( (code==SYS_DOWN) || (code==SYS_HALT) )		wdrtas_timer_stop();	return NOTIFY_DONE;}/*** initialization stuff */static struct file_operations wdrtas_fops = {	.owner		= THIS_MODULE,	.llseek		= no_llseek,	.write		= wdrtas_write,	.ioctl		= wdrtas_ioctl,	.open		= wdrtas_open,	.release	= wdrtas_close,};static struct miscdevice wdrtas_miscdev = {	.minor =	WATCHDOG_MINOR,	.name =		"watchdog",	.fops =		&wdrtas_fops,};static struct file_operations wdrtas_temp_fops = {	.owner		= THIS_MODULE,	.llseek		= no_llseek,	.read		= wdrtas_temp_read,	.open		= wdrtas_temp_open,	.release	= wdrtas_temp_close,};static struct miscdevice wdrtas_tempdev = {	.minor =	TEMP_MINOR,	.name =		"temperature",	.fops =		&wdrtas_temp_fops,};static struct notifier_block wdrtas_notifier = {	.notifier_call =	wdrtas_reboot,};/** * wdrtas_get_tokens - reads in RTAS tokens * * returns 0 on succes, <0 on failure * * wdrtas_get_tokens reads in the tokens for the RTAS calls used in * this watchdog driver. It tolerates, if "get-sensor-state" and * "ibm,get-system-parameter" are not available. */static intwdrtas_get_tokens(void){	wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");	if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {		printk(KERN_WARNING "wdrtas: couldn't get token for "		       "get-sensor-state. Trying to continue without "		       "temperature support.\n");	}	wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");	if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {		printk(KERN_WARNING "wdrtas: couldn't get token for "		       "ibm,get-system-parameter. Trying to continue with "		       "a default timeout value of %i seconds.\n",		       WDRTAS_DEFAULT_INTERVAL);	}	wdrtas_token_set_indicator = rtas_token("set-indicator");	if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {		printk(KERN_ERR "wdrtas: couldn't get token for "		       "set-indicator. Terminating watchdog code.\n");		return -EIO;	}	wdrtas_token_event_scan = rtas_token("event-scan");	if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {		printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "		       "Terminating watchdog code.\n");		return -EIO;	}	return 0;}/** * wdrtas_unregister_devs - unregisters the misc dev handlers * * wdrtas_register_devs unregisters the watchdog and temperature watchdog * misc devs */static voidwdrtas_unregister_devs(void){	misc_deregister(&wdrtas_miscdev);	if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)		misc_deregister(&wdrtas_tempdev);}/** * wdrtas_register_devs - registers the misc dev handlers * * returns 0 on succes, <0 on failure * * wdrtas_register_devs registers the watchdog and temperature watchdog * misc devs */static intwdrtas_register_devs(void){	int result;	result = misc_register(&wdrtas_miscdev);	if (result) {		printk(KERN_ERR "wdrtas: couldn't register watchdog misc "		       "device. Terminating watchdog code.\n");		return result;	}	if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {		result = misc_register(&wdrtas_tempdev);		if (result) {			printk(KERN_WARNING "wdrtas: couldn't register "			       "watchdog temperature misc device. Continuing "			       "without temperature support.\n");			wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;		}	}	return 0;}/** * wdrtas_init - init function of the watchdog driver * * returns 0 on succes, <0 on failure * * registers the file handlers and the reboot notifier */static int __initwdrtas_init(void){	if (wdrtas_get_tokens())		return -ENODEV;	if (wdrtas_register_devs())		return -ENODEV;	if (register_reboot_notifier(&wdrtas_notifier)) {		printk(KERN_ERR "wdrtas: could not register reboot notifier. "		       "Terminating watchdog code.\n");		wdrtas_unregister_devs();		return -ENODEV;	}	if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)		wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;	else		wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);	return 0;}/** * wdrtas_exit - exit function of the watchdog driver * * unregisters the file handlers and the reboot notifier */static void __exitwdrtas_exit(void){	if (!wdrtas_nowayout)		wdrtas_timer_stop();	wdrtas_unregister_devs();	unregister_reboot_notifier(&wdrtas_notifier);}module_init(wdrtas_init);module_exit(wdrtas_exit);

⌨️ 快捷键说明

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