/*----------------------------------------------------------------------------
 * @ingroup WDT
 * @file wdt_ioctl.c
 * $Revision: 1.6 $
 *----------------------------------------------------------------------------
 */

/*
* INTEL CONFIDENTIAL
* Copyright 2007,2008,2009 Intel Corporation All Rights Reserved.
* 
* The source code contained or described herein and all documents related to the
* source code ("Material") are owned by Intel Corporation or its suppliers or
* licensors. Title to the Material remains with Intel Corporation or its
* suppliers and licensors. The Material may contain trade secrets and proprietary
* and confidential information of Intel Corporation and its suppliers and
* licensors, and is protected by worldwide copyright and trade secret laws and
* treaty provisions. No part of the Material may be used, copied, reproduced,
* modified, published, uploaded, posted, transmitted, distributed, or disclosed
* in any way without Intels prior express written permission.
* No license under any patent, copyright, trade secret or other intellectual
* property right is granted to or conferred upon you by disclosure or delivery
* of the Materials, either expressly, by implication, inducement, estoppel or
* otherwise. Any license under such intellectual property rights must be
* express and approved by Intel in writing.
* 
* Include any supplier copyright notices as supplier requires Intel to use.
* Include supplier trademarks or logos as supplier requires Intel to use,
* preceded by an asterisk.
* An asterisked footnote can be added as follows: 
*   *Third Party trademarks are the property of their respective owners.
* 
* Unless otherwise agreed by Intel in writing, you may not remove or alter this
* notice or any other notice embedded in Materials by Intel or Intels suppliers
* or licensors in any way.
* 
*  version: Embedded.X.1.0.3-127
*/

#include <NTDDK.h>
#include <wdf.h>
#include "wdt.h"
#include "driver.h"


/*!
 * ioctl_enable_wdt() enables/disables the WDT
 *
 * Enable or Disable the Watchdog Timer.  This function will modify the
 * bits in the WDT_LOCK_REGISTER.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] Enable TRUE to enable, FALSE to disable
 *
 * @return N/A
 */

void ioctl_enable_wdt( PDEVICE_EXTENSION DevExt, BOOLEAN Enable )
{
    PUCHAR port_base = (PUCHAR) DevExt->PortBase;
    UCHAR LockReg    = 0;

    /* Read current register state */
    LockReg = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );

    KdPrint(("%s-ioctl_enable_wdt: Current Lockreg status = %x\n", DRIVERNAME, LockReg));

    /* Check if we are Enabling or Disabling the WDT */
    if( Enable ) {
        /* Write a '1' into the WDT_LOCK Register  Bit [1] to enable the WDT
         * Use a logical OR to set bit 1 to 1 */
        LockReg |= ENABLE;
        KdPrint(("%s-ioctl_enable_wdt: ENABLING\n", DRIVERNAME));
    }
    else {
		/* need to make sure timeout is not about to occur before disabling */
		ioctl_ping_wdt( DevExt );
        /* Write a '0' into the WDT_LOCK Register  Bit [1] to disable the WDT
         * use a logical AND to set just bit 1 to a (0) */
        LockReg &= ~(ENABLE);
        KdPrint(("%s-ioctl_enable_wdt: DISABLING\n", DRIVERNAME));
    }

    WRITE_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET, LockReg );

    LockReg = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );

    KdPrint(("%s-ioctl_enable_wdt: LockReg status after IO write called = %x\n", DRIVERNAME, LockReg));
}


/*!
 * ioctl_get_wdt_enable() gets wdt timer enable
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return WDT Timer Enable state
 */

ULONG ioctl_get_wdt_enable( PDEVICE_EXTENSION DevExt)
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;
    ULONG value;

    /* Get WDT Timer Enable */
    value = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );

    if (WDT_DISABLED == (value & ENABLE_TEST))
    {
		return WDT_DISABLED;
	}
    return WDT_ENABLED;
}



/*!
 * ioctl_lock_wdt() locks the WDT until a hard reset
 *
 * This function will lock the values in the WDT lock Register.
 * This sets bit [0] of the WDT lock register to a 1, this bit is R/WO. It
 * can not be unlocked until a hard reset or power cycle occurs.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_lock_wdt( PDEVICE_EXTENSION DevExt )
{
    UCHAR  reg_val   = 0;
    PUCHAR port_base = (PUCHAR) DevExt->PortBase;

    /* Read current register state */
    reg_val = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );


    /* Set bit 0, the lock bit */
    reg_val |= 1;

    /* Write a '1' into the WDT_LOCK Register */
    WRITE_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET, reg_val );

    /* Read it back to double check */
    if( !(READ_PORT_UCHAR(port_base + WDT_LOCK_REGISTER_OFFSET) & 0x01) )
    {
        return WDT_FAILURE;
    }

    return WDT_SUCCESS;
}


/*!
 * ioctl_set_timeout_1() loads preload values 1
 *
 * Value 1 is loaded into the main counter when WDT enters stage 1.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] Value Value that goes into the preload counter 1
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_timeout_1( PDEVICE_EXTENSION DevExt,
                            ULONG Value)
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;

    KdPrint(("%s-ioct_set_timeout_1: Preload input values Val1 = %X  BasePort = %X\n",
             DRIVERNAME, Value, port_base));

    /* Load preload counter value 1 */
    /* Write 20 bits, one byte at a time.  Need to go through register
     * unlocking sequence 3 times*/
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG0_OFFSET,
        (UCHAR) Value );

    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG1_OFFSET,
        (UCHAR) (Value >> INT_8) );

    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG2_OFFSET,
        (UCHAR) ((Value >> INT_16) & 0x0F));

    return WDT_SUCCESS;
}


/*!
 * ioctl_set_timeout_2() loads preload values 2
 *
 * Value 2 is loaded when WDT enters stage 2 or when in free mode.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] Value2 Value that goes into the preload counter 2
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_timeout_2( PDEVICE_EXTENSION DevExt,
                            ULONG Value)
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;

    KdPrint(("%s-ioct_set_timeout_2: Preload input values Val2 = %X  BasePort = %X\n",
             DRIVERNAME, Value, port_base));

    /* Load preload counter value 2 */
    /* Write 20 bits, one byte at a time.  Need to go through register
     * unlocking sequence 3 times*/
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG0_OFFSET,
        (UCHAR) Value );

    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG1_OFFSET,
        (UCHAR) (Value >> INT_8) );

    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG2_OFFSET, \
        (UCHAR) ((Value >> INT_16) & 0x0F));

    return WDT_SUCCESS;
}


/*!
 * ioctl_get_timeout_1() gets preload values 1
 *
 * Value 1 is loaded into the main counter when WDT enters stage 1.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return Timeout value
 */

ULONG ioctl_get_timeout_1( PDEVICE_EXTENSION DevExt)
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;
    ULONG value;

    /* Get preload counter value 1 */
    value = READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG2_OFFSET);
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG1_OFFSET);
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL1_REG0_OFFSET);

    return value;
}


/*!
 * ioctl_get_timeout_2() gets preload values 2
 *
 * Value 2 is loaded into the main counter when WDT enters stage 2.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return Timeout value
 */

ULONG ioctl_get_timeout_2( PDEVICE_EXTENSION DevExt)
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;
    ULONG value;

    /* Get preload counter value 1 */
    value = READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG2_OFFSET);
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG1_OFFSET);
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_PRELOAD_VAL2_REG0_OFFSET);

    return value;
}


/*!
 * ioctl_ping_wdt() reloads the 35-bit main down counter
 *
 * Reloads the 35 bit down counter with values in Preload counters (1 and 2).
 * Preload Value 1 is used if were in Stage 1, or Preload value 2 is used
 * if we are in stage2
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return Always returns WDT_SUCCESS
 */

BOOLEAN ioctl_ping_wdt( PDEVICE_EXTENSION DevExt )
{
    PUCHAR port_base  = (PUCHAR) DevExt->PortBase;

    /* Write a 1 to reload register 1's bit one */
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY1 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG0_OFFSET, CONFIG_UNLOCK_KEY2 );
    WRITE_PORT_UCHAR( port_base + WDT_RELOAD_REG1_OFFSET, 0x01 );

    return WDT_SUCCESS;
}


/*!
 * ioctl_get_down_counter() reads current value of the down counter
 *
 * Reads the first 20-bit of the down counter.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return first 20-bit of the down counter
 */

ULONG ioctl_get_down_counter( PDEVICE_EXTENSION DevExt )
{
    PUCHAR   port_base = (PUCHAR) DevExt->PortBase;
    ULONG value = 0;

    value = READ_PORT_UCHAR( port_base + WDT_DOWN_CNT_REG2_OFFSET );
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_DOWN_CNT_REG1_OFFSET );
    value = (value << INT_8) | READ_PORT_UCHAR( port_base + WDT_DOWN_CNT_REG0_OFFSET );

    return value;
}


/*!
 * ioctl_set_mode() sets WDT in free-running or WDT mode
 *
 * This function will set the device mode by setting bit [2] of the WDT Lock
 * register.
 *    Bit
 *    [2] 0 = Watchdog Timer Mode
 *      1 = Free Running Mode
 *
 *  In Free Running Mode the Timer will only use Preload value 2.  The time
 *  will also be reloaded automaticly every time its decrementer reaches 0.
 *
 * @param [IN] DevExt:  device extension, need this to get hardware information
 * @param [IN] mode:    mode value set to 0 - WDT, 1 - free running.
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_mode( PDEVICE_EXTENSION DevExt,
                        ULONG mode )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );

    if ( WDT_MODE == mode )
    {
		value &= MODE_MASK;
	}
	else if ( FREE_MODE == mode )
	{
		value |= ~MODE_MASK;
	}
	else
	{
		return WDT_FAILURE;
	}

     /* Write the bit patern back to the lock register */
    WRITE_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET, value );

    return WDT_SUCCESS;
}


/*!
 * ioctl_get_mode() gets WDT in free-running or WDT mode
 *
 * This function will get the device mode by getting bit [2] of the WDT Lock
 * register.
 *    Bit
 *    [2] 0 = Watchdog Timer Mode
 *        1 = Free Running Mode
 *
 *  In Free Running Mode the Timer will only use Preload value 2.  The time
 *  will also be reloaded automaticly every time its decrementer reaches 0.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return WDT_MODE or FREE_MODE
 */

ULONG ioctl_get_mode( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* First the Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_LOCK_REGISTER_OFFSET );

    if (WDT_MODE == (value & MODE_TEST))
    {
		return WDT_MODE;
	}
    return FREE_MODE;
}


/*!
 * ioctl_get_timeout() reads the timeout bit
 *
 * Reads the 'Reload Register' to get the value of the WDT_TIMEOUT bit.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return UNSTABLE or NORMAL
 */

ULONG ioctl_get_timeout( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Get timeout status bit */
    value = READ_PORT_UCHAR( port_base + WDT_RELOAD_REG1_OFFSET );

    if (NORMAL == (value & TIMEOUT_TEST))
    {
		return NORMAL;
	}
	return UNSTABLE;
}


/*!
 * ioctl_clr_timeout() clears the timeout bit
 *
 * Clears the WDT_TIMEOUT bit from the 'Reload Register' then reads the WDT_TIMEOUR bit.
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return UNSTABLE or NORMAL
 */

ULONG ioctl_clr_timeout( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Get timeout status bit */
    value = READ_PORT_UCHAR( port_base + WDT_RELOAD_REG1_OFFSET );

    /* write 1 to the timeout bit following a register unlocking sequence
    * to clear the time out bit */
    value |= TIMEOUT_TEST;

    WRITE_PORT_UCHAR(port_base+WDT_RELOAD_REG0_OFFSET,CONFIG_UNLOCK_KEY1);
    WRITE_PORT_UCHAR(port_base+WDT_RELOAD_REG0_OFFSET,CONFIG_UNLOCK_KEY2);
    WRITE_PORT_UCHAR(port_base+WDT_RELOAD_REG1_OFFSET,value );

    return ioctl_get_timeout( DevExt );
}


/*!
 * ioctl_set_prescaler() sets the clock frequency to 1KHz or 1MHz
 *
 * Select how the the 20 bit preload value will be loaded into the 35 bit
 * down counter.
 *
 *     Bit
 *     [2] to 0  - Loads 20 bit preload value into bits 34:15 (== 1KHz)
 *            1  - Loads 20 bit preload value into bits 24:5  (== 1MHz)
 *
 *     Bit Patern x x y x   x 0 y y
 *                x x x x   x 1 x x
 *
 *   Bits 0,1 and 5 Must be preserved
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] HigherFreq 0 sets clock to 1KHz, 1 sets clock to 1MHz
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_prescaler( PDEVICE_EXTENSION DevExt,
                             ULONG scale )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    KdPrint(("%s-ioctl_set_prescaler: PreScaler = %u\n",
             DRIVERNAME, scale));

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

    /* Now set the prescaler bit as specified by the input value */
    if ( HIGH_SCALE == scale ) {
        value &= MODE_MASK;
    }
    else if ( LOW_SCALE == scale ) {
        value |= ~MODE_MASK;
    }
    else
    {
		return WDT_FAILURE;
	}

    /* Write the bit patern back to the configuration register */
    WRITE_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET, value );

    return WDT_SUCCESS;
}


/*!
 * ioctl_get_prescaler() gets the clock frequency of 1KHz or 1MHz
 *
 *     Bit
 *     [2] to 0  - Loads 20 bit preload value into bits 34:15 (== 1KHz)
 *            1  - Loads 20 bit preload value into bits 24:5  (== 1MHz)
 *
 *     Bit Patern x x y x   x 0 y y
 *                x x x x   x 1 x x
 *
 *   Bits 0,1 and 5 Must be preserved
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return 0 for clock to 1KHz, or 1 for clock to 1MHz
 */

ULONG ioctl_get_prescaler( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* First the Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

    if (HIGH_SCALE == (value & MODE_TEST))
    {
		return HIGH_SCALE;
	}
    return LOW_SCALE;
}


/*!
 * ioctl_set_external_out() enable/disable WDT_OUT# pin when timer expires
 *
 * Select wether WDT will toggle the External WDT_OUT# pin if the
 * WDT times out
 *
 *  Bit [5] to 0  - Enables toggling (Default)
 *             1  - Disables toggling
 *
 *  Bit Patern x x 0 x   x x x x
 *             x x 1 x   x x x x
 *
 *  Bits 0,1 and 2 Must be preserved
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] state ENABLED to enable, DISABLED to disable
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_external_out( PDEVICE_EXTENSION DevExt,
                                ULONG state )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

    if( EXTOUT_ENABLED == state )
    {
        value &= EXTOUT_MASK;
    }
    else if ( EXTOUT_DISABLED == state )
    {
        value |= ~EXTOUT_MASK;
    }
	else
	{
		return WDT_FAILURE;
	}

    /* Write the bit patern back to the configuration register */
    WRITE_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET, value );

    return WDT_SUCCESS;
}


/*!
 * ioctl_get_external_out() get WDT_OUT# pin
 *
 * This function will get the external out by getting bit [5] of the WDT
 * Configuration register.
 *
 *  Bit [5] to 0  - Enables toggling (Default)
 *             1  - Disables toggling
 *
 *  Bit Patern x x 0 x   x x x x
 *             x x 1 x   x x x x
 *
 *  Bits 0,1 and 2 Must be preserved
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return ENABLED or DISABLED
 */

ULONG ioctl_get_external_out( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

    if (EXTOUT_ENABLED == (value & EXTOUT_TEST))
    {
 		return EXTOUT_ENABLED;
 	}
    return EXTOUT_DISABLED;
}


/*!
 * ioctl_set_intr_type() sets the interrupt type when stage 1 times out
 *
 * Select how the stage 1 inturrupt will be handled.  This function
 * sets the first 2 bits of the WDT Configuration register.  Bit 2
 * (pre-scaler select) and bit 5 (WDT Tout Enable) must be preservered
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 * @param [IN] IntType type of interrupt to trigger
 *
 * @return WDT_SUCCESS if successful, WDT_FAILURE if failed
 */

BOOLEAN ioctl_set_intr_type( PDEVICE_EXTENSION DevExt,
                               unsigned long IntType )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    BOOLEAN status    = WDT_SUCCESS;
    UCHAR   value = 0;

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

    switch( IntType )
    {
        case WDT_INT_TYPE_IRQ:
        case WDT_INT_TYPE_NMI:
        case WDT_INT_TYPE_SMI:
        case WDT_INT_TYPE_DIS:
			/* Mask bits [1:0] to 0 */
			value &= INTTYPE_MASK;

			/* Modify (here we change the target bits) */
			value |= (UCHAR) (IntType & INTTYPE_TEST);

			KdPrint(("%s-ioctl_set_intr_type: INTR type value that is being"
					 " written is  %x\n", DRIVERNAME, IntType));

			/* Write the bit patern back to the configuration register */
			WRITE_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET, value );

			break;

        default:
			KdPrint(("%s-ioctl_set_intr_type: Invalid Interrupt type specified\n",
					 DRIVERNAME));
			status = WDT_FAILURE;
    }

    return status;
}


/*!
 * ioctl_get_intr_type() gets the interrupt type
 *
 * @param [IN] DevExt device extension, need this to get hardware information
 *
 * @return interrupt type
 */

ULONG ioctl_get_intr_type( PDEVICE_EXTENSION DevExt )
{
    PUCHAR  port_base = (PUCHAR) DevExt->PortBase;
    UCHAR   value = 0;

    /* Read the current register state */
    value = READ_PORT_UCHAR( port_base + WDT_CONFIG_REG_OFFSET );

	/* Need only bits [1:0] */
	value &= INTTYPE_TEST;

    return value;
}
