Exemplo n.º 1
0
NTSTATUS VIOSerialPortEvtDeviceD0Entry(
    IN WDFDEVICE Device,
    IN WDF_POWER_DEVICE_STATE PreviousState)
{
    PVIOSERIAL_PORT port = RawPdoSerialPortGetData(Device)->port;
    PPORTS_DEVICE pCtx = GetPortsDevice(port->BusDevice);
    NTSTATUS status;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);

    PAGED_CODE();

    if ((pCtx->in_vqs == NULL) || (pCtx->in_vqs[port->PortId] == NULL))
    {
        return STATUS_NOT_FOUND;
    }

    status = VIOSerialFillQueue(GetInQueue(port), port->InBufLock);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "Error allocating input queue's buffers.\n");
        return status;
    }

    VIOSerialSendCtrlMsg(port->BusDevice, port->PortId,
        VIRTIO_CONSOLE_PORT_READY, 1);

    if (port->GuestConnected)
    {
        VIOSerialSendCtrlMsg(port->BusDevice, port->PortId,
            VIRTIO_CONSOLE_PORT_OPEN, 1);
    }

    port->Removed = FALSE;

    VIOSerialEnableInterruptQueue(GetInQueue(port));

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);

    return status;
}
VOID
VIOSerialRenewAllPorts(
    IN WDFDEVICE Device
)
{
    NTSTATUS                     status = STATUS_SUCCESS;
    WDFCHILDLIST                 list;
    WDF_CHILD_LIST_ITERATOR      iterator;
    PPORTS_DEVICE                pContext = GetPortsDevice(Device);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> %s\n", __FUNCTION__);

    if(pContext->isHostMultiport)
    {
        VIOSerialFillQueue(pContext->c_ivq, pContext->CVqLock);
    }

    list = WdfFdoGetDefaultChildList(Device);
    WDF_CHILD_LIST_ITERATOR_INIT(&iterator,
                                 WdfRetrievePresentChildren );

    WdfChildListBeginIteration(list, &iterator);

    for (;;)
    {
        WDF_CHILD_RETRIEVE_INFO  childInfo;
        VIOSERIAL_PORT           vport;
        WDFDEVICE                hChild;

        WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(
                                 &vport.Header,
                                 sizeof(vport)
                                 );
        WDF_CHILD_RETRIEVE_INFO_INIT(&childInfo, &vport.Header);

        status = WdfChildListRetrieveNextDevice(
                                 list,
                                 &iterator,
                                 &hChild,
                                 &childInfo
                                 );
        if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES)
        {
            break;
        }
        ASSERT(childInfo.Status == WdfChildListRetrieveDeviceSuccess);

        VIOSerialEnableInterruptQueue(GetInQueue(&vport));

        WdfIoQueueStart(vport.ReadQueue);
        WdfIoQueueStart(vport.WriteQueue);
        WdfIoQueueStart(vport.IoctlQueue);

        if(vport.GuestConnected)
        {
           VIOSerialSendCtrlMsg(vport.BusDevice, vport.PortId, VIRTIO_CONSOLE_PORT_OPEN, 1);
        }
    }
    WdfChildListEndIteration(list, &iterator);
    WdfChildListUpdateAllChildDescriptionsAsPresent(list);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"<-- %s\n", __FUNCTION__);
    return;
}