/************************************************************* Required NDIS procedure Stops TX and RX path and finished the function of adapter *************************************************************/ static VOID ParaNdis5_Halt( IN NDIS_HANDLE MiniportAdapterContext) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; BOOLEAN bUnused; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 1, 0, 0); NdisCancelTimer(&pContext->ConnectTimer, &bUnused); NdisResetEvent(&pContext->HaltEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopSend(pContext, TRUE, OnSendStopped)) NdisSetEvent(&pContext->HaltEvent); WaitHaltEvent(pContext, "Send"); NdisResetEvent(&pContext->HaltEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopReceive(pContext, TRUE, OnReceiveStopped)) NdisSetEvent(&pContext->HaltEvent); WaitHaltEvent(pContext, "Receive"); ParaNdis_CleanupContext(pContext); NdisCancelTimer(&pContext->DPCPostProcessTimer, &bUnused); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 0, 0, 0); ParaNdis_DebugRegisterMiniport(pContext, FALSE); NdisFreeMemory(pContext, 0, 0); DEBUG_EXIT_STATUS(0, status); }
VOID LtInitRemoveAdapter( IN NDIS_HANDLE MacAdapterContext ) /*++ Routine Description: Called to remove an adapter. This is only called after all bindings are closed. Arguments: MacAdapterContext : Context value passed to NdisRegister. Adapter Return Value: None. --*/ { BOOLEAN Cancelled, TimerQueued, Closing; PLT_ADAPTER Adapter = (PLT_ADAPTER)MacAdapterContext; NdisAcquireSpinLock(&Adapter->Lock); Closing = ((Adapter->Flags & ADAPTER_CLOSING) != 0); Adapter->Flags |= ADAPTER_CLOSING; TimerQueued = ((Adapter->Flags & ADAPTER_TIMER_QUEUED) != 0); Adapter->Flags &= ~ADAPTER_TIMER_QUEUED; NdisReleaseSpinLock(&Adapter->Lock); if (Closing) { ASSERTMSG("LtInitRemoveAdapter: Removing twice!\n", 0); return; } // Acording to Adam, this routine will NEVER be called with // outstanding opens. ASSERTMSG("LtRemoveAdapter: OpenCount is not zero!\n", (Adapter->OpenCount == 0)); // There are no opens left so remove ourselves. if (TimerQueued) { NdisCancelTimer(&Adapter->PollingTimer, &Cancelled); if (Cancelled) { // Remove the timer reference LtDeReferenceAdapter(Adapter); } } ASSERTMSG("LtRemoveAdapter: RefCount not correct!\n", (Adapter->RefCount == 1)); // Remove the creation reference LtDeReferenceAdapter(Adapter); return; }
void shared_interrupt_deregister(PNDIS_MINIPORT_INTERRUPT pintr, shared_info_t *sh) { if (sh->BusType == NdisInterfacePci || sh->BusType == NdisInterfacePcMcia) { NdisMDeregisterInterrupt(pintr); } else if (sh->BusType == NdisInterfaceSDIO) { if (sh->sdh != NULL) { bcmsdh_intr_disable(sh->sdh); bcmsdh_intr_dereg(sh->sdh); if (sh->dpc_handle) CloseHandle(sh->dpc_handle); NdisFreeEvent(&sh->dpc_event); } sh->isr_cb = sh->isr_arg = NULL; } { BOOLEAN cancelled; sh->dpc_cb = sh->dpc_arg = NULL; NdisCancelTimer(&sh->dpc_reshed_timer, &cancelled); } }
/************************************************************************ * SteMiniportHalt() * * NDIS Miniport エントリポイント * Halt ハンドラは NDIS が PNP マネージャから IRP_MN_STOP_DEVICE、 * IRP_MN_SUPRISE_REMOVE、IRP_MN_REMOVE_DEVICE 要求を受け取ったと * きに呼ばれる。SteMiniportInitialize で確保された全てのリソース * を解放する。(特定のミニポートドライバインスタンスに限定される) * * o 全ての I/O リソースを free し、unmap する。 * o NdisMRegisterAdapterShutdownHandler によって登録されたシャッ * トダウンハンドラを登録解除する。 * o NdisMCancelTimer を呼んでキューイングされているコールバック * ルーチンをキャンセルする。 * o 全ての未処理の受信パケットが処理され終わるまで待つ。 * * 引数: * MiniportAdapterContext アダプタへのポインタ * * 返り値: * * 無し ********************************************************************/ VOID SteMiniportHalt( IN NDIS_HANDLE MiniportAdapterContext ) { STE_ADAPTER *Adapter; BOOLEAN bTimerCancelled; INT i; DEBUG_PRINT0(3, "SteMiniportHalt called\n"); Adapter = (STE_ADAPTER *) MiniportAdapterContext; SteMiniportShutdown( (PVOID) Adapter //IN PVOID ); // // NdisMCancelTimer を呼んでキューイングされているコールバック // ルーチンをキャンセルする。 // // ReceiveIndication タイマーをキャンセル NdisCancelTimer( &Adapter->RecvTimer, // IN PNDIS_TIMER &bTimerCancelled // OUT PBOOLEAN ); // Reset タイマーをキャンセル NdisCancelTimer( &Adapter->ResetTimer, // IN PNDIS_TIMER &bTimerCancelled // OUT PBOOLEAN ); if (bTimerCancelled == TRUE){ // キャンセルされたコールバックルーチンがあったようだ。 // 受信キューに残っている Packet はこの後の SteDeleteAdapter() // によって Free されるので、ここでは何もしない。 } // NdisMRegisterAdapterShutdownHandler によって登録された // シャットダウンハンドラを登録解除する。 NdisMDeregisterAdapterShutdownHandler( Adapter->MiniportAdapterHandle // IN NDIS_HANDLE ); // // 仮想 NIC デーモンからの IOCT/READ/WRITE 用のデバイスの登録を解除する。 // SteDeregisterDevice(Adapter); // // 処理中の受信通知済みパケットがないかどうかチェックする。 // 1 秒おきに、STE_MAX_WAIT_FOR_RECVINDICATE(=5)回確認し、 // RecvIndicatedPackets が 0 にならないようであれば、 // なにか問題があったと考え無視してリソースの開放に進む。 // for ( i = 0 ; i < STE_MAX_WAIT_FOR_RECVINDICATE ; i++){ if (Adapter->RecvIndicatedPackets == 0) { break; } NdisMSleep(1000); } // // Adapter を削除する。このなかで、Adapter の為に確保されたリソースの // 開放も(Packet や、Buffer)行われる。 // SteDeleteAdapter(Adapter); return; }