/*++
 * Copyright (c) 1990-96 Digi International Inc., All Rights Reserved
 * 
 * This software contains proprietary and confidential information of Digi
 * International Inc.  By accepting transfer of this copy, Recipient agrees
 * to retain this software in confidence, to prevent disclosure to others,
 * and to make no use of this software other than that for which it was
 * delivered.  This is an unpublished copyrighted work of Digi International
 * Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 * prohibited.
 * 
 * Restricted Rights Legend
 *
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7031 or
 * subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 * Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 *
 * Last Update: $Date: 10/22/97 11:57a $
 *
 * $Header: /Components/Windows/NT/Sync/Build/Mp570/snaioctl.c 3     10/22/97 11:57a Darinh $
 *
 * Revision History:
 * $Log: /Components/Windows/NT/Sync/Build/Mp570/snaioctl.c $
 * 
 * 3     10/22/97 11:57a Darinh
 * Changes to make multiple board installations work better.
 * 
 * 2     7/15/97 1:05p Darinh
 * Added DigiLogError statements and message file, altered code to function
 * in DStreams environment and SNA environment with a conditional
 * compilation.
 * 
 * 1     6/19/97 4:50p Darinh
 * 
--*/

#if !NT5_BUILD

#include <ntddk.h>
#include "digilib.h"
#include "def570.h"
#include "def64570.h"
#include "board.h"
#include "dsmp.h"	
#include "proto.h"
#include "ioctls.h"
#include "io.h"
#include "hwsca.h"
#include "hw570.h"
#include "hwutils.h"
#include "debug.h"
#include "snaioctl.h"



NTSTATUS
SnaIoctlSetLinkConfig (
	IN PDEVICE_EXT		pDeviceExt,
	IN PLINKCHAR		pLinkChars)
/*++

Description:

Parameters:

	pDeviceExt
		Address of the Device extension.

	pLinkChars
		Pointer to the Link Characteristics to set.

Return Value:

	None.

--*/
{
	NTSTATUS	Status = STATUS_SUCCESS;


	DigiDump (DIGIFLOW, ("Entering SnaIoctlSetLinkConfig()\n"));

	Status = fnSetLinkConfig (pDeviceExt, pLinkChars);

	//  Start the transmitter and receiver
	if (NT_SUCCESS (Status))
		fnStartChannel (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlSetLinkConfig()\n"));

	return (Status);
}



VOID
SnaIoctlGetV24Status (
	IN PDEVICE_EXT		pDeviceExt)
/*++

Description:

	This function updates the status of DSR, DCD, and CTS in the Interface
	Record.

Parameters:

	pDeviceExt
		Address of the Device Extension.

Return Value:

	None.

--*/
{
	volatile UCHAR	DcdReg, St3;
	UCHAR			V24Status = 0;


	DigiDump (DIGIFLOW, ("Entering SnaIoctlGetV24Status()\n"));

	if (PT_X21 == pDeviceExt->PortType)
	{
		//  DCD and CTS are not present in X.21, so we have to spoof
		//  the signals to SNA Server in order for it to give us
		//  any frames to transmit.
		V24Status = IV24_DCD | IV24_CTS | IV24_DSR ;
	}
	else
	{

		DcdReg = (pDeviceExt->pControllerExt->pIO_IN) (pDeviceExt->pControllerExt->pDigiDcdIntReg);
		V24Status = (DcdReg & pDeviceExt->DigiDcdMask) ? 0 : IV24_DCD;

		EnableScaMemMap (pDeviceExt);
		St3 = READ_REGISTER_UCHAR ((PUCHAR) &pDeviceExt->pScaMsci->St3);
		DisableMemory (pDeviceExt);

		V24Status |= (St3 & MSCI_ST3_CTSM) ? 0 : IV24_CTS;
		V24Status |= (St3 & MSCI_ST3_DCDM) ? 0 : IV24_DSR;
	}

	//  Update the interface record
	pDeviceExt->IR.InputV24Status = V24Status;
	DigiDump (DIGIVERYLOUD, ("  Current Modem Status is 0x%02x\n", V24Status));

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlGetV24Status()\n"));
}



VOID
SnaIoctlSetV24Status (
	IN PDEVICE_EXT		pDeviceExt)
/*++

Description:

	This function controls DTR and RTS according the desired user settings.

Parameters:

	pDeviceExt
		Address of the Device Extension.

Return Value:

	None.

--*/
{
	UCHAR				ModemSignals = pDeviceExt->IR.OutputV24Status;
	UCHAR				DtrMask = 0;
	volatile UCHAR		Ctl;


	DigiDump (DIGIFLOW, ("Entering SnaIoctlSetV24Status()  Port: %d\n",
		pDeviceExt->PortNumber));

	//
	//  Modify DTR
	//
	DtrMask = pDeviceExt->DigiDtrTxE & 0xC;

	DigiDump (DIGIVERYLOUD, ("DTR is %s\n",
		(pDeviceExt->DigiRegTxClkDtrCtrl & DtrMask) ? "ON" : "OFF"));

	if (ModemSignals & OV24_DTR)
	{
		DigiDump (DIGIVERYLOUD, ("Raising DTR\n"));
		fnWriteDTR(pDeviceExt,RAISE);
	}
	else
	{
		DigiDump (DIGIVERYLOUD, ("Lowering DTR\n"));
		fnWriteDTR(pDeviceExt,LOWER);
	}

	//
	//  Modify RTS
	//
	EnableScaMemMap (pDeviceExt);

	Ctl = READ_REGISTER_UCHAR ((PUCHAR) &pDeviceExt->pScaMsci->Ctl);
	if ((ModemSignals & OV24_RTS) || (pDeviceExt->LinkOptions & LO_4WIRE))
	{
		DigiDump (DIGIVERYLOUD, ("Raising RTS\n"));
		Ctl &= ~MSCI_CTL_RTS_HIGH;
	}
	else
	{
		DigiDump (DIGIVERYLOUD, ("Lowering RTS\n"));
		Ctl |= MSCI_CTL_RTS_HIGH;
	}
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Ctl, Ctl);

	DisableMemory (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlSetV24Status()\n"));
}



VOID
SnaIoctlAbortTx (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function performs the abort procedure for the Transmitter.
		1. Stop the transmitter
		2. Reinitialize the Transmit Descriptor Chains

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering SnaIoctlAbortTx()\n"));

	fnDisableTxInterrupts (pDeviceExt);
	fnStopTransmit (pDeviceExt);
	fnInitializeTxDmaChains (pDeviceExt);
	fnEnableTxInterrupts (pDeviceExt);
	pDeviceExt->IR.TransmitBufferSpace =
		(pDeviceExt->NumberOfDmaChains - 1) * DEFAULT_FRAME_SIZE;

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlAbortTx()\n"));
}



VOID
SnaIoctlAbortRx (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function performs the abort procedure for the Receiver.
		1. Stop the Receive SCA MSCI
		2. Stop the Receive DMAC Channel 0 or 2.
		3. Reinitialize the Receive DMA Descriptor Chains

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering SnaIoctlAbortRx()\n"));

	fnDisableRxInterrupts (pDeviceExt);
	fnStopReceiver (pDeviceExt);

	// Reset receiver
	EnableScaMemMap (pDeviceExt);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Cmd, CMD_RX_RESET);
	DisableMemory (pDeviceExt);

	fnInitializeRxDmaChains (pDeviceExt);

	fnEnableRxInterrupts (pDeviceExt);
	fnStartReceiver (pDeviceExt);

	pDeviceExt->ReceivedFrames = 0;
	pDeviceExt->IR.ReceivedFrames = 0;

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlAbortRx()\n"));
}



VOID
SnaIoctlGetIR (
	IN PDEVICE_EXT	pDeviceExt,
	IN PIRP			pIrp)
/*++

Description:

	This function copies the Interface Record into the passed in buffer,
	then zeroes out the local copy of the interface record.

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering SnaIoctlGetIR()\n"));

	RtlCopyMemory (MmGetSystemAddressForMdl (pIrp->MdlAddress),
		&pDeviceExt->IR, sizeof (IR));

	pDeviceExt->IR.StatusEvents = 0;
	RtlZeroMemory (pDeviceExt->IR.StatisticsCounters,
		sizeof (pDeviceExt->IR.StatisticsCounters));

	DigiDump (DIGIFLOW, ("Exiting SnaIoctlGetIR()\n"));
}

#endif
