|
|
#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()
}
|