/********************************************************** Required NDIS handler for RESET operation Never happens under normal condition, only if OID or other call returns PENDING and not completed or if ParaNdis6_CheckForHang returns true ***********************************************************/ static NDIS_STATUS ParaNdis6_Reset( NDIS_HANDLE miniportAdapterContext, PBOOLEAN pAddressingReset) { NDIS_STATUS status = NDIS_STATUS_FAILURE; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; NDIS_HANDLE hwo; tGeneralWorkItem *pwi; DEBUG_ENTRY(0); *pAddressingReset = TRUE; ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 1, 0, 0); hwo = NdisAllocateIoWorkItem(pContext->MiniportHandle); pwi = ParaNdis_AllocateMemory(pContext, sizeof(tGeneralWorkItem)); if (pwi && hwo) { pwi->pContext = pContext; pwi->WorkItem = hwo; NdisQueueIoWorkItem(hwo, OnResetWorkItem, pwi); status = NDIS_STATUS_PENDING; } else { if (pwi) NdisFreeMemory(pwi, 0, 0); if (hwo) NdisFreeIoWorkItem(hwo); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, status, 0); } DEBUG_EXIT_STATUS(0, status); return status; }
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; }
NDIS_STATUS Hvl11Allocate( _In_ NDIS_HANDLE MiniportAdapterHandle, _Outptr_result_maybenull_ PHVL* ppHvl, _In_ PADAPTER pAdapter ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PHVL pHvl = NULL; NDIS_HANDLE ctxSWorkItemHandle = NULL, notificationsWorkItemHandle = NULL; BOOLEAN fFreeCtxSWorkItemHandle = FALSE, fFreeNotifWorkItemHandle = FALSE; PHVL_EX_ACCESS_REQ pExReq = NULL; ASSERT(MiniportAdapterHandle && ppHvl && pAdapter); *ppHvl = NULL; do { ndisStatus = ALLOC_MEM(MiniportAdapterHandle, sizeof(HVL), &pHvl); if (NDIS_STATUS_SUCCESS != ndisStatus) { MpTrace(COMP_HVL, DBG_SERIOUS, ("Failed to allocate memory for a new HVL")); break; } // the list heads should be the first ones to be initialized. This allows us to free things // correctly if Free is called without Initialize being called in between InitializeListHead(&pHvl->VNiclist); InitializeListHead(&pHvl->InactiveContextList); InitializeListHead(&pHvl->PendingOpQueue); InitializeListHead(&pHvl->NotificationsQueue); // Allocate memory for fields inside the HVL structure // pre-allocate the exclusive access request structure for PnP related exclusive accesses ndisStatus = ALLOC_MEM(MiniportAdapterHandle, sizeof(HVL_EX_ACCESS_REQ), &pExReq); if (NDIS_STATUS_SUCCESS != ndisStatus) { MpTrace(COMP_HVL, DBG_SERIOUS, ("Failed to allocate memory for exclusive access request")); break; } NdisAllocateSpinLock(&(pHvl->Lock)); // Allocate the context switch work item ctxSWorkItemHandle = NdisAllocateIoWorkItem(MiniportAdapterHandle); if(NULL == ctxSWorkItemHandle) { MpTrace (COMP_HVL, DBG_SERIOUS, ("NdisAllocateIoWorkItem failed")); ndisStatus = NDIS_STATUS_RESOURCES; break; } fFreeCtxSWorkItemHandle = TRUE; notificationsWorkItemHandle = NdisAllocateIoWorkItem(MiniportAdapterHandle); if(NULL == notificationsWorkItemHandle) { MpTrace (COMP_HVL, DBG_SERIOUS, ("NdisAllocateIoWorkItem failed")); ndisStatus = NDIS_STATUS_RESOURCES; break; } fFreeNotifWorkItemHandle = TRUE; pHvl->MiniportAdapterHandle = MiniportAdapterHandle; pHvl->Adapter = pAdapter; pHvl->CtxSWorkItemHandle = ctxSWorkItemHandle; pHvl->NotificationsWorkItemHandle = notificationsWorkItemHandle; pHvl->fVirtualizationEnabled = TRUE; pHvl->pPnpOpExReq = pExReq; *ppHvl = pHvl; }while (FALSE); if (NDIS_STATUS_SUCCESS != ndisStatus) { if (fFreeNotifWorkItemHandle) { NdisFreeIoWorkItem(notificationsWorkItemHandle); } if (fFreeCtxSWorkItemHandle) { NdisFreeIoWorkItem(ctxSWorkItemHandle); } if (pExReq) { FREE_MEM(pExReq); } if (pHvl) { FREE_MEM(pHvl); } } return ndisStatus; }
NDIS_STATUS Hw11Allocate( __in NDIS_HANDLE MiniportAdapterHandle, __deref_out_opt PHW* Hw, __in PADAPTER Adapter ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PHW newHw = NULL; ULONG size; NDIS_TIMER_CHARACTERISTICS timerChar; *Hw = NULL; do { // Allocate a HW data structure MP_ALLOCATE_MEMORY(MiniportAdapterHandle, &newHw, sizeof(HW), HW_MEMORY_TAG); if (newHw == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate %d bytes for HW\n", sizeof(HW))); ndisStatus = NDIS_STATUS_RESOURCES; break; } // Clear everything NdisZeroMemory(newHw, sizeof(HW)); // We start in the PAUSED state HW_SET_ADAPTER_STATUS(newHw, HW_ADAPTER_PAUSED); newHw->InterruptDisableCount = 1; // Since we are paused, we want the interrupts to be disabled #if DBG NdisInterlockedIncrement(&newHw->Tracking_InterruptDisable[HW_ISR_TRACKING_PAUSE]); #endif // Allocate memory for fields inside the HW structure size = sizeof(DOT11_REG_DOMAINS_SUPPORT_VALUE) + (HW_MAX_NUM_DOT11_REG_DOMAINS_VALUE - 1) * sizeof(DOT11_REG_DOMAIN_VALUE); MP_ALLOCATE_MEMORY(MiniportAdapterHandle, &(newHw->PhyState.RegDomainsSupportValue), size, HW_MEMORY_TAG); if (newHw->PhyState.RegDomainsSupportValue == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate memory for RegDomainsSupportValue\n")); ndisStatus = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(newHw->PhyState.RegDomainsSupportValue, size); size = sizeof(DOT11_DIVERSITY_SELECTION_RX_LIST) + (HW_MAX_NUM_DIVERSITY_SELECTION_RX_LIST - 1) * sizeof(DOT11_DIVERSITY_SELECTION_RX); MP_ALLOCATE_MEMORY(MiniportAdapterHandle, &(newHw->PhyState.DiversitySelectionRxList), size, HW_MEMORY_TAG); if (newHw->PhyState.DiversitySelectionRxList == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate memory for DiversitySelectionRxList\n")); ndisStatus = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(newHw->PhyState.DiversitySelectionRxList, size); NdisZeroMemory(&timerChar, sizeof(NDIS_TIMER_CHARACTERISTICS)); // Allocate the power save wake timer timerChar.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS; timerChar.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1; timerChar.Header.Size = sizeof(NDIS_TIMER_CHARACTERISTICS); timerChar.AllocationTag = HW_MEMORY_TAG; timerChar.TimerFunction = HwAwakeTimer; timerChar.FunctionContext = newHw; ndisStatus = NdisAllocateTimerObject( MiniportAdapterHandle, &timerChar, &newHw->PhyState.Timer_Awake ); if (ndisStatus != NDIS_STATUS_SUCCESS) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate power save awake timer\n")); break; } // Allocate the power save sleep timer timerChar.TimerFunction = HwDozeTimer; timerChar.FunctionContext = newHw; ndisStatus = NdisAllocateTimerObject( MiniportAdapterHandle, &timerChar, &newHw->PhyState.Timer_Doze ); if (ndisStatus != NDIS_STATUS_SUCCESS) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate power save doze timer\n")); break; } // Allocate the scan timer timerChar.TimerFunction = HwScanTimer; timerChar.FunctionContext = newHw; ndisStatus = NdisAllocateTimerObject( MiniportAdapterHandle, &timerChar, &newHw->ScanContext.Timer_Scan ); if (ndisStatus != NDIS_STATUS_SUCCESS) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate scan timer\n")); break; } newHw->PhyState.PhyProgramWorkItem = NdisAllocateIoWorkItem(MiniportAdapterHandle); if(newHw->PhyState.PhyProgramWorkItem == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate channel switch work item\n")); ndisStatus = NDIS_STATUS_RESOURCES; break; } // The hardware lock NdisAllocateSpinLock(&newHw->Lock); // Save the Adapter pointer in the HW newHw->Adapter = Adapter; newHw->MiniportAdapterHandle = MiniportAdapterHandle; // Return the newly created structure to the caller *Hw = newHw; } while (FALSE); if (ndisStatus != NDIS_STATUS_SUCCESS) { if (newHw != NULL) { Hw11Free(newHw); } } return ndisStatus; }