wdrtas.c
字号:
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 + -