NDIS_STATUS MpGetAdapterStatus( _In_ PADAPTER Adapter ) { NDIS_STATUS ndisStatus; if (MP_TEST_ADAPTER_STATUS(Adapter, MP_ADAPTER_PAUSED)) ndisStatus = NDIS_STATUS_PAUSED; else if (MP_TEST_ADAPTER_STATUS(Adapter, MP_ADAPTER_PAUSING)) ndisStatus = NDIS_STATUS_PAUSED; else if (MP_TEST_ADAPTER_STATUS(Adapter, MP_ADAPTER_IN_RESET)) ndisStatus = NDIS_STATUS_RESET_IN_PROGRESS; else if (MP_TEST_ADAPTER_STATUS(Adapter, MP_ADAPTER_HALTING)) ndisStatus = NDIS_STATUS_CLOSING; else if (MP_TEST_ADAPTER_STATUS(Adapter, MP_ADAPTER_SURPRISE_REMOVED)) ndisStatus = NDIS_STATUS_ADAPTER_REMOVED; else ndisStatus = NDIS_STATUS_FAILURE; // return a generc error return ndisStatus; }
NDIS_STATUS MPOidRequest( __in NDIS_HANDLE MiniportAdapterContext, __in PNDIS_OID_REQUEST NdisOidRequest ) { PADAPTER adapter = (PADAPTER)MiniportAdapterContext; NDIS_STATUS ndisStatus = NDIS_STATUS_NOT_SUPPORTED; NDIS_OID oid; // Depending on the OID, hand it to the appropriate component for processing oid = NdisOidRequest->DATA.QUERY_INFORMATION.Oid; // Oid is at same offset for all RequestTypes // Save the request (for tracking purpose) adapter->Tracking_LastRequest = NdisOidRequest; adapter->Tracking_LastOid = oid; #if DBG if (adapter->Debug_BreakOnOid == oid) { DbgPrint("Received OID request %p for desired OID\n", NdisOidRequest); adapter->Debug_BreakOnOid = 0; // Only break once DbgBreakPoint(); } #endif // // If the adapter has been surprise removed, fail request // if (MP_TEST_ADAPTER_STATUS(adapter, MP_ADAPTER_SURPRISE_REMOVED)) { ndisStatus = NDIS_STATUS_FAILURE; MpTrace(COMP_OID, DBG_SERIOUS, ("NDIS_OID_REQUEST failed as surprise removal is in progress\n")); return ndisStatus; } // Save the deferred OID request // adapter->DeferredOidRequest = NdisOidRequest; // // Queue the workitem. We always defer the Oid requests // NdisQueueIoWorkItem( adapter->OidWorkItem, MpOidRequestWorkItem, adapter ); return NDIS_STATUS_PENDING; }
NDIS_STATUS MPReset( NDIS_HANDLE MiniportAdapterContext, PBOOLEAN AddressingReset ) { PADAPTER adapter = (PADAPTER)MiniportAdapterContext; NDIS_STATUS ndisStatus = NDIS_STATUS_PENDING; NDIS_HANDLE workitemHandle; *AddressingReset = TRUE; #if DBG if (adapter->Debug_BreakOnReset) { DbgPrint("Received NdisReset\n"); DbgBreakPoint(); } #endif do { // // Set the flag so that other routines stop proceeding // MP_SET_ADAPTER_STATUS(adapter, MP_ADAPTER_IN_RESET); // // If our halt handler has been called, we should not reset // if (MP_TEST_ADAPTER_STATUS(adapter, MP_ADAPTER_HALTING)) { MPASSERT(FALSE); // Would be an interesting scenario to investigate ndisStatus = NDIS_STATUS_SUCCESS; break; } // // Handle the reset asynchronously since we can be called at either dispatch // or passive IRQL // workitemHandle = NdisAllocateIoWorkItem(adapter->MiniportAdapterHandle); if(workitemHandle == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate Reset workitem\n")); NdisWriteErrorLogEntry(adapter->MiniportAdapterHandle, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0 ); ndisStatus = NDIS_STATUS_RESOURCES; break; } // Queue the workitem NdisQueueIoWorkItem(workitemHandle, MpResetWorkItem, adapter ); } while (FALSE); if (ndisStatus != NDIS_STATUS_PENDING) { // Something failed, clear the in reset flag MP_CLEAR_ADAPTER_STATUS(adapter, MP_ADAPTER_IN_RESET); } return ndisStatus; }
VOID MPSendNetBufferLists( NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, NDIS_PORT_NUMBER PortNumber, ULONG SendFlags ) { PADAPTER adapter = (PADAPTER)MiniportAdapterContext; NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PMP_PORT destinationPort = NULL; PNET_BUFFER_LIST currentNetBufferList; // // We increment the port list refcount. This would avoid a pause from finishing // while we are processing this NBL and that ensures that the port list does not // change // MP_INCREMENT_PORTLIST_REFCOUNT(adapter); do { // // If the adapter is paused, surprise removed, etc, fail the send // if (MP_TEST_ADAPTER_STATUS(adapter, MP_ADAPTER_CANNOT_SEND_MASK)) { ndisStatus = MpGetAdapterStatus(adapter); MpTrace(COMP_SEND, DBG_NORMAL, ("Sends failed as adapter is not in a valid send state\n")); break; } // // First we would need to translate from the NDIS_PORT_NUMBER // to our port structure. This is done by walking the PortList // destinationPort = Port11TranslatePortNumberToPort( adapter, PortNumber ); if (destinationPort == NULL) { MpTrace(COMP_SEND, DBG_SERIOUS, ("Unable to find Port corresponding to PortNumber %d\n", PortNumber)); ndisStatus = NDIS_STATUS_INVALID_PORT; } else { // // Pass it to the appropriate port for processing // Port11HandleSendNetBufferLists( destinationPort, NetBufferLists, SendFlags ); } } while (FALSE); // // We were protecting the port list only until we hand it to the port. After this point, the port // is responsible for ensuring that it does not let the port get deleted while // it has packets pending on it // MP_DECREMENT_PORTLIST_REFCOUNT(adapter); if (ndisStatus != NDIS_STATUS_SUCCESS) { #if DBG ULONG ulNumFailedNBLs = 0; #endif // // Send failed. Complete the NBLs back to NDIS // for(currentNetBufferList = NetBufferLists; currentNetBufferList != NULL; currentNetBufferList = NET_BUFFER_LIST_NEXT_NBL(currentNetBufferList)) { #if DBG ulNumFailedNBLs++; #endif NET_BUFFER_LIST_STATUS(currentNetBufferList) = ndisStatus; } #if DBG MpTrace(COMP_SEND, DBG_NORMAL, ("NdisMSendNetBufferListsComplete called with %d NBLs\n", ulNumFailedNBLs)); #endif if (NetBufferLists != NULL) { NdisMSendNetBufferListsComplete( adapter->MiniportAdapterHandle, NetBufferLists, (NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags) ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0) ); } } }
NDIS_STATUS MPDirectOidRequest( __in NDIS_HANDLE MiniportAdapterContext, __in PNDIS_OID_REQUEST NdisOidRequest ) { PADAPTER adapter = (PADAPTER)MiniportAdapterContext; NDIS_STATUS ndisStatus = NDIS_STATUS_NOT_SUPPORTED; NDIS_OID oid; PMP_PORT destinationPort = NULL; // // If the adapter has been surprise removed, fail request // if (MP_TEST_ADAPTER_STATUS(adapter, MP_ADAPTER_SURPRISE_REMOVED)) { ndisStatus = NDIS_STATUS_FAILURE; MpTrace(COMP_OID, DBG_SERIOUS, ("NDIS_OID_REQUEST failed as surprise removal is in progress\n")); return ndisStatus; } // Depending on the OID, hand it to the appropriate component for processing oid = NdisOidRequest->DATA.QUERY_INFORMATION.Oid; // Oid is at same offset for all RequestTypes MpTrace(COMP_OID, DBG_SERIOUS, ("Processing NDIS_OID_REQUEST for Direct OID 0x%08x\n", oid)); // // Now determine if the OID is something the helper port would process or one of the // ports from the port list should process // switch (oid) { default: { // All OIDs would need to get forwarded to the appropriate port // for processing. // // First we would need to translate from the NDIS_PORT_NUMBER // to our port structure. This is done by walking the PortList // destinationPort = Port11TranslatePortNumberToPort( adapter, NdisOidRequest->PortNumber ); if (destinationPort == NULL) { MpTrace(COMP_OID, DBG_SERIOUS, ("Unable to find Port corresponding to PortNumber %d\n", NdisOidRequest->PortNumber)); ndisStatus = NDIS_STATUS_INVALID_PORT; } else { // // Pass it to the appropriate port for processing // ndisStatus = Port11HandleDirectOidRequest( destinationPort, NdisOidRequest ); } } break; } if ((ndisStatus != NDIS_STATUS_SUCCESS) && (ndisStatus != NDIS_STATUS_PENDING)) { MpTrace(COMP_OID, DBG_SERIOUS, ("NDIS_OID_REQUEST for Direct OID 0x%08x failed. Status = 0x%08x\n", oid, ndisStatus)); } else { MpTrace(COMP_OID, DBG_SERIOUS, ("NDIS_OID_REQUEST for Direct OID 0x%08x succeeded. Status = 0x%08x\n", oid, ndisStatus)); } return ndisStatus; }