📄 mp_main.c
字号:
// Get the packets from SendCancelQueue and complete them if any
//
while (!IsQueueEmpty(&Adapter->SendCancelQueue))
{
pEntry = RemoveHeadQueue(&Adapter->SendCancelQueue);
NdisReleaseSpinLock(&Adapter->SendLock);
ASSERT(pEntry);
Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);
NdisMSendComplete(
MP_GET_ADAPTER_HANDLE(Adapter),
Packet,
NDIS_STATUS_REQUEST_ABORTED);
NdisAcquireSpinLock(&Adapter->SendLock);
}
NdisReleaseSpinLock(&Adapter->SendLock);
DBGPRINT(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 handler - NDIS51 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;
//
// Turn off the warings.
//
UNREFERENCED_PARAMETER(InformationBuffer);
UNREFERENCED_PARAMETER(InformationBufferLength);
UNREFERENCED_PARAMETER(Adapter);
DBGPRINT(MP_TRACE, ("====> MPPnPEventNotify\n"));
switch (PnPEvent)
{
case NdisDevicePnPEventQueryRemoved:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventQueryRemoved\n"));
break;
case NdisDevicePnPEventRemoved:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventRemoved\n"));
break;
case NdisDevicePnPEventSurpriseRemoved:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventSurpriseRemoved\n"));
break;
case NdisDevicePnPEventQueryStopped:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventQueryStopped\n"));
break;
case NdisDevicePnPEventStopped:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventStopped\n"));
break;
case NdisDevicePnPEventPowerProfileChanged:
DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventPowerProfileChanged\n"));
break;
default:
DBGPRINT(MP_ERROR, ("MPPnPEventNotify: unknown PnP event %x \n", PnPEvent));
break;
}
DBGPRINT(MP_TRACE, ("<==== MPPnPEventNotify\n"));
}
#if LBFO
VOID MPUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
The Unload handler
This handler is registered through NdisMRegisterUnloadHandler
Arguments:
DriverObject Not used
Return Value:
None
--*/
{
ASSERT(IsListEmpty(&g_AdapterList));
NdisFreeSpinLock(&g_Lock);
}
VOID MpAddAdapterToList(
IN PMP_ADAPTER Adapter
)
/*++
Routine Description:
This function adds a new adapter to the global adapter list
1. Not part of bundle (primary) if BundleId string is empty
2. Primary if no adapter with the same BundleId
3. Secondary if there is already one adapter with the same BundleId
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PMP_ADAPTER ThisAdapter;
PMP_ADAPTER PrimaryAdapter = NULL;
DBGPRINT(MP_WARN, ("Add adapter "PTR_FORMAT" ...", Adapter));
//
// Set the primary adapter to itself by default
//
Adapter->PrimaryAdapter = Adapter;
//
// Is this adapter part of a bundle? Just insert it in the list if not
//
if (Adapter->BundleId.Length == 0)
{
DBGPRINT_RAW(MP_WARN, ("not in a bundle\n"));
NdisInterlockedInsertTailList(&g_AdapterList, &Adapter->List, &g_Lock);
return;
}
NdisAllocateSpinLock(&Adapter->LockLBFO);
do
{
NdisAcquireSpinLock(&g_Lock);
//
// Search for the primary adapter if it exists.
// Skip searching if the list is empty
//
if (IsListEmpty(&g_AdapterList))
{
DBGPRINT_RAW(MP_WARN, ("Primary\n"));
break;
}
ThisAdapter = (PMP_ADAPTER)GetListHeadEntry(&g_AdapterList);
while ((PLIST_ENTRY)ThisAdapter != &g_AdapterList)
{
if (!MP_TEST_FLAG(ThisAdapter, fMP_ADAPTER_SECONDARY) &&
ThisAdapter->BundleId.Length == Adapter->BundleId.Length)
{
if (NdisEqualMemory(ThisAdapter->BundleId.Buffer,
Adapter->BundleId.Buffer, Adapter->BundleId.Length))
{
PrimaryAdapter = ThisAdapter;
break;
}
}
ThisAdapter = (PMP_ADAPTER)GetListFLink((PLIST_ENTRY)ThisAdapter);
}
//
// Does a primary adapter exist? If not, this adapter will be primary.
//
if (PrimaryAdapter == NULL)
{
DBGPRINT_RAW(MP_WARN, ("Primary\n"));
break;
}
//
// Found the primary adapter, so set this adapter as secondary
// Put a ref on the primary adapter so it won't go away while
// we are calling NdisMSetMiniportSecondary.
//
MP_LBFO_INC_REF(PrimaryAdapter);
NdisReleaseSpinLock(&g_Lock);
//
// We found the primary adapter with the same BundleIdentifier string
// Set this adapter as scondary
//
Status = NdisMSetMiniportSecondary(
Adapter->AdapterHandle,
PrimaryAdapter->AdapterHandle);
ASSERT(Status == NDIS_STATUS_SUCCESS);
NdisAcquireSpinLock(&g_Lock);
if (Status == NDIS_STATUS_SUCCESS)
{
MP_SET_FLAG(Adapter, fMP_ADAPTER_SECONDARY);
Adapter->PrimaryAdapter = PrimaryAdapter;
DBGPRINT_RAW(MP_WARN, ("Secondary, use primary adapter "PTR_FORMAT"\n",
PrimaryAdapter));
//
// Add this to the end of primary's secondary miniport list
//
NdisAcquireSpinLock(&PrimaryAdapter->LockLBFO);
PrimaryAdapter->NumSecondary++;
ThisAdapter = PrimaryAdapter;
while (ThisAdapter->NextSecondary)
{
ThisAdapter = ThisAdapter->NextSecondary;
}
ThisAdapter->NextSecondary = Adapter;
NdisReleaseSpinLock(&PrimaryAdapter->LockLBFO);
}
MP_LBFO_DEC_REF(PrimaryAdapter);
} while (FALSE);
InsertTailList(&g_AdapterList, &Adapter->List);
NdisReleaseSpinLock(&g_Lock);
return;
}
VOID MpRemoveAdapterFromList(
IN PMP_ADAPTER Adapter
)
/*++
Routine Description:
This function removes the adapter from the global adapter list
1. Not part of bundle (primary) if BundleId string is empty
2. Secondary - Remove it from primary's secondary adapter list
3. Primary - If a secondary adapter exists, promote the secondary
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
PMP_ADAPTER PrimaryAdapter;
PMP_ADAPTER ThisAdapter;
DBGPRINT(MP_WARN, ("Remove adapter "PTR_FORMAT" ...", Adapter));
ASSERT(!IsListEmpty(&g_AdapterList));
//
// Is this adapter part of a bundle? Just remove it if not
//
if (Adapter->BundleId.Length == 0)
{
DBGPRINT_RAW(MP_WARN, ("not in a bundle\n"));
NdisAcquireSpinLock(&g_Lock);
RemoveEntryList(&Adapter->List);
NdisReleaseSpinLock(&g_Lock);
return;
}
NdisAcquireSpinLock(&g_Lock);
//
// Check to see if it's secondary adapter, need to remove it from primary
// adapter's secondary list so the primary adapter won't pass more packets
// to this adapter
//
if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_SECONDARY))
{
//
// This is a secondary adapter
//
PrimaryAdapter = Adapter->PrimaryAdapter;
DBGPRINT_RAW(MP_WARN, ("Secondary, primary adapter = "PTR_FORMAT"\n",
PrimaryAdapter));
NdisAcquireSpinLock(&PrimaryAdapter->LockLBFO);
//
// Remove it from the primary's secondary miniport list
//
ThisAdapter = PrimaryAdapter;
while (ThisAdapter)
{
if (ThisAdapter->NextSecondary == Adapter)
{
ThisAdapter->NextSecondary = Adapter->NextSecondary;
PrimaryAdapter->NumSecondary--;
break;
}
ThisAdapter = ThisAdapter->NextSecondary;
}
NdisReleaseSpinLock(&PrimaryAdapter->LockLBFO);
//
// Remove this adapter from the list
//
RemoveEntryList(&Adapter->List);
}
//
// Need to wait for the ref count to be zero ...
// For a primary adapter, non-zero ref count means one or more adapters are
// trying to become this adapter's secondary adapters
// For a secondary adapter, non-zero ref count means the primary is actively
// sending some packets on this adapter
//
while (TRUE)
{
if (MP_LBFO_GET_REF(Adapter) == 0)
{
break;
}
NdisReleaseSpinLock(&g_Lock);
NdisMSleep(100);
NdisAcquireSpinLock(&g_Lock);
}
if (!MP_TEST_FLAG(Adapter, fMP_ADAPTER_SECONDARY))
{
//
// Remove this adapter from the list
//
RemoveEntryList(&Adapter->List);
DBGPRINT_RAW(MP_WARN, ("Primary\n"));
if (Adapter->NumSecondary > 0)
{
//
// Promote a secondary adapter
//
MpPromoteSecondary(Adapter);
}
}
NdisReleaseSpinLock(&g_Lock);
NdisFreeSpinLock(&Adapter->LockLBFO);
}
VOID MpPromoteSecondary(
IN PMP_ADAPTER Adapter)
/*++
Routine Description:
This function promotes a secondary miniport and sets up this new primary's
secondary adapter list
Arguments:
MiniportAdapterContext Pointer to our adapter
Return Value:
None
--*/
{
NDIS_STATUS Status;
PMP_ADAPTER ThisAdapter;
PMP_ADAPTER PromoteAdapter = NULL;
//
// Promote a secondary adapter
//
ThisAdapter = Adapter->NextSecondary;
while (ThisAdapter)
{
DBGPRINT(MP_WARN, ("Promote adapter "PTR_FORMAT"\n", ThisAdapter));
Status = NdisMPromoteMiniport(ThisAdapter->AdapterHandle);
ASSERT(Status == NDIS_STATUS_SUCCESS);
if (Status == NDIS_STATUS_SUCCESS)
{
PromoteAdapter = ThisAdapter;
MP_CLEAR_FLAG(PromoteAdapter, fMP_ADAPTER_SECONDARY);
break;
}
ThisAdapter = ThisAdapter->NextSecondary;
}
if (PromoteAdapter)
{
//
// Remove the new primary from old primary's secondary miniport list
//
NdisAcquireSpinLock(&Adapter->LockLBFO);
ThisAdapter = Adapter;
while (ThisAdapter)
{
if (ThisAdapter->NextSecondary == PromoteAdapter)
{
ThisAdapter->NextSecondary = PromoteAdapter->NextSecondary;
Adapter->NumSecondary--;
break;
}
ThisAdapter = ThisAdapter->NextSecondary;
}
NdisReleaseSpinLock(&Adapter->LockLBFO);
//
// Set all adapters in the bundle to use the new primary
//
PromoteAdapter->PrimaryAdapter = PromoteAdapter;
while (ThisAdapter)
{
ThisAdapter->PrimaryAdapter = PromoteAdapter;
ThisAdapter = ThisAdapter->NextSecondary;
}
//
// Set the new primary's secondary miniport list
//
NdisAcquireSpinLock(&PromoteAdapter->LockLBFO);
PromoteAdapter->NextSecondary = Adapter->NextSecondary;
PromoteAdapter->NumSecondary = Adapter->NumSecondary;
NdisReleaseSpinLock(&PromoteAdapter->LockLBFO);
}
else
{
//
// This shouldn't happen!
// Set each secondary's primary to point to itself
//
DBGPRINT(MP_ERROR, ("Failed to promote any seconday adapter\n"));
ASSERT(FALSE);
ThisAdapter = Adapter->NextSecondary;
while (ThisAdapter)
{
ThisAdapter->PrimaryAdapter = ThisAdapter;
ThisAdapter = ThisAdapter->NextSecondary;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -