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

📄 pcwd.c

📁 PC watch dog driver
💻 C
📖 第 1 页 / 共 3 页
字号:
{	printk(" pcwd proc command interface help:\n");	printk("   ping, pong, tickle - tickle the timer\n");	printk("   hardreset - reset pc\n");	printk("   disable, enable - set watchdog mode\n");	printk("   clear - clear trip status and led - pci card only\n");	printk("   verbose, debug, quiet - command reponse\n");	printk("   fahrenheit, celsius - display temp in\n");	printk(" extended commands:\n");	printk("   arm [val] - isa [30,60,90], pci [any]\n");	printk("   nvarm [val] - pci card only\n");	printk("   timeout [val] - isa [2,4,8], pci [any]\n");	printk("   nvtimeout [val] - pci card only\n");	printk("   dio [val] - pci card only\n");	printk("   relay [1on,1off,2on,2off,1invert,1noinvert,\n");	printk	    ("          1nvinvert,1nvnoinvert,2temp,2notemp] - pci card only\n");	printk("    tempoffset [val] - pci card only\n");}static intpcwd_user_command(char *user_command){	if ((strcmp(user_command, "ping") == 0)	    || (strcmp(user_command, "pong") == 0)	    || (strcmp(user_command, "tickle") == 0)) {		pcwd_ping();		if (pcwd_verbose >= VERBOSE)			printk(KERN_INFO "pcwd: ping...\n");	} else if (strcmp(user_command, "disable") == 0) {		if (pcwd_disable_card()) {			if (pcwd_verbose >= VERBOSE)				printk(KERN_INFO "pcwd: watchdog disabled!\n");		} else {			printk(KERN_ERR "pcwd: disable watchdog FAILED!\n");		}	} else if (strcmp(user_command, "enable") == 0) {		if (pcwd_enable_card()) {			if (pcwd_verbose >= VERBOSE)				printk(KERN_INFO "pcwd: watchdog enabled.\n");		} else {			printk(KERN_ERR "pcwd: enable watchdog FAILED.\n");		}	} else if (strcmp(user_command, "clear") == 0) {		pcwd_clear_status();		if (pcwd_verbose >= VERBOSE)			printk(KERN_INFO "pcwd: cleared trip status\n");	} else if (strcmp(user_command, "hardreset") == 0) {		pcwd_reset_pc();		if (pcwd_verbose >= VERBOSE)			printk(KERN_INFO "pcwd: hardreset PC!\n");	} else if (strcmp(user_command, "verbose") == 0) {		printk(KERN_INFO "pcwd: verbose mode on.\n");		pcwd_verbose = VERBOSE;	} else if (strcmp(user_command, "debug") == 0) {		printk(KERN_INFO "pcwd: debug mode on.\n");		pcwd_verbose = DEBUG;	} else if (strcmp(user_command, "quiet") == 0) {		pcwd_verbose = QUIET;	} else if (strcmp(user_command, "celsius") == 0) {		pcwd_temp_mode = CELSIUS;		if (pcwd_verbose >= VERBOSE)			printk(KERN_INFO "pcwd: display temp in Celsius.\n");	} else if (strcmp(user_command, "fahrenheit") == 0) {		pcwd_temp_mode = FAHRENHEIT;		if (pcwd_verbose >= VERBOSE)			printk(KERN_INFO "pcwd: display temp in Fahrenheit.\n");	} else if (strcmp(user_command, "help") == 0) {		pcwd_user_help();	} else if (strncmp(user_command, "arm", 3) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_arm_pci(&user_command[3])) {				printk(KERN_ERR "arm FAILED.\n");				return 0;			}		} else {	// ISA CARD			if ((pcwd_fw_string[0] >= '1')			    && (pcwd_fw_string[2] >= '2')) {				if (pcwd_set_arm(&user_command[3])) {					printk(KERN_ERR "arm FAILED.\n");					return 0;				}			} else {				printk(KERN_ERR				       "pcwd: ISA Card and firmware > 1.20 needed.\n");				return 0;			}		}	} else if (strncmp(user_command, "nvarm", 5) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_nv_arm_pci(&user_command[5])) {				printk(KERN_ERR "nvarm FAILED.\n");				return 0;			}		} else {	// ISA CARD			printk(KERN_ERR			       "pcwd: nvarm only works with a pci card.\n");			return 0;		}	} else if (strncmp(user_command, "timeout", 7) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_timeout_pci(&user_command[7])) {				printk(KERN_ERR "timeout FAILED.\n");				return 0;			}		} else {	// ISA CARD			if ((pcwd_fw_string[0] >= '1')			    && (pcwd_fw_string[2] >= '2')) {				if (pcwd_set_timeout(&user_command[7])) {					printk(KERN_ERR "timeout FAILED.\n");					return 0;				}			} else {	// ISA FIRMWARE TOO OLD				printk(KERN_ERR				       "pcwd: ISA Card and firmware > 1.20 needed.\n");				return 0;			}		}	} else if (strncmp(user_command, "nvtimeout", 9) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_nv_timeout_pci(&user_command[9])) {				printk(KERN_ERR "nvtimeout FAILED.\n");				return 0;			}		} else {	// ISA CARD			printk(KERN_ERR			       "pcwd: nvtimeout only works with a pci card.\n");			return 0;		}	} else if (strncmp(user_command, "dio", 3) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_dio(&user_command[3])) {				printk(KERN_ERR "dio FAILED.\n");				return 0;			}		} else {	// ISA CARD			printk(KERN_ERR			       "pcwd: dio only works with a pci card.\n");			return 0;		}	} else if (strncmp(user_command, "relay", 5) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_relay(&user_command[5])) {				printk(KERN_ERR "relay FAILED.\n");				return 0;			}		} else {	// ISA CARD			printk(KERN_ERR			       "pcwd: relay only works with a pci card.\n");			return 0;		}	} else if (strncmp(user_command, "tempoffset", 10) == 0) {		if (revision == PCWD_PCI) {			if (pcwd_set_tempoffset_pci(&user_command[10])) {				printk(KERN_ERR "tempoffset FAILED.\n");				return 0;			}		} else {	// ISA CARD			printk(KERN_ERR			       "pcwd: tempoffset only works with a pci card.\n");			return 0;		}	} else {		printk(KERN_ERR "illegal user command: '%s'\n", user_command);		pcwd_user_help();		return 0;	}	return 1;}static intpcwd_write_proc(struct file *file, const char *buffer,		unsigned long count, void *data){	char command_buffer[80];	int rc, length;	/* write only allowed for root users */	if (current->euid != 0)		return -EACCES;	if (count > sizeof (command_buffer) - 1)		return -EINVAL;	if (copy_from_user(command_buffer, buffer, count))		return -EFAULT;	command_buffer[count] = '\0';	length = strlen(command_buffer);	if (command_buffer[length - 1] == '\n')		command_buffer[--length] = '\0';	spin_lock(&pcwd_lock);	rc = pcwd_user_command(command_buffer);	spin_unlock(&pcwd_lock);	return (rc ? count : -EBUSY);}static int pcwd_proc_info(unsigned char *contents, char *buffer,			  int *len, off_t * begin, off_t offset, int size);static struct proc_dir_entry *proc_pcwd;static intpcwd_read_proc(char *buffer, char **start, off_t offset,	       int size, int *eof, void *data){	int len = 0;	off_t begin = 0;	spin_lock(&pcwd_lock);	*eof = pcwd_proc_info(NULL, buffer, &len, &begin, offset, size);	spin_unlock(&pcwd_lock);	if (offset >= begin + len)		return (0);	*start = buffer + (offset - begin);	// CORRECTED !!!!	return (size < begin + len - offset ? size : begin + len - offset);}/* This macro frees the machine specific function from bounds checking and *  * this like that... [from nvram.c]*/#define PRINT_PROC(fmt,args...)                         \    do {                                                \        *len += sprintf( buffer+*len, fmt, ##args );    \        if (*begin + *len > offset + size)              \            return( 0 );                                \        if (*begin + *len < offset) {                   \            *begin += *len;                             \            *len = 0;                                   \        }                                               \    } while(0)static intpcwd_proc_info(unsigned char *buf, char *buffer, int *len,	       off_t * begin, off_t offset, int size){	int sw, i, j, t = 0;	if (revision == PCWD_REVISION_C) {		PRINT_PROC("PC Watchdog Driver %s\n", pcwd_driver_version);		PRINT_PROC("Firmware     : Version %s\n", pcwd_fw_string);		PRINT_PROC("Option Switch: Delay Time ");		sw = pcwd_get_switches();		switch (sw & 0x07) {		case 0:			PRINT_PROC("20 s");			break;		case 1:			PRINT_PROC("40 s");			break;		case 2:			PRINT_PROC("1 min");			break;		case 3:			PRINT_PROC("5 min");			break;		case 4:			PRINT_PROC("10 min");			break;		case 5:			PRINT_PROC("30 min");			break;		case 6:			PRINT_PROC("1 h");			break;		case 7:			PRINT_PROC("2 h");			break;		}		if (sw & 0x08) {			PRINT_PROC(", POD on");		} else {			PRINT_PROC(", POD off");		}		if (sw & 0x10) {			PRINT_PROC(", TRE on");		} else {			PRINT_PROC(", TRE off");		}		if (sw & 0x20) {			PRINT_PROC(", R2M on");		} else {			PRINT_PROC(", R2M off");		}		if (sw & 0x40) {			PRINT_PROC(", R1M on");		} else {			PRINT_PROC(", R1M off");		}		if (sw & 0x80) {			PRINT_PROC(", RTM on\n");		} else {			PRINT_PROC(", RTM off\n");		}	} else if (revision == PCWD_PCI) {		PRINT_PROC("PC PCI Watchdog Driver %s\n", pcwd_driver_version);		PRINT_PROC("Firmware     : Version %s\n", pcwd_fw_string);		PRINT_PROC("Option Switch: Delay Time ");		sw = pcwd_get_switches();		switch (sw & 0x07) {		case 0:			PRINT_PROC("5 s");			t = 5;			break;		case 1:			PRINT_PROC("10 s");			t = 10;			break;		case 2:			PRINT_PROC("30 s");			t = 30;			break;		case 3:			PRINT_PROC("1 min");			t = 60;			break;		case 4:			PRINT_PROC("5 min");			t = 300;			break;		case 5:			PRINT_PROC("10 min");			t = 600;			break;		case 6:			PRINT_PROC("30 min");			t = 1800;			break;		case 7:			PRINT_PROC("1 h");			t = 3600;			break;		}		if (sw & 0x08) {			PRINT_PROC(", POD on");		} else {			PRINT_PROC(", POD off");		}		if (sw & 0x10) {			PRINT_PROC(", TRE on");		} else {			PRINT_PROC(", TRE off");		}		if (sw & 0x20) {			PRINT_PROC(", R2M on");		} else {			PRINT_PROC(", R2M off");		}		if (sw & 0x40) {			PRINT_PROC(", R1M on");		} else {			PRINT_PROC(", R1M off");		}		if (sw & 0x80) {			PRINT_PROC(", RTM on\n");		} else {			PRINT_PROC(", RTM off\n");		}		sw = send_command_ret8(0x50, 0, 0);		PRINT_PROC("Relays       : ");		if (sw & 0x01) {			PRINT_PROC("Relay 1 on");		} else {			PRINT_PROC("Relay 1 off");		}		if (sw & 0x02) {			PRINT_PROC(", Relay 2 on");		} else {			PRINT_PROC(", Relay 2 off");		}		PRINT_PROC("\n               ");		if (sw & 0x10) {			PRINT_PROC("Relay 1 invert, ");		}		if (sw & 0x80) {			PRINT_PROC("Relay 1 invert in nvram, ");		}		if (temp_mode_relay2 == TEMPERATURE_TRIP) {			PRINT_PROC("Relay 2 temp");		} else {			PRINT_PROC("Relay 2 notemp");		}		PRINT_PROC("\n");		i = send_command_ret16(0x14, 0, 0);	// ARM NVRAM		j = send_command_ret16(0x10, 0, 0);	// ARM current		PRINT_PROC("Arm Time     : %d s (NVRAM: %d s)\n", j, i);		i = send_command_ret16(0x1C, 0, 0);	// Time NVRAM		j = send_command_ret16(0x18, 0, 0);	// Time current		PRINT_PROC("Timer        : %d s (NVRAM: %d s)\n", j, i);		PRINT_PROC("Status       : ");		sw = send_command_ret8(0x04, 0, 0);		if (sw & 0x01) {			PRINT_PROC("NVRAM OK");		} else {			PRINT_PROC("NVRAM FAILED");		}		if (sw & 0x02) {			PRINT_PROC(", TEMP SENSOR OK");		} else {			PRINT_PROC(", TEMP SENSOR FAILED");		}		if (sw & 0x80) {			PRINT_PROC(", POD COMPLETED");		} else {			PRINT_PROC(", POD ACTIVE");		}		PRINT_PROC(".\n");		sw = inb(card_ioport + 7);		PRINT_PROC("Digi I/O Port: OUT=%d, IN=%d\n", (sw & 15),			   ((sw / 16) & 15));		sw = send_command_ret8(0x84, 0, 0);		PRINT_PROC("Reset Count  : %d\n", sw);		sw = inb(card_ioport + 2) & 15;		PRINT_PROC("Temp.TripPt. : LOWER=%d 癈 UPPER=%d 癈\n", 46 + sw,			   56 + sw);	} else {		PRINT_PROC("Firmware ROM not present\n");	}	PRINT_PROC("Temperature  : ");	if (supports_temp) {		PRINT_PROC("%d ", pcwd_get_temperature());		if (pcwd_temp_mode == CELSIUS)			PRINT_PROC("癈\n");		else			PRINT_PROC("癋\n");	} else {		PRINT_PROC("Card without temp option\n");	}	if (card_status == ENABLED)		PRINT_PROC("Card status  : Timer enabled\n");	else		PRINT_PROC("Card status  : Timer disabled\n");	if (pcwd_get_trip_status())		PRINT_PROC("Reboot status: Tripped\n");	else		PRINT_PROC("Reboot status: Not tripped\n");	if (pcwd_verbose >= DEBUG)		printk(KERN_INFO "pcwd: initial_status: 0x%02x\n",		       initial_status);	if (initial_status & 0x02) {		PRINT_PROC("Boot status  : cleared by operator\n");	} else if ((initial_status & 0x01) && (initial_status & 0x04)) {		PRINT_PROC		    ("Boot status  : CPU Overheat  + Watchdog caused reboot\n");	} else if (initial_status & 0x01) {		PRINT_PROC("Boot status  : Watchdog caused reboot\n");	} else if (initial_status & 0x04) {		PRINT_PROC("Boot status  : CPU Overheat\n");	} else {		PRINT_PROC("Boot status  : Cold boot or reset\n");	}	// PRINT_PROC("Ping Count   : %d\n", ping_counter);	return 1;}#endif				/* PROC_FS */static intpcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused){	if (code == SYS_DOWN || code == SYS_HALT) {		pcwd_disable_card();		printk(KERN_INFO		       "pcwd: reboot notifier has disabled the card!\n");		//printk(KERN_INFO "pcwd: reboot notifier did not disable the card!\n");	}	return NOTIFY_DONE;}static struct file_operations pcwd_fops = {	owner:THIS_MODULE,	write:pcwd_write,	ioctl:pcwd_ioctl,	open:pcwd_open,	release:pcwd_release,};static struct miscdevice pcwd_miscdev = {	WATCHDOG_MINOR,	"watchdog",	&pcwd_fops};static struct file_operations pcwd_temp_fops = {	owner:THIS_MODULE,	read:pcwd_read,	open:pcwd_open,	release:pcwd_release,};static struct miscdevice temp_miscdev = {	TEMP_MINOR,	"temperature",	&pcwd_temp_fops};static struct notifier_block pcwd_notifier = {	pcwd_notify_sys,	NULL,	0};int __initpcwatchdog_init(void){	spin_lock_init(&pcwd_io_lock);	spin_lock_init(&pcwd_lock);	pcwd_get_version();	printk(KERN_INFO "pcwd: %s by <holger@eiboeck.de>\n",	       pcwd_driver_version);	initial_status = 0;	initial_status_set = 0;	if ((!pcwd_find_card()) || (card_ioport == 0x000)) {		printk(KERN_ERR "pcwd: No card detected.\n");		return -ENODEV;	}	pcwd_disable_card();	get_support();	get_revision();	pcwd_get_fw_string();	switch (revision) {	case PCWD_REVISION_C:		request_region(card_ioport, 4, "PCWD Rev C");		break;	case PCWD_REVISION_A:		request_region(card_ioport, 2, "PCWD Rev A");		break;	case PCWD_PCI:		request_region(card_ioport, 8, "PCWD PCI");		break;	default:		printk(KERN_ERR "pcwd: Unknown card revision.\n");		return -ENODEV;		break;	}	pcwd_show_card_stats();	pcwd_init_status();	if (misc_register(&pcwd_miscdev) != 0) {		release_region(card_ioport, (revision == PCWD_REVISION_A) ?			       2 : (revision == PCWD_REVISION_C) ? 4 : 8);		return -EIO;	}	if (supports_temp)		if (misc_register(&temp_miscdev) != 0) {			misc_deregister(&pcwd_miscdev);			release_region(card_ioport,				       (revision ==					PCWD_REVISION_A) ? 2 : (revision ==								PCWD_REVISION_C)				       ? 4 : 8);			return -EIO;		}#ifdef CONFIG_PROC_FS	if ((proc_pcwd =	     create_proc_entry("pcwd", S_IFREG | S_IRUGO | S_IWUSR, 0))) {		proc_pcwd->read_proc = pcwd_read_proc;		proc_pcwd->write_proc = pcwd_write_proc;	}#endif	if (nowayout)		printk(KERN_INFO		       "pcwd: Watchdog cannot be stopped once started\n");	register_reboot_notifier(&pcwd_notifier);	return 0;}void __exitpcwatchdog_exit(void){#ifdef CONFIG_PROC_FS	if (proc_pcwd)		remove_proc_entry("pcwd", 0);#endif	lock_kernel();	if (!nowayout)		pcwd_disable_card();	misc_deregister(&pcwd_miscdev);	if (supports_temp)		misc_deregister(&temp_miscdev);	unregister_reboot_notifier(&pcwd_notifier);	release_region(card_ioport,		       (revision == PCWD_REVISION_A) ? 2 :		       (revision == PCWD_REVISION_C) ? 4 : 8);	unlock_kernel();	printk(KERN_INFO "pcwd: Watchdog Module Unloaded.\n");}module_init(pcwatchdog_init);module_exit(pcwatchdog_exit);MODULE_AUTHOR("Holger Eiboeck");MODULE_DESCRIPTION("Driver for the Berkshire PC watchdog cards");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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