예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}