VOID VIOSerialPortClose( IN WDFFILEOBJECT FileObject ) { PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData( WdfFileObjectGetDevice(FileObject)); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE, "--> %s\n", __FUNCTION__); if (!pdoData->port->Removed && pdoData->port->GuestConnected) { VIOSerialSendCtrlMsg(pdoData->port->BusDevice, pdoData->port->PortId, VIRTIO_CONSOLE_PORT_OPEN, 0); } pdoData->port->GuestConnected = FALSE; WdfSpinLockAcquire(pdoData->port->InBufLock); VIOSerialDiscardPortDataLocked(pdoData->port); WdfSpinLockRelease(pdoData->port->InBufLock); WdfSpinLockAcquire(pdoData->port->OutVqLock); VIOSerialReclaimConsumedBuffers(pdoData->port); WdfSpinLockRelease(pdoData->port->OutVqLock); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE, "<-- %s\n", __FUNCTION__); }
NTSTATUS VIOSerialPortEvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port; PPORT_BUFFER buf; PSINGLE_LIST_ENTRY iter; UNREFERENCED_PARAMETER(TargetState); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__); WdfIoQueuePurge(Port->ReadQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT); WdfIoQueuePurge(Port->WriteQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT); WdfIoQueuePurge(Port->IoctlQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT); 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)VirtIODeviceDetachUnusedBuf(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; }
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); VIOSerialReclaimConsumedBuffers(Port); 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); WdfObjectDelete(entry->EntryHandle); iter = PopEntryList(&Port->WriteBuffersList); }; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__); return STATUS_SUCCESS; }