NTSTATUS VIOSerialEvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { PPORTS_DEVICE pContext = GetPortsDevice(Device); PPORT_BUFFER buf; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> %s TargetState: %d\n", __FUNCTION__, TargetState); PAGED_CODE(); while (buf = (PPORT_BUFFER)virtqueue_detach_unused_buf(pContext->c_ivq)) { VIOSerialFreeBuffer(buf); } VIOSerialShutDownAllQueues(Device); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__); return STATUS_SUCCESS; }
NTSTATUS VIOSerialPortEvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port; PPORT_BUFFER buf; PSINGLE_LIST_ENTRY iter; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s TargetState: %d\n", __FUNCTION__, TargetState); Port->Removed = TRUE; VIOSerialDisableInterruptQueue(GetInQueue(Port)); WdfSpinLockAcquire(Port->InBufLock); VIOSerialDiscardPortDataLocked(Port); Port->InBuf = NULL; WdfSpinLockRelease(Port->InBufLock); WdfSpinLockAcquire(Port->OutVqLock); VIOSerialReclaimConsumedBuffers(Port); WdfSpinLockRelease(Port->OutVqLock); while (buf = (PPORT_BUFFER)virtqueue_detach_unused_buf(GetInQueue(Port))) { VIOSerialFreeBuffer(buf); } iter = PopEntryList(&Port->WriteBuffersList); while (iter != NULL) { PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter, WRITE_BUFFER_ENTRY, ListEntry); ExFreePoolWithTag(entry->Buffer, VIOSERIAL_DRIVER_MEMORY_TAG); ExFreePoolWithTag(entry, VIOSERIAL_DRIVER_MEMORY_TAG); iter = PopEntryList(&Port->WriteBuffersList); }; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__); return STATUS_SUCCESS; }
/* Disable the CAIF interface and free the memory-pool */ static int cfv_netdev_close(struct net_device *netdev) { struct cfv_info *cfv = netdev_priv(netdev); unsigned long flags; struct buf_info *buf_info; /* Disable interrupts, queues and NAPI polling */ netif_carrier_off(netdev); virtqueue_disable_cb(cfv->vq_tx); vringh_notify_disable_kern(cfv->vr_rx); napi_disable(&cfv->napi); /* Release any TX buffers on both used and avilable rings */ cfv_release_used_buf(cfv->vq_tx); spin_lock_irqsave(&cfv->tx_lock, flags); while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx))) free_buf_info(cfv, buf_info); spin_unlock_irqrestore(&cfv->tx_lock, flags); /* Release all dma allocated memory and destroy the pool */ cfv_destroy_genpool(cfv); return 0; }