
/*****************************************************************************
* Copyright (c) 1990-98 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
*
*****************************************************************************/

#include "digilib.h"

typedef enum 
{
	DIGIPNP_ADDED,		// Device object exists, but card hasn't started or is stopped
	DIGIPNP_STARTED,	// Means card is running
	DIGIPNP_REMOVED,	// Used only to protect against multiple remove requests
	DIGIPNP_COUNT
} DIGIPNP_STATE;

// Debug Flags
#define DIGIINIT					DEBUG_00000001
#define DIGIOPENCLOSE				DEBUG_00000002
#define DIGIIOCTL					DEBUG_00000004
#define DIGIMODEM					DEBUG_00000008

#define DIGIREAD					DEBUG_00000010
#define DIGIWRITE					DEBUG_00000020
#define DIGIREADDATA				DEBUG_00000040
#define DIGIWRITEDATA				DEBUG_00000080

#define DIGIINTFREC					DEBUG_00000100
#define DIGIPNP						DEBUG_00000200



#define LS_2400BPS              1
#define LS_4800BPS              2
#define LS_9600BPS              3
#define LS_19200BPS             4
#define LS_38400BPS             5
#define LS_56000BPS             6
#define LS_64000BPS             7
#define LS_128000BPS            8
#define LS_256000BPS            9
#define LS_512000BPS            10
#define LS_1024000BPS           11
#define LS_1536000BPS           12
#define LS_2048000BPS           13


#define	WAN_NRZI				0x02
#define	WAN_HDLC				0x04
#define	WAN_WAIT_CTS			0x08

#define	DGSNA_DEFAULT_RTS_DELAY	0x01

#define	DGSNA_MICRO_SECOND		10L		// 10ns interval
#define	DGSNA_MILLESECOND		1000L * DGSNA_MICRO_SECOND
#define	DGSNA_SECOND			DGSNA_MILLESECOND * 1000L

#define	DGSNA_READ_REQ_TIMEOUT	DGSNA_MILLESECOND 

#define  DGSNA_MAX_PATH_LENGTH	200

#define	DGSNA_DEVICE_PATH		L"\\Device\\DgSna"

// Port States
enum
{
    IdleState,
    OpeningState,
    OpenState,
    ClosingState,
    ShutdownState,
	ResetState,
	PendingRemove,
	PendingStop,
	Stopped
} DGSNA_STATES;


typedef struct _SDLC_BUFFER
{
	UCHAR	SdlcAddr;						// SDLC address field

#define POLLBIT_ON              0x10
	UCHAR	SdlcCtrl;						// SDLC Control field

#define DEFAULT_DATA_SIZE        254
	UCHAR	Data[DEFAULT_DATA_SIZE];		// TH + RH + RU

} SDLC_BUFFER, *PSDLC_BUFFER;

// By request of DickDaly(WeatherCentral)
#define	DGSNA_MAX_PACKET_SIZE	0x2000		// Room to handle 5800 bytes, plus some.

typedef struct readBuffer {
	VOID		*pPortExt;						// pointer to the port this is attached to
	ULONG		bufferSize;						// size of the buffer
	ULONG		numberOfBytes;					// bytes used by useful/received info
	UCHAR		buffer[DGSNA_MAX_PACKET_SIZE];	// buffer
	LIST_ENTRY	listEntry;
} DGSNA_READ_BUFFER;

typedef struct writeBuffer {
	VOID			*pPortExt;						// pointer to the port this is attached to
	ULONG			bufferSize;						// size of the buffer
	ULONG			numberOfBytes;					// bytes used by useful info
	struct wan_msg	controlBlock;
	UCHAR			buffer[DGSNA_MAX_PACKET_SIZE];	// buffer
	LIST_ENTRY			listEntry;
} DGSNA_WRITE_BUFFER;



//
// Device Interface Record - Statistics Counters (SC_)
//
#define SC_CRC_ERROR		0
#define SC_LONGFRAME		1
#define SC_SHORTFRAME		2
#define SC_SPARE			3
#define SC_RXABORT			4
#define SC_TXUNDERRUN		5
#define SC_RXOVERRUN		6
#define SC_DCDDROP			7
#define SC_CTSDROP			8
#define SC_DSRDROP			9
#define SC_HARDWAREERROR	10

#define	MAX_SC				11



typedef struct _INTERFACE_RECORD
{
	int		ReceivedFrames;
	int		TransmitBufferSpace;
	int		StatusEvents;
	UCHAR	InputV24Status;
	UCHAR	OutputV24Status;
	int		StatisticsCounters[MAX_SC];

} IR, *PIR;

#define DGSNA_MAX_READ_ENTRIES	8
#define DGSNA_MAX_WRITE_ENTRIES	8






//
// Port related information data structure
// This data structure is used to stored the information related to a
// particular port . 
//


typedef enum SNA_DEVICE_TYPE
{
	SNA_FDO_DEVICE_EXT		= 0xDDBB0000,
	SNA_PORT_DEVICE_EXT,
	SNA_DEVICE_TYPE_MAX
} SNA_DEVICE_TYPE, *PSNA_DEVICE_TYPE;


typedef struct _PORT_DEVICE_EXT
{

	SNA_DEVICE_TYPE			DeviceType;			// The Type Must be the first field in this structure.

#if NT5_BUILD
	PDEVICE_OBJECT			pPdo;
	PDEVICE_OBJECT			pNextDeviceObject;	// Could be different than Pdo if filter 
	DIGIPNP_STATE			PnpState;
	DEVICE_POWER_STATE		PowerState;			// PNP Power state: D0 (on) or D3 (off).
	PDEVICE_OBJECT			pSdo;				// For an FDO Device, this points to the SNA device
#endif

	ULONG					constantRTS;    
	ULONG					lineSpeed;			// Line speed
	ULONG					lineType;
	ULONG					internalClocking;	// Internal Clocks if true
	UCHAR					linkOptions;		// Link protocol parameters
	UCHAR					bSdlcCtrl;			// SDLC control field
	PKEVENT					pUserEvent;			// Handle to Link Serive Driver

	IR						IR;					// Local Interface Record
	DSMP_CONFIG				config;				// Config record (max frame, baud rate, etc)

   	
	UCHAR					stationAddress1;	// Station address 1
	UCHAR					stationAddress2;	// Station address 2

  	DSMP_STATS				stats;				// Statistics counters
	ULONG					information;		// IRP information field to return

	ULONG					adc;				// ADC (Analog to Digital Converter)
	ULONG					portType;			// Interface Type
	ULONG					receivedFrames;
	
	IRP 					* openIrp;			// pending open request
	IRP						* closeIrp;			// pending close Irp
	ULONG					state;				// State of the port ie opn, idle etc.
	WCHAR					adapterNameBuffer[64];
	UNICODE_STRING			adapterName;
	UNICODE_STRING			snadeviceName;
	WCHAR					snadeviceNameBuffer[64];	// Name of this Sna Device
	HANDLE					dsAdapterHandle;	// Handle for the adapter returned by DsOpenDevice
	CHAR					deviceName[64];		// Name of this port for DsOpen
	HANDLE					dsPortHandle;		// Handle for the port returned by DsOpen

	ULONG					snid;

	LIST_ENTRY				readBuffers;		// available read buffers
	LIST_ENTRY				pendedReadBuffers;	// pended read buffers
	LIST_ENTRY				completedReadBuffers;

	LIST_ENTRY				writeBuffers;		// available write buffers
	LIST_ENTRY				pendedWriteBuffers; // pended write buffers

	KSPIN_LOCK				ownership;
	KIRQL					portIrql;

	KEVENT					evClose;			// Event for the Read DPC to signal Close

	KDPC					dpcReadRequest;
	KTIMER					readRequestTimer;
	LARGE_INTEGER			readRequestTimeout;
	BOOLEAN					dpcReadRequestIsRunning;

	DGSNA_READ_BUFFER		readListEntryArray[DGSNA_MAX_READ_ENTRIES];

	DGSNA_WRITE_BUFFER		writeListEntryArray[DGSNA_MAX_WRITE_ENTRIES];

	PDEVICE_OBJECT			nextPort;
	PDEVICE_OBJECT			pDeviceObject;

	UNICODE_STRING			symbolicName;
	WCHAR					symbolicNameBuffer[DGSNA_MAX_PATH_LENGTH];
	ULONG					configured;
	ULONG					ibmComServer;


} PORT_EXT, *PPORT_EXT;



extern	DRIVER_OBJECT   * gpDriverObject;
extern	KSPIN_LOCK		gSnaDevicesSpinLock;
extern	DEVICE_OBJECT	* DgSnaDevices;


STATIC __inline VOID 
DgSnaIoCompleteRequest( PIRP pIrp, NTSTATUS Status, ULONG Information )
{
	pIrp->IoStatus.Status = Status;
	pIrp->IoStatus.Information = Information;
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
}


// ProtoTypes
NTSTATUS
DgSnaFindAdapters(	IN UNICODE_STRING	* registryPath,
					IN DRIVER_OBJECT	* pDriverObject
	);

NTSTATUS
DgSnaFindAndInitTheLinkService(	IN UNICODE_STRING	* pDeviceName,
								IN PORT_EXT			* pDeviceExtension
);

NTSTATUS
DgSnaInitializeDevice(	IN	UNICODE_STRING	* pdeviceName,
						IN	DRIVER_OBJECT	* pDriverObject,
						IN  PDEVICE_OBJECT	* ppDeviceObject

	);

VOID
DgSnaRemoveSnaDevice(IN PDEVICE_OBJECT	pSdo
	);
