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

📄 pcwd_pci.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	/dev/watchdog handling */static ssize_t pcipcwd_write(struct file *file, const char __user *data,			     size_t len, loff_t *ppos){	/* See if we got the magic character 'V' and reload the timer */	if (len) {		if (!nowayout) {			size_t i;			/* note: just in case someone wrote the magic character			 * five months ago... */			expect_release = 0;			/* scan to see whether or not we got the magic character */			for (i = 0; i != len; i++) {				char c;				if(get_user(c, data+i))					return -EFAULT;				if (c == 'V')					expect_release = 42;			}		}		/* someone wrote to us, we should reload the timer */		pcipcwd_keepalive();	}	return len;}static int pcipcwd_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, unsigned long arg){	void __user *argp = (void __user *)arg;	int __user *p = argp;	static struct watchdog_info ident = {		.options =		WDIOF_OVERHEAT |					WDIOF_CARDRESET |					WDIOF_KEEPALIVEPING |					WDIOF_SETTIMEOUT |					WDIOF_MAGICCLOSE,		.firmware_version =	1,		.identity =		WATCHDOG_DRIVER_NAME,	};	switch (cmd) {		case WDIOC_GETSUPPORT:			return copy_to_user(argp, &ident,				sizeof (ident)) ? -EFAULT : 0;		case WDIOC_GETSTATUS:		{			int status;			pcipcwd_get_status(&status);			return put_user(status, p);		}		case WDIOC_GETBOOTSTATUS:			return put_user(pcipcwd_private.boot_status, p);		case WDIOC_GETTEMP:		{			int temperature;			if (pcipcwd_get_temperature(&temperature))				return -EFAULT;			return put_user(temperature, p);		}		case WDIOC_KEEPALIVE:			pcipcwd_keepalive();			return 0;		case WDIOC_SETOPTIONS:		{			int new_options, retval = -EINVAL;			if (get_user (new_options, p))				return -EFAULT;			if (new_options & WDIOS_DISABLECARD) {				if (pcipcwd_stop())					return -EIO;				retval = 0;			}			if (new_options & WDIOS_ENABLECARD) {				if (pcipcwd_start())					return -EIO;				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)) {		if (debug >= VERBOSE)			printk(KERN_ERR PFX "Attempt to open already opened device.\n");		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 int __devinit pcipcwd_card_init(struct pci_dev *pdev,		const struct pci_device_id *ent){	int ret = -EIO;	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 */	pcipcwd_check_temperature_support();	/* Show info about the card itself */	pcipcwd_show_card_info();	/* 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_register_driver(&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 + -