1053 lines
26 KiB
C
1053 lines
26 KiB
C
/*++
|
||
|
||
Copyright (c) 1992 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
adsp.h
|
||
|
||
Abstract:
|
||
|
||
This module contains definitions for the ADSP code.
|
||
|
||
Author:
|
||
|
||
Jameel Hyder (jameelh@microsoft.com)
|
||
Nikhil Kamkolkar (nikhilk@microsoft.com)
|
||
|
||
Revision History:
|
||
20 May 1993 Initial Version
|
||
|
||
Notes: Tab stop: 4
|
||
--*/
|
||
|
||
#ifndef _ADSP_
|
||
#define _ADSP_
|
||
|
||
// ADSP_ version.
|
||
|
||
#define ADSP_VERSION 0x0100
|
||
|
||
// ADSP_ field offsets within a Ddp datagram.
|
||
#define ADSP_SRC_CONNID_OFF 0
|
||
#define ADSP_FIRST_BYTE_SEQNUM_OFF 2
|
||
#define ADSP_THIS_ATTEN_SEQNUM_OFF 2
|
||
#define ADSP_NEXT_RX_BYTESEQNUM_OFF 6
|
||
#define ADSP_NEXT_RX_ATTNSEQNUM_OFF 6
|
||
#define ADSP_RX_WINDOW_SIZE_OFF 10
|
||
#define ADSP_RX_ATTEN_SIZE_OFF 10
|
||
#define ADSP_DESCRIPTOR_OFF 12
|
||
#define ADSP_DATA_OFF 13
|
||
#define ADSP_VERSION_STAMP_OFF 13
|
||
#define ADSP_ATTEN_CODE_OFF 13
|
||
#define ADSP_ATTEN_DATA_OFF 15
|
||
#define ADSP_DEST_CONNID_OFF 15
|
||
#define ADSP_NEXT_ATTEN_SEQNUM_OFF 17
|
||
|
||
// Bit fields in the ADSP_ descriptor
|
||
#define ADSP_CONTROL_FLAG 0x80
|
||
#define ADSP_ACK_REQ_FLAG 0x40
|
||
#define ADSP_EOM_FLAG 0x20
|
||
#define ADSP_ATTEN_FLAG 0x10
|
||
|
||
// Control codes in the ADSP_ descriptor:
|
||
#define ADSP_CONTROL_MASK 0x0F
|
||
#define ADSP_PROBE_OR_ACK_CODE 0
|
||
#define ADSP_OPENCONN_REQ_CODE 1
|
||
#define ADSP_OPENCONN_ACK_CODE 2
|
||
#define ADSP_OPENCONN_REQANDACK_CODE 3
|
||
#define ADSP_OPENCONN_DENY_CODE 4
|
||
#define ADSP_CLOSE_CONN_CODE 5
|
||
#define ADSP_FORWARD_RESET_CODE 6
|
||
#define ADSP_FORWARD_RESETACK_CODE 7
|
||
#define ADSP_RETRANSMIT_CODE 8
|
||
|
||
// Data sizes:
|
||
#define ADSP_MAX_DATA_SIZE 572
|
||
#define ADSP_MAX_ATTEN_DATA_SIZE 570
|
||
#define ADSP_MAX_ATTEN_PKT_SIZE 572
|
||
#define ADSP_MIN_ATTEN_PKT_SIZE sizeof(USHORT)
|
||
|
||
// Largest allowed send/receive window size.
|
||
#define ADSP_MAX_SEND_RX_WINDOW_SIZE 0xFFFF
|
||
#define ADSP_DEF_SEND_RX_WINDOW_SIZE ((1024*8)+1) // 8K + 1 (EOM)
|
||
|
||
// Attention code info:
|
||
#define ADSP_MIN_ATTENCODE 0x0000
|
||
#define ADSP_MAX_ATTENCODE 0xEFFF
|
||
|
||
// How long do we try Open's for?
|
||
#define ADSP_MAX_OPEN_ATTEMPTS 10
|
||
#define ADSP_OPEN_INTERVAL 20 // In 100ms units
|
||
|
||
// Connection maintenance timer values:
|
||
#define ADSP_PROBE_INTERVAL 30
|
||
#define ADSP_CONNECTION_INTERVAL 1200 // In 100ms units
|
||
|
||
// Retransmit timer values:
|
||
#define ADSP_RETRANSMIT_INTERVAL 20 // In 100ms units
|
||
|
||
// How often do we retransmit attentions?
|
||
#define ADSP_ATTENTION_INTERVAL 20 // In 100ms units
|
||
|
||
#define ADSP_DISCONNECT_DELAY 7 // In 100ms units
|
||
|
||
// How often do we retransmit forward resets?
|
||
#define ADSP_FORWARD_RESET_INTERVAL 20 // In 100ms units
|
||
|
||
// How many out of sequence packets do we allow before requesting a retransmition.
|
||
#define ADSP_OUT_OF_SEQ_PACKETS_MAX 3
|
||
|
||
// For resolving forward references
|
||
struct _ADSP_CONNOBJ;
|
||
struct _ADSP_ADDROBJ;
|
||
|
||
typedef enum
|
||
{
|
||
ADSP_SEND_QUEUE,
|
||
ADSP_RECV_QUEUE
|
||
|
||
} ADSP_QUEUE_TYPE;
|
||
|
||
|
||
#define BC_EOM (USHORT)0x0001
|
||
#define BC_SEND (USHORT)0x0002
|
||
#define BC_DISCONNECT (USHORT)0x4000
|
||
#define BC_CLOSING (USHORT)0x8000
|
||
|
||
// We use buffer chunks for the send receive queues
|
||
typedef struct _BUFFER_CHUNK
|
||
{
|
||
struct _BUFFER_CHUNK * bc_Next;
|
||
ATALK_SPIN_LOCK bc_Lock;
|
||
ULONG bc_RefCount;
|
||
|
||
// Size of data copied over from the users mdl. This
|
||
// could be less than the size of the users data.
|
||
USHORT bc_DataSize;
|
||
USHORT bc_Flags;
|
||
|
||
// Write completion information. This is only valid if
|
||
// the BC_SEND bit is set. With a week left to ship, i'm
|
||
// wimping out and making a copy to keep things as consistent
|
||
// and stable as possible. Eventually though, we should just
|
||
// use the User's buffer to make mdl's out of.
|
||
PAMDL bc_WriteBuf;
|
||
GENERIC_WRITE_COMPLETION bc_WriteCompletion;
|
||
PVOID bc_WriteCtx;
|
||
ATALK_ERROR bc_WriteError;
|
||
|
||
// Backpointer to the connection object on which this is queued
|
||
struct _ADSP_CONNOBJ * bc_ConnObj;
|
||
|
||
//
|
||
// BYTE bc_Data[]
|
||
//
|
||
|
||
} BUFFER_CHUNK, *PBUFFER_CHUNK;
|
||
|
||
|
||
|
||
// Buffer queues used for send/receive
|
||
typedef struct _BUFFER_QUEUE
|
||
{
|
||
ULONG bq_StartIndex;
|
||
PBUFFER_CHUNK bq_Head;
|
||
PBUFFER_CHUNK bq_Tail;
|
||
|
||
} BUFFER_QUEUE, *PBUFFER_QUEUE;
|
||
|
||
|
||
#define ADSP_CONN_HASH_SIZE 23
|
||
|
||
|
||
// ADSP ADDRESS OBJECT STATES
|
||
#define ADSPAO_LISTENER 0x00000001
|
||
#define ADSPAO_CONNECT 0x00000002
|
||
#define ADSPAO_MESSAGE 0x00000010
|
||
#define ADSPAO_CLOSING 0x80000000
|
||
|
||
#define ADSPAO_SIGNATURE (*(PULONG)"ADAO")
|
||
|
||
#define VALID_ADSPAO(pAdspAddr) (((pAdspAddr) != NULL) && \
|
||
(((struct _ADSP_ADDROBJ *)(pAdspAddr))->adspao_Signature == ADSPAO_SIGNATURE))
|
||
|
||
typedef struct _ADSP_ADDROBJ
|
||
{
|
||
ULONG adspao_Signature;
|
||
|
||
// Global list of address objects.
|
||
struct _ADSP_ADDROBJ * adspao_pNextGlobal;
|
||
|
||
ULONG adspao_Flags;
|
||
ULONG adspao_RefCount;
|
||
ATALK_SPIN_LOCK adspao_Lock;
|
||
PATALK_DEV_CTX adspao_pDevCtx;
|
||
|
||
// List of connections associated with this address object.
|
||
// Potentially greater than one if this address object is a listener.
|
||
struct _ADSP_CONNOBJ * adspao_pAssocConn;
|
||
|
||
// List of connections that are associated, but also have a listen/connect
|
||
// posted on them.
|
||
union
|
||
{
|
||
struct _ADSP_CONNOBJ * adspao_pListenConn;
|
||
struct _ADSP_CONNOBJ * adspao_pConnectConn;
|
||
};
|
||
|
||
// List of indicated connections waiting for acceptance.
|
||
struct _ADSP_OPEN_REQ * adspao_OpenReq;
|
||
|
||
// Lookup list of all active connections hashed by connId and remote
|
||
// address.
|
||
struct _ADSP_CONNOBJ * adspao_pActiveHash[ADSP_CONN_HASH_SIZE];
|
||
|
||
// Next connection to use.
|
||
USHORT adspao_NextConnId;
|
||
|
||
// Event support routines.
|
||
//
|
||
// This function pointer points to a connection indication handler for this
|
||
// Address. Any time a connect request is received on the address, this
|
||
// routine is invoked.
|
||
PTDI_IND_CONNECT adspao_ConnHandler;
|
||
PVOID adspao_ConnHandlerCtx;
|
||
|
||
PTDI_IND_DISCONNECT adspao_DisconnectHandler;
|
||
PVOID adspao_DisconnectHandlerCtx;
|
||
|
||
PTDI_IND_RECEIVE adspao_RecvHandler;
|
||
PVOID adspao_RecvHandlerCtx;
|
||
|
||
PTDI_IND_RECEIVE_EXPEDITED adspao_ExpRecvHandler;
|
||
PVOID adspao_ExpRecvHandlerCtx;
|
||
|
||
PTDI_IND_SEND_POSSIBLE adspao_SendPossibleHandler;
|
||
PVOID adspao_SendPossibleHandlerCtx;
|
||
|
||
// DDP Address for this adsp address. If this is a listener, then the DDP
|
||
// address will be what the listens effectively will be posted on. This
|
||
// will also be the address over which the connections will be active.
|
||
// if this is a connect address object, then this ddp address will be what the
|
||
// associated connection be active over.
|
||
PDDP_ADDROBJ adspao_pDdpAddr;
|
||
|
||
// Completion routine to be called when address is closed
|
||
GENERIC_COMPLETION adspao_CloseComp;
|
||
PVOID adspao_CloseCtx;
|
||
|
||
} ADSP_ADDROBJ, *PADSP_ADDROBJ;
|
||
|
||
|
||
#define ADSPCO_ASSOCIATED 0x00000001
|
||
#define ADSPCO_IND_RECV 0x00000002
|
||
#define ADSPCO_LISTENING 0x00000004
|
||
#define ADSPCO_CONNECTING 0x00000008
|
||
#define ADSPCO_ACCEPT_IRP 0x00000010
|
||
#define ADSPCO_LISTEN_IRP 0x00000020
|
||
#define ADSPCO_HALF_ACTIVE 0x00000040
|
||
#define ADSPCO_ACTIVE 0x00000080
|
||
#define ADSPCO_SEEN_REMOTE_OPEN 0x00000100
|
||
#define ADSPCO_DISCONNECTING 0x00000200
|
||
#define ADSPCO_SERVER_JOB 0x00000400
|
||
#define ADSPCO_REMOTE_CLOSE 0x00000800
|
||
#define ADSPCO_SEND_IN_PROGRESS 0x00001000
|
||
#define ADSPCO_SEND_DENY 0x00002000
|
||
#define ADSPCO_SEND_OPENACK 0x00004000
|
||
#define ADSPCO_SEND_WINDOW_CLOSED 0x00008000
|
||
#define ADSPCO_READ_PENDING 0x00010000
|
||
#define ADSPCO_EXREAD_PENDING 0x00020000
|
||
#define ADSPCO_FORWARD_RESET_RECD 0x00040000
|
||
#define ADSPCO_ATTN_DATA_RECD 0x00080000
|
||
#define ADSPCO_ATTN_DATA_EOM 0x00100000
|
||
#define ADSPCO_EXSEND_IN_PROGRESS 0x00200000
|
||
#define ADSPCO_OPEN_TIMER 0x01000000
|
||
#define ADSPCO_RETRANSMIT_TIMER 0x02000000
|
||
#define ADSPCO_CONN_TIMER 0x04000000
|
||
#define ADSPCO_LOCAL_DISCONNECT 0x08000000
|
||
#define ADSPCO_REMOTE_DISCONNECT 0x10000000
|
||
#define ADSPCO_DELAYED_DISCONNECT 0x20000000
|
||
#define ADSPCO_STOPPING 0x40000000
|
||
#define ADSPCO_CLOSING 0x80000000
|
||
|
||
#define ADSPCO_SIGNATURE (*(PULONG)"ADCO")
|
||
|
||
#define VALID_ADSPCO(pAdspConn) (((pAdspConn) != NULL) && \
|
||
(((struct _ADSP_CONNOBJ *)(pAdspConn))->adspco_Signature == ADSPCO_SIGNATURE))
|
||
|
||
// This will represent a 'job' on the Pap address. This could either be a
|
||
// workstation job or a server job. In the latter case it could either
|
||
// be in a 'listen' state or active state. In the former case it is either
|
||
// active or 'waiting'
|
||
typedef struct _ADSP_CONNOBJ
|
||
{
|
||
ULONG adspco_Signature;
|
||
|
||
// Used to queue into the address object's associated list.
|
||
struct _ADSP_CONNOBJ * adspco_pNextAssoc;
|
||
|
||
ULONG adspco_Flags;
|
||
ULONG adspco_RefCount;
|
||
ATALK_SPIN_LOCK adspco_Lock;
|
||
PATALK_DEV_CTX adspco_pDevCtx;
|
||
|
||
// !!!NOTE!!!
|
||
// The address this connection uses will be the address object's DDP address.
|
||
PDDP_ADDROBJ adspco_pDdpAddr;
|
||
|
||
// Used to queue into the address object's listen/connect list. When it
|
||
// is removed from the listen/connect, it goes into the active list of the
|
||
// address object.
|
||
union
|
||
{
|
||
struct _ADSP_CONNOBJ * adspco_pNextListen;
|
||
struct _ADSP_CONNOBJ * adspco_pNextConnect;
|
||
struct _ADSP_CONNOBJ * adspco_pNextActive;
|
||
};
|
||
|
||
// Global list of connection objects.
|
||
struct _ADSP_CONNOBJ * adspco_pNextGlobal;
|
||
|
||
// Used to queue into the lookup by remote connid/remote address
|
||
// list in address obj.
|
||
struct _ADSP_CONNOBJ * adspco_pHashNext;
|
||
|
||
// Backpointer to the associated address
|
||
struct _ADSP_ADDROBJ * adspco_pAssocAddr;
|
||
|
||
// Address of remote end of the connection
|
||
ATALK_ADDR adspco_RemoteAddr;
|
||
|
||
// Connection ids
|
||
USHORT adspco_LocalConnId;
|
||
USHORT adspco_RemoteConnId;
|
||
|
||
// Connection timer. During open time this will be the open timer.
|
||
union
|
||
{
|
||
TIMERLIST adspco_ConnTimer;
|
||
TIMERLIST adspco_OpenTimer;
|
||
};
|
||
|
||
TIMERLIST adspco_RetransmitTimer;
|
||
ULONG adspco_LastTimerRtmtSeq;
|
||
LONG adspco_LastContactTime;
|
||
|
||
// Connection context
|
||
PVOID adspco_ConnCtx;
|
||
|
||
// List of pended sends
|
||
LIST_ENTRY adspco_PendedSends;
|
||
|
||
// Sequence numbers
|
||
ULONG adspco_SendSeq;
|
||
ULONG adspco_FirstRtmtSeq;
|
||
ULONG adspco_SendWindowSeq;
|
||
ULONG adspco_SendAttnSeq;
|
||
|
||
ULONG adspco_RecvSeq;
|
||
ULONG adspco_RecvAttnSeq;
|
||
|
||
// Window/buffers
|
||
LONG adspco_RecvWindow;
|
||
LONG adspco_SendQueueMax;
|
||
LONG adspco_RecvQueueMax;
|
||
|
||
// Previously indicated data
|
||
ULONG adspco_PrevIndicatedData;
|
||
|
||
// Buffer queues
|
||
BUFFER_QUEUE adspco_SendQueue;
|
||
BUFFER_QUEUE adspco_NextSendQueue;
|
||
BUFFER_QUEUE adspco_RecvQueue;
|
||
|
||
// Number of out of sequence packets received
|
||
ULONG adspco_OutOfSeqCount;
|
||
|
||
// The connection object can have either a CONNECT or a LISTEN posted
|
||
// on it, but not both.
|
||
union
|
||
{
|
||
struct
|
||
{
|
||
// Pending Listen routine.
|
||
GENERIC_COMPLETION adspco_ListenCompletion;
|
||
PVOID adspco_ListenCtx;
|
||
};
|
||
|
||
struct
|
||
{
|
||
// Pending Connect routine. The status buffer is remember and
|
||
// returned via socket options. The pConnectRespBuf is remembered
|
||
// to avoid having to get the system address for it. It is freed
|
||
// when connection is taken off the connectlist.
|
||
GENERIC_COMPLETION adspco_ConnectCompletion;
|
||
PVOID adspco_ConnectCtx;
|
||
ULONG adspco_ConnectAttempts;
|
||
};
|
||
};
|
||
|
||
// Read completion information
|
||
ULONG adspco_ReadFlags;
|
||
PAMDL adspco_ReadBuf;
|
||
USHORT adspco_ReadBufLen;
|
||
GENERIC_READ_COMPLETION adspco_ReadCompletion;
|
||
PVOID adspco_ReadCtx;
|
||
|
||
PBYTE adspco_ExRecdData;
|
||
USHORT adspco_ExRecdLen;
|
||
|
||
// Expedited Read completion information
|
||
ULONG adspco_ExReadFlags;
|
||
USHORT adspco_ExReadBufLen;
|
||
PAMDL adspco_ExReadBuf;
|
||
GENERIC_READ_COMPLETION adspco_ExReadCompletion;
|
||
PVOID adspco_ExReadCtx;
|
||
|
||
// Expedited Write completion information
|
||
TIMERLIST adspco_ExRetryTimer;
|
||
PBYTE adspco_ExWriteChBuf;
|
||
|
||
ULONG adspco_ExWriteFlags;
|
||
USHORT adspco_ExWriteBufLen;
|
||
PAMDL adspco_ExWriteBuf;
|
||
GENERIC_WRITE_COMPLETION adspco_ExWriteCompletion;
|
||
PVOID adspco_ExWriteCtx;
|
||
|
||
// Disconnect inform routine
|
||
GENERIC_COMPLETION adspco_DisconnectInform;
|
||
PVOID adspco_DisconnectInformCtx;
|
||
|
||
// Disconnect request completion
|
||
ATALK_ERROR adspco_DisconnectStatus;
|
||
GENERIC_COMPLETION adspco_DisconnectCompletion;
|
||
PVOID adspco_DisconnectCtx;
|
||
|
||
// The following is a hack to get around the problem of rcv/disconnet race condn.
|
||
// Since this involves major rework, a safe approach is taken
|
||
TIMERLIST adspco_DisconnectTimer;
|
||
|
||
// Cleanup irp completion
|
||
GENERIC_COMPLETION adspco_CleanupComp;
|
||
PVOID adspco_CleanupCtx;
|
||
|
||
// Completion routine to be called when socket is closed
|
||
GENERIC_COMPLETION adspco_CloseComp;
|
||
PVOID adspco_CloseCtx;
|
||
|
||
} ADSP_CONNOBJ, *PADSP_CONNOBJ;
|
||
|
||
|
||
// Used for the list of indicated connections waiting acceptance
|
||
typedef struct _ADSP_OPEN_REQ
|
||
{
|
||
struct _ADSP_OPEN_REQ * or_Next;
|
||
ATALK_ADDR or_RemoteAddr;
|
||
ULONG or_FirstByteSeq;
|
||
ULONG or_NextRecvSeq;
|
||
LONG or_RecvWindow;
|
||
USHORT or_RemoteConnId;
|
||
|
||
} ADSP_OPEN_REQ, *PADSP_OPEN_REQ;
|
||
|
||
|
||
|
||
// Routine prototypes
|
||
VOID
|
||
AtalkInitAdspInitialize(
|
||
VOID);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCreateAddress(
|
||
IN PATALK_DEV_CTX pDevCtx OPTIONAL,
|
||
IN BYTE SocketType,
|
||
OUT PADSP_ADDROBJ * ppAdspAddr);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCleanupAddress(
|
||
IN PADSP_ADDROBJ pAdspAddr);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCloseAddress(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN GENERIC_COMPLETION CompletionRoutine,
|
||
IN PVOID pCloseCtx);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCreateConnection(
|
||
IN PVOID pConnCtx, // Context to associate with the session
|
||
IN PATALK_DEV_CTX pDevCtx OPTIONAL,
|
||
OUT PADSP_CONNOBJ * ppAdspConn);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCloseConnection(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN GENERIC_COMPLETION CompletionRoutine,
|
||
IN PVOID pCloseCtx);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCleanupConnection(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspAssociateAddress(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspDissociateAddress(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspPostListen(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PVOID pListenCtx,
|
||
IN GENERIC_COMPLETION CompletionRoutine);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspCancelListen(
|
||
IN PADSP_CONNOBJ pAdspConn) ;
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspPostConnect(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PATALK_ADDR pRemoteAddr,
|
||
IN PVOID pConnectCtx,
|
||
IN GENERIC_COMPLETION CompletionRoutine);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspDisconnect(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN ATALK_DISCONNECT_TYPE DisconnectType,
|
||
IN PVOID pDisconnectCtx,
|
||
IN GENERIC_COMPLETION CompletionRoutine);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspRead(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PAMDL pReadBuf,
|
||
IN USHORT ReadBufLen,
|
||
IN ULONG ReadFlags,
|
||
IN PVOID pReadCtx,
|
||
IN GENERIC_READ_COMPLETION CompletionRoutine);
|
||
|
||
ATALK_ERROR
|
||
AtalkAdspWrite(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PAMDL pWriteBuf,
|
||
IN USHORT WriteBufLen,
|
||
IN ULONG SendFlags,
|
||
IN PVOID pWriteCtx,
|
||
IN GENERIC_WRITE_COMPLETION CompletionRoutine);
|
||
|
||
VOID
|
||
AtalkAdspQuery(
|
||
IN PVOID pObject,
|
||
IN ULONG ObjectType,
|
||
IN PAMDL pAmdl,
|
||
OUT PULONG BytesWritten);
|
||
|
||
VOID
|
||
atalkAdspAddrRefNonInterlock(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
VOID
|
||
atalkAdspAddrDeref(
|
||
IN PADSP_ADDROBJ pAdspAddr);
|
||
|
||
VOID
|
||
atalkAdspConnRefByPtrNonInterlock(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN ULONG NumCount,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
VOID
|
||
atalkAdspConnRefByCtxNonInterlock(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN CONNECTION_CONTEXT Ctx,
|
||
OUT PADSP_CONNOBJ * pAdspConn,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
VOID
|
||
atalkAdspConnRefBySrcAddr(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PATALK_ADDR pRemoteAddr,
|
||
IN USHORT RemoteConnId,
|
||
OUT PADSP_CONNOBJ * ppAdspConn,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
VOID
|
||
atalkAdspConnRefNextNc(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PADSP_CONNOBJ * ppAdspConnNext,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
VOID
|
||
AtalkAdspProcessQueuedSend(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
VOID
|
||
atalkAdspConnDeref(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
|
||
|
||
|
||
// MACROS
|
||
#define UNSIGNED_BETWEEN_WITH_WRAP(Low, High, Target) \
|
||
((Low <= High) ? ((Target >= Low) && (Target <= High)) : \
|
||
((Target >= Low) || (Target <= High)))
|
||
|
||
// This didnt make sense until JameelH explained what was going on.
|
||
// This is with the assumption that the window size will never be greater
|
||
// than the difference of 0x80000 and 0x10000. If High is < 10000 and Low
|
||
// is > 80000 then we can assume a wrap happened. Otherwise, we assume no
|
||
// wrap and do a straight compare.
|
||
#define UNSIGNED_GREATER_WITH_WRAP(High, Low) \
|
||
(((High < 0x10000) && (Low > 0x80000)) ? TRUE : (High > Low))
|
||
// (((High < 0x80000) && (Low > 0x10000)) ? TRUE : (High > Low))
|
||
|
||
|
||
#define AtalkAdspGetDdpAddress(pAdspAddr) \
|
||
((pAdspAddr)->adspao_pDdpAddr)
|
||
|
||
#define AtalkAdspAddrReferenceNonInterlock(pAdspAddr, pError) \
|
||
{ \
|
||
DBGPRINT(DBG_COMP_ADSP, DBG_LEVEL_INFO, ("RefAddr %lx at %s %d - %d\n", \
|
||
pAdspAddr, __FILE__, __LINE__, ((pAdspAddr)->adspao_RefCount))); \
|
||
atalkAdspAddrRefNonInterlock(pAdspAddr, pError); \
|
||
}
|
||
|
||
#define AtalkAdspAddrReference(pAdspAddr, pError) \
|
||
{ \
|
||
KIRQL OldIrql; \
|
||
\
|
||
ACQUIRE_SPIN_LOCK(&(pAdspAddr)->adspao_Lock, &OldIrql); \
|
||
AtalkAdspAddrReferenceNonInterlock(pAdspAddr, pError); \
|
||
RELEASE_SPIN_LOCK(&(pAdspAddr)->adspao_Lock, OldIrql); \
|
||
}
|
||
|
||
#define AtalkAdspAddrDereference(pAdspAddr) \
|
||
{ \
|
||
DBGPRINT(DBG_COMP_ADSP, DBG_LEVEL_INFO, ("DerefAddr %lx at %s %d - %d\n",\
|
||
pAdspAddr, __FILE__, __LINE__, ((pAdspAddr)->adspao_RefCount))); \
|
||
atalkAdspAddrDeref(pAdspAddr); \
|
||
}
|
||
|
||
#define AtalkAdspConnReferenceByPtrNonInterlock(pAdspConn, NumCount, pError) \
|
||
{ \
|
||
atalkAdspConnRefByPtrNonInterlock(pAdspConn, NumCount, pError); \
|
||
}
|
||
|
||
#define AtalkAdspConnReferenceByPtr(pAdspConn, pError) \
|
||
{ \
|
||
KIRQL OldIrql; \
|
||
\
|
||
ACQUIRE_SPIN_LOCK(&(pAdspConn)->adspco_Lock, &OldIrql); \
|
||
AtalkAdspConnReferenceByPtrNonInterlock(pAdspConn, 1, pError);\
|
||
RELEASE_SPIN_LOCK(&(pAdspConn)->adspco_Lock, OldIrql); \
|
||
}
|
||
|
||
#define AtalkAdspConnReferenceByCtxNonInterlock(pAdspAddr, Ctx, ppAdspConn, pError) \
|
||
atalkAdspConnRefByCtxNonInterlock(pAdspAddr, Ctx, ppAdspConn, pError)
|
||
|
||
#define AtalkAdspConnReferenceBySrcAddr(pAdspAddr, pSrc, SessId, pErr) \
|
||
atalkAdspConnRefBySrcAddr(pAdspAddr, pSrc, SessId, pErr)
|
||
|
||
#define AtalkAdspConnDereference(pAdspConn) \
|
||
{ \
|
||
DBGPRINT(DBG_COMP_ADSP, DBG_LEVEL_INFO, \
|
||
("DerefConn %lx at %s %d - %d\n", \
|
||
pAdspConn, __FILE__, __LINE__, \
|
||
(pAdspConn)->adspco_RefCount)); \
|
||
atalkAdspConnDeref(pAdspConn); \
|
||
}
|
||
|
||
// How many bytes/seqnums does eom occupy?
|
||
#define BYTECOUNT(eom) ((ULONG)((eom) ? 1 : 0))
|
||
|
||
//
|
||
// PLIST_ENTRY
|
||
// WRITECTX_LINKAGE(
|
||
// IN PVOID WriteCtx
|
||
// );
|
||
//
|
||
// Returns a pointer to a linkage field in the write context (Assumed to be IRP).
|
||
//
|
||
|
||
#define WRITECTX_LINKAGE(_Request) \
|
||
(&(((PIRP)_Request)->Tail.Overlay.ListEntry))
|
||
|
||
|
||
#define WRITECTX(_Request) ((PIRP)(_Request))
|
||
|
||
//
|
||
// PVOID
|
||
// LIST_ENTRY_TO_WRITECTX(
|
||
// IN PLIST_ENTRY ListEntry
|
||
// );
|
||
//
|
||
// Returns a request given a linkage field in it.
|
||
//
|
||
|
||
#define LIST_ENTRY_TO_WRITECTX(_ListEntry) \
|
||
((PVOID)(CONTAINING_RECORD(_ListEntry, IRP, Tail.Overlay.ListEntry)))
|
||
|
||
//
|
||
// PVOID
|
||
// WRITECTX_TDI_BUFFER
|
||
// IN PVOID Request
|
||
// );
|
||
//
|
||
// Returns the TDI buffer chain associated with a request.
|
||
//
|
||
|
||
#define WRITECTX_TDI_BUFFER(_Request) \
|
||
((PVOID)(((PIRP)(_Request))->MdlAddress))
|
||
|
||
|
||
//
|
||
// ULONG
|
||
// WRITECTX_SIZE(
|
||
// IN PVOID Request
|
||
// );
|
||
//
|
||
// Obtains size of send
|
||
//
|
||
|
||
#define WRITECTX_SIZE(_Request) \
|
||
(((PTDI_REQUEST_KERNEL_SEND)(&((IoGetCurrentIrpStackLocation((PIRP)_Request))->Parameters)))->SendLength)
|
||
|
||
//
|
||
// ULONG
|
||
// WRITECTX_FLAGS(
|
||
// IN PVOID Request
|
||
// );
|
||
//
|
||
// Obtains size of send
|
||
//
|
||
|
||
#define WRITECTX_FLAGS(_Request) \
|
||
(((PTDI_REQUEST_KERNEL_SEND)(&((IoGetCurrentIrpStackLocation((PIRP)_Request))->Parameters)))->SendFlags)
|
||
|
||
extern PADSP_ADDROBJ atalkAdspAddrList;
|
||
extern PADSP_CONNOBJ atalkAdspConnList;
|
||
extern ATALK_SPIN_LOCK atalkAdspLock;
|
||
|
||
PBUFFER_CHUNK
|
||
atalkAdspAllocCopyChunk(
|
||
IN PVOID pWriteBuf,
|
||
IN USHORT WriteBufLen,
|
||
IN BOOLEAN Eom,
|
||
IN BOOLEAN IsCharBuffer);
|
||
|
||
VOID
|
||
atalkAdspPacketIn(
|
||
IN PPORT_DESCRIPTOR pPortDesc,
|
||
IN PDDP_ADDROBJ pDdpAddr,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN PATALK_ADDR pDestAddr,
|
||
IN ATALK_ERROR ErrorCode,
|
||
IN BYTE DdpType,
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN BOOLEAN OptimizePath,
|
||
IN PVOID OptimizeCtx);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandleOpenControl(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN USHORT RemoteConnId,
|
||
IN ULONG RemoteFirstByteSeq,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandleAttn(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN ULONG RemoteFirstByteSeq,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandlePiggyBackAck(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandleControl(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN ULONG RemoteFirstByteSeq,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandleData(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN ULONG RemoteFirstByteSeq,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspHandleOpenReq(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PBYTE pPkt,
|
||
IN USHORT PktLen,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
IN USHORT RemoteConnId,
|
||
IN ULONG RemoteFirstByteSeq,
|
||
IN ULONG RemoteNextRecvSeq,
|
||
IN ULONG RemoteRecvWindow,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspListenIndicateNonInterlock(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_OPEN_REQ pOpenReq,
|
||
IN PADSP_CONNOBJ * ppAdspConn,
|
||
IN PATALK_ERROR pError);
|
||
|
||
ATALK_ERROR
|
||
atalkAdspSendExpedited(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN PAMDL pWriteBuf,
|
||
IN USHORT WriteBufLen,
|
||
IN ULONG SendFlags,
|
||
IN PVOID pWriteCtx,
|
||
IN GENERIC_WRITE_COMPLETION CompletionRoutine);
|
||
|
||
LOCAL VOID
|
||
atalkAdspSendOpenControl(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspSendControl(
|
||
IN PADSP_CONNOBJ pAdspConn,
|
||
IN BYTE Descriptor);
|
||
|
||
LOCAL VOID
|
||
atalkAdspSendAttn(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspSendData(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspRecvAttn(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspRecvData(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspSendDeny(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PATALK_ADDR pRemoteAddr,
|
||
IN USHORT pRemoteConnId);
|
||
|
||
VOID FASTCALL
|
||
atalkAdspSendAttnComplete(
|
||
IN NDIS_STATUS Status,
|
||
IN PSEND_COMPL_INFO pSendInfo);
|
||
|
||
VOID FASTCALL
|
||
atalkAdspConnSendComplete(
|
||
IN NDIS_STATUS Status,
|
||
IN PSEND_COMPL_INFO pSendInfo);
|
||
|
||
VOID FASTCALL
|
||
atalkAdspAddrSendComplete(
|
||
IN NDIS_STATUS Status,
|
||
IN PSEND_COMPL_INFO pSendInfo);
|
||
|
||
VOID FASTCALL
|
||
atalkAdspSendDataComplete(
|
||
IN NDIS_STATUS Status,
|
||
IN PSEND_COMPL_INFO pSendInfo);
|
||
|
||
LOCAL LONG FASTCALL
|
||
atalkAdspConnMaintenanceTimer(
|
||
IN PTIMERLIST pTimer,
|
||
IN BOOLEAN TimerShuttingDown);
|
||
|
||
LOCAL LONG FASTCALL
|
||
atalkAdspRetransmitTimer(
|
||
IN PTIMERLIST pTimer,
|
||
IN BOOLEAN TimerShuttingDown);
|
||
|
||
LOCAL LONG FASTCALL
|
||
atalkAdspAttnRetransmitTimer(
|
||
IN PTIMERLIST pTimer,
|
||
IN BOOLEAN TimerShuttingDown);
|
||
|
||
LOCAL LONG FASTCALL
|
||
atalkAdspOpenTimer(
|
||
IN PTIMERLIST pTimer,
|
||
IN BOOLEAN TimerShuttingDown);
|
||
|
||
LOCAL LONG FASTCALL
|
||
atalkAdspDisconnectTimer(
|
||
IN PTIMERLIST pTimer,
|
||
IN BOOLEAN TimerShuttingDown);
|
||
|
||
VOID
|
||
atalkAdspDecodeHeader(
|
||
IN PBYTE Datagram,
|
||
OUT PUSHORT RemoteConnId,
|
||
OUT PULONG FirstByteSeq,
|
||
OUT PULONG NextRecvSeq,
|
||
OUT PLONG Window,
|
||
OUT PBYTE Descriptor);
|
||
|
||
LOCAL USHORT
|
||
atalkAdspGetNextConnId(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
OUT PATALK_ERROR pError);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspConnDeQueueAssocList(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspConnDeQueueConnectList(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspConnDeQueueListenList(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspConnDeQueueActiveList(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL VOID
|
||
atalkAdspAddrQueueGlobalList(
|
||
IN PADSP_ADDROBJ pAdspAddr);
|
||
|
||
LOCAL VOID
|
||
atalkAdspAddrDeQueueGlobalList(
|
||
IN PADSP_ADDROBJ pAdspAddr);
|
||
|
||
LOCAL VOID
|
||
atalkAdspConnDeQueueGlobalList(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspAddrDeQueueOpenReq(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN USHORT RemoteConnId,
|
||
IN PATALK_ADDR pSrcAddr,
|
||
OUT PADSP_OPEN_REQ * ppOpenReq);
|
||
|
||
LOCAL BOOLEAN
|
||
atalkAdspIsDuplicateOpenReq(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN USHORT RemoteConnId,
|
||
IN PATALK_ADDR pSrcAddr);
|
||
|
||
LOCAL VOID
|
||
atalkAdspGenericComplete(
|
||
IN ATALK_ERROR ErrorCode,
|
||
IN PIRP pIrp);
|
||
|
||
ULONG
|
||
atalkAdspMaxSendSize(
|
||
IN PADSP_CONNOBJ pAdspConn);
|
||
|
||
ULONG
|
||
atalkAdspMaxNextReadSize(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
OUT PBOOLEAN pEom,
|
||
OUT PBUFFER_CHUNK * pBufferChunk);
|
||
|
||
ULONG
|
||
atalkAdspBufferQueueSize(
|
||
IN PBUFFER_QUEUE pQueue);
|
||
|
||
ULONG
|
||
atalkAdspMessageSize(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
IN PBOOLEAN pEom);
|
||
|
||
PBYTE
|
||
atalkAdspGetLookahead(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
OUT PULONG pLookaheadSize);
|
||
|
||
ULONG
|
||
atalkAdspReadFromBufferQueue(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
IN ULONG pFlags,
|
||
OUT PAMDL pReadBuf,
|
||
IN OUT PUSHORT pReadLen,
|
||
OUT PBOOLEAN pEom);
|
||
|
||
BOOLEAN
|
||
atalkAdspDiscardFromBufferQueue(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
IN ULONG DataSize,
|
||
OUT PBUFFER_QUEUE pAuxQueue,
|
||
IN ATALK_ERROR Error,
|
||
IN PADSP_CONNOBJ pAdspConn OPTIONAL);
|
||
|
||
VOID
|
||
atalkAdspAddToBufferQueue(
|
||
IN OUT PBUFFER_QUEUE pQueue,
|
||
IN PBUFFER_CHUNK pChunk,
|
||
IN OUT PBUFFER_QUEUE pAuxQueue OPTIONAL);
|
||
|
||
VOID
|
||
atalkAdspBufferChunkReference(
|
||
IN PBUFFER_CHUNK pBufferChunk);
|
||
|
||
VOID
|
||
atalkAdspBufferChunkDereference(
|
||
IN PBUFFER_CHUNK pBufferChunk,
|
||
IN BOOLEAN CreationDeref,
|
||
IN PADSP_CONNOBJ pAdspConn OPTIONAL);
|
||
|
||
VOID
|
||
atalkAdspConnFindInConnect(
|
||
IN PADSP_ADDROBJ pAdspAddr,
|
||
IN USHORT DestConnId,
|
||
IN PATALK_ADDR pRemoteAddr,
|
||
OUT PADSP_CONNOBJ * ppAdspConn,
|
||
IN PATALK_ERROR pError);
|
||
|
||
ULONG
|
||
atalkAdspDescribeFromBufferQueue(
|
||
IN PBUFFER_QUEUE pQueue,
|
||
OUT PBOOLEAN pEom,
|
||
IN ULONG WindowSize,
|
||
OUT PBUFFER_CHUNK * ppBufferChunk,
|
||
OUT PBUFFER_DESC * ppBufDesc);
|
||
|
||
#endif // _ADSP_
|
||
|
||
|