?? isrdpc.c
字號(hào):
{
NTSTATUS status;
DebugPrint(TRACE, DBG_DPC, "---> MPReset\n");
KeAcquireSpinLockAtDpcLevel(&FdoData->Lock);
KeAcquireSpinLockAtDpcLevel(&FdoData->SendLock);
KeAcquireSpinLockAtDpcLevel(&FdoData->RcvLock);
do
{
ASSERT(!MP_TEST_FLAG(FdoData, fMP_ADAPTER_HALT_IN_PROGRESS));
//
// Is this adapter already doing a reset?
//
if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS))
{
status = STATUS_SUCCESS;
MP_EXIT;
}
MP_SET_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);
//
// Is this adapter doing link detection?
//
if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION))
{
DebugPrint(WARNING, DBG_DPC, "Reset is pended...\n");
//FdoData->bResetPending = TRUE;
status = STATUS_SUCCESS;
MP_EXIT;
}
//
// Is this adapter going to be removed
//
if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_NON_RECOVER_ERROR))
{
status = STATUS_DEVICE_DATA_ERROR;
if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS))
{
MP_EXIT;
}
//
// This is an unrecoverable hardware failure.
// We need to tell PNP system to remove this miniport
//
MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);
KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
// TODO: Log an entry into the eventlog
IoInvalidateDeviceState(FdoData->UnderlyingPDO);
DebugPrint(ERROR, DBG_DPC, "<--- MPReset, status=%x\n", status);
return status;
}
//
// Disable the interrupt and issue a reset to the NIC
//
NICDisableInterrupt(FdoData);
NICIssueSelectiveReset(FdoData);
//
// release all the locks and then acquire back the send lock
// we are going to clean up the send queues
// which may involve calling Ndis APIs
// release all the locks before grabbing the send lock to
// avoid deadlocks
//
KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
KeAcquireSpinLockAtDpcLevel(&FdoData->SendLock);
//
// Free the packets on SendQueueList
//
NICFreeQueuedSendPackets(FdoData);
//
// Free the packets being actively sent & stopped
//
NICFreeBusySendPackets(FdoData);
RtlZeroMemory(FdoData->MpTcbMem, FdoData->MpTcbMemSize);
//
// Re-initialize the send structures
//
NICInitSend(FdoData);
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
//
// get all the locks again in the right order
//
KeAcquireSpinLockAtDpcLevel(&FdoData->Lock);
KeAcquireSpinLockAtDpcLevel(&FdoData->SendLock);
KeAcquireSpinLockAtDpcLevel(&FdoData->RcvLock);
//
// Reset the RFD list and re-start RU
//
NICResetRecv(FdoData);
status = NICStartRecv(FdoData);
if (status != STATUS_SUCCESS)
{
// Are we having failures in a few consecutive resets?
if (FdoData->HwErrCount < NIC_HARDWARE_ERROR_THRESHOLD)
{
// It's not over the threshold yet, let it to continue
FdoData->HwErrCount++;
}
else
{
//
// This is an unrecoverable hardware failure.
// We need to tell PNP system to remove this miniport
//
MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);
KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
// TODO: Log an entry into the eventlog
IoInvalidateDeviceState(FdoData->UnderlyingPDO);
DebugPrint(ERROR, DBG_DPC, "<--- MPReset, status=%x\n", status);
return(status);
}
break;
}
FdoData->HwErrCount = 0;
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_HARDWARE_ERROR);
NICEnableInterrupt(FdoData);
} while (FALSE);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);
exit:
KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
DebugPrint(TRACE, DBG_DPC, "<--- MPReset, status=%x\n", status);
return(status);
}
NTSTATUS
NICLinkDetection(
PFDO_DATA FdoData
)
/*++
Routine Description:
Timer function for postponed link negotiation. Called from
the NICWatchDogTimerDpc. After the link detection is over
we will complete any pending ioctl or send IRPs.
Arguments:
FdoData Pointer to our FdoData
Return Value:
NT status
--*/
{
NTSTATUS status = STATUS_SUCCESS;
MEDIA_STATE currMediaState;
PNDISPROT_QUERY_OID pQuery = NULL;
PNDISPROT_SET_OID pSet = NULL;
PVOID DataBuffer;
ULONG BytesWritten;
NDIS_OID oid;
PIRP queryRequest = NULL;
PIRP setRequest = NULL;
PVOID informationBuffer;
//
// Handle the link negotiation.
//
if (FdoData->bLinkDetectionWait)
{
status = ScanAndSetupPhy(FdoData);
}
else
{
status = PhyDetect(FdoData);
}
if (status == STATUS_PENDING)
{
//
// We are not done with link detection yet.
//
return status;
}
//
// Reset some variables for link detection
//
FdoData->bLinkDetectionWait = FALSE;
DebugPrint(LOUD, DBG_DPC, "NICLinkDetection - negotiation done\n");
KeAcquireSpinLockAtDpcLevel(&FdoData->Lock);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
//
// Any OID query request pending?
//
if (FdoData->QueryRequest)
{
//
// Clear the cancel routine.
//
queryRequest = FdoData->QueryRequest;
if(IoSetCancelRoutine(queryRequest, NULL)){
//
// Cancel routine cannot run now and cannot have already
// started to run.
//
DataBuffer = queryRequest->AssociatedIrp.SystemBuffer;
pQuery = (PNDISPROT_QUERY_OID)DataBuffer;
oid = pQuery->Oid;
informationBuffer = &pQuery->Data[0];
switch(pQuery->Oid)
{
case OID_GEN_LINK_SPEED:
*((PULONG)informationBuffer) = FdoData->usLinkSpeed * 10000;
BytesWritten = sizeof(ULONG);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
default:
ASSERT(oid == OID_GEN_MEDIA_CONNECT_STATUS);
currMediaState = NICIndicateMediaState(FdoData);
RtlMoveMemory(informationBuffer,
&currMediaState,
sizeof(NDIS_MEDIA_STATE));
BytesWritten = sizeof(NDIS_MEDIA_STATE);
}
FdoData->QueryRequest = NULL;
queryRequest->IoStatus.Information = sizeof(ULONG);
queryRequest->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(queryRequest, IO_NO_INCREMENT);
PciDrvIoDecrement (FdoData);
}
}
//
// Any OID set request pending?
//
if (FdoData->SetRequest)
{
ULONG PacketFilter;
setRequest = FdoData->SetRequest;
if(IoSetCancelRoutine(setRequest, NULL)){
DataBuffer = setRequest->AssociatedIrp.SystemBuffer;
pSet = (PNDISPROT_SET_OID)DataBuffer;
oid = pSet->Oid;
informationBuffer = &pSet->Data[0];
if (oid == OID_GEN_CURRENT_PACKET_FILTER)
{
RtlMoveMemory(&PacketFilter, informationBuffer, sizeof(ULONG));
KeAcquireSpinLockAtDpcLevel(&FdoData->Lock);
status = NICSetPacketFilter(
FdoData,
PacketFilter);
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
if (status == STATUS_SUCCESS)
{
FdoData->PacketFilter = PacketFilter;
}
FdoData->SetRequest = NULL;
setRequest->IoStatus.Information = 0;
setRequest->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(setRequest, IO_NO_INCREMENT);
PciDrvIoDecrement (FdoData);
}
}
}
//
// Any read pending?
//
KeAcquireSpinLockAtDpcLevel(&FdoData->RcvLock);
//
// Start the NIC receive unit
//
status = NICStartRecv(FdoData);
if (status != STATUS_SUCCESS)
{
MP_SET_HARDWARE_ERROR(FdoData);
}
KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
KeAcquireSpinLockAtDpcLevel(&FdoData->SendLock);
//
// Send packets which have been queued while link detection was going on.
//
while (!IsListEmpty(&FdoData->SendQueueHead) &&
MP_TCB_RESOURCES_AVAIABLE(FdoData))
{
PIRP irp;
PLIST_ENTRY pEntry;
pEntry = RemoveHeadList(&FdoData->SendQueueHead);
ASSERT(pEntry);
FdoData->nWaitSend--;
irp = CONTAINING_RECORD(pEntry, IRP, Tail.Overlay.ListEntry);
DebugPrint(INFO, DBG_DPC,
"NICLinkDetection - send a queued packet\n");
NICWritePacket(FdoData, irp, TRUE);
}
KeReleaseSpinLockFromDpcLevel(&FdoData->SendLock);
return status;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -