750 lines
18 KiB
C
750 lines
18 KiB
C
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "macros.h"
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoOpenAfComplete(
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_HANDLE ProtocolAfContext,
|
||
|
IN NDIS_HANDLE NdisAfHandle
|
||
|
)
|
||
|
{
|
||
|
ENTER("OpenAdapterComplete", 0x5d75dabd)
|
||
|
PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
|
||
|
PTASK_AF pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
|
||
|
RM_DECLARE_STACK_RECORD(sr)
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoOpenAfComplete Context %p Status %x AfHAndle %x",
|
||
|
pMiniport, Status, NdisAfHandle) );
|
||
|
|
||
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
//
|
||
|
// Store the Af Handle
|
||
|
//
|
||
|
|
||
|
if (NDIS_STATUS_SUCCESS == Status)
|
||
|
{
|
||
|
LOCKOBJ (pMiniport, &sr);
|
||
|
pMiniport->af.AfHandle = NdisAfHandle;
|
||
|
|
||
|
//
|
||
|
// Update variables on the miniport structure
|
||
|
// as this task has been given the go ahead
|
||
|
//
|
||
|
MiniportSetFlag (pMiniport, fMP_AddressFamilyOpened);
|
||
|
MiniportClearFlag (pMiniport, fMP_InfoAfClosed);
|
||
|
|
||
|
epvcLinkToExternal(
|
||
|
&pMiniport->Hdr, // pObject
|
||
|
0x5546d299,
|
||
|
(UINT_PTR)pMiniport->af.AfHandle , // Instance1
|
||
|
EPVC_ASSOC_MINIPORT_OPEN_AF, // AssociationID
|
||
|
" Open AF NdisHandle=%p\n",// szFormat
|
||
|
&sr
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
UNLOCKOBJ(pMiniport, &sr);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT (pMiniport->af.AfHandle == NULL);
|
||
|
|
||
|
pMiniport->af.AfHandle = NULL;
|
||
|
}
|
||
|
|
||
|
pAfTask ->ReturnStatus = Status;
|
||
|
|
||
|
//
|
||
|
// Add an association between
|
||
|
//
|
||
|
|
||
|
RmResumeTask (&pAfTask->TskHdr , 0, &sr);
|
||
|
RM_ASSERT_CLEAR(&sr);
|
||
|
|
||
|
EXIT();
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
epvcCoCloseAfCompleteWorkItem(
|
||
|
PRM_OBJECT_HEADER pObj,
|
||
|
NDIS_STATUS Status,
|
||
|
PRM_STACK_RECORD pSR
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Resuming the Af task
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
ENTER("epvcCoCloseAfCompleteWorkItem", 0xf6edfcb8)
|
||
|
PEPVC_I_MINIPORT pMiniport = NULL ;
|
||
|
PTASK_AF pAfTask = NULL;
|
||
|
|
||
|
|
||
|
pMiniport = (PEPVC_I_MINIPORT)pObj ;
|
||
|
|
||
|
LOCKOBJ (pMiniport, pSR);
|
||
|
MiniportSetFlag (pMiniport, fMP_InfoAfClosed);
|
||
|
UNLOCKOBJ (pMiniport, pSR);
|
||
|
|
||
|
pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
|
||
|
|
||
|
|
||
|
if (NDIS_STATUS_SUCCESS==Status )
|
||
|
{
|
||
|
LOCKOBJ (pMiniport, pSR);
|
||
|
|
||
|
epvcUnlinkFromExternal(
|
||
|
&pMiniport->Hdr, // pObject
|
||
|
0x5546d299,
|
||
|
(UINT_PTR)pMiniport->af.AfHandle , // Instance1
|
||
|
EPVC_ASSOC_MINIPORT_OPEN_AF, // AssociationID
|
||
|
pSR
|
||
|
);
|
||
|
|
||
|
pMiniport->af.AfHandle = NULL;
|
||
|
|
||
|
UNLOCKOBJ(pMiniport, pSR);
|
||
|
|
||
|
}
|
||
|
|
||
|
RmResumeTask (&pAfTask->TskHdr , 0, pSR);
|
||
|
|
||
|
EXIT();
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
EpvcCoCloseAfComplete(
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_HANDLE ProtocolAfContext
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Signifies that the AF has been closed.
|
||
|
Resume the Af task - through a workitem
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ENTER("EpvcCoCloseAfComplete ", 0x5d75dabd)
|
||
|
PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
|
||
|
PTASK_AF pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
|
||
|
RM_DECLARE_STACK_RECORD(sr)
|
||
|
|
||
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoCloseAfComplete Context %p Status %x ",
|
||
|
pMiniport, Status) );
|
||
|
|
||
|
//
|
||
|
// Store the Status
|
||
|
//
|
||
|
|
||
|
pAfTask->ReturnStatus = Status;
|
||
|
|
||
|
//
|
||
|
// Queue the WorkItem
|
||
|
//
|
||
|
epvcMiniportQueueWorkItem (
|
||
|
&pMiniport->af.CloseAfWorkItem,
|
||
|
pMiniport,
|
||
|
epvcCoCloseAfCompleteWorkItem,
|
||
|
Status,
|
||
|
&sr
|
||
|
);
|
||
|
|
||
|
EXIT();
|
||
|
RM_ASSERT_CLEAR(&sr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoMakeCallComplete(
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_HANDLE ProtocolVcContext,
|
||
|
IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
|
||
|
IN PCO_CALL_PARAMETERS pCallParameters
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This is a notification from Ndis that the Make Call has completed.
|
||
|
We need to pass the Status back to the original thread, so use the Vc
|
||
|
Task as a context
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
ENTER ("EpvcCoMakeCallComplete", 0x1716ee4b)
|
||
|
|
||
|
PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) ProtocolVcContext;
|
||
|
PTASK_VC pTaskVc = pMiniport->vc.pTaskVc;
|
||
|
|
||
|
RM_DECLARE_STACK_RECORD(SR);
|
||
|
|
||
|
//ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoMakeCallComplete Status %x", Status) );
|
||
|
|
||
|
pTaskVc->ReturnStatus = Status;
|
||
|
|
||
|
ASSERT (pCallParameters != NULL);
|
||
|
epvcFreeMemory (pCallParameters ,CALL_PARAMETER_SIZE, 0);
|
||
|
|
||
|
|
||
|
RmResumeTask (&pTaskVc->TskHdr, 0 , &SR);
|
||
|
|
||
|
EXIT();
|
||
|
RM_ASSERT_CLEAR(&SR);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
epvcCoCloseCallCompleteWorkItem(
|
||
|
PRM_OBJECT_HEADER pObj,
|
||
|
NDIS_STATUS Status,
|
||
|
PRM_STACK_RECORD pSR
|
||
|
)
|
||
|
{
|
||
|
ENTER ("EpvcCoCloseCallComplete", 0xbd67524a)
|
||
|
|
||
|
PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) pObj;
|
||
|
PTASK_VC pTaskVc = pMiniport->vc.pTaskVc;
|
||
|
|
||
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoCloseCallComplete") );
|
||
|
|
||
|
pTaskVc->ReturnStatus = Status;
|
||
|
|
||
|
RmResumeTask (&pTaskVc->TskHdr, 0 , pSR);
|
||
|
RM_ASSERT_CLEAR(pSR);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoCloseCallComplete(
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_HANDLE ProtocolVcContext,
|
||
|
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
ENTER ("EpvcCoCloseCallComplete", 0xbd67524a)
|
||
|
|
||
|
PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) ProtocolVcContext;
|
||
|
|
||
|
RM_DECLARE_STACK_RECORD(SR);
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoCloseCallComplete") );
|
||
|
|
||
|
epvcMiniportQueueWorkItem (&pMiniport->vc.CallVcWorkItem,
|
||
|
pMiniport,
|
||
|
epvcCoCloseCallCompleteWorkItem,
|
||
|
Status,
|
||
|
&SR
|
||
|
);
|
||
|
|
||
|
RM_ASSERT_CLEAR(&SR);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
EpvcCoIncomingCall(
|
||
|
IN NDIS_HANDLE ProtocolSapContext,
|
||
|
IN NDIS_HANDLE ProtocolVcContext,
|
||
|
IN OUT PCO_CALL_PARAMETERS CallParameters
|
||
|
)
|
||
|
{
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoIncomingCall") );
|
||
|
return NDIS_STATUS_FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoCallConnected(
|
||
|
IN NDIS_HANDLE ProtocolVcContext
|
||
|
)
|
||
|
{
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoCallConnected") );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoIncomingClose(
|
||
|
IN NDIS_STATUS CloseStatus,
|
||
|
IN NDIS_HANDLE ProtocolVcContext,
|
||
|
IN PVOID CloseData OPTIONAL,
|
||
|
IN UINT Size OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoIncomingClose") );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// CO_CREATE_VC_HANDLER and CO_DELETE_VC_HANDLER are synchronous calls
|
||
|
//
|
||
|
NDIS_STATUS
|
||
|
EpvcClientCreateVc(
|
||
|
IN NDIS_HANDLE ProtocolAfContext,
|
||
|
IN NDIS_HANDLE NdisVcHandle,
|
||
|
OUT PNDIS_HANDLE ProtocolVcContext
|
||
|
)
|
||
|
{
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcClientCreateVc") );
|
||
|
|
||
|
|
||
|
return NDIS_STATUS_FAILURE;
|
||
|
}
|
||
|
|
||
|
NDIS_STATUS
|
||
|
EpvcClientDeleteVc(
|
||
|
IN NDIS_HANDLE ProtocolVcContext
|
||
|
)
|
||
|
{
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcClientDeleteVc") );
|
||
|
return NDIS_STATUS_FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
EpvcCoRequest(
|
||
|
IN NDIS_HANDLE ProtocolAfContext,
|
||
|
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
|
||
|
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
|
||
|
IN OUT PNDIS_REQUEST pNdisRequest
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called by NDIS when our Call Manager sends us an
|
||
|
NDIS Request. NDIS Requests that are of significance to us are:
|
||
|
- OID_CO_ADDRESS_CHANGE
|
||
|
The set of addresses registered with the switch has changed,
|
||
|
i.e. address registration is complete. We issue an NDIS Request
|
||
|
ourselves to get the list of addresses registered.
|
||
|
- OID_CO_SIGNALING_ENABLED
|
||
|
We ignore this as of now.
|
||
|
TODO: Add code that uses this and the SIGNALING_DISABLED
|
||
|
OIDs to optimize on making calls.
|
||
|
- OID_CO_SIGNALING_DISABLED
|
||
|
We ignore this for now.
|
||
|
- OID_CO_AF_CLOSE
|
||
|
The Call manager wants us to shut down this AF open .
|
||
|
|
||
|
We ignore all other OIDs.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ProtocolAfContext - Our context for the Address Family binding,
|
||
|
which is a pointer to the ATMEPVC Interface.
|
||
|
ProtocolVcContext - Our context for a VC, which is a pointer to
|
||
|
an ATMEPVC VC structure.
|
||
|
ProtocolPartyContext - Our context for a Party. Since we don't do
|
||
|
PMP, this is ignored (must be NULL).
|
||
|
pNdisRequest - Pointer to the NDIS Request.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NDIS_STATUS_SUCCESS if we recognized the OID
|
||
|
NDIS_STATUS_NOT_RECOGNIZED if we didn't.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
ENTER("EpvcCoRequest",0xcc5aff85)
|
||
|
PEPVC_I_MINIPORT pMiniport;
|
||
|
NDIS_STATUS Status;
|
||
|
RM_DECLARE_STACK_RECORD (SR)
|
||
|
|
||
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
|
||
|
|
||
|
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" ==> EpvcCoRequest") );
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Initialize
|
||
|
//
|
||
|
Status = NDIS_STATUS_NOT_RECOGNIZED;
|
||
|
|
||
|
if (pNdisRequest->RequestType == NdisRequestSetInformation)
|
||
|
{
|
||
|
switch (pNdisRequest->DATA.SET_INFORMATION.Oid)
|
||
|
{
|
||
|
case OID_CO_ADDRESS_CHANGE:
|
||
|
TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_ADDRESS_CHANGE\n"));
|
||
|
//
|
||
|
// The Call Manager says that the list of addresses
|
||
|
// registered on this interface has changed. Get the
|
||
|
// (potentially) new ATM address for this interface.
|
||
|
Status = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
|
||
|
case OID_CO_SIGNALING_ENABLED:
|
||
|
TRACE (TL_I, TM_Cl, ("CoRequestHandler: CoRequestHandler: CO_SIGNALING_ENABLED\n"));
|
||
|
// ignored for now
|
||
|
Status = NDIS_STATUS_FAILURE;
|
||
|
break;
|
||
|
|
||
|
case OID_CO_SIGNALING_DISABLED:
|
||
|
TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_SIGNALING_DISABLEDn"));
|
||
|
// Ignored for now
|
||
|
Status = NDIS_STATUS_FAILURE;
|
||
|
break;
|
||
|
|
||
|
case OID_CO_AF_CLOSE:
|
||
|
TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_AF_CLOSE on MINIPORT %x\n", pMiniport));
|
||
|
|
||
|
Status = epvcProcessOidCloseAf(pMiniport, &SR);
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" <== EpvcCoRequest") );
|
||
|
RM_ASSERT_CLEAR(&SR)
|
||
|
EXIT()
|
||
|
return (Status);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EpvcCoRequestComplete(
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_HANDLE ProtocolAfContext OPTIONAL,
|
||
|
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
|
||
|
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
|
||
|
IN PNDIS_REQUEST pRequest
|
||
|
)
|
||
|
{
|
||
|
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, (" == EpvcCoRequest pRequest %x", pRequest) );
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
epvcPrepareAndSendNdisRequest(
|
||
|
IN PEPVC_ADAPTER pAdapter,
|
||
|
IN PEPVC_NDIS_REQUEST pEpvcNdisRequest,
|
||
|
IN REQUEST_COMPLETION pFunc, // OPTIONAL
|
||
|
IN NDIS_OID Oid,
|
||
|
IN PVOID pBuffer,
|
||
|
IN ULONG BufferLength,
|
||
|
IN NDIS_REQUEST_TYPE RequestType,
|
||
|
IN PEPVC_I_MINIPORT pMiniport, // OPTIONAL
|
||
|
IN BOOLEAN fPendedRequest, // OPTIONAL
|
||
|
IN BOOLEAN fPendedSet, // OPTIONAL
|
||
|
IN PRM_STACK_RECORD pSR
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Send an NDIS Request to query an adapter for information.
|
||
|
If the request pends, block on the EPVC Adapter structure
|
||
|
till it completes.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pAdapter - Points to EPVCAdapter structure
|
||
|
pNdisRequest - Pointer to UNITIALIZED NDIS request structure
|
||
|
pTask - OPTIONAL Task. If NULL, we block until the operation
|
||
|
completes.
|
||
|
PendCode - PendCode to suspend pTask
|
||
|
Oid - OID to be passed in the request
|
||
|
pBuffer - place for value(s)
|
||
|
BufferLength - length of above
|
||
|
pMiniport - Minport associated withe this request - OPTIONAL
|
||
|
fPendedRequest - A request was pended at the miniport - OPTIONAL
|
||
|
fPendedSet - Pended a Set Request - OPTIONAL
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The NDIS status of the request.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ENTER("epvcPrepareAndSendNdisRequest",0x1cc515d5)
|
||
|
|
||
|
NDIS_STATUS Status;
|
||
|
PNDIS_REQUEST pNdisRequest = &pEpvcNdisRequest->Request;
|
||
|
|
||
|
TRACE (TL_T, TM_Cl, ("==>epvcSendAdapterNdisRequest pAdapter %x, pRequest %x",
|
||
|
pAdapter, pNdisRequest));
|
||
|
|
||
|
//ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||
|
|
||
|
TRACE (TL_V, TM_Rq, ("Cl Requesting Adapter %x, Oid %x, Buffer %x, Length %x, pFunc %x",
|
||
|
pAdapter,
|
||
|
Oid,
|
||
|
pBuffer,
|
||
|
BufferLength,
|
||
|
pFunc) );
|
||
|
|
||
|
ASSERT (pNdisRequest != NULL);
|
||
|
|
||
|
EPVC_ZEROSTRUCT(pEpvcNdisRequest);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Fill in the NDIS Request structure
|
||
|
//
|
||
|
if (RequestType == NdisRequestQueryInformation)
|
||
|
{
|
||
|
pNdisRequest->RequestType = NdisRequestQueryInformation;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(RequestType == NdisRequestSetInformation);
|
||
|
pNdisRequest->RequestType = NdisRequestSetInformation;
|
||
|
pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
|
||
|
pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
|
||
|
pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
|
||
|
pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
|
||
|
pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
|
||
|
}
|
||
|
|
||
|
ASSERT (pAdapter->bind.BindingHandle != NULL);
|
||
|
|
||
|
//
|
||
|
// If the completion routine is not defined then wait for this request
|
||
|
// to complete.
|
||
|
//
|
||
|
|
||
|
if (pFunc == NULL)
|
||
|
{
|
||
|
// We might potentially wait.
|
||
|
//
|
||
|
ASSERT_PASSIVE();
|
||
|
|
||
|
//
|
||
|
//Insure that we aren't blocking a request that reached our miniport edge
|
||
|
//
|
||
|
ASSERT (pMiniport == NULL);
|
||
|
|
||
|
NdisInitializeEvent(&pEpvcNdisRequest->Event);
|
||
|
|
||
|
NdisRequest(
|
||
|
&Status,
|
||
|
pAdapter->bind.BindingHandle,
|
||
|
pNdisRequest
|
||
|
);
|
||
|
if (PEND(Status))
|
||
|
{
|
||
|
NdisWaitEvent(&pEpvcNdisRequest->Event, 0);
|
||
|
Status = pEpvcNdisRequest->Status;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pEpvcNdisRequest->pFunc = pFunc;
|
||
|
pEpvcNdisRequest->pMiniport = pMiniport;
|
||
|
pEpvcNdisRequest->fPendedRequest = fPendedRequest ;
|
||
|
pEpvcNdisRequest->fSet = fPendedSet;
|
||
|
|
||
|
//
|
||
|
// Set up an assoc between the miniport and this request
|
||
|
//
|
||
|
|
||
|
|
||
|
epvcLinkToExternal (&pMiniport->Hdr, // pHdr
|
||
|
0x46591e2d, // LUID
|
||
|
(UINT_PTR)pEpvcNdisRequest, // External entity
|
||
|
EPVC_ASSOC_MINIPORT_REQUEST, // AssocID
|
||
|
"NetWorKAddressRequest %p\n",
|
||
|
pSR
|
||
|
) ;
|
||
|
|
||
|
|
||
|
NdisRequest(
|
||
|
&Status,
|
||
|
pAdapter->bind.BindingHandle,
|
||
|
pNdisRequest
|
||
|
);
|
||
|
|
||
|
if (!PEND(Status))
|
||
|
{
|
||
|
(pFunc) (pEpvcNdisRequest, Status);
|
||
|
|
||
|
// Let this thread complete with a status of pending
|
||
|
Status = NDIS_STATUS_PENDING;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (Status == NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
TRACE(TL_V, TM_Rq,("Adapter Query - Oid %x", Oid));
|
||
|
DUMPDW (TL_V, TM_Rq, pBuffer, BufferLength);
|
||
|
}
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
epvcCoGenericWorkItem (
|
||
|
IN PNDIS_WORK_ITEM pNdisWorkItem,
|
||
|
IN PVOID Context
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Deref the miniport and invoke the function associated with
|
||
|
the workitem
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
ENTER ("epvcCoGenericWorkItem ", 0x45b597e8)
|
||
|
PEPVC_WORK_ITEM pEpvcWorkItem = (PEPVC_WORK_ITEM )pNdisWorkItem;
|
||
|
RM_DECLARE_STACK_RECORD (SR);
|
||
|
//
|
||
|
// Deref the miniport or adapter
|
||
|
//
|
||
|
|
||
|
epvcUnlinkFromExternal(
|
||
|
pEpvcWorkItem->pParentObj, // pObject
|
||
|
0x3a70de02,
|
||
|
(UINT_PTR)pNdisWorkItem, // Instance1
|
||
|
EPVC_ASSOC_WORKITEM, // AssociationID
|
||
|
&SR
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Call the function so that the work is completed
|
||
|
//
|
||
|
(pEpvcWorkItem->pFn) (pEpvcWorkItem->pParentObj, pEpvcWorkItem->ReturnStatus, &SR);
|
||
|
|
||
|
EXIT();
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
epvcMiniportQueueWorkItem (
|
||
|
IN PEPVC_WORK_ITEM pEpvcWorkItem,
|
||
|
IN PEPVC_I_MINIPORT pMiniport,
|
||
|
IN PEVPC_WORK_ITEM_FUNC pFn,
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN PRM_STACK_RECORD pSR
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Set up the Epvc Work Item with the pfn, Status and , ref the miniport
|
||
|
and then queue the workitem
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ENTER("epvcMiniportQueueWorkItem ", 0xc041af99);
|
||
|
|
||
|
//
|
||
|
// Store the contexts
|
||
|
//
|
||
|
|
||
|
pEpvcWorkItem->ReturnStatus = Status;
|
||
|
pEpvcWorkItem->pParentObj = &pMiniport->Hdr;
|
||
|
pEpvcWorkItem->pFn = pFn;
|
||
|
|
||
|
//
|
||
|
// Ref the RM Obj (its a miniport or an adapter)
|
||
|
//
|
||
|
epvcLinkToExternal( &pMiniport->Hdr,
|
||
|
0x62efba09,
|
||
|
(UINT_PTR)&pEpvcWorkItem->WorkItem,
|
||
|
EPVC_ASSOC_WORKITEM,
|
||
|
" WorkItem %p\n",
|
||
|
pSR);
|
||
|
|
||
|
//
|
||
|
// Queue the WorkItem
|
||
|
//
|
||
|
|
||
|
epvcInitializeWorkItem (&pMiniport->Hdr,
|
||
|
&pEpvcWorkItem->WorkItem,
|
||
|
epvcCoGenericWorkItem,
|
||
|
NULL,
|
||
|
pSR);
|
||
|
|
||
|
|
||
|
EXIT()
|
||
|
|
||
|
}
|