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

📄 pcwd_pci.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
				return -EFAULT;			if (new_options & WDIOS_DISABLECARD) {				pcipcwd_stop();				retval = 0;			}			if (new_options & WDIOS_ENABLECARD) {				pcipcwd_start();				retval = 0;			}			if (new_options & WDIOS_TEMPPANIC) {				temp_panic = 1;				retval = 0;			}			return retval;		}		case WDIOC_SETTIMEOUT:		{			int new_heartbeat;			if (get_user(new_heartbeat, p))				return -EFAULT;			if (pcipcwd_set_heartbeat(new_heartbeat))			    return -EINVAL;			pcipcwd_keepalive();			/* Fall */		}		case WDIOC_GETTIMEOUT:			return put_user(heartbeat, p);		default:			return -ENOIOCTLCMD;	}}static int pcipcwd_open(struct inode *inode, struct file *file){	/* /dev/watchdog can only be opened once */	if (test_and_set_bit(0, &is_active))		return -EBUSY;	/* Activate */	pcipcwd_start();	pcipcwd_keepalive();	return nonseekable_open(inode, file);}static int pcipcwd_release(struct inode *inode, struct file *file){	/*	 *      Shut off the timer.	 */	if (expect_release == 42) {		pcipcwd_stop();	} else {		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");		pcipcwd_keepalive();	}	expect_release = 0;	clear_bit(0, &is_active);	return 0;}/* *	/dev/temperature handling */static ssize_t pcipcwd_temp_read(struct file *file, char __user *data,				size_t len, loff_t *ppos){	int temperature;	if (pcipcwd_get_temperature(&temperature))		return -EFAULT;	if (copy_to_user (data, &temperature, 1))		return -EFAULT;	return 1;}static int pcipcwd_temp_open(struct inode *inode, struct file *file){	if (!pcipcwd_private.supports_temp)		return -ENODEV;	return nonseekable_open(inode, file);}static int pcipcwd_temp_release(struct inode *inode, struct file *file){	return 0;}/* *	Notify system */static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused){	if (code==SYS_DOWN || code==SYS_HALT) {		/* Turn the WDT off */		pcipcwd_stop();	}	return NOTIFY_DONE;}/* *	Kernel Interfaces */static struct file_operations pcipcwd_fops = {	.owner =	THIS_MODULE,	.llseek =	no_llseek,	.write =	pcipcwd_write,	.ioctl =	pcipcwd_ioctl,	.open =		pcipcwd_open,	.release =	pcipcwd_release,};static struct miscdevice pcipcwd_miscdev = {	.minor =	WATCHDOG_MINOR,	.name =		"watchdog",	.fops =		&pcipcwd_fops,};static struct file_operations pcipcwd_temp_fops = {	.owner =	THIS_MODULE,	.llseek =	no_llseek,	.read =		pcipcwd_temp_read,	.open =		pcipcwd_temp_open,	.release =	pcipcwd_temp_release,};static struct miscdevice pcipcwd_temp_miscdev = {	.minor =	TEMP_MINOR,	.name =		"temperature",	.fops =		&pcipcwd_temp_fops,};static struct notifier_block pcipcwd_notifier = {	.notifier_call =	pcipcwd_notify_sys,};/* *	Init & exit routines */static inline void check_temperature_support(void){	if (inb_p(pcipcwd_private.io_addr) != 0xF0)		pcipcwd_private.supports_temp = 1;}static int __devinit pcipcwd_card_init(struct pci_dev *pdev,		const struct pci_device_id *ent){	int ret = -EIO;	int got_fw_rev, fw_rev_major, fw_rev_minor;	char fw_ver_str[20];	char option_switches;	cards_found++;	if (cards_found == 1)		printk(KERN_INFO PFX DRIVER_VERSION);	if (cards_found > 1) {		printk(KERN_ERR PFX "This driver only supports 1 device\n");		return -ENODEV;	}	if (pci_enable_device(pdev)) {		printk(KERN_ERR PFX "Not possible to enable PCI Device\n");		return -ENODEV;	}	if (pci_resource_start(pdev, 0) == 0x0000) {		printk(KERN_ERR PFX "No I/O-Address for card detected\n");		ret = -ENODEV;		goto err_out_disable_device;	}	pcipcwd_private.pdev = pdev;	pcipcwd_private.io_addr = pci_resource_start(pdev, 0);	if (pci_request_regions(pdev, WATCHDOG_NAME)) {		printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",			(int) pcipcwd_private.io_addr);		ret = -EIO;		goto err_out_disable_device;	}	/* get the boot_status */	pcipcwd_get_status(&pcipcwd_private.boot_status);	/* clear the "card caused reboot" flag */	pcipcwd_clear_status();	/* disable card */	pcipcwd_stop();	/* Check whether or not the card supports the temperature device */	check_temperature_support();	/* Get the Firmware Version */	got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);	if (got_fw_rev) {		sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);	} else {		sprintf(fw_ver_str, "<card no answer>");	}	/* Get switch settings */	option_switches = inb_p(pcipcwd_private.io_addr + 3);	printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",		(int) pcipcwd_private.io_addr, fw_ver_str,		(pcipcwd_private.supports_temp ? "with" : "without"));	printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",		option_switches,		((option_switches & 0x10) ? "ON" : "OFF"),		((option_switches & 0x08) ? "ON" : "OFF"));	if (pcipcwd_private.boot_status & WDIOF_CARDRESET)		printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");	if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)		printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");	if (pcipcwd_private.boot_status == 0)		printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");	/* Check that the heartbeat value is within it's range ; if not reset to the default */	if (pcipcwd_set_heartbeat(heartbeat)) {		pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);		printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",			WATCHDOG_HEARTBEAT);	}	ret = register_reboot_notifier(&pcipcwd_notifier);	if (ret != 0) {		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",			ret);		goto err_out_release_region;	}	if (pcipcwd_private.supports_temp) {		ret = misc_register(&pcipcwd_temp_miscdev);		if (ret != 0) {			printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",				TEMP_MINOR, ret);			goto err_out_unregister_reboot;		}	}	ret = misc_register(&pcipcwd_miscdev);	if (ret != 0) {		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",			WATCHDOG_MINOR, ret);		goto err_out_misc_deregister;	}	printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",		heartbeat, nowayout);	return 0;err_out_misc_deregister:	if (pcipcwd_private.supports_temp)		misc_deregister(&pcipcwd_temp_miscdev);err_out_unregister_reboot:	unregister_reboot_notifier(&pcipcwd_notifier);err_out_release_region:	pci_release_regions(pdev);err_out_disable_device:	pci_disable_device(pdev);	return ret;}static void __devexit pcipcwd_card_exit(struct pci_dev *pdev){	/* Stop the timer before we leave */	if (!nowayout)		pcipcwd_stop();	/* Deregister */	misc_deregister(&pcipcwd_miscdev);	if (pcipcwd_private.supports_temp)		misc_deregister(&pcipcwd_temp_miscdev);	unregister_reboot_notifier(&pcipcwd_notifier);	pci_release_regions(pdev);	pci_disable_device(pdev);	cards_found--;}static struct pci_device_id pcipcwd_pci_tbl[] = {	{ PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_WATCHDOG_PCIPCWD,		PCI_ANY_ID, PCI_ANY_ID, },	{ 0 },			/* End of list */};MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);static struct pci_driver pcipcwd_driver = {	.name		= WATCHDOG_NAME,	.id_table	= pcipcwd_pci_tbl,	.probe		= pcipcwd_card_init,	.remove		= __devexit_p(pcipcwd_card_exit),};static int __init pcipcwd_init_module(void){	spin_lock_init (&pcipcwd_private.io_lock);	return pci_module_init(&pcipcwd_driver);}static void __exit pcipcwd_cleanup_module(void){	pci_unregister_driver(&pcipcwd_driver);}module_init(pcipcwd_init_module);module_exit(pcipcwd_cleanup_module);MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver");MODULE_LICENSE("GPL");MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);MODULE_ALIAS_MISCDEV(TEMP_MINOR);

⌨️ 快捷键说明

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