📄 protocol.c
字号:
PNDIS_PACKET MyPacket;
BOOLEAN Remaining;
//
// Drop the packet silently if the upper miniport edge isn't initialized or
// the miniport edge is in low power state
//
if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
{
return 0;
}
#ifdef NDIS51
//
// Check if we can reuse the same packet for indicating up.
// See also: PtReceive().
//
(VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
if (Remaining)
{
//
// We can reuse "Packet". Indicate it up and be done with it.
//
Status = NDIS_GET_PACKET_STATUS(Packet);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
}
#endif // NDIS51
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
&MyPacket,
pAdapt->RecvPacketPoolHandle);
if (Status == NDIS_STATUS_SUCCESS)
{
PRECV_RSVD RecvRsvd;
RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
RecvRsvd->OriginalPkt = Packet;
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;
//
// Get the original packet (it could be the same packet as the one
// received or a different one based on the number of layered miniports
// below) and set it on the indicated packet so the OOB data is visible
// correctly to protocols above us.
//
NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
//
// Set Packet Flags
//
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
Status = NDIS_GET_PACKET_STATUS(Packet);
NDIS_SET_PACKET_STATUS(MyPacket, Status);
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);
//
// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
// it might have changed! Use the value saved in the local variable.
//
if (Status == NDIS_STATUS_RESOURCES)
{
//
// Our ReturnPackets handler will not be called for this packet.
// We should reclaim it right here.
//
NdisDprFreePacket(MyPacket);
}
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
}
else
{
//
// We are out of packets. Silently drop it.
//
return(0);
}
}
NDIS_STATUS
PtPNPHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
This is called by NDIS to notify us of a PNP event related to a lower
binding. Based on the event, this dispatches to other helper routines.
NDIS 5.1: forward this event to the upper protocol(s) by calling
NdisIMNotifyPnPEvent.
Arguments:
ProtocolBindingContext - Pointer to our adapter structure. Can be NULL
for "global" notifications
pNetPnPEvent - Pointer to the PNP event to be processed.
Return Value:
NDIS_STATUS code indicating status of event processing.
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT(("PtPnPHandler: Adapt %p, Event %d\n", pAdapt, pNetPnPEvent->NetEvent));
switch (pNetPnPEvent->NetEvent)
{
case NetEventSetPower:
Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
break;
case NetEventReconfigure:
Status = PtPnPNetEventReconfigure(pAdapt, pNetPnPEvent);
break;
default:
#ifdef NDIS51
//
// Pass on this notification to protocol(s) above, before
// doing anything else with it.
//
if (pAdapt && pAdapt->MiniportHandle)
{
Status = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);
}
#else
Status = NDIS_STATUS_SUCCESS;
#endif // NDIS51
break;
}
return Status;
}
NDIS_STATUS
PtPnPNetEventReconfigure(
IN PADAPT pAdapt,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
This routine is called from NDIS to notify our protocol edge of a
reconfiguration of parameters for either a specific binding (pAdapt
is not NULL), or global parameters if any (pAdapt is NULL).
Arguments:
pAdapt - Pointer to our adapter structure.
pNetPnPEvent - the reconfigure event
Return Value:
NDIS_STATUS_SUCCESS
--*/
{
NDIS_STATUS ReconfigStatus = NDIS_STATUS_SUCCESS;
NDIS_STATUS ReturnStatus = NDIS_STATUS_SUCCESS;
do
{
//
// Is this is a global reconfiguration notification ?
//
if (pAdapt == NULL)
{
//
// An important event that causes this notification to us is if
// one of our upper-edge miniport instances was enabled after being
// disabled earlier, e.g. from Device Manager in Win2000. Note that
// NDIS calls this because we had set up an association between our
// miniport and protocol entities by calling NdisIMAssociateMiniport.
//
// Since we would have torn down the lower binding for that miniport,
// we need NDIS' assistance to re-bind to the lower miniport. The
// call to NdisReEnumerateProtocolBindings does exactly that.
//
NdisReEnumerateProtocolBindings (ProtHandle);
break;
}
#ifdef NDIS51
//
// Pass on this notification to protocol(s) above before doing anything
// with it.
//
if (pAdapt->MiniportHandle)
{
ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);
}
#endif // NDIS51
ReconfigStatus = NDIS_STATUS_SUCCESS;
} while(FALSE);
DBGPRINT(("<==PtPNPNetEventReconfigure: pAdapt %p\n", pAdapt));
#ifdef NDIS51
//
// Overwrite status with what upper-layer protocol(s) returned.
//
ReconfigStatus = ReturnStatus;
#endif
return ReconfigStatus;
}
NDIS_STATUS
PtPnPNetEventSetPower(
IN PADAPT pAdapt,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
This is a notification to our protocol edge of the power state
of the lower miniport. If it is going to a low-power state, we must
wait here for all outstanding sends and requests to complete.
NDIS 5.1: Since we use packet stacking, it is not sufficient to
check usage of our local send packet pool to detect whether or not
all outstanding sends have completed. For this, use the new API
NdisQueryPendingIOCount.
NDIS 5.1: Use the 5.1 API NdisIMNotifyPnPEvent to pass on PnP
notifications to upper protocol(s).
Arguments:
pAdapt - Pointer to the adpater structure
pNetPnPEvent - The Net Pnp Event. this contains the new device state
Return Value:
NDIS_STATUS_SUCCESS or the status returned by upper-layer protocols.
--*/
{
PNDIS_DEVICE_POWER_STATE pDeviceState =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
NDIS_DEVICE_POWER_STATE PrevDeviceState = pAdapt->PTDeviceState;
NDIS_STATUS Status;
NDIS_STATUS ReturnStatus;
#ifdef NDIS51
ULONG PendingIoCount = 0;
#endif // NDIS51
ReturnStatus = NDIS_STATUS_SUCCESS;
//
// Set the Internal Device State, this blocks all new sends or receives
//
NdisAcquireSpinLock(&pAdapt->Lock);
pAdapt->PTDeviceState = *pDeviceState;
//
// Check if the miniport below is going to a low power state.
//
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
//
// If the miniport below is going to standby, fail all incoming requests
//
if (PrevDeviceState == NdisDeviceStateD0)
{
pAdapt->StandingBy = TRUE;
}
NdisReleaseSpinLock(&pAdapt->Lock);
#ifdef NDIS51
//
// Notify upper layer protocol(s) first.
//
if (pAdapt->MiniportHandle != NULL)
{
ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);
}
#endif // NDIS51
//
// Wait for outstanding sends and requests to complete.
//
while (pAdapt->OutstandingSends != 0)
{
NdisMSleep(2);
}
while (pAdapt->OutstandingRequests == TRUE)
{
//
// sleep till outstanding requests complete
//
NdisMSleep(2);
}
//
// If the below miniport is going to low power state, complete the queued request
//
NdisAcquireSpinLock(&pAdapt->Lock);
if (pAdapt->QueuedRequest)
{
pAdapt->QueuedRequest = FALSE;
NdisReleaseSpinLock(&pAdapt->Lock);
PtRequestComplete(pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE);
}
else
{
NdisReleaseSpinLock(&pAdapt->Lock);
}
ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);
ASSERT(pAdapt->OutstandingRequests == FALSE);
}
else
{
//
// If the physical miniport is powering up (from Low power state to D0),
// clear the flag
//
if (PrevDeviceState > NdisDeviceStateD0)
{
pAdapt->StandingBy = FALSE;
}
//
// The device below is being turned on. If we had a request
// pending, send it down now.
//
if (pAdapt->QueuedRequest == TRUE)
{
pAdapt->QueuedRequest = FALSE;
pAdapt->OutstandingRequests = TRUE;
NdisReleaseSpinLock(&pAdapt->Lock);
NdisRequest(&Status,
pAdapt->BindingHandle,
&pAdapt->Request);
if (Status != NDIS_STATUS_PENDING)
{
PtRequestComplete(pAdapt,
&pAdapt->Request,
Status);
}
}
else
{
NdisReleaseSpinLock(&pAdapt->Lock);
}
#ifdef NDIS51
//
// Pass on this notification to protocol(s) above
//
if (pAdapt->MiniportHandle)
{
ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);
}
#endif // NDIS51
}
return ReturnStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -