Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e6fa3fb authored by Alan Cox's avatar Alan Cox Committed by Wim Van Sebroeck
Browse files

[WATCHDOG 18/57] iTCO: unlocked_ioctl, coding style and cleanup



Review and switch to unlocked_ioctl

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent 30abcec1
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
/* iTCO Vendor Specific Support hooks */
#ifdef CONFIG_ITCO_VENDOR_SUPPORT
extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
extern void iTCO_vendor_pre_stop(unsigned long);
extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
extern int iTCO_vendor_check_noreboot_on(void);
#else
#define iTCO_vendor_pre_start(acpibase, heartbeat)	{}
#define iTCO_vendor_pre_stop(acpibase)			{}
#define iTCO_vendor_pre_keepalive(acpibase, heartbeat)	{}
#define iTCO_vendor_pre_set_heartbeat(heartbeat)	{}
#define iTCO_vendor_check_noreboot_on()			1
				/* 1=check noreboot; 0=don't check */
#endif
+29 −24
Original line number Diff line number Diff line
@@ -32,7 +32,9 @@
#include <linux/init.h>			/* For __init/__exit/... */
#include <linux/ioport.h>		/* For io-port access */

#include <asm/io.h>			/* For inb/outb/... */
#include <linux/io.h>			/* For inb/outb/... */

#include "iTCO_vendor.h"

/* iTCO defines */
#define	SMI_EN		acpibase + 0x30	/* SMI Control and Enable Register */
@@ -40,10 +42,12 @@
#define	TCO1_STS	TCOBASE + 0x04	/* TCO1 Status Register		*/

/* List of vendor support modes */
#define SUPERMICRO_OLD_BOARD	1	/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
#define SUPERMICRO_NEW_BOARD	2	/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
#define SUPERMICRO_OLD_BOARD	1
/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
#define SUPERMICRO_NEW_BOARD	2

static int vendorsupport = 0;
static int vendorsupport;
module_param(vendorsupport, int, 0);
MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");

@@ -167,10 +171,11 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)

static void supermicro_new_unlock_watchdog(void)
{
	outb(SM_WATCHPAGE, SM_REGINDEX);	/* Write 0x87 to port 0x2e twice */
	/* Write 0x87 to port 0x2e twice */
	outb(SM_WATCHPAGE, SM_REGINDEX);

	outb(SM_CTLPAGESW, SM_REGINDEX);	/* Switch to watchdog control page */
	outb(SM_WATCHPAGE, SM_REGINDEX);
	/* Switch to watchdog control page */
	outb(SM_CTLPAGESW, SM_REGINDEX);
	outb(SM_CTLPAGE, SM_DATAIO);
}

+145 −151
Original line number Diff line number Diff line
@@ -66,7 +66,8 @@
#include <linux/types.h>		/* For standard types (like size_t) */
#include <linux/errno.h>		/* For the -ENODEV/... values */
#include <linux/kernel.h>		/* For printk/panic/... */
#include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
#include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV
							(WATCHDOG_MINOR) */
#include <linux/watchdog.h>		/* For the watchdog specific items */
#include <linux/init.h>			/* For __init/__exit/... */
#include <linux/fs.h>			/* For file operations */
@@ -74,9 +75,10 @@
#include <linux/pci.h>			/* For pci functions */
#include <linux/ioport.h>		/* For io-port access */
#include <linux/spinlock.h>		/* For spin_lock/spin_unlock/... */
#include <linux/uaccess.h>		/* For copy_to_user/put_user/... */
#include <linux/io.h>			/* For inb/outb/... */

#include <asm/uaccess.h>		/* For copy_to_user/put_user/... */
#include <asm/io.h>			/* For inb/outb/... */
#include "iTCO_vendor.h"

/* TCO related info */
enum iTCO_chipsets {
@@ -206,10 +208,12 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);

/* Address definitions for the TCO */
#define	TCOBASE		iTCO_wdt_private.ACPIBASE + 0x60	/* TCO base address                */
#define	SMI_EN		iTCO_wdt_private.ACPIBASE + 0x30	/* SMI Control and Enable Register */
/* TCO base address */
#define	TCOBASE		iTCO_wdt_private.ACPIBASE + 0x60
/* SMI Control and Enable Register */
#define	SMI_EN		iTCO_wdt_private.ACPIBASE + 0x30

#define TCO_RLD		TCOBASE + 0x00	/* TCO Timer Reload and Current Value */
#define TCO_RLD		TCOBASE + 0x00	/* TCO Timer Reload and Curr. Value */
#define TCOv1_TMR	TCOBASE + 0x01	/* TCOv1 Timer Initial Value	*/
#define	TCO_DAT_IN	TCOBASE + 0x02	/* TCO Data In Register		*/
#define	TCO_DAT_OUT	TCOBASE + 0x03	/* TCO Data Out Register	*/
@@ -223,14 +227,20 @@ MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
static unsigned long is_active;
static char expect_release;
static struct {		/* this is private data for the iTCO_wdt device */
	unsigned int iTCO_version;	/* TCO version/generation */
	unsigned long ACPIBASE;		/* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
	unsigned long __iomem *gcs;	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */
	spinlock_t io_lock;		/* the lock for io operations */
	struct pci_dev *pdev;		/* the PCI-device */
	/* TCO version/generation */
	unsigned int iTCO_version;
	/* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
	unsigned long ACPIBASE;
	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
	unsigned long __iomem *gcs;
	/* the lock for io operations */
	spinlock_t io_lock;
	/* the PCI-device */
	struct pci_dev *pdev;
} iTCO_wdt_private;

static struct platform_device *iTCO_wdt_platform_device;	/* the watchdog platform device */
/* the watchdog platform device */
static struct platform_device *iTCO_wdt_platform_device;

/* module parameters */
#define WATCHDOG_HEARTBEAT 30	/* 30 sec default heartbeat */
@@ -240,22 +250,9 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO

static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

/* iTCO Vendor Specific Support hooks */
#ifdef CONFIG_ITCO_VENDOR_SUPPORT
extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
extern void iTCO_vendor_pre_stop(unsigned long);
extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
extern int iTCO_vendor_check_noreboot_on(void);
#else
#define iTCO_vendor_pre_start(acpibase, heartbeat)	{}
#define iTCO_vendor_pre_stop(acpibase)			{}
#define iTCO_vendor_pre_keepalive(acpibase,heartbeat)	{}
#define iTCO_vendor_pre_set_heartbeat(heartbeat)	{}
#define iTCO_vendor_check_noreboot_on()			1	/* 1=check noreboot; 0=don't check */
#endif
MODULE_PARM_DESC(nowayout,
	"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

/*
 * Some TCO specific functions
@@ -369,11 +366,10 @@ static int iTCO_wdt_keepalive(void)
	iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat);

	/* Reload the timer by writing to the TCO Timer Counter register */
	if (iTCO_wdt_private.iTCO_version == 2) {
	if (iTCO_wdt_private.iTCO_version == 2)
		outw(0x01, TCO_RLD);
	} else if (iTCO_wdt_private.iTCO_version == 1) {
	else if (iTCO_wdt_private.iTCO_version == 1)
		outb(0x01, TCO_RLD);
	}

	spin_unlock(&iTCO_wdt_private.io_lock);
	return 0;
@@ -476,7 +472,8 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file)
	if (expect_release == 42) {
		iTCO_wdt_stop();
	} else {
		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
		printk(KERN_CRIT PFX
			"Unexpected close, not stopping watchdog!\n");
		iTCO_wdt_keepalive();
	}
	clear_bit(0, &is_active);
@@ -492,11 +489,12 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
		if (!nowayout) {
			size_t i;

			/* note: just in case someone wrote the magic character
			 * five months ago... */
			/* 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 */
			/* 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))
@@ -512,8 +510,8 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
	return len;
}

static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
			  unsigned int cmd, unsigned long arg)
static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int new_options, retval = -EINVAL;
	int new_heartbeat;
@@ -529,9 +527,7 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,

	switch (cmd) {
	case WDIOC_GETSUPPORT:
			return copy_to_user(argp, &ident,
				sizeof (ident)) ? -EFAULT : 0;

		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
@@ -549,41 +545,31 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
			iTCO_wdt_stop();
			retval = 0;
		}

		if (new_options & WDIOS_ENABLECARD) {
			iTCO_wdt_keepalive();
			iTCO_wdt_start();
			retval = 0;
		}

		return retval;
	}

	case WDIOC_SETTIMEOUT:
	{
		if (get_user(new_heartbeat, p))
			return -EFAULT;

		if (iTCO_wdt_set_heartbeat(new_heartbeat))
			return -EINVAL;

		iTCO_wdt_keepalive();
		/* Fall */
	}

	case WDIOC_GETTIMEOUT:
		return put_user(heartbeat, p);

	case WDIOC_GETTIMELEFT:
	{
		int time_left;

		if (iTCO_wdt_get_timeleft(&time_left))
			return -EINVAL;

		return put_user(time_left, p);
	}

	default:
		return -ENOTTY;
	}
@@ -597,7 +583,7 @@ static const struct file_operations iTCO_wdt_fops = {
	.owner =		THIS_MODULE,
	.llseek =		no_llseek,
	.write =		iTCO_wdt_write,
	.ioctl =	iTCO_wdt_ioctl,
	.unlocked_ioctl =	iTCO_wdt_ioctl,
	.open =			iTCO_wdt_open,
	.release =		iTCO_wdt_release,
};
@@ -612,7 +598,8 @@ static struct miscdevice iTCO_wdt_miscdev = {
 *	Init & exit routines
 */

static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev)
static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
		const struct pci_device_id *ent, struct platform_device *dev)
{
	int ret;
	u32 base_address;
@@ -632,13 +619,15 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
		pci_dev_put(pdev);
		return -ENODEV;
	}
	iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version;
	iTCO_wdt_private.iTCO_version =
			iTCO_chipset_info[ent->driver_data].iTCO_version;
	iTCO_wdt_private.ACPIBASE = base_address;
	iTCO_wdt_private.pdev = pdev;

	/* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */
	/* To get access to it you have to read RCBA from PCI Config space 0xf0
	   and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */
	/* Get the Memory-Mapped GCS register, we need it for the
	   NO_REBOOT flag (TCO v2). To get access to it you have to
	   read RCBA from PCI Config space 0xf0 and use it as base.
	   GCS = RCBA + ICH6_GCS(0x3410). */
	if (iTCO_wdt_private.iTCO_version == 2) {
		pci_read_config_dword(pdev, 0xf0, &base_address);
		RCBA = base_address & 0xffffc000;
@@ -657,8 +646,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device

	/* Set the TCO_EN bit in SMI_EN register */
	if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
		printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
			SMI_EN );
		printk(KERN_ERR PFX
			"I/O address 0x%04lx already in use\n", SMI_EN);
		ret = -EIO;
		goto out;
	}
@@ -667,7 +656,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
	outl(val32, SMI_EN);
	release_region(SMI_EN, 4);

	/* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */
	/* The TCO I/O registers reside in a 32-byte range pointed to
	   by the TCOBASE value */
	if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) {
		printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
			TCOBASE);
@@ -675,7 +665,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
		goto out;
	}

	printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
	printk(KERN_INFO PFX
		"Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
			iTCO_chipset_info[ent->driver_data].name,
			iTCO_chipset_info[ent->driver_data].iTCO_version,
			TCOBASE);
@@ -687,7 +678,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
	/* Make sure the watchdog is not running */
	iTCO_wdt_stop();

	/* Check that the heartbeat value is within it's range ; if not reset to the default */
	/* Check that the heartbeat value is within it's range;
	   if not reset to the default */
	if (iTCO_wdt_set_heartbeat(heartbeat)) {
		iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
		printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n",
@@ -696,7 +688,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device

	ret = misc_register(&iTCO_wdt_miscdev);
	if (ret != 0) {
		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
		printk(KERN_ERR PFX
			"cannot register miscdev on minor=%d (err=%d)\n",
							WATCHDOG_MINOR, ret);
		goto unreg_region;
	}
@@ -796,7 +789,8 @@ static int __init iTCO_wdt_init_module(void)
	if (err)
		return err;

	iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
	iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME,
								-1, NULL, 0);
	if (IS_ERR(iTCO_wdt_platform_device)) {
		err = PTR_ERR(iTCO_wdt_platform_device);
		goto unreg_platform_driver;