static NTSTATUS VIOSerialInitAllQueues( IN WDFOBJECT Device) { NTSTATUS status = STATUS_SUCCESS; PPORTS_DEVICE pContext = GetPortsDevice(Device); UINT nr_ports, i, j; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__); nr_ports = pContext->consoleConfig.max_nr_ports; if(pContext->isHostMultiport) { nr_ports++; } for(i = 0, j = 0; i < nr_ports; i++) { if(i == 1) // Control Port { if (pContext->c_ivq) VirtIODeviceRenewQueue(pContext->c_ivq); else pContext->c_ivq = FindVirtualQueue(pContext->pIODevice, 2); if (pContext->c_ovq) VirtIODeviceRenewQueue(pContext->c_ovq); else pContext->c_ovq = FindVirtualQueue(pContext->pIODevice, 3); } else { if (pContext->in_vqs[j]) VirtIODeviceRenewQueue(pContext->in_vqs[j]); else pContext->in_vqs[j] = FindVirtualQueue(pContext->pIODevice, i * 2); if (pContext->out_vqs[j]) VirtIODeviceRenewQueue(pContext->out_vqs[j]); else pContext->out_vqs[j] = FindVirtualQueue(pContext->pIODevice, (i * 2) + 1); ++j; } } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__); return status; }
NTSTATUS BalloonInit( IN WDFOBJECT WdfDevice ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_CONTEXT devCtx = GetDeviceContext(WdfDevice); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> BalloonInit\n"); VirtIODeviceReset(&devCtx->VDevice); VirtIODeviceAddStatus(&devCtx->VDevice, VIRTIO_CONFIG_S_ACKNOWLEDGE); VirtIODeviceAddStatus(&devCtx->VDevice, VIRTIO_CONFIG_S_DRIVER); do { if (!devCtx->InfVirtQueue) { devCtx->InfVirtQueue = FindVirtualQueue(&devCtx->VDevice, 0); } else { VirtIODeviceRenewQueue(devCtx->InfVirtQueue); } if (!devCtx->InfVirtQueue) { status = STATUS_INSUFFICIENT_RESOURCES; break; } if (!devCtx->DefVirtQueue) { devCtx->DefVirtQueue = FindVirtualQueue(&devCtx->VDevice, 1); } else { VirtIODeviceRenewQueue(devCtx->DefVirtQueue); } if (!devCtx->DefVirtQueue) { status = STATUS_INSUFFICIENT_RESOURCES; break; } if(VirtIODeviceGetHostFeature(&devCtx->VDevice, VIRTIO_BALLOON_F_STATS_VQ)) { BOOLEAN bNeedBuffer = FALSE; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> VIRTIO_BALLOON_F_STATS_VQ\n"); if(!devCtx->StatVirtQueue) { devCtx->StatVirtQueue = FindVirtualQueue(&devCtx->VDevice, 2); bNeedBuffer = TRUE; } else { VirtIODeviceRenewQueue(devCtx->StatVirtQueue); } if(!devCtx->StatVirtQueue) { status = STATUS_INSUFFICIENT_RESOURCES; break; } if (bNeedBuffer) { VIO_SG sg; sg.physAddr = MmGetPhysicalAddress(devCtx->MemStats); sg.ulSize = sizeof (BALLOON_STAT) * VIRTIO_BALLOON_S_NR; if(devCtx->StatVirtQueue->vq_ops->add_buf(devCtx->StatVirtQueue, &sg, 1, 0, devCtx, NULL, 0) < 0) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> %s :: Cannot add buffer\n", __FUNCTION__); } } devCtx->StatVirtQueue->vq_ops->kick(devCtx->StatVirtQueue); if(devCtx->bServiceConnected) { VirtIODeviceEnableGuestFeature(&devCtx->VDevice, VIRTIO_BALLOON_F_STATS_VQ); } } } while(FALSE); if(NT_SUCCESS(status)) { VirtIODeviceAddStatus(&devCtx->VDevice, VIRTIO_CONFIG_S_DRIVER_OK); } else { VirtIODeviceAddStatus(&devCtx->VDevice, VIRTIO_CONFIG_S_FAILED); } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- BalloonInit\n"); return status; }
static NTSTATUS VIOSerialInitAllQueues( IN WDFOBJECT Device) { NTSTATUS status = STATUS_SUCCESS; PPORTS_DEVICE pContext = GetPortsDevice(Device); UINT nr_ports, i, j; USHORT ControlVector, QueuesVector; WDF_INTERRUPT_INFO info; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__); WDF_INTERRUPT_INFO_INIT(&info); WdfInterruptGetInfo(pContext->WdfInterrupt, &info); ControlVector = info.MessageSignaled ? 0 : VIRTIO_MSI_NO_VECTOR; WDF_INTERRUPT_INFO_INIT(&info); WdfInterruptGetInfo(pContext->QueuesInterrupt, &info); QueuesVector = (ControlVector != VIRTIO_MSI_NO_VECTOR) ? (info.Vector ? 1 : 0) : VIRTIO_MSI_NO_VECTOR; nr_ports = pContext->consoleConfig.max_nr_ports; if(pContext->isHostMultiport) { nr_ports++; } for(i = 0, j = 0; i < nr_ports; i++) { if(i == 1) // Control Port { if (pContext->c_ivq) VirtIODeviceRenewQueue(pContext->c_ivq); else pContext->c_ivq = FindVirtualQueue(pContext->pIODevice, 2, ControlVector); if (pContext->c_ovq) VirtIODeviceRenewQueue(pContext->c_ovq); else pContext->c_ovq = FindVirtualQueue(pContext->pIODevice, 3, ControlVector); } else { if (pContext->in_vqs[j]) VirtIODeviceRenewQueue(pContext->in_vqs[j]); else pContext->in_vqs[j] = FindVirtualQueue(pContext->pIODevice, i * 2, QueuesVector); if (pContext->out_vqs[j]) VirtIODeviceRenewQueue(pContext->out_vqs[j]); else pContext->out_vqs[j] = FindVirtualQueue(pContext->pIODevice, (i * 2) + 1, QueuesVector); ++j; } } if (pContext->isHostMultiport && (pContext->c_ovq == NULL)) { status = STATUS_NOT_FOUND; } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__); return status; }