/*++
*******************************************************************************
* Copyright (c) 1999-2000 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				
*																										
*******************************************************************************

Module Name:

   AsynRead.h

Abstract:


Author:
	Sandy Haapala

--*/
#ifndef ASYNREAD_H
#define ASYNREAD_H

#define READ_DEFAULT_RX_QUEUE_SIZE 256	// Default receive queue size. 
													// Queue size will be modified by IOCTL_SERIAL_SET_QUEUE_SIZE

typedef enum
{
	NoTotalTimeout				= 0,
	CompleteImmediately,				// Complete reads immediately, even if zero data received
	CompleteOnRxDataPresent,		// Complete reads immediately if data present,
											//    otherwise use the timeouts as specified.
	CompleteOnFirstRxChar,			// Complete when the first char arrives.
	UseTotalTimeout					// Use read total timeout.
}	READ_TOTAL_TIMEOUT_TYPE;


typedef struct 
{
	DIGI_SPINLOCK Lock;						// Spinlock to protect access to this Read structure:
													//  Never take the read spinlock while holding any other spinlock.
	LIST_ENTRY    RxQ;						// Queue of Receive Buffers
	ULONG         cbRxQ;						// Total bytes available on the RxQ
	ULONG         cbMaxRxQ;					// Maximum bytes that driver will buffer on the RxQ before pausing RxEngine
	BOOLEAN       fRxPaused;				// True if RxEngine is paused

	LIST_ENTRY    PendingIrps;				// Queue of pending read irps

	ULONG         cbTotalRead;				// Keep track of bytes read.

	struct 
	{
		KDPC       IntervalDpc;				// Read Interval Timeout DPC
		KTIMER     IntervalTimer;			// Read Interval Timer
		ULONG      Interval;					// Read Interval Timeout
		BOOLEAN    fIntervalTimeout;		// True if interval timeouts will be used
		ULONG      cbInterval;     		// Interval timer prior byte count.
		LARGE_INTEGER IntervalDuration;
		BOOLEAN    fIntervalActive;		// Read interval timer is active.

		KDPC       Dpc;						// Read Total Timeout DPC 
		KTIMER     Timer;						// Read Total Timer 
		ULONG      Multiplier;				// Read Total Timeout Multiplier
		ULONG      Constant;					// Read Total Timeout Constant
		BOOLEAN    fTotalActive;			// Total timer is active
		READ_TOTAL_TIMEOUT_TYPE Type;
		PIRP       pIrp;						// Read IRP that has timers in use.

	} Timeout;
} ASYN_READ, *PASYN_READ;


/*
 * Receive Buffer structure.
 */
typedef struct RX_BUF
{
	LIST_ENTRY ListEntry;  					// Allow queueing of buffers
	ULONG      cbData;						// Length of data 
	ULONG      iNext;							// index of next data byte
	ULONG      cbRemaining;					// Count of remaining bytes in buffer
} RX_BUF, *PRX_BUF;							// First byte of data immediately follows the RX_BUF structure


VOID AsynRead_OnCreate( IN PASYN_READ pReadExt );
VOID AsynReadSetInQueueSize( IN PASYN_PORT_EXT pPortExt, IN ULONG InSize );
VOID AsynSetReadTimeouts(IN PASYN_READ pReadExt, IN PSERIAL_TIMEOUTS pTimeouts);  
VOID AsynGetReadTimeouts(IN PASYN_READ pReadExt, IN PSERIAL_TIMEOUTS pTimeouts);	

NTSTATUS AsynReadInit(IN PASYN_PORT_EXT pPortExt);
VOID AsynCancelReadIrps(IN PASYN_PORT_EXT pPortExt);
VOID AsynPurgeRxBuffers(IN PASYN_PORT_EXT pPortExt);

void AsynOnData( IN PASYN_PORT_EXT pPortExt, IN PRX_BUF pRxBuf, IN ULONG cbData);

NTSTATUS AsynDeviceRead(IN PDEVICE_OBJECT pDevice, IN PIRP pIrp);

#endif
