⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isrdpc.c

📁 plx9054的WDM驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
{
    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;    
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -