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

📄 pcwd.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
				return -EFAULT;		return 0;	case WDIOC_SETOPTIONS:		if (revision == PCWD_REVISION_C) 		{			if(copy_from_user(&rv, (int*) arg, sizeof(int)))				return -EFAULT;			if (rv & WDIOS_DISABLECARD) 			{				spin_lock(&io_lock);				outb_p(0xA5, current_readport + 3);				outb_p(0xA5, current_readport + 3);				cdat = inb_p(current_readport + 2);				spin_unlock(&io_lock);				if ((cdat & 0x10) == 0) 				{					printk("pcwd: Could not disable card.\n");					return -EIO;				}				return 0;			}			if (rv & WDIOS_ENABLECARD) 			{				spin_lock(&io_lock);				outb_p(0x00, current_readport + 3);				cdat = inb_p(current_readport + 2);				spin_unlock(&io_lock);				if (cdat & 0x10) 				{					printk("pcwd: Could not enable card.\n");					return -EIO;				}				return 0;			}			if (rv & WDIOS_TEMPPANIC) 			{				temp_panic = 1;			}		}		return -EINVAL;			case WDIOC_KEEPALIVE:		pcwd_send_heartbeat();		return 0;	}	return 0;}static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,			  loff_t *ppos){	/*  Can't seek (pwrite) on this device  */	if (ppos != &file->f_pos)		return -ESPIPE;	if (len)	{		pcwd_send_heartbeat();		return 1;	}	return 0;}static int pcwd_open(struct inode *ino, struct file *filep){        switch (MINOR(ino->i_rdev))        {                case WATCHDOG_MINOR:                    if (is_open)                        return -EBUSY;                    MOD_INC_USE_COUNT;                    /*  Enable the port  */                    if (revision == PCWD_REVISION_C)                    {                    	spin_lock(&io_lock);                    	outb_p(0x00, current_readport + 3);                    	spin_unlock(&io_lock);                    }                    is_open = 1;                    return(0);                case TEMP_MINOR:                    return(0);                default:                    return (-ENODEV);        }}static ssize_t pcwd_read(struct file *file, char *buf, size_t count,			 loff_t *ppos){	unsigned short c;	unsigned char cp;	/*  Can't seek (pread) on this device  */	if (ppos != &file->f_pos)		return -ESPIPE;	switch(MINOR(file->f_dentry->d_inode->i_rdev)) 	{		case TEMP_MINOR:			/*			 * Convert metric to Fahrenheit, since this was			 * the decided 'standard' for this return value.			 */						c = inb(current_readport);			cp = (c * 9 / 5) + 32;			if(copy_to_user(buf, &cp, 1))				return -EFAULT;			return 1;		default:			return -EINVAL;	}}static int pcwd_close(struct inode *ino, struct file *filep){	if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)	{		lock_kernel();	        is_open = 0;#ifndef CONFIG_WATCHDOG_NOWAYOUT		/*  Disable the board  */		if (revision == PCWD_REVISION_C) {			spin_lock(&io_lock);			outb_p(0xA5, current_readport + 3);			outb_p(0xA5, current_readport + 3);			spin_unlock(&io_lock);		}		unlock_kernel();#endif	}	return 0;}static inline void get_support(void){	if (inb(current_readport) != 0xF0)		supports_temp = 1;}static inline int get_revision(void){	int r = PCWD_REVISION_C;		spin_lock(&io_lock);	if ((inb(current_readport + 2) == 0xFF) ||	    (inb(current_readport + 3) == 0xFF))		r=PCWD_REVISION_A;	spin_unlock(&io_lock);	return r;}static int __init send_command(int cmd){	int i;	outb_p(cmd, current_readport + 2);	mdelay(1);	i = inb(current_readport);	i = inb(current_readport);	return(i);}static inline char *get_firmware(void){	int i, found = 0, count = 0, one, ten, hund, minor;	char *ret;	ret = kmalloc(6, GFP_KERNEL);	while((count < 3) && (!found)) {		outb_p(0x80, current_readport + 2);		i = inb(current_readport);		if (i == 0x00)			found = 1;		else if (i == 0xF3)			outb_p(0x00, current_readport + 2);		udelay(400L);		count++;	}	if (found) {		mode_debug = 1;		one = send_command(0x81);		ten = send_command(0x82);		hund = send_command(0x83);		minor = send_command(0x84);	}	if (found)		sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);	else		sprintf(ret, "ERROR");	return(ret);}static void debug_off(void){	outb_p(0x00, current_readport + 2);	mode_debug = 0;}static struct file_operations pcwd_fops = {	owner:		THIS_MODULE,	read:		pcwd_read,	write:		pcwd_write,	ioctl:		pcwd_ioctl,	open:		pcwd_open,	release:	pcwd_close,};static struct miscdevice pcwd_miscdev = {	WATCHDOG_MINOR,	"watchdog",	&pcwd_fops};static struct miscdevice temp_miscdev = {	TEMP_MINOR,	"temperature",	&pcwd_fops}; static int __init pcwatchdog_init(void){	int i, found = 0;	spin_lock_init(&io_lock);		revision = PCWD_REVISION_A;	printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);	/* Initial variables */	is_open = 0;	supports_temp = 0;	mode_debug = 0;	temp_panic = 0;	initial_status = 0x0000;#ifndef	PCWD_BLIND	for (i = 0; pcwd_ioports[i] != 0; i++) {		current_readport = pcwd_ioports[i];		if (pcwd_checkcard()) {			found = 1;			break;		}	}	if (!found) {		printk("pcwd: No card detected, or port not available.\n");		return(-EIO);	}#endif#ifdef	PCWD_BLIND	current_readport = PCWD_BLIND;#endif	get_support();	revision = get_revision();	if (revision == PCWD_REVISION_A)		printk("pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport);	else if (revision == PCWD_REVISION_C)		printk("pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n",			current_readport, get_firmware());	else {		/* Should NEVER happen, unless get_revision() fails. */		printk("pcwd: Unable to get revision.\n");		return -1;	}	if (supports_temp)		printk("pcwd: Temperature Option Detected.\n");	debug_off();	pcwd_showprevstate();	/*  Disable the board  */	if (revision == PCWD_REVISION_C) {		outb_p(0xA5, current_readport + 3);		outb_p(0xA5, current_readport + 3);	}	if (revision == PCWD_REVISION_A)		request_region(current_readport, 2, "PCWD Rev.A (Berkshire)");	else		request_region(current_readport, 4, "PCWD Rev.C (Berkshire)");	misc_register(&pcwd_miscdev);	if (supports_temp)		misc_register(&temp_miscdev);	return 0;}static void __exit pcwatchdog_exit(void){	/*  Disable the board  */	if (revision == PCWD_REVISION_C) {		outb_p(0xA5, current_readport + 3);		outb_p(0xA5, current_readport + 3);	}	misc_deregister(&pcwd_miscdev);	if (supports_temp)		misc_deregister(&temp_miscdev);	release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4);}module_init(pcwatchdog_init);module_exit(pcwatchdog_exit);

⌨️ 快捷键说明

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