📄 miniport.c
字号:
CheckForHang handler is called in the context of a timer DPC.
take advantage of this fact when acquiring/releasing spinlocks
--*/
{
DEBUGP(MP_LOUD, ("---> MPCheckForHang\n"));
DEBUGP(MP_LOUD, ("<--- MPCheckForHang\n"));
return(FALSE);
}
VOID
MPHandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
MiniportHandleInterrupt is a DPC function called to do deferred
processing of all outstanding interrupt operations. When a NIC
generates an interrupt, a miniport's MiniportISR or
MiniportDisableInterrupt function dismisses the interrupt on the
NIC, saves any necessary state about the operation, and returns
control as quickly as possible, thereby deferring most
interrupt-driven I/O operations to MiniportHandleInterrupt. This
handler is called only if the MiniportISR function returned
QueueMiniportHandleInterrupt set to TRUE.
MiniportHandleInterrupt then re-enables interrupts on the NIC,
either by letting NDIS call the miniport driver's
MiniportEnableInterrupt function after MiniportHandleInterrupt
returns control or by enabling the interrupt from within
MiniportHandleInterrupt, which is faster.
Note that more than one instance of this function can execute
concurrently in SMP machines.
Runs at IRQL = DISPATCH_LEVEL
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
DEBUGP(MP_TRACE, ("---> MPHandleInterrupt\n"));
DEBUGP(MP_TRACE, ("<--- MPHandleInterrupt\n"));
}
VOID
MPIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
MiniportIsr handler is called to when the device asserts an interrupt.
MiniportISR dismisses the interrupt on the NIC, saves whatever state
it must about the interrupt, and defers as much of the I/O processing
for each interrupt as possible to the MiniportHandleInterrupt function.
MiniportISR is not re-entrant, although two instantiations of this
function can execute concurrently in SMP machines, particularly if
the miniport driver supports full-duplex sends and receives. A driver
writer should not rely on a one-to-one correspondence between the
execution of MiniportISR and MiniportHandleInterrupt.
If the NIC shares an IRQ with other devices (check NdisMRegisterInterrupt),
this function should determine whether the NIC generated the interrupt.
If the NIC did not generated the interrupt, MiniportISR should return FALSE
immediately so that the driver of the device that generated the interrupt
is called quickly.
Runs at IRQL = DIRQL assigned when the NIC driver's MiniportInitialize
function called NdisMRegisterInterrupt.
Arguments:
InterruptRecognized TRUE on return if the interrupt comes
from this NIC
QueueMiniportHandleInterrupt TRUE on return if MiniportHandleInterrupt
should be called
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
DEBUGP(MP_TRACE, ("---> MPIsr\n"));
DEBUGP(MP_TRACE, ("<--- MPIsr\n"));
}
VOID
MPDisableInterrupt(
IN PVOID MiniportAdapterContext
)
/*++
Routine Description:
MiniportDisableInterrupt typically disables interrupts by writing
a mask to the NIC. If a driver does not have this function, typically
its MiniportISR disables interrupts on the NIC.
This handler is required by drivers of NICs that support dynamic
enabling and disabling of interrupts but do not share an IRQ.
Runs at IRQL = DIRQL
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
DEBUGP(MP_TRACE, ("---> MPDisableInterrupt\n"));
DEBUGP(MP_TRACE, ("<--- MPDisableInterrupt\n"));
}
VOID
MPEnableInterrupt(
IN PVOID MiniportAdapterContext
)
/*++
Routine Description:
MiniportEnableInterrupt typically enables interrupts by writing a mask
to the NIC. A NIC driver that exports a MiniportDisableInterrupt function
need not have a reciprocal MiniportEnableInterrupt function.
Such a driver's MiniportHandleInterrupt function is responsible for
re-enabling interrupts on the NIC.
Runs at IRQL = DIRQL
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
DEBUGP(MP_TRACE, ("---> MPEnableInterrupt\n"));
DEBUGP(MP_TRACE, ("<--- MPEnableInterrupt\n"));
}
VOID
MPAllocateComplete(
NDIS_HANDLE MiniportAdapterContext,
IN PVOID VirtualAddress,
IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG Length,
IN PVOID Context
)
/*++
Routine Description:
This handler is needed if the driver makes calls to
NdisMAllocateSharedMemoryAsync. Drivers of bus-master DMA NICs call
NdisMAllocateSharedMemoryAsync to dynamically allocate shared memory
for transfer operations when high network traffic places excessive
demands on the shared memory space that the driver allocated during
initialization.
Runs at IRQL = DISPATCH_LEVEL.
Arguments:
MiniportAdapterContext Pointer to our adapter
VirtualAddress Pointer to the allocated memory block
PhysicalAddress Physical address of the memory block
Length Length of the memory block
Context Context in NdisMAllocateSharedMemoryAsync
Return Value:
None
--*/
{
DEBUGP(MP_TRACE, ("---> MPAllocateComplete\n"));
}
#ifdef NDIS51_MINIPORT
VOID
MPCancelSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PVOID CancelId
)
/*++
Routine Description:
MiniportCancelSendPackets cancels the transmission of all packets that
are marked with a specified cancellation identifier. Miniport drivers
that queue send packets for more than one second should export this
handler. When a protocol driver or intermediate driver calls the
NdisCancelSendPackets function, NDIS calls the MiniportCancelSendPackets
function of the appropriate lower-level driver (miniport driver or
intermediate driver) on the binding.
Runs at IRQL <= DISPATCH_LEVEL.
Available - NDIS5.1 (WinXP) and later.
Arguments:
MiniportAdapterContext Pointer to our adapter
CancelId All the packets with this Id should be cancelled
Return Value:
None
--*/
{
PNDIS_PACKET Packet;
PVOID PacketId;
PLIST_ENTRY thisEntry, nextEntry, listHead;
SINGLE_LIST_ENTRY SendCancelList;
PSINGLE_LIST_ENTRY entry;
PMP_ADAPTER Adapter = (PMP_ADAPTER)MiniportAdapterContext;
#define MP_GET_PACKET_MR(_p) (PSINGLE_LIST_ENTRY)(&(_p)->MiniportReserved[0])
DEBUGP(MP_TRACE, ("---> MPCancelSendPackets\n"));
SendCancelList.Next = NULL;
NdisAcquireSpinLock(&Adapter->SendLock);
//
// Walk through the send wait queue and complete the sends with matching Id
//
listHead = &Adapter->SendWaitList;
for(thisEntry = listHead->Flink,nextEntry = thisEntry->Flink;
thisEntry != listHead;
thisEntry = nextEntry,nextEntry = thisEntry->Flink) {
Packet = CONTAINING_RECORD(thisEntry, NDIS_PACKET, MiniportReserved);
PacketId = NdisGetPacketCancelId(Packet);
if (PacketId == CancelId)
{
//
// This packet has the right CancelId
//
RemoveEntryList(thisEntry);
//
// Put this packet on SendCancelList
//
PushEntryList(&SendCancelList, MP_GET_PACKET_MR(Packet));
}
}
NdisReleaseSpinLock(&Adapter->SendLock);
//
// Get the packets from SendCancelList and complete them if any
//
entry = PopEntryList(&SendCancelList);
while (entry)
{
Packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReserved);
NdisMSendComplete(
Adapter->AdapterHandle,
Packet,
NDIS_STATUS_REQUEST_ABORTED);
entry = PopEntryList(&SendCancelList);
}
DEBUGP(MP_TRACE, ("<--- MPCancelSendPackets\n"));
}
VOID MPPnPEventNotify(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_DEVICE_PNP_EVENT PnPEvent,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength
)
/*++
Routine Description:
MiniportPnPEventNotify is to handle PnP notification messages.
All NDIS 5.1 miniport drivers must export a MiniportPnPEventNotify
function. Miniport drivers that have a WDM lower edge should export
a MiniportPnPEventNotify function.
Runs at IRQL = PASSIVE_LEVEL in the context of system thread.
Available - NDIS5.1 (WinXP) and later.
Arguments:
MiniportAdapterContext Pointer to our adapter
PnPEvent Self-explanatory
InformationBuffer Self-explanatory
InformationBufferLength Self-explanatory
Return Value:
None
--*/
{
PMP_ADAPTER Adapter = (PMP_ADAPTER)MiniportAdapterContext;
PNDIS_POWER_PROFILE NdisPowerProfile;
//
// Turn off the warings.
//
UNREFERENCED_PARAMETER(Adapter);
DEBUGP(MP_TRACE, ("---> MPPnPEventNotify\n"));
switch (PnPEvent)
{
case NdisDevicePnPEventQueryRemoved:
//
// Called when NDIS receives IRP_MN_QUERY_REMOVE_DEVICE.
//
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventQueryRemoved\n"));
break;
case NdisDevicePnPEventRemoved:
//
// Called when NDIS receives IRP_MN_REMOVE_DEVICE.
// NDIS calls MiniportHalt function after this call returns.
//
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventRemoved\n"));
break;
case NdisDevicePnPEventSurpriseRemoved:
//
// Called when NDIS receives IRP_MN_SUPRISE_REMOVAL.
// NDIS calls MiniportHalt function after this call returns.
//
MP_SET_FLAG(Adapter, fMP_ADAPTER_SURPRISE_REMOVED);
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventSurpriseRemoved\n"));
break;
case NdisDevicePnPEventQueryStopped:
//
// Called when NDIS receives IRP_MN_QUERY_STOP_DEVICE. ??
//
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventQueryStopped\n"));
break;
case NdisDevicePnPEventStopped:
//
// Called when NDIS receives IRP_MN_STOP_DEVICE.
// NDIS calls MiniportHalt function after this call returns.
//
//
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventStopped\n"));
break;
case NdisDevicePnPEventPowerProfileChanged:
//
// After initializing a miniport driver and after miniport driver
// receives an OID_PNP_SET_POWER notification that specifies
// a device power state of NdisDeviceStateD0 (the powered-on state),
// NDIS calls the miniport's MiniportPnPEventNotify function with
// PnPEvent set to NdisDevicePnPEventPowerProfileChanged.
//
DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventPowerProfileChanged\n"));
if(InformationBufferLength == sizeof(NDIS_POWER_PROFILE)) {
NdisPowerProfile = (PNDIS_POWER_PROFILE)InformationBuffer;
if(*NdisPowerProfile == NdisPowerProfileBattery) {
DEBUGP(MP_INFO,
("The host system is running on battery power\n"));
}
if(*NdisPowerProfile == NdisPowerProfileAcOnLine) {
DEBUGP(MP_INFO,
("The host system is running on AC power\n"));
}
}
break;
default:
DEBUGP(MP_ERROR, ("MPPnPEventNotify: unknown PnP event %x \n", PnPEvent));
break;
}
DEBUGP(MP_TRACE, ("<--- MPPnPEventNotify\n"));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -