Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3355 lines
91 KiB

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
priv.h
Abstract:
Private structure definitions and function templates for the 1394 ARP module.
Author:
Revision History:
Who When What
-------- -------- ----
josephj 11-17-98 created
--*/
#define ARP1394_SYMBOLIC_NAME L"\\DosDevices\\ARP1394"
#define ARP1394_DEVICE_NAME L"\\Device\\ARP1394"
#define ARP1394_UL_NAME L"ARP1394"
#define ARP1394_LL_NAME L"TCPIP_ARP1394"
#define ARP1394_NDIS_MAJOR_VERSION 5
#define ARP1394_NDIS_MINOR_VERSION 0
// The physical address length, as reported to IP in the following places:
//
// IFEntry.if_physaddr (on WIN98, IFEntry.if_physaddr is truncated to 6 bytes)
// LLIPBindInfo.lip_addr
// IPNetToMediaEntry.inme_physaddr
//
// Note that may be (and in fact currently is) less then the actual length of
// the actual IEEE1394 FIFO physical-address length.
//
#define ARP1394_IP_PHYSADDR_LEN 6 // TODO: make 8
// The levels of the various types of locks
//
enum
{
LOCKLEVEL_GLOBAL=1, // Must start > 0.
LOCKLEVEL_ADAPTER,
LOCKLEVEL_IF_SEND
};
#define ARP1394_GLOBALS_SIG 'G31A'
// TODO: read this from configuration. Set default based on the ip/1394 standard.
//
#define ARP1394_ADAPTER_MTU 1520
#define ARP1394_MAX_PROTOCOL_PKTS 1000
#define ARP1394_MAX_PROTOCOL_PACKET_SIZE 1600 // We need to forward between ICS.
#define ARP1394_ADDRESS_RESOLUTION_TIMEOUT 1000 // Ms
#define ARP1394_MAX_ETHERNET_PKTS 4
// Delay between polling for connect status.
//
#define ARP1394_WAIT_FOR_CONNECT_STATUS_TIMEOUT 5000
//
// Packet flags for packets allocated by us.
// Go into protocol-context (pc_common.pc_flags) of the packet.
//
#define ARP1394_PACKET_FLAGS_ARP 0
#define ARP1394_PACKET_FLAGS_ICS 1
#define ARP1394_PACKET_FLAGS_MCAP 2
#define ARP1394_PACKET_FLAGS_DBGCOPY 3
#define ARP1394_PACKET_FLAGS_IOCTL 4
//
// Pre allocation constants to avoid low memory condition
//
#define ARP1394_BACKUP_TASKS 4
// Forward references
//
typedef struct _ARP1394_INTERFACE ARP1394_INTERFACE;
typedef struct _ARPCB_LOCAL_IP ARPCB_LOCAL_IP;
typedef struct _ARPCB_REMOTE_IP ARPCB_REMOTE_IP;
typedef struct _ARPCB_REMOTE_ETH ARPCB_REMOTE_ETH;
typedef struct _ARPCB_DEST ARPCB_DEST, *PARPCB_DEST;
typedef IPAddr IP_ADDRESS, *PIP_ADDRESS;
typedef IPMask IP_MASK, *PIP_MASK;
typedef int MYBOOL; // Like BOOL
typedef struct _ARP1394_GLOBALS
{
RM_OBJECT_HEADER Hdr;
RM_LOCK Lock;
// Driver global state
//
struct
{
// Handle to Driver Object for ARP1394
//
PVOID pDriverObject;
// Handle to the single device object representing this driver.
//
PVOID pDeviceObject;
} driver;
// Global NDIS State
//
struct
{
// NDIS' protocol handle, returned in NdisRegisterProtocol
//
NDIS_HANDLE ProtocolHandle;
// NDIS Protocol characteristics
//
NDIS_PROTOCOL_CHARACTERISTICS PC;
// NDIS Client characteristics
NDIS_CLIENT_CHARACTERISTICS CC;
} ndis;
// Global IP State
//
struct
{
// Handle returned by IPRegisterARP
//
HANDLE ARPRegisterHandle;
// Following are callback's into IP, set in IPRegisterARP
//
IP_ADD_INTERFACE pAddInterfaceRtn; // add an interface
IP_DEL_INTERFACE pDelInterfaceRtn; // delete an interface
IP_BIND_COMPLETE pBindCompleteRtn; // inform of bind cmpl
IP_ADD_LINK pAddLinkRtn;
IP_DELETE_LINK pDeleteLinkRtn;
} ip;
// Global adapter list
//
struct {
RM_GROUP Group;
} adapters;
// Global List of backup tasks
SLIST_HEADER BackupTasks;
NDIS_SPIN_LOCK BackupTaskLock;
UINT NumTasks;
}
ARP1394_GLOBALS;
extern ARP1394_GLOBALS ArpGlobals;
typedef struct // ARP1394_ADAPTER
{
RM_OBJECT_HEADER Hdr;
RM_LOCK Lock;
//
// PRIMARY_STATE flags (in Hdr.State)
//
// PRIMARY_STATE is the primary state of the adapter.
//
#define ARPAD_PS_MASK 0x00f
#define ARPAD_PS_DEINITED 0x000
#define ARPAD_PS_INITED 0x001
#define ARPAD_PS_FAILEDINIT 0x002
#define ARPAD_PS_INITING 0x003
#define ARPAD_PS_REINITING 0x004
#define ARPAD_PS_DEINITING 0x005
#define SET_AD_PRIMARY_STATE(_pAD, _IfState) \
RM_SET_STATE(_pAD, ARPAD_PS_MASK, _IfState)
#define CHECK_AD_PRIMARY_STATE(_pAD, _IfState) \
RM_CHECK_STATE(_pAD, ARPAD_PS_MASK, _IfState)
#define GET_AD_PRIMARY_STATE(_pAD) \
RM_GET_STATE(_pAD, ARPAD_PS_MASK)
//
// ACTIVE_STATE flags (in Hdr.State)
//
// ACTIVE_STATE is a secondary state of the adapter.
// Primary state takes precedence over secondary sate. For example,
// the interface is REINITING and ACTIVE, one should not actively use the
// interface.
//
// NOTE: When the primary state is INITED, the secondary state WILL be
// ACTIVATED. It is thus usually only necessary to look at the primary state.
//
#define ARPAD_AS_MASK 0x0f0
#define ARPAD_AS_DEACTIVATED 0x000
#define ARPAD_AS_ACTIVATED 0x010
#define ARPAD_AS_FAILEDACTIVATE 0x020
#define ARPAD_AS_DEACTIVATING 0x030
#define ARPAD_AS_ACTIVATING 0x040
#define SET_AD_ACTIVE_STATE(_pAD, _IfState) \
RM_SET_STATE(_pAD, ARPAD_AS_MASK, _IfState)
#define CHECK_AD_ACTIVE_STATE(_pAD, _IfState) \
RM_CHECK_STATE(_pAD, ARPAD_AS_MASK, _IfState)
#define GET_AD_ACTIVE_STATE(_pAD) \
RM_GET_STATE(_pAD, ARPAD_AS_MASK)
// BRIDGE (Ethernet Emulation) state (in Hdr.State)
//
#define ARPAD_BS_MASK 0x100
#define ARPAD_BS_ENABLED 0x100
#define ARP_ENABLE_BRIDGE(_pAD) \
RM_SET_STATE(_pAD, ARPAD_BS_MASK, ARPAD_BS_ENABLED)
#define ARP_BRIDGE_ENABLED(_pAD) \
RM_CHECK_STATE(_pAD, ARPAD_BS_MASK, ARPAD_BS_ENABLED)
#define SET_BS_FLAG(_pAD, _IfState) \
RM_SET_STATE(_pAD, ARPAD_BS_MASK, _IfState)
#define CHECK_BS_FLAG(_pAD, _IfState) \
RM_CHECK_STATE(_pAD, ARPAD_BS_MASK, _IfState)
#define GET_BS_ACTIVE_STATE(_pAD) \
RM_GET_STATE(_pAD, ARPAD_BS_MASK)
#define ARPAD_POWER_MASK 0xf000
#define ARPAD_POWER_LOW_POWER 0x1000
#define ARPAD_POWER_NORMAL 0x0000
#define SET_POWER_STATE(_pAD, _PoState) \
RM_SET_STATE(_pAD, ARPAD_POWER_MASK , _PoState)
#define CHECK_POWER_STATE(_pAD, _PoState) \
RM_CHECK_STATE(_pAD, ARPAD_POWER_MASK, _PoState)
#define GET_POWER_ACTIVE_STATE(_pAD) \
RM_GET_STATE(_pAD, ARPAD_POWER_MASK)
// NDIS bind info.
//
struct
{
NDIS_STRING ConfigName;
NDIS_STRING DeviceName;
PVOID IpConfigHandle;
NDIS_HANDLE BindContext;
// Init/Deinit/Reinit task
//
PRM_TASK pPrimaryTask;
// Activate/Deactivate task
//
PRM_TASK pSecondaryTask;
NDIS_HANDLE AdapterHandle;
// This is read from the configuration information in the registry.
// It is a multisz string, in theory it could contain the config-strings
// of multiple interfaces, although IP/1394 only provides one.
//
NDIS_STRING IpConfigString;
} bind;
// Information about the adapter, obtained by querying it.
// Note: MTU is the MTU reported by the adapter, and is not the same
// as the MTU reported up to ip (the latter MTU is in the ARP1394_INTERFACE
// structure).
//
struct
{
ULONG MTU;
// Maximum speed, in bytes per second, that the local host controller
// is capable of.
//
ULONG Speed;
#if OBSOLETE
// Minimum size (in bytes) of:
// -- Max individual async write to any remote node
// -- Max individual async write to any channel
// -- Max block we can receive on our recv FIFO
// -- Max block we can receive on any channel
//
ULONG MaxBlockSize;
#endif // 0
// max_rec (Maximum bus data record size)
// size == 2^(max_rec+1).
// (Macro IP1394_MAXREC_TO_SIZE in rfc.h)
//
//
ULONG MaxRec;
ULONG MaxSpeedCode;
//NIC1394_FIFO_ADDRESS LocalHwAddress;
UINT64 LocalUniqueID;
UCHAR * szDescription;
UINT DescriptionLength; // including null termination.
// This address is synthesized using the adapter's EU64 unique ID.
//
ENetAddr EthernetMacAddress;
} info;
struct
{
//
// Current Power State
//
NET_DEVICE_POWER_STATE State;
NDIS_EVENT Complete;
//
// Boolean variable to track the state on resume
//
BOOLEAN bReceivedSetPowerD0;
BOOLEAN bReceivedAf;
BOOLEAN bReceivedUnbind;
BOOLEAN bResuming;
BOOLEAN bFailedResume;
}PoMgmt;
// The IP interface control block (only one per adapter).
//
ARP1394_INTERFACE *pIF;
// Bus Topology of the 1394 card below this adapter
//
EUID_TOPOLOGY EuidMap;
//
// Set when a Workitem is queued to query Node Addresses
//
MYBOOL fQueryAddress;
//
// Power State of the Adapter
//
NET_DEVICE_POWER_STATE PowerState;
}
ARP1394_ADAPTER, *PARP1394_ADAPTER;
// This structure maintains a pool of buffers, all pointing to
// the same area of memory (whose contents are expected to be CONSTANT).
// The primary use of this structure is to maintain a pool of encapsulation headers
// buffers.
//
typedef struct _ARP_CONST_BUFFER_POOL
{
NDIS_HANDLE NdisHandle; // Buffer pool handle
PRM_OBJECT_HEADER pOwningObject; // ptr to object that owns this list
// Following stuff just for statistics gathering.
// TODO: consider conditionally-compiling this.
//
struct
{
UINT TotBufAllocs; // # allocs from buffer pool
UINT TotCacheAllocs; // # allocs from cache list
UINT TotAllocFails; // # failed allocs
} stats;
UINT NumBuffersToCache; // Number to keep inited and cached
UINT MaxBuffers; // Max number to allocate
UINT cbMem; // Size in bytes of mem below...
const VOID* pvMem; // Ptr to memory containg encap data
UINT NumAllocd; // # outstanding allocs from pool
UINT NumInCache; // # items sitting in cache.
NDIS_SPIN_LOCK NdisLock; // Spinlock protecting the list below
SLIST_HEADER BufferList; // List of available, inited bufs
} ARP_CONST_BUFFER_POOL;
// This structure is used when calling NdisRequest.
//
typedef struct _ARP_NDIS_REQUEST
{
NDIS_REQUEST Request; // The NDIS request structure.
NDIS_EVENT Event; // Event to signal when done.
PRM_TASK pTask; // Task to resume when done.
NDIS_STATUS Status; // Status of completed request.
} ARP_NDIS_REQUEST, *PARP_NDIS_REQUEST;
// Static set of information associated with a VC, mainly co-ndis call handlers.
//
typedef struct
{
PCHAR Description;
CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler;
// CO_STATUS_HANDLER CoStatusHandler;
CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler;
// CO_AF_REGISTER_NOTIFY_HANDLER CoAfRegisterNotifyHandler;
// CL_MAKE_CALL_COMPLETE_HANDLER ClMakeCallCompleteHandler;
// CL_CLOSE_CALL_COMPLETE_HANDLER ClCloseCallCompleteHandler;
CL_INCOMING_CLOSE_CALL_HANDLER ClIncomingCloseCallHandler;
// Vc type is currently used just for stats. We may get rid of some of the
// handlers above and use the vctype instead.
//
enum
{
ARPVCTYPE_SEND_FIFO,
ARPVCTYPE_RECV_FIFO,
ARPVCTYPE_BROADCAST_CHANNEL,
ARPVCTYPE_MULTI_CHANNEL,
ARPVCTYPE_ETHERNET,
ARPVCTYPE_SEND_CHANNEL,
ARPVCTYPE_RECV_CHANNEL,
} VcType;
BOOLEAN IsDestVc;
} ARP_STATIC_VC_INFO, *PARP_STATIC_VC_INFO;
// ARP's protocol vc context has this common header.
//
typedef struct
{
PARP_STATIC_VC_INFO pStaticInfo;
// Ndis VC handle associated with the VC.
//
NDIS_HANDLE NdisVcHandle;
// These two tasks are for making and tearingdown the VC,
// respectively.
//
PRM_TASK pMakeCallTask;
PRM_TASK pCleanupCallTask;
} ARP_VC_HEADER, *PARP_VC_HEADER;
typedef struct
{
// Channel number.
//
UINT Channel;
// IP multicast group address bound to this channel.
//
IP_ADDRESS GroupAddress;
// Absolute time at which this information was updated,
// in seconds.
//
UINT UpdateTime;
// Absolute time at which this mapping will expire.
// In seconds.
//
UINT ExpieryTime;
UINT SpeedCode;
// TBD
//
UINT Flags; // One of the MCAP_CHANNEL_FLAGS_*
#define MCAP_CHANNEL_FLAGS_LOCALLY_ALLOCATED 0x1
// NodeID of owner of this channel.
//
UINT NodeId;
} MCAP_CHANNEL_INFO, *PMCAP_CHANNEL_INFO;
// The IP interface control block.
//
typedef struct _ARP1394_INTERFACE
{
RM_OBJECT_HEADER Hdr;
//
// PRIMARY_STATE flags (in Hdr.State)
//
// PRIMARY_STATE is the primary state of the interface.
//
#define ARPIF_PS_MASK 0x00f
#define ARPIF_PS_DEINITED 0x000
#define ARPIF_PS_INITED 0x001
#define ARPIF_PS_FAILEDINIT 0x002
#define ARPIF_PS_INITING 0x003
#define ARPIF_PS_REINITING 0x004
#define ARPIF_PS_DEINITING 0x005
#define ARPIF_PS_LOW_POWER 0x006
#define SET_IF_PRIMARY_STATE(_pIF, _IfState) \
RM_SET_STATE(_pIF, ARPIF_PS_MASK, _IfState)
#define CHECK_IF_PRIMARY_STATE(_pIF, _IfState) \
RM_CHECK_STATE(_pIF, ARPIF_PS_MASK, _IfState)
#define GET_IF_PRIMARY_STATE(_pIF) \
RM_GET_STATE(_pIF, ARPIF_PS_MASK)
//
// ACTIVE_STATE flags (in Hdr.State)
//
// ACTIVE_STATE is a secondary state of the interface.
// Primary state takes precedence over secondary sate. For example,
// the interface is REINITING and ACTIVE, one should not actively use the
// interface.
//
// NOTE: When the primary state is INITED, the secondary state WILL be
// ACTIVATED. It is thus usually only necessary to look at the primary state.
//
#define ARPIF_AS_MASK 0x0f0
#define ARPIF_AS_DEACTIVATED 0x000
#define ARPIF_AS_ACTIVATED 0x010
#define ARPIF_AS_FAILEDACTIVATE 0x020
#define ARPIF_AS_DEACTIVATING 0x030
#define ARPIF_AS_ACTIVATING 0x040
#define SET_IF_ACTIVE_STATE(_pIF, _IfState) \
RM_SET_STATE(_pIF, ARPIF_AS_MASK, _IfState)
#define CHECK_IF_ACTIVE_STATE(_pIF, _IfState) \
RM_CHECK_STATE(_pIF, ARPIF_AS_MASK, _IfState)
#define GET_IF_ACTIVE_STATE(_pIF) \
RM_GET_STATE(_pIF, ARPIF_AS_MASK)
//
// IP_STATE flags (in Hdr.State)
//
// This state is set to OPEN when our open handler (ArpIpOpen) is called, and
// to CLOSED when our close handler (ArpIpClose) is called
//
#define ARPIF_IPS_MASK 0xf00
#define ARPIF_IPS_CLOSED 0x000
#define ARPIF_IPS_OPEN 0x100
#define SET_IF_IP_STATE(_pIF, _IfState) \
RM_SET_STATE(_pIF, ARPIF_IPS_MASK, _IfState)
#define CHECK_IF_IP_STATE(_pIF, _IfState) \
RM_CHECK_STATE(_pIF, ARPIF_IPS_MASK, _IfState)
#define GET_IF_IP_STATE(_pIF) \
RM_GET_STATE(_pIF, ARPIF_IPS_MASK)
// Init/Deinit/Reinit task
//
PRM_TASK pPrimaryTask;
// Activate/Deactivate task
//
PRM_TASK pActDeactTask;
// Maintenance task
//
PRM_TASK pMaintenanceTask;
// Ndis-provided handlers and handles.
//
struct
{
// Cashed value of the adapter handle.
//
NDIS_HANDLE AdapterHandle;
// The address family handle.
//
NDIS_HANDLE AfHandle;
} ndis;
// Stuff directly relating to interaction with IP.
//
struct
{
//
// Following passed in from IP.
//
PVOID Context; // Use in calls to IP
ULONG IFIndex; // Interface number
IPRcvRtn RcvHandler; // Indicate Receive
IPTxCmpltRtn TxCmpltHandler; // Transmit Complete
IPStatusRtn StatusHandler;
IPTDCmpltRtn TDCmpltHandler; // Transfer Data Complete
IPRcvCmpltRtn RcvCmpltHandler; // Receive Complete
IPRcvPktRtn RcvPktHandler; // Indicate Receive Packet
IP_PNP PnPEventHandler;
//
// Following passed up to IP.
//
ULONG MTU; // Max Transmision Unit (bytes)
NDIS_STRING ConfigString;
// Following are for IP's query/set info functionality.
//
UINT ATInstance; // Instance # for this AT Entity
UINT IFInstance; // Instance # for this IF Entity
//
// Other stuff ...
//
// Defaults to all-1's, but may be set by ip to be something different
// (actually the only other possibility is all-0's, when the stack is
// running in "BSD compatibility mode".
// This field is used to decide where a given destination address is
// unicast or not.
//
//
IP_ADDRESS BroadcastAddress;
// This address is used in filling out ARP requests.
//
IP_ADDRESS DefaultLocalAddress;
#if TODO
#ifdef PROMIS
NDIS_OID EnabledIpFilters; // Set of enabled oids --
// set/cleared using
// arpIfSetNdisRequest.
#endif // PROMIS
#endif // TODO
} ip;
// Statistics
//
// WARNING: arpResetIfStats() zeros this entire structure, then
// selectively re-inits some fields, such as StatsResetTime.
//
struct
{
// Following for MIB stats
//
ULONG LastChangeTime; // Time of last state change
ULONG InOctets; // Input octets
ULONG InUnicastPkts; // Input Unicast packets
ULONG InNonUnicastPkts; // Input Non-unicast packets
ULONG OutOctets; // Output octets
ULONG OutUnicastPkts; // Output Unicast packets
ULONG OutNonUnicastPkts; // Output Non-unicast packets
ULONG InDiscards;
ULONG InErrors;
ULONG UnknownProtos;
ULONG OutDiscards;
ULONG OutErrors;
ULONG OutQlen;
//
// Following for our private statistics gathering.
//
// Timestamp since the last reset of statistics collection.
// Set by a call to NdisGetCurrentSystemTime.
//
LARGE_INTEGER StatsResetTime; // In 100-nanoseconds.
LARGE_INTEGER PerformanceFrequency; // In Hz.
//
// Some send pkt stats
//
struct
{
UINT TotSends;
UINT FastSends;
UINT MediumSends;
UINT SlowSends;
UINT BackFills;
// UINT HeaderBufUses;
// UINT HeaderBufCacheHits;
ARP1394_PACKET_COUNTS SendFifoCounts;
ARP1394_PACKET_COUNTS SendChannelCounts;
} sendpkts;
//
// Some recv pkt stats
//
struct
{
UINT TotRecvs;
UINT NoCopyRecvs;
UINT CopyRecvs;
UINT ResourceRecvs;
ARP1394_PACKET_COUNTS RecvFifoCounts;
ARP1394_PACKET_COUNTS RecvChannelCounts;
} recvpkts;
//
// Task statistics
//
struct
{
UINT TotalTasks;
UINT CurrentTasks;
UINT TimeCounts[ARP1394_NUM_TASKTIME_SLOTS];
} tasks;
//
// Arp cache stats
//
struct {
UINT TotalQueries;
UINT SuccessfulQueries;
UINT FailedQueries;
UINT TotalResponses;
UINT TotalLookups;
// UINT TraverseRatio; << this is picked up by looking into the
// << hash table data structure.
} arpcache;
//
// Call stats
//
struct
{
//
// FIFO-related call stats.
//
UINT TotalSendFifoMakeCalls;
UINT SuccessfulSendFifoMakeCalls;
UINT FailedSendFifoMakeCalls;
UINT IncomingClosesOnSendFifos;
//
// Channel-related call stats.
//
UINT TotalChannelMakeCalls;
UINT SuccessfulChannelMakeCalls;
UINT FailedChannelMakeCalls;
UINT IncomingClosesOnChannels;
} calls;
} stats;
// Group containing local ip addresses, of type ARPCB_LOCAL_IP
//
RM_GROUP LocalIpGroup;
// Group containing remote ip addresses, of type ARPCB_REMOTE_IP
// (this is the arp cache)
//
RM_GROUP RemoteIpGroup;
// Group containing remote ethernet destinations. This group is only used
// if the adapter is operating in bridge mode.
// This is the Ethernet address cache.
//
RM_GROUP RemoteEthGroup;
// Group containing remote h/w distinations, of type ARPCB_DEST
// (each ARPCB_DEST has a group of VCs)
//
RM_GROUP DestinationGroup;
// Group containing the table (bridge only) of dhcp session, and their
// associated physical addresses
//
RM_GROUP EthDhcpGroup;
// Stuff relating to the receive FIFO, which is owned by the interface.
//
//
struct {
ARP_VC_HEADER VcHdr;
// Address offset of the receive VC
//
struct
{
ULONG Off_Low;
USHORT Off_High;
} offset;
} recvinfo;
// This maintains interface-wide information relevant to the send path.
//
struct
{
// Lock used exclusively for sending.
// Protects the following:
// ??? this->sendinfo.listPktsWaitingForHeaders
// ??? this->sendinfo.NumSendPacketsWaiting
// pLocalIp->sendinfo
// pDest->sendinfo
//
//
RM_LOCK Lock;
// List of send packets waiting for header buffers to become available.
//
LIST_ENTRY listPktsWaitingForHeaders;
// Length of the above list
//
UINT NumSendPacketsWaiting;
// Pool of header buffer pool. This is seralized by its OWN lock,
// not by sendinfo.Lock.
//
ARP_CONST_BUFFER_POOL HeaderPool;
// Pool of Channel header buffers. This is serialized by its OWN lock,
// not by sendinfo.Lock
//
ARP_CONST_BUFFER_POOL ChannelHeaderPool;
} sendinfo;
//
// Following 3 are "special" destinations ....
//
// Pointer to the broadcast-channel destination object.
//
PARPCB_DEST pBroadcastDest;
// Pointer to the multi-channel destination object.
//
PARPCB_DEST pMultiChannelDest;
// Pointer to the ethernet destination object.
//
PARPCB_DEST pEthernetDest;
// Stuff relating to running the ARP protocol
// (All serialized by the IF lock (not the IF SEND lock).
//
struct
{
// The NDIS packet pool for ARP pkts.
//
NDIS_HANDLE PacketPool;
// The NDIS buffer pool for ARP pkts.
//
NDIS_HANDLE BufferPool;
// Number of currently allocated packets.
//
LONG NumOutstandingPackets;
// Maximum size of the packet that can be allocated from this pool.
//
UINT MaxBufferSize;
} arp;
// Stuff relating to the Ethernet VC, which is owned by the interface.
//
struct {
// The NDIS packet pool for Ethernet pkts.
//
NDIS_HANDLE PacketPool;
// The NDIS buffer pool for Ethernet packet headers.
//
NDIS_HANDLE BufferPool;
#if TEST_ICS_HACK
PRM_TASK pTestIcsTask;
#endif // TEST_ICS_HACK;
} ethernet;
#define ARP_NUM_CHANNELS 64
struct
{
// Information about each channel. Information includes:
// IP multicast group address and expiry time.
//
MCAP_CHANNEL_INFO rgChannelInfo[ARP_NUM_CHANNELS];
} mcapinfo;
struct
{
PRM_TASK pAfPendingTask;
} PoMgmt;
}
ARP1394_INTERFACE, *PARP1394_INTERFACE;
#define ARP_OBJECT_IS_INTERFACE(_pHdr) ((_pHdr)->Sig == MTAG_INTERFACE)
#define ASSERT_VALID_INTERFACE(_pIF) ASSERT((_pIF)->Hdr.Sig == MTAG_INTERFACE)
#define ARP_WRITELOCK_IF_SEND_LOCK(_pIF, _psr) \
RmDoWriteLock(&(_pIF)->sendinfo.Lock, (_psr))
#define ARP_READLOCK_IF_SEND_LOCK(_pIF, _psr) \
RmDoReadLock(&(_pIF)->sendinfo.Lock, (_psr))
#define ARP_UNLOCK_IF_SEND_LOCK(_pIF, _psr) \
RmDoUnlock(&(_pIF)->sendinfo.Lock, (_psr))
#define ARP_FASTREADLOCK_IF_SEND_LOCK(_pIF) \
NdisAcquireSpinLock(&(_pIF)->sendinfo.Lock.OsLock)
#define ARP_FASTUNLOCK_IF_SEND_LOCK(_pIF) \
NdisReleaseSpinLock(&(_pIF)->sendinfo.Lock.OsLock)
/*++
VOID
ARP_IF_STAT_INCR(
IN ARP1394_INTERFACE * _pIF
IN OPAQUE StatsCounter
)
Increment the specified StatsCounter on an Interface by 1.
--*/
#define ARP_IF_STAT_INCR(_pIF, StatsCounter) \
NdisInterlockedIncrement(&(_pIF)->stats.StatsCounter)
/*++
VOID
ARP_IF_STAT_ADD(
IN ARP1394_INTERFACE * _pIF
IN OPAQUE StatsCounter,
IN ULONG IncrValue
)
Increment the specified StatsCounter on an Interface by the specified IncrValue.
Take a lock on the interface to do so.
--*/
#if BINARY_COMPATIBLE
#define ARP_IF_STAT_ADD(_pIF, StatsCounter, IncrValue) \
((_pIF)->stats.StatsCounter += (IncrValue))
#else // !BINARY_COMPATIBLE
#define ARP_IF_STAT_ADD(_pIF, StatsCounter, IncrValue) \
InterlockedExchangeAdd(&(_pIF)->stats.StatsCounter, IncrValue)
#endif // !BINARY_COMPATIBLE
//
// This is the table used to store the DHCP entries used in the bridge mode
//
typedef struct _ARP1394_ETH_DHCP_ENTRY
{
RM_OBJECT_HEADER Hdr;
//
// xid - per dhcp session (e.g discover, offer)
//
ULONG xid;
//
// HW address in the dhcp packet.
//
ENetAddr requestorMAC;
//
// New HW address that arp1394 inserts in the dhcp packet
//
ENetAddr newMAC;
//
// Time last checked to be used for aging purposes
//
UINT TimeLastChecked;
//
// Task used in unloading DhcpEntry
//
PRM_TASK pUnloadTask;
}ARP1394_ETH_DHCP_ENTRY, *PARP1394_ETH_DHCP_ENTRY;
typedef enum _ARP_RESUME_CAUSE {
Cause_SetPowerD0,
Cause_AfNotify,
Cause_Unbind
} ARP_RESUME_CAUSE;
//=========================================================================
// N D I S H A N D L E R S
//=========================================================================
INT
ArpNdBindAdapter(
OUT PNDIS_STATUS pStatus,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING pDeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
);
VOID
ArpNdUnbindAdapter(
OUT PNDIS_STATUS pStatus,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE UnbindContext
);
VOID
ArpNdOpenAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
);
VOID
ArpNdCloseAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
);
VOID
ArpNdResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
);
VOID
ArpNdReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
);
VOID
ArpNdRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST pNdisRequest,
IN NDIS_STATUS Status
);
VOID
ArpNdStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID pStatusBuffer,
IN UINT StatusBufferSize
);
VOID
ArpNdStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
);
VOID
ArpNdSendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET pNdisPacket,
IN NDIS_STATUS Status
);
//
// Following are some connectionless handlers we provide because we're calling
// connectionless entrypoints.
//
NDIS_STATUS
ArpNdReceive (
NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE Context,
VOID *Header,
UINT HeaderSize,
VOID *Data,
UINT Size,
UINT TotalSize
);
INT
ArpNdReceivePacket (
NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet
);
NDIS_STATUS
ArpNdPnPEvent(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
);
VOID
ArpNdUnloadProtocol(
VOID
);
VOID
ArpCoSendComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN PNDIS_PACKET pNdisPacket
);
VOID
ArpCoStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_STATUS GeneralStatus,
IN PVOID pStatusBuffer,
IN UINT StatusBufferSize
);
UINT
ArpCoReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE ProtocolVcContext,
IN PNDIS_PACKET pNdisPacket
);
VOID
ArpCoAfRegisterNotify(
IN NDIS_HANDLE ProtocolBindingContext,
IN PCO_ADDRESS_FAMILY pAddressFamily
);
NDIS_STATUS
ArpCoCreateVc(
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE NdisVcHandle,
OUT PNDIS_HANDLE pProtocolVcContext
);
NDIS_STATUS
ArpCoDeleteVc(
IN NDIS_HANDLE ProtocolVcContext
);
NDIS_STATUS
ArpCoIncomingCall(
IN NDIS_HANDLE ProtocolSapContext,
IN NDIS_HANDLE ProtocolVcContext,
IN OUT PCO_CALL_PARAMETERS pCallParameters
);
VOID
ArpCoCallConnected(
IN NDIS_HANDLE ProtocolVcContext
);
VOID
ArpCoIncomingClose(
IN NDIS_STATUS CloseStatus,
IN NDIS_HANDLE ProtocolVcContext,
IN PVOID pCloseData OPTIONAL,
IN UINT Size OPTIONAL
);
VOID
ArpCoQosChange(
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS pCallParameters
);
VOID
ArpCoOpenAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE NdisAfHandle
);
VOID
ArpCoCloseAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext
);
VOID
ArpCoMakeCallComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
IN PCO_CALL_PARAMETERS pCallParameters
);
VOID
ArpCoCloseCallComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
);
VOID
ArpCoModifyQosComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS pCallParameters
);
NDIS_STATUS
ArpCoRequest(
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
IN OUT PNDIS_REQUEST pNdisRequest
);
VOID
ArpCoRequestComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
IN PNDIS_REQUEST pNdisRequest
);
//=========================================================================
// I P H A N D L E R S
//=========================================================================
INT
ArpIpDynRegister(
IN PNDIS_STRING pAdapterString,
IN PVOID IpContext,
IN struct _IP_HANDLERS * pIpHandlers,
IN struct LLIPBindInfo * pBindInfo,
IN UINT InterfaceNumber
);
VOID
ArpIpOpen(
IN PVOID Context
);
VOID
ArpIpClose(
IN PVOID Context
);
UINT
ArpIpAddAddress(
IN PVOID Context,
IN UINT AddressType,
IN IP_ADDRESS IpAddress,
IN IP_MASK Mask,
IN PVOID Context2
);
UINT
ArpIpDelAddress(
IN PVOID Context,
IN UINT AddressType,
IN IP_ADDRESS IpAddress,
IN IP_MASK Mask
);
NDIS_STATUS
ArpIpMultiTransmit(
IN PVOID Context,
IN PNDIS_PACKET * pNdisPacketArray,
IN UINT NumberOfPackets,
IN IP_ADDRESS Destination,
IN RouteCacheEntry * pRCE OPTIONAL,
IN VOID * ArpCtxt
);
NDIS_STATUS
ArpIpTransmit(
IN PVOID Context,
IN PNDIS_PACKET pNdisPacket,
IN IP_ADDRESS Destination,
IN RouteCacheEntry * pRCE OPTIONAL,
IN VOID * ArpCtxt
);
NDIS_STATUS
ArpIpTransfer(
IN PVOID Context,
IN NDIS_HANDLE Context1,
IN UINT ArpHdrOffset,
IN UINT ProtoOffset,
IN UINT BytesWanted,
IN PNDIS_PACKET pNdisPacket,
OUT PUINT pTransferCount
);
VOID
ArpIpInvalidate(
IN PVOID Context,
IN RouteCacheEntry * pRCE
);
INT
ArpIpQueryInfo(
IN PVOID Context,
IN TDIObjectID * pID,
IN PNDIS_BUFFER pNdisBuffer,
IN OUT PUINT pBufferSize,
IN PVOID QueryContext
);
INT
ArpIpSetInfo(
IN PVOID Context,
IN TDIObjectID * pID,
IN PVOID pBuffer,
IN UINT BufferSize
);
INT
ArpIpGetEList(
IN PVOID Context,
IN TDIEntityID * pEntityList,
IN OUT PUINT pEntityListSize
);
VOID
ArpIpPnPComplete(
IN PVOID Context,
IN NDIS_STATUS Status,
IN PNET_PNP_EVENT pNetPnPEvent
);
#ifdef PROMIS
EXTERN
NDIS_STATUS
ArpIpSetNdisRequest(
IN PVOID Context,
IN NDIS_OID Oid,
IN UINT On
);
#endif // PROMIS
// The following structure has the general form of NDIS_CO_MEDIA_PARAMETERS.
// To properly track changes in NDIS_CO_MEDIA_PARAMETERS (however unlikeley!),
// code which uses any field in this structure should assert that the field is at
// the same offset as the corresponding NDIS structure.
// For example:
// ASSERT(FIELD_OFFSET(ARP1394_CO_MEDIA_PARAMETERS, Parameters)
// == FIELD_OFFSET(CO_MEDIA_PARAMETERS, MediaSpecific.Parameters))
//
//
typedef struct
{
// First 3 fields of CO_MEDIA_PARAMETERS
//
ULONG Flags; // TRANSMIT_VC and/or RECEIVE_VC
ULONG ReceivePriority; // 0 (unused)
ULONG ReceiveSizeHint; // 0 (unused)
// Followed by 1st 2 fields of CO_SPECIFIC_PARAMETERS
//
ULONG POINTER_ALIGNMENT ParamType; // Set to NIC1394_MEDIA_SPECIFIC
ULONG Length; // Set to sizeof(NIC1394_MEDIA_PARAMETERS)
// Followed by the NIC1394-specific media parameters.
// Note: we can't directly put the NIC1394_MEDIA_PARAMETERS structure here because
// it (currently) requires 8-byte alignment.
//
UCHAR Parameters[sizeof(NIC1394_MEDIA_PARAMETERS)];
} ARP1394_CO_MEDIA_PARAMETERS;
typedef enum _TASK_CAUSE {
SetLowPower = 1,
SetPowerOn
}TASK_CAUSE ;
typedef struct
{
RM_TASK TskHdr;
// Used to save the true return status (typically a failure status,
// which we don't want to forget during async cleanup).
//
NDIS_STATUS ReturnStatus;
} TASK_ADAPTERINIT, *PTASK_ADAPTERINIT;
typedef struct
{
RM_TASK TskHdr;
ARP_NDIS_REQUEST ArpNdisRequest;
NIC1394_LOCAL_NODE_INFO LocalNodeInfo;
// Following is used to switch to PASSIVE before calling IP's add interface
// Rtn.
//
NDIS_WORK_ITEM WorkItem;
} TASK_ADAPTERACTIVATE, *PTASK_ADAPTERACTIVATE;
typedef struct
{
RM_TASK TskHdr;
NDIS_HANDLE pUnbindContext;
} TASK_ADAPTERSHUTDOWN, *PTASK_ADAPTERSHUTDOWN;
// This is the task structure to be used with arpTaskActivateInterface
//
typedef struct
{
RM_TASK TskHdr;
#if ARP_DEFERIFINIT
// Following is used when waiting for the adapter to go to connected status
//
//
NDIS_TIMER Timer;
#endif // ARP_DEFERIFINIT
// Following is used to switch to PASSIVE before calling IP's add interface
// Rtn.
//
NDIS_WORK_ITEM WorkItem;
} TASK_ACTIVATE_IF, *PTASK_ACTIVATE_IF;
// This is the task structure to be used with arpTaskDeactivateInterface
//
typedef struct
{
RM_TASK TskHdr;
BOOLEAN fPendingOnIpClose;
TASK_CAUSE Cause;
// Following is used to switch to PASSIVE before calling IP's del interface
// Rtn.
//
NDIS_WORK_ITEM WorkItem;
} TASK_DEACTIVATE_IF, *PTASK_DEACTIVATE_IF;
// This is the task structure to be used with arpTaskReinitInterface
//
typedef struct
{
RM_TASK TskHdr;
NDIS_HANDLE pUnbindContext;
// Net PnP event to complete when reinit task is done.
//
PNET_PNP_EVENT pNetPnPEvent;
} TASK_REINIT_IF, *PTASK_REINIT_IF;
typedef struct
{
RM_TASK TskHdr;
// Ndis call params and media params for this call.
//
CO_CALL_PARAMETERS CallParams;
ARP1394_CO_MEDIA_PARAMETERS MediaParams;
} TASK_MAKECALL;
// This is the task structure to be used with arpTaskResolveIpAddress
//
typedef struct
{
RM_TASK TskHdr;
// Number of retry attempts left before we declare an address resolution failure.
//
UINT RetriesLeft;
// Used for the response timeout
//
NDIS_TIMER Timer;
} TASK_RESOLVE_IP_ADDRESS, *PTASK_RESOLVE_IP_ADDRESS;
typedef struct
{
RM_TASK TskHdr;
MYBOOL Quit; // If set, task will quit.
NDIS_TIMER Timer; // Used for the periodically sending out packets.
PNDIS_PACKET p1394Pkt; // Used for testing forward to ethernet
PNDIS_PACKET pEthPkt; // Used for sending connectionless ethernet pkts.
UINT Delay; // Delay (ms) in between sending packets.
UINT PktType; // Type of operation: do nothing, send over ethernet
// etc.
} TASK_ICS_TEST, *PTASK_ICS_TEST;
typedef struct
{
RM_TASK TskHdr;
MYBOOL Quit; // If set, task will quit.
NDIS_TIMER Timer; // Used for periodically waking up to do stuff.
UINT Delay; // Current value of delay (seconds). Can change.
UINT RemoteIpMaintenanceTime; // Absolute time in seconds
UINT RemoteEthMaintenanceTime; // Absolute time in seconds
UINT LocalIpMaintenanceTime; // Absolute time in seconds.
UINT McapDbMaintenanceTime; // Absolute time in seconds.
UINT DhcpTableMaintainanceTime; // Absolute time in seconds
} TASK_IF_MAINTENANCE, *PTASK_IF_MAINTENANCE;
typedef struct _TASK_BACKUP
{
RM_TASK Hdr;
//
// We are using Backup Task flag at position 31 because we do
// not want to conflict with the ResumeDelayed flags
//
#define ARP_BACKUP_TASK_MASK 0x80000000
#define ARP_BACKUP_TASK_FLAG 0x80000000
#define MARK_TASK_AS_BACKUP(_pT) \
RM_SET_STATE(_pT, ARP_BACKUP_TASK_MASK , ARP_BACKUP_TASK_FLAG )
#define CHECK_TASK_IS_BACKUP(_pT) \
RM_CHECK_STATE(_pT, ARP_BACKUP_TASK_MASK , ARP_BACKUP_TASK_FLAG )
#define GET_TASK_BACKUP_STATE(_pT) \
RM_GET_STATE(_pT, ARP_BACKUP_TASK_MASK )
DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) SINGLE_LIST_ENTRY List; // Linked list pointing to next task
} TASK_BACKUP, *PTASK_BACKUP;
// This is the task structure to be used with arpTaskResolveIpAddress
//
typedef struct
{
RM_TASK TskHdr;
NDIS_WORK_ITEM WorkItem;
} TASK_UNLOAD_REMOTE, *PTASK_UNLOAD_REMOTE;
//
// This task is used during a SetPower.
// It contains structures that will be track of the
// the numbero of calls that are closed /opened
// and the events that need to be waited for.
//
typedef struct _CALL_COUNT
{
// Count of Destination that will closeVc
//
ULONG DestCount;
// Event which the Close VC will wait on.
//
NDIS_EVENT VcEvent;
} CALL_COUNT, *PCALL_COUNT;
typedef struct _TASK_POWER {
RM_TASK Hdr;
// Event which the Set Power will wait on.
//
NDIS_EVENT CompleteEvent;
// Status of the Task
//
PNDIS_STATUS pStatus;
// Power state we are transitioning to
//
NET_DEVICE_POWER_STATE PowerState;
//
//WorkItem to switch to passive
NDIS_WORK_ITEM WorkItem;
//
// Last working Stage of task - dbg purpose only
//
UINT LastStage;
//
// Previous state of parent object. This is used so
// that the object can be placed back into its previous
// state.
//
UINT PrevState;
} TASK_POWER, *PTASK_POWER;
//
// This structure is used to keep track of a close call
// that originated becuase of a SetPower
//
typedef struct _TASK_SET_POWER_CALL
{
RM_TASK Hdr;
TASK_CAUSE Cause;
// The Call Call Count is used as place to count the number of outstanding close calls
// It uses DestCount as a place to store this information
//
PCALL_COUNT pCount;
}TASK_SET_POWER_CALL, *PTASK_SET_POWER_CALL;
//
// ARP1394_TASK is the union of all tasks structures used in arp1394.
// arpAllocateTask allocates memory of sizeof(ARP1394_TASK), which is guaranteed
// to be large enough to hold any task.
//
typedef union
{
RM_TASK TskHdr;
TASK_ADAPTERINIT AdapterInit;
TASK_ADAPTERSHUTDOWN AdapterShutdown;
TASK_ADAPTERACTIVATE AdapterActivate;
TASK_ACTIVATE_IF ActivateIf;
TASK_DEACTIVATE_IF DeactivateIf;
TASK_REINIT_IF ReinitIf;
TASK_MAKECALL MakeFifoCall;
TASK_RESOLVE_IP_ADDRESS ResolveIpAddress;
#if TEST_ICS_HACK
TASK_ICS_TEST IcsTest;
#endif // TEST_ICS_HACK
TASK_IF_MAINTENANCE IfMaintenance;
TASK_BACKUP Backup;
TASK_UNLOAD_REMOTE Unload;
TASK_SET_POWER_CALL CloseCall;
TASK_POWER TaskPower;
} ARP1394_TASK;
//
// ---------------------------- DESTINATION (REMOTE) KEY --------------
//
#pragma pack (push, 1)
typedef union _REMOTE_DEST_KEY
{
ENetAddr ENetAddress;
IPAddr IpAddress;
UCHAR Addr[ARP_802_ADDR_LENGTH];
struct
{
ULONG u32;
USHORT u16;
} u;
} REMOTE_DEST_KEY, *PREMOTE_DEST_KEY;
#pragma pack (pop)
#define REMOTE_DEST_IP_ADDRESS_FLAG 0xffff
#define IS_REMOTE_DEST_IP_ADDRESS(_R) ((_R)->u.u16 == REMOTE_DEST_IP_ADDRESS_FLAG )
#define REMOTE_DEST_IP_ADDRESS(_R) ((&(_R)->IpAddress))
#define REMOTE_DEST_ETH_ADDRESS(_R) ((&(_R)->ENetAddress))
#define REMOTE_DEST_KEY_INIT(_R) { (_R)->u.u32 = 0; (_R)->u.u16=REMOTE_DEST_IP_ADDRESS_FLAG ; };
//const REMOTE_DEST_KEY DefaultRemoteDestKey = {0,0,0,0,0xff,0xff};
//
// ---------------------------- DESTINATION (REMOTE) IP CONTROL BLOCK --------------
//
// Contains information about one destination (remote) IP address.
//
// Parent Object: pInterface
// Lock: It's own lock.
//
// There is atmost one ARP Table entry for a given IP address.
//
// The IP Entry participates in two lists:
// (1) A list of all entries that hash to the same bucket in the ARP Table
// (2) A list of all entries that resolve to the same destination H/W Address --
// this is only if the IP address is unicast.
//
// A pointer to this structure is also used as our context value in the
// Route Cache Entry prepared by the higher layer protocol(s).
//
// Reference Count: We add one to its ref count for each of the following:
// TBD:
//
typedef struct _ARPCB_REMOTE_IP
{
RM_OBJECT_HEADER Hdr; // Common header
//
// State flags for RemoteIp (in Hdr.State)
//
#define ARPREMOTEIP_RESOLVED_MASK 0x0f
#define ARPREMOTEIP_UNRESOLVED 0x00
#define ARPREMOTEIP_RESOLVED 0x01
#define ARPREMOTEIP_SDTYPE_MASK 0x10 // "SD" == Static/Dynamic
#define ARPREMOTEIP_STATIC 0x00
#define ARPREMOTEIP_DYNAMIC 0x10
#define ARPREMOTEIP_FCTYPE_MASK 0x20 // "FC" == FIFO/Channel
#define ARPREMOTEIP_FIFO 0x00
#define ARPREMOTEIP_CHANNEL 0x20
#define ARPREMOTEIP_MCAP_MASK 0x40 // "FC" == FIFO/Channel
#define ARPREMOTEIP_MCAP_CAPABLE 0x40
#define SET_REMOTEIP_RESOLVE_STATE(_pRIp, _IfState) \
RM_SET_STATE(_pRIp, ARPREMOTEIP_RESOLVED_MASK, _IfState)
#define CHECK_REMOTEIP_RESOLVE_STATE(_pRIp, _IfState) \
RM_CHECK_STATE(_pRIp, ARPREMOTEIP_RESOLVED_MASK, _IfState)
#define SET_REMOTEIP_SDTYPE(_pRIp, _IfState) \
RM_SET_STATE(_pRIp, ARPREMOTEIP_SDTYPE_MASK, _IfState)
#define CHECK_REMOTEIP_SDTYPE(_pRIp, _IfState) \
RM_CHECK_STATE(_pRIp, ARPREMOTEIP_SDTYPE_MASK, _IfState)
#define SET_REMOTEIP_FCTYPE(_pRIp, _IfState) \
RM_SET_STATE(_pRIp, ARPREMOTEIP_FCTYPE_MASK, _IfState)
#define CHECK_REMOTEIP_FCTYPE(_pRIp, _IfState) \
RM_CHECK_STATE(_pRIp, ARPREMOTEIP_FCTYPE_MASK, _IfState)
#define SET_REMOTEIP_MCAP(_pRIp, _IfState) \
RM_SET_STATE(_pRIp, ARPREMOTEIP_MCAP_MASK, _IfState)
#define CHECK_REMOTEIP_MCAP(_pRIp, _IfState) \
RM_CHECK_STATE(_pRIp, ARPREMOTEIP_MCAP_MASK, _IfState)
IP_ADDRESS IpAddress; // IP Address
LIST_ENTRY linkSameDest; // List of entries pointing to
// the same destination.
ARPCB_DEST *pDest; // Pointer to destination CB.
REMOTE_DEST_KEY Key; // Ip address or Mac Address
#if TODO
// Timers are: (all exclusive)
// - Aging timer
// - Waiting for ARP reply
// - Waiting for InARP reply
// - Delay after NAK
// - Waiting for MARS MULTI
// - Delay before marking for reval
#endif // TODO
ULONG RetriesLeft;
// The information in this struct is protected by the IF send lock,
// EXCEPT as noted.
//
struct
{
// Singly-linked list of Route Cache Entries (no space in RCE to hold
// a doubly-linked list, unfortunately.)
//
RouteCacheEntry *pRceList;
// listSendPkts is NOT protected by the IF send lock. Instead it is protected
// by this object(pRemoteIp)'s lock.
//
LIST_ENTRY listSendPkts;
// This entry is NOT protected by any lock. It is set to ZERO
// each time a packet is sent to this address and is set to the
// current system time periodically by the garbage collecting task.
//
UINT TimeLastChecked;
} sendinfo;
PRM_TASK pSendPktsTask;// Points to the task (if any)
// Attempting to send queued packets.
PRM_TASK pResolutionTask;// Points to the task (if any)
// attempting to resolve
// this destination IP address.
PRM_TASK pUnloadTask; // Unload (shutdown) this object.
} ARPCB_REMOTE_IP, *PARPCB_REMOTE_IP;
#define ASSERT_VALID_REMOTE_IP(_pRemoteIp) \
ASSERT((_pRemoteIp)->Hdr.Sig == MTAG_REMOTE_IP)
#define VALID_REMOTE_IP(_pRemoteIp) ((_pRemoteIp)->Hdr.Sig == MTAG_REMOTE_IP)
//
// --------------------- DESTINATION (REMOTE) ETHERNET CONTROL BLOCK --------------
// Creation Params -- passed into the function that creates an
// instance of a remote ethernet control block.
//
typedef struct
{
ENetAddr EthAddress;
IP_ADDRESS IpAddress;
} ARP_REMOTE_ETH_PARAMS, *PARP_REMOTE_ETH_PARAMS;
//
// Contains information about one destination (remote) Ethernet address.
//
// Parent Object: pInterface
// Lock: pInterface
//
// There is atmost one Ethernet Table entry for a given Remote ethernet address.
//
// The Ethernet entry participates in one group:
// A list of all entries that hash to the same bucket in the Ethernet Table
//
typedef struct _ARPCB_REMOTE_ETH
{
RM_OBJECT_HEADER Hdr; // Common header
IP_ADDRESS IpAddress; // Remote IP address
ENetAddr EthAddress; // Remote Ethernet MAC addres
PRM_TASK pUnloadTask; // Unload (shutdown) this object.
// This entry is NOT protected by any lock. It is set to ZERO
// each time a packet is sent to this address and is set to the
// current system time periodically by the garbage collecting task.
//
UINT TimeLastChecked;
} ARPCB_REMOTE_ETH, *PARPCB_REMOTE_ETH;
#define ASSERT_VALID_REMOTE_ETH(_pRemoteEth) \
ASSERT((_pRemoteEth)->Hdr.Sig == MTAG_REMOTE_ETH)
//
// ---------------------------- LOCAL IP CONTROL BLOCK --------------
//
// Contains information about one local IP address.
//
// Parent Object: pInterface
// Lock: uses parent's (pInterface's) lock.
//
typedef struct _ARPCB_LOCAL_IP
{
RM_OBJECT_HEADER Hdr; // Common header
//
// State flags for LocalIp (in Hdr.State)
//
#define ARPLOCALIP_MCAP_MASK 0x40
#define ARPLOCALIP_MCAP_CAPABLE 0x40
#define SET_LOCALIP_MCAP(_pLIp, _IfState) \
RM_SET_STATE(_pLIp, ARPLOCALIP_MCAP_MASK, _IfState)
#define CHECK_LOCALIP_MCAP(_pLIp, _IfState) \
RM_CHECK_STATE(_pLIp, ARPLOCALIP_MCAP_MASK, _IfState)
UINT IpAddressType; // One of the LLIP_ADDR_* consts
IP_ADDRESS IpAddress; // The Address
IP_MASK IpMask; // Mask for the above.
UINT AddAddressCount; // No of times address was added
PRM_TASK pRegistrationTask; // Points to the task (if any)
// that is doing the unsolicited
// ARP request to report and
// validate this IP address is
// owned by the local interface.
PRM_TASK pUnloadTask; // Unload (shutdown) this object.
LIST_ENTRY linkSameDest; // List of entries pointing to
ARPCB_DEST *pDest; // Pointer to destination CB.
} ARPCB_LOCAL_IP, *PARPCB_LOCAL_IP;
// Returns true IFF pLocalIp is in the process of going away (assumes
// pLocalIp's lock is held) ...
//
#define ARP_LOCAL_IP_IS_UNLOADING(pLocalIp) (pLocalIp->pUnloadTask != NULL)
typedef struct
{
NIC1394_DESTINATION HwAddr; // Must be 1st for hash function.
UINT ChannelSeqNo;
BOOLEAN ReceiveOnly;
BOOLEAN AcquireChannel;
} ARP_DEST_PARAMS, *PARP_DEST_PARAMS;
//
// ---------------------------- DESTINATION CONTROL BLOCK --------------
//
// All information about an remote destination, including list of VCs to it.
// This is used for both unicast destinations and multicast/broadcast
// destinations.
//
// Parent Object: PARCB_INTERFACE (Interface control block).
// Lock: uses parent's (Interface).
//
typedef struct _ARPCB_DEST
{
RM_OBJECT_HEADER Hdr; // Common header
LIST_ENTRY listIpToThisDest; // List of IP entries that
// point to this entry
LIST_ENTRY listLocalIp; // List of local IP entries
// related to this dest. that
// (Currently only related to
// MCAP recv channels, but
// could be extended to
// using async stream for
// FIFO as well!).
ARP_DEST_PARAMS Params; // Dest HW Address, etc.
ARP_VC_HEADER VcHdr; // Single VC associated
// with this object.
PRM_TASK pUnloadTask; // Unload (shutdown) this object.
// The following structure is protected by the IF send lock.
// It contains all the information required for the fast send path.
//
struct
{
PRM_TASK pSuspendedCleanupCallTask;
UINT NumOutstandingSends;
BOOLEAN OkToSend;
BOOLEAN IsFifo;
} sendinfo;
#define ARP_DEST_IS_FIFO(_pDest) ((_pDest)->sendinfo.IsFifo != 0)
#define ARP_CAN_SEND_ON_DEST(_pDest) ((_pDest)->sendinfo.OkToSend != 0)
} ARPCB_DEST, *PARPCB_DEST;
#define ARP_OBJECT_IS_DEST(_pHdr) ((_pHdr)->Sig == MTAG_DEST)
#define ASSERT_VALID_DEST(_pDest) \
ASSERTEX((_pDest)->Hdr.Sig == MTAG_DEST, (_pDest))
#if OBSOLETE
//
// ---------------------------- RECV CHANNEL CONTROL BLOCK --------------
//
// All information about a receive channel destination.
//
// Parent Object: PARCB_INTERFACE (Interface control block).
// Lock: uses parent's (Interface).
//
typedef struct _ARPCB_RCVCH
{
RM_OBJECT_HEADER Hdr; // Common header
LIST_ENTRY listLIpToThisDest; // List of Local IP entries
// that point to this entry
NIC1394_DESTINATION HwAddr; // Destination HW Address.
ARP_VC_HEADER VcHdr; // Single VC associated
// with this object.
PRM_TASK pUnloadTask; // Unload (shutdown) this object.
} ARPCB_DEST, *PARPCB_RCVCH;
#endif // OBSOLETE
// Following sits in the miniport-reserved portion of send-pkts, before they
// are sent out. We have 4 UINT_PTRs of space available to us.
//
typedef struct
{
LIST_ENTRY linkQueue;
union
{
struct
{
IP_ADDRESS IpAddress;
ULONG Flags;
#define ARPSPI_BACKFILLED 0x1
#define ARPSPI_HEADBUF 0x2
#define ARPSPI_FIFOPKT 0x4
#define ARPSPI_CHANNELPKT 0x8
} IpXmit;
};
} ARP_SEND_PKT_MPR_INFO;
//
// Various macros for getting and setting information saved in the
// MiniportReserved portion of packets waiting to be sent...
//
#define ARP_OUR_CTXT_FROM_SEND_PACKET(_pPkt) \
((ARP_SEND_PKT_MPR_INFO *) &(_pPkt)->MiniportReserved)
#define ARP_SEND_PKT_FROM_OUR_CTXT(_pCtxt) \
CONTAINING_RECORD((_pCtxt), NDIS_PACKET, MiniportReserved)
// Our context in the IP RouteCacheEntry.
// (Max 2 UINT_PTRs available)
// Since we also want to keep the destination type (FIFO or CHANNEL) in the RCE,
// we resort to the questionable technique of saving the FIFO/CHANNEL info in
// LSB bit of the UINT_PTR used for storing the pointer to the RemoteIp object.
// We want to keep the FIFO/CHANNEL info in the RCE so that we can prepend
// the correct header block WITHOUT holding the send lock. We want to keep
// the send lock held for as little time as possible.
//
typedef struct
{
ARPCB_REMOTE_IP *pRemoteIp; // Ptr to pRemoteIp
RouteCacheEntry *pNextRce; // Ptr to next RCE associated with the above
// RemoteIP
} ARP_RCE_CONTEXT;
#define ARP_OUR_CTXT_FROM_RCE(_pRCE) \
((ARP_RCE_CONTEXT*) &(_pRCE)->rce_context)
// Parsed version of the IP/1394 ARP packet.
//
typedef struct
{
NIC1394_FIFO_ADDRESS SenderHwAddr; // requires 8-byte alignment.
UINT OpCode;
UINT SenderMaxRec;
UINT SenderMaxSpeedCode;
IP_ADDRESS SenderIpAddress;
IP_ADDRESS TargetIpAddress;
UCHAR SourceNodeAdddress;
UCHAR fPktHasNodeAddress;
ENetAddr SourceMacAddress;
} IP1394_ARP_PKT_INFO, *PIP1394_ARP_PKT_INFO;
// Parsed version of the IP/1394 MCAP Group Descriptor
//
typedef struct
{
UINT Expiration;
UINT Channel;
UINT SpeedCode;
IP_ADDRESS GroupAddress;
} IP1394_MCAP_GD_INFO, * PIP1394_MCAP_GD_INFO;
// Parsed version of an IP/1394 MCAP packet.
//
typedef struct
{
UINT SenderNodeID;
UINT OpCode;
UINT NumGroups;
PIP1394_MCAP_GD_INFO pGdis;
// Space for storing up-to 4 GD_INFOs
//
IP1394_MCAP_GD_INFO GdiSpace[4];
} IP1394_MCAP_PKT_INFO, *PIP1394_MCAP_PKT_INFO;
typedef struct _EUID_NODE_MAC_TABLE_WORKITEM
{
// WorkItem used in the request
NDIS_WORK_ITEM WorkItem;
} EUID_NODE_MAC_TABLE_WORKITEM, *PEUID_NODE_MAC_TABLE_WORKITEM;
typedef struct _ARP1394_WORK_ITEM ARP1394_WORK_ITEM, *PARP1394_WORK_ITEM;
typedef
NDIS_STATUS
(*ARP_WORK_ITEM_PROC)(
struct _ARP1394_WORK_ITEM*,
PRM_OBJECT_HEADER,
PRM_STACK_RECORD
);
typedef struct _ARP1394_WORK_ITEM
{
union
{
EUID_TOPOLOGY Euid;
NDIS_WORK_ITEM NdisWorkItem;
} u;
ARP_WORK_ITEM_PROC pFunc;
} ARP1394_WORK_ITEM, *PARP1394_WORK_ITEM;
// Structure to express the information carried in an IP header
typedef struct _ARP_IP_HEADER_INFO
{
UCHAR protocol;
IP_ADDRESS ipSource, ipTarget;
USHORT headerSize;
ULONG IpHeaderOffset;
ULONG IpPktLength;
} ARP_IP_HEADER_INFO, *PARP_IP_HEADER_INFO;
//=========================================================================
// I N T E R N A L P R O T O T Y P E S
//=========================================================================
NTSTATUS
ArpDeviceIoControl(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
);
NTSTATUS
ArpWmiDispatch(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
);
NTSTATUS
ArpHandleIoctlRequest(
IN PIRP pIrp,
IN PIO_STACK_LOCATION pIrpSp
);
NDIS_STATUS
arpCfgGetInterfaceConfiguration(
IN ARP1394_INTERFACE * pIF,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpCfgReadAdapterConfiguration(
IN ARP1394_ADAPTER * pAdapter,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpCfgReadInterfaceConfiguration(
IN NDIS_HANDLE InterfaceConfigHandle,
IN ARP1394_INTERFACE * pF,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpAllocateTask(
IN PRM_OBJECT_HEADER pParentObject,
IN PFN_RM_TASK_HANDLER pfnHandler,
IN UINT Timeout,
IN const char * szDescription, OPTIONAL
OUT PRM_TASK *ppTask,
IN PRM_STACK_RECORD pSR
);
VOID
arpFreeTask(
IN PRM_TASK pTask,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskInitInterface(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskDeinitInterface(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskReinitInterface(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskActivateInterface(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskDeactivateInterface(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskMakeRecvFifoCall(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskCleanupRecvFifoCall(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskMakeCallToDest(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskCleanupCallToDest(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskResolveIpAddress(
IN struct _RM_TASK * pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
PRM_OBJECT_HEADER
arpAdapterCreate(
PRM_OBJECT_HEADER pParentObject,
PVOID pCreateParams,
PRM_STACK_RECORD psr
);
VOID
arpDeinitIf(
PARP1394_INTERFACE pIF,
PRM_TASK pCallingTask, // OPTIONAL
UINT SuspendCode, // OPTIONAL
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskUnloadLocalIp(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskUnloadRemoteIp(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskUnloadRemoteEth(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskUnloadDestination(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
VOID
arpObjectDelete (
PRM_OBJECT_HEADER pObj,
PRM_STACK_RECORD psr
);
VOID
arpAdapterDelete (
PRM_OBJECT_HEADER pObj,
PRM_STACK_RECORD psr
);
NDIS_STATUS
arpCopyUnicodeString(
OUT PNDIS_STRING pDest,
IN PNDIS_STRING pSrc,
BOOLEAN fUpCase
);
NDIS_STATUS
arpTaskInitializeAdapter(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskShutdownAdapter(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskActivateAdapter(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskDeactivateAdapter(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskInterfaceTimer(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskInterfaceTimer(
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
#if TEST_ICS_HACK
NDIS_STATUS
arpTaskDoIcsTest(
IN struct _RM_TASK * pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
#endif // TEST_ICS_HACK
NDIS_STATUS
arpTaskIfMaintenance(
IN struct _RM_TASK * pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpInitializeConstBufferPool(
IN UINT NumBuffersToCache,
IN UINT MaxBuffers,
IN const VOID* pvMem,
IN UINT cbMem,
IN PRM_OBJECT_HEADER pOwningObject,
IN OUT ARP_CONST_BUFFER_POOL * pHdrPool,
IN PRM_STACK_RECORD pSR
);
VOID
arpDeinitializeConstBufferPool(
IN ARP_CONST_BUFFER_POOL * pHdrPool,
IN PRM_STACK_RECORD pSR
);
PNDIS_BUFFER
arpAllocateConstBuffer(
ARP_CONST_BUFFER_POOL * pHdrPool
);
VOID
arpDeallocateConstBuffer(
ARP_CONST_BUFFER_POOL * pHdrPool,
PNDIS_BUFFER pNdisBuffer
);
VOID
arpCompleteSentPkt(
IN NDIS_STATUS Status,
IN ARP1394_INTERFACE * pIF,
IN ARPCB_DEST * pDest,
IN PNDIS_PACKET pNdisPacket
);
NDIS_STATUS
arpParseArpPkt(
IN PIP1394_ARP_PKT pArpPkt,
IN UINT cbBufferSize,
OUT PIP1394_ARP_PKT_INFO pPktInfo
);
VOID
arpPrepareArpPkt(
IN PIP1394_ARP_PKT_INFO pArpPktInfo,
// IN UINT SenderMaxRec,
OUT PIP1394_ARP_PKT pArpPkt
);
NDIS_STATUS
arpPrepareArpResponse(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PIP1394_ARP_PKT_INFO pArpRequest,
OUT PIP1394_ARP_PKT_INFO pArpResponse,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpAddOneStaticArpEntry(
IN PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
IN IP_ADDRESS IpAddress,
IN PNIC1394_FIFO_ADDRESS pFifoAddr,
IN PRM_STACK_RECORD pSR
);
VOID
arpSetPrimaryIfTask(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG PrimaryState,
PRM_STACK_RECORD pSR
);
VOID
arpClearPrimaryIfTask(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG PrimaryState,
PRM_STACK_RECORD pSR
);
VOID
arpSetSecondaryIfTask(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG SecondaryState,
PRM_STACK_RECORD pSR
);
VOID
arpClearSecondaryIfTask(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG SecondaryState,
PRM_STACK_RECORD pSR
);
VOID
arpSetPrimaryAdapterTask(
PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG PrimaryState,
PRM_STACK_RECORD pSR
);
VOID
arpClearPrimaryAdapterTask(
PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG PrimaryState,
PRM_STACK_RECORD pSR
);
VOID
arpSetSecondaryAdapterTask(
PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG SecondaryState,
PRM_STACK_RECORD pSR
);
VOID
arpClearSecondaryAdapterTask(
PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT
PRM_TASK pTask,
ULONG SecondaryState,
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTryReconfigureIf(
PARP1394_INTERFACE pIF,
PNET_PNP_EVENT pNetPnPEvent,
PRM_STACK_RECORD pSR
);
VOID
arpResetIfStats(
IN PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
IN PRM_STACK_RECORD pSR
);
VOID
arpGetPktCountBins(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PNDIS_PACKET pNdisPacket,
OUT PULONG pSizeBin,
OUT PULONG pTimeBin
);
VOID
arpLogSendFifoCounts(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PNDIS_PACKET pNdisPacket,
IN NDIS_STATUS Status
);
VOID
arpLogRecvFifoCounts(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PNDIS_PACKET pNdisPacket
);
VOID
arpLogSendChannelCounts(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PNDIS_PACKET pNdisPacket,
IN NDIS_STATUS Status
);
VOID
arpLogRecvChannelCounts(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PNDIS_PACKET pNdisPacket
);
NDIS_STATUS
arpInitializeVc(
PARP1394_INTERFACE pIF,
PARP_STATIC_VC_INFO pVcInfo,
PRM_OBJECT_HEADER pOwner,
PARP_VC_HEADER pVcHdr,
PRM_STACK_RECORD pSR
);
VOID
arpDeinitializeVc(
PARP1394_INTERFACE pIF,
PARP_VC_HEADER pVcHdr,
PRM_OBJECT_HEADER pOwner, // NOLOCKIN NOLOCKOUT
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpAllocateControlPacketPool(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
UINT MaxBufferSize,
PRM_STACK_RECORD pSR
);
VOID
arpFreeControlPacketPool(
PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpAllocateControlPacket(
IN PARP1394_INTERFACE pIF,
IN UINT cbBufferSize,
IN UINT PktFlags,
OUT PNDIS_PACKET *ppNdisPacket,
OUT PVOID *ppvData,
PRM_STACK_RECORD pSR
);
VOID
arpFreeControlPacket(
PARP1394_INTERFACE pIF,
PNDIS_PACKET pNdisPacket,
PRM_STACK_RECORD pSR
);
VOID
arpRefSendPkt(
PNDIS_PACKET pNdisPacket,
PARPCB_DEST pDest
);
VOID
arpProcessArpPkt(
PARP1394_INTERFACE pIF,
PIP1394_ARP_PKT pArpPkt,
UINT cbBufferSize
);
VOID
arpProcessMcapPkt(
PARP1394_INTERFACE pIF,
PIP1394_MCAP_PKT pMcapPkt,
UINT cbBufferSize
);
VOID
arpLinkRemoteIpToDest(
ARPCB_REMOTE_IP *pRemoteIp,
ARPCB_DEST *pDest,
PRM_STACK_RECORD pSR
);
VOID
arpUnlinkRemoteIpFromDest(
ARPCB_REMOTE_IP *pRemoteIp, // LOCKIN LOCKOUT
PRM_STACK_RECORD pSR
);
VOID
arpUnlinkAllRemoteIpsFromDest(
ARPCB_DEST *pDest, // LOCKIN LOCKOUT
PRM_STACK_RECORD pSR
);
VOID
arpLinkLocalIpToDest(
ARPCB_LOCAL_IP * pLocalIp,
ARPCB_DEST *pDest,
PRM_STACK_RECORD pSR
);
VOID
arpUnlinkLocalIpFromDest(
ARPCB_LOCAL_IP *pLocalIp, // LOCKIN LOCKOUT
PRM_STACK_RECORD pSR
);
VOID
arpUnlinkAllLocalIpsFromDest(
ARPCB_DEST *pDest, // LOCKIN LOCKOUT
PRM_STACK_RECORD pSR
);
#if 0
NDIS_STATUS
arpCopyAnsiStringToUnicodeString(
OUT PNDIS_STRING pDest,
IN PANSI_STRING pSrc
);
NDIS_STATUS
arpCopyUnicodeStringToAnsiString(
OUT PANSI_STRING pDest,
IN PNDIS_STRING pSrc
);
#endif // 0
VOID
arpUpdateReceiveMultichannels(
PARP1394_INTERFACE pIF,
UINT SecondsSinceLastCall,
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpPrepareAndSendNdisRequest(
IN PARP1394_ADAPTER pAdapter,
IN PARP_NDIS_REQUEST pArpNdisRequest,
IN PRM_TASK pTask, // OPTIONAL
IN UINT PendCode,
IN NDIS_OID Oid,
IN PVOID pBuffer,
IN ULONG BufferLength,
IN NDIS_REQUEST_TYPE RequestType,
IN PRM_STACK_RECORD pSR
);
typedef enum
{
ARP_ICS_FORWARD_TO_1394,
ARP_ICS_FORWARD_TO_ETHERNET,
} ARP_ICS_FORWARD_DIRECTION;
#if TEST_ICS_HACK
VOID
arpEthSendComplete(
IN ARP1394_ADAPTER * pAdapter,
IN PNDIS_PACKET pNdisPacket,
IN NDIS_STATUS Status
);
NDIS_STATUS
arpEthReceive(
ARP1394_ADAPTER * pAdapter,
NDIS_HANDLE Context,
VOID *Header,
UINT HeaderSize,
VOID *Data,
UINT Size,
UINT TotalSize
);
#endif // TEST_ICS_HACK
VOID
arpEthReceivePacket(
ARP1394_INTERFACE * pIF,
PNDIS_PACKET Packet
);
NDIS_STATUS
arpAllocateEthernetPools(
IN PARP1394_INTERFACE pIF,
IN PRM_STACK_RECORD pSR
);
VOID
arpFreeEthernetPools(
IN PARP1394_INTERFACE pIF,
IN PRM_STACK_RECORD pSR
);
#if TEST_ICS_HACK
VOID
arpDbgStartIcsTest(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
PRM_STACK_RECORD pSR
);
VOID
arpDbgTryStopIcsTest(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
PRM_STACK_RECORD pSR
);
#endif // TEST_ICS_HACK
VOID
arpDbgIncrementReentrancy(
PLONG pReentrancyCount
);
VOID
arpDbgDecrementReentrancy(
PLONG pReentrancyCount
);
VOID
arpHandleControlPktSendCompletion(
IN ARP1394_INTERFACE * pIF,
IN PNDIS_PACKET pNdisPacket
);
VOID
arpStartIfMaintenanceTask(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTryStopIfMaintenanceTask(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PRM_TASK pTask, // task to pend until M task completes
IN UINT PendCode, // Pend code to suspend task.
PRM_STACK_RECORD pSR
);
UINT
arpGetSystemTime(VOID);
BOOLEAN
arpCanTryMcap(
IP_ADDRESS IpAddress
);
UINT
arpFindAssignedChannel(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN IP_ADDRESS IpAddress,
IN UINT CurrentTime,
PRM_STACK_RECORD pSR
);
VOID
arpUpdateRemoteIpDest(
IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IN PARPCB_REMOTE_IP pRemoteIp,
IN PARP_DEST_PARAMS pDestParams,
PRM_STACK_RECORD pSR
);
MYBOOL
arpIsActiveMcapChannel(
PMCAP_CHANNEL_INFO pMci,
UINT CurrentTime
);
VOID
arpSendControlPkt(
IN ARP1394_INTERFACE * pIF, // LOCKIN NOLOCKOUT (IF send lk)
IN PNDIS_PACKET pNdisPacket,
IN PARPCB_DEST pDest,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpCreateMcapPkt(
IN PARP1394_INTERFACE pIF,
IN PIP1394_MCAP_PKT_INFO pPktInfo,
OUT PNDIS_PACKET *ppNdisPacket,
PRM_STACK_RECORD pSR
);
UINT
arpProcessReceivedPacket(
IN PARP1394_INTERFACE pIF,
IN PNDIS_PACKET pNdisPacket,
IN MYBOOL IsChannel
);
VOID
arpUpdateArpCache(
PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
IP_ADDRESS RemoteIpAddress,
ENetAddr *pRemoteEthAddress,
PARP_DEST_PARAMS pDestParams,
MYBOOL fCreateIfRequired,
PRM_STACK_RECORD pSR
);
UINT
arpEthernetReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE ProtocolVcContext,
IN PNDIS_PACKET pNdisPacket
);
VOID
arpEthReceive1394Packet(
IN PARP1394_INTERFACE pIF,
IN PNDIS_PACKET pNdisPacket,
IN PVOID pvHeader,
IN UINT HeaderSize,
IN MYBOOL IsChannel
);
NDIS_STATUS
arpSlowIpTransmit(
IN ARP1394_INTERFACE * pIF,
IN PNDIS_PACKET pNdisPacket,
IN REMOTE_DEST_KEY Destination,
IN RouteCacheEntry * pRCE OPTIONAL
);
VOID
arpDelRceList(
IN PARPCB_REMOTE_IP pRemoteIp, // IF send lock WRITELOCKIN WRITELOCKOUTD
IN PRM_STACK_RECORD pSR
);
VOID
arpGenericWorkItem(
struct _NDIS_WORK_ITEM * pWorkItem,
PVOID pContext
);
VOID
arpQueueWorkItem (
PARP1394_WORK_ITEM pWorkItem,
ARP_WORK_ITEM_PROC pFunc,
PRM_OBJECT_HEADER pHdr,
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpGetEuidTopology (
IN PARP1394_ADAPTER pAdapter,
PRM_STACK_RECORD pSR
);
VOID
arpNdProcessBusReset(
IN PARP1394_ADAPTER pAdapter
);
NDIS_STATUS
arpAddIpAddressToRemoteIp (
PARPCB_REMOTE_IP pRemoteIp,
PNDIS_PACKET pNdisPacket
);
VOID
arpReturnBackupTask (
IN ARP1394_TASK* pTask
);
VOID
arpAllocateBackupTasks (
ARP1394_GLOBALS* pGlobals
);
VOID
arpFreeBackupTasks (
ARP1394_GLOBALS* pGlobals
);
ARP1394_TASK *
arpGetBackupTask (
IN ARP1394_GLOBALS* pGlobals
);
NTSTATUS
arpDelArpEntry(
PARP1394_INTERFACE pIF,
IPAddr IpAddress,
PRM_STACK_RECORD pSR
);
VOID
arpAddBackupTasks (
IN ARP1394_GLOBALS* pGlobals,
UINT Num
);
VOID
arpRemoveBackupTasks (
IN ARP1394_GLOBALS* pGlobals,
UINT Num
);
MYBOOL
arpNeedToCleanupDestVc(
ARPCB_DEST *pDest // LOCKING LOCKOUT
);
VOID
arpLowPowerCloseAllCalls (
ARP1394_INTERFACE *pIF,
PRM_STACK_RECORD pSR
);
VOID
arpDeactivateIf(
PARP1394_INTERFACE pIF,
PRM_TASK pCallingTask, // OPTIONAL
UINT SuspendCode, // OPTIONAL
PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskLowPower(
IN struct _RM_TASK * pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpSetupSpecialDest(
IN PARP1394_INTERFACE pIF,
IN NIC1394_ADDRESS_TYPE AddressType,
IN PRM_TASK pParentTask,
IN UINT PendCode,
OUT PARPCB_DEST * ppSpecialDest,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpResume (
IN ARP1394_ADAPTER* pAdapter,
IN ARP_RESUME_CAUSE Cause,
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpTaskOnPower (
IN PRM_TASK pTask,
IN RM_TASK_OPERATION Code,
IN UINT_PTR UserParam, // Unused
IN PRM_STACK_RECORD pSR
);
NDIS_STATUS
arpMakeCallOnDest(
IN PARPCB_REMOTE_IP pRemoteIp,
IN PARPCB_DEST pDest,
IN PRM_TASK pTaskToPend,
IN ULONG PEND_StageMakeCallComplete,
IN PRM_STACK_RECORD pSR
);
//=========================================================================
// G L O B A L D A T A
//=========================================================================
extern
RM_STATIC_OBJECT_INFO
ArpGlobals_AdapterStaticInfo;
extern const
NIC1394_ENCAPSULATION_HEADER
Arp1394_IpEncapHeader;
// Warning -- FAIL(NDIS_STATUS_PENDING) == TRUE
//
#define FAIL(_Status) ((_Status) != NDIS_STATUS_SUCCESS)
#define PEND(_Status) ((_Status) == NDIS_STATUS_PENDING)
#if RM_EXTRA_CHECKING
#define LOCKHDR(_pHdr, _psr) \
RmWriteLockObject((_pHdr), dbg_func_locid, (_psr))
#else // !RM_EXTRA_CHECKING
#define LOCKHDR(_pHdr, _psr) \
RmWriteLockObject((_pHdr), (_psr))
#endif // !RM_EXTRA_CHECKING
#define LOCKOBJ(_pObj, _psr) \
LOCKHDR(&(_pObj)->Hdr, (_psr))
#define UNLOCKHDR(_pHdr, _psr) \
RmUnlockObject((_pHdr), (_psr))
#define UNLOCKOBJ(_pObj, _psr) \
UNLOCKHDR(&(_pObj)->Hdr, (_psr))
#define ARP_ALLOCSTRUCT(_p, _tag) \
NdisAllocateMemoryWithTag(&(_p), sizeof(*(_p)), (_tag))
#define ARP_FREE(_p) NdisFreeMemory((_p), 0, 0)
#define ARP_ZEROSTRUCT(_p) \
NdisZeroMemory((_p), sizeof(*(_p)))
#define ARRAY_LENGTH(_array) (sizeof(_array)/sizeof((_array)[0]))
#if RM_EXTRA_CHECKING
#define DBG_ADDASSOC(_phdr, _e1, _e2, _assoc, _fmt, _psr)\
RmDbgAddAssociation( \
dbg_func_locid, \
(_phdr), \
(UINT_PTR) (_e1), \
(UINT_PTR) (_e2), \
(_assoc), \
(_fmt), \
(_psr) \
)
#define DBG_DELASSOC(_phdr, _e1, _e2, _assoc, _psr) \
RmDbgDeleteAssociation( \
dbg_func_locid, \
(_phdr), \
(UINT_PTR) (_e1), \
(UINT_PTR) (_e2), \
(_assoc), \
(_psr) \
)
// (debug only) Enumeration of types of associations.
//
enum
{
ARPASSOC_IP_OPEN, // IP has called ArpIpOpen
ARPASSOC_LINK_IPADDR_OF_DEST,
ARPASSOC_LINK_DEST_OF_IPADDR,
ARPASSOC_LOCALIP_UNLOAD_TASK,
ARPASSOC_REMOTEIP_UNLOAD_TASK,
ARPASSOC_REMOTEETH_UNLOAD_TASK,
ARPASSOC_DEST_UNLOAD_TASK,
ARPASSOC_CBUFPOOL_ALLOC,
ARPASSOC_EXTLINK_DEST_TO_PKT,
ARPASSOC_EXTLINK_RIP_TO_RCE,
ARPASSOC_EXTLINK_TO_NDISVCHANDLE,
ARPASSOC_REMOTEIP_SENDPKTS_TASK,
ARPASSOC_IF_MAKECALL_TASK,
ARPASSOC_IF_CLEANUPCALL_TASK,
ARPASSOC_DEST_MAKECALL_TASK,
ARPASSOC_DEST_CLEANUPCALL_TASK,
ARPASSOC_DEST_CLEANUPCALLTASK_WAITING_ON_SENDS,
ARPASSOC_PKTS_QUEUED_ON_REMOTEIP,
ARPASSOC_PRIMARY_IF_TASK,
ARPASSOC_ACTDEACT_IF_TASK,
ARPASSOC_IF_OPENAF,
ARPASSOC_PRIMARY_AD_TASK,
ARPASSOC_ACTDEACT_AD_TASK,
ARPASSOC_LINK_IF_OF_BCDEST,
ARPASSOC_LINK_BCDEST_OF_IF,
ARPASSOC_IF_PROTOPKTPOOL,
ARPASSOC_IF_PROTOBUFPOOL,
ARPASSOC_RESOLUTION_IF_TASK,
ARPASSOC_LINK_IF_OF_MCDEST,
ARPASSOC_LINK_MCDEST_OF_IF,
ARPASSOC_LINK_IF_OF_ETHDEST,
ARPASSOC_LINK_ETHDEST_OF_IF,
ARPASSOC_IF_ETHPKTPOOL,
ARPASSOC_IF_ETHBUFPOOL,
ARPASSOC_ETH_SEND_PACKET,
ARPASSOC_IF_MAINTENANCE_TASK,
ARPASSOC_WORK_ITEM,
ARPASSOC_ETHDHCP_UNLOAD_TASK,
ARPASSOC_REMOTEIP_RESOLVE_TASK,
ARPASSOC_TASK_TO_RESOLVE_REMOTEIP
};
#else // !RM_EXTRA_CHECKING
#define DBG_ADDASSOC(_phdr, _e1, _e2, _assoc, _fmt, _psr) (0)
#define DBG_DELASSOC(_phdr, _e1, _e2, _assoc, _psr) (0)
#endif // !RM_EXTRA_CHECKING
#define ARPDBG_REF_EVERY_PACKET 1
#define ARPDBG_REF_EVERY_RCE 1
// USHORT
// SWAPBYTES_USHORT(USHORT Val )
//
#define SWAPBYTES_USHORT(Val) \
((((Val) & 0xff) << 8) | (((Val) & 0xff00) >> 8))
// ULONG
// SWAPBYTES_ULONG(ULONG Val )
//
#define SWAPBYTES_ULONG(Val) \
((((Val) & 0x000000ff) << 24) | \
(((Val) & 0x0000ff00) << 8) | \
(((Val) & 0x00ff0000) >> 8) | \
(((Val) & 0xff000000) >> 24) )
#define N2H_USHORT(Val) SWAPBYTES_USHORT(Val)
#define H2N_USHORT(Val) SWAPBYTES_USHORT(Val)
#define N2H_ULONG(Val) SWAPBYTES_ULONG(Val)
#define H2N_ULONG(Val) SWAPBYTES_ULONG(Val)
#define ARP_ATPASSIVE() (KeGetCurrentIrql()==PASSIVE_LEVEL)
#define LOGSTATS_NoCopyRecvs(_pIF, _pNdisPacket) \
NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.NoCopyRecvs))
#define LOGSTATS_CopyRecvs(_pIF, _pNdisPacket) \
NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.CopyRecvs))
#define LOGSTATS_ResourceRecvs(_pIF, _pNdisPacket) \
NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.ResourceRecvs))
#define LOGSTATS_TotRecvs(_pIF, _pNdisPacket) \
NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.TotRecvs))
#define LOGSTATS_RecvFifoCounts(_pIF, _pNdisPacket) \
arpLogRecvFifoCounts(_pIF, _pNdisPacket)
#define LOGSTATS_RecvChannelCounts(_pIF, _pNdisPacket) \
arpLogRecvChannelCounts(_pIF, _pNdisPacket)
#define LOGSTATS_TotalSendFifoMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.TotalSendFifoMakeCalls))
#define LOGSTATS_SuccessfulSendFifoMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.SuccessfulSendFifoMakeCalls))
#define LOGSTATS_FailedSendFifoMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.FailedSendFifoMakeCalls))
#define LOGSTATS_IncomingClosesOnSendFifos(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.IncomingClosesOnSendFifos))
#define LOGSTATS_TotalChannelMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.TotalChannelMakeCalls))
#define LOGSTATS_SuccessfulChannelMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.SuccessfulChannelMakeCalls))
#define LOGSTATS_FailedChannelMakeCalls(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.FailedChannelMakeCalls))
#define LOGSTATS_IncomingClosesOnChannels(_pIF) \
NdisInterlockedIncrement(&((_pIF)->stats.calls.IncomingClosesOnChannels))
#define IF_FROM_LOCALIP(_pLIp) \
(PARP1394_INTERFACE) RM_PARENT_OBJECT(_pLIp)
#define IF_FROM_REMOTEIP(_pRIp) \
(PARP1394_INTERFACE) RM_PARENT_OBJECT(_pRIp)
#define IF_FROM_DEST(_pDest) \
(PARP1394_INTERFACE) RM_PARENT_OBJECT(_pDest)
#if RM_EXTRA_CHECKING
#define OBJLOG0(_pObj, _szFmt) \
RmDbgLogToObject( \
&(_pObj)->Hdr, \
NULL, (_szFmt), \
0, 0, 0, 0, NULL, NULL \
)
#define OBJLOG1(_pObj, _szFmt, _P1) \
RmDbgLogToObject( \
&(_pObj)->Hdr, \
NULL, (_szFmt), \
(UINT_PTR) (_P1), \
0, 0, 0, NULL, NULL \
)
#define OBJLOG2(_pObj, _szFmt, _P1, _P2) \
RmDbgLogToObject( \
&(_pObj)->Hdr, \
NULL, (_szFmt), \
(UINT_PTR) (_P1), \
(UINT_PTR) (_P2), \
0, 0, NULL, NULL \
)
#else // !RM_EXTRA_CHECKING
#define OBJLOG0(_pObj, _szFmt) (0)
#define OBJLOG1(_pObj, _szFmt, _P1) (0)
#define OBJLOG2(_pObj, _szFmt, _P1, _P2) (0)
#endif // !RM_EXTRA_CHECKING
#if ARP_DO_TIMESTAMPS
void
arpTimeStamp(
char *szFormatString,
UINT Val
);
#define TIMESTAMPX(_FormatString) \
arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", 0)
#if ARP_DO_ALL_TIMESTAMPS
#define TIMESTAMP(_FormatString) \
arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", 0)
#define TIMESTAMP1(_FormatString, _Val) \
arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", (_Val))
#else
#define TIMESTAMP(_FormatString)
#define TIMESTAMP1(_FormatString, _Val)
#endif
#else // !ARP_DO_TIMESTAMPS
#define TIMESTAMP(_FormatString)
#define TIMESTAMPX(_FormatString)
#define TIMESTAMP1(_FormatString, _Val)
#endif // !ARP_DO_TIMESTAMPS