Ejemplo n.º 1
0
PVIOSERIAL_PORT
VIOSerialFindPortById(
    IN WDFDEVICE Device,
    IN ULONG id
)
{
    NTSTATUS        status = STATUS_SUCCESS;
    WDFCHILDLIST    list;
    WDF_CHILD_LIST_ITERATOR     iterator;
    PRAWPDO_VIOSERIAL_PORT          rawPdo = NULL;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,"%s  port = %d\n", __FUNCTION__, id);

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

    WdfChildListBeginIteration(list, &iterator);

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

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

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

        if(rawPdo && rawPdo->port->PortId == id)
        {
            WdfChildListEndIteration(list, &iterator);
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"%s  id = %d port = 0x%p\n", __FUNCTION__, id, rawPdo->port);
            return rawPdo->port;
        }
    }
    WdfChildListEndIteration(list, &iterator);
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s\n", __FUNCTION__);
    return NULL;
}
Ejemplo n.º 2
0
NTSTATUS
Bus_EjectDevice(
    WDFDEVICE   Device,
    ULONG       SerialNo
    )

/*++

Routine Description:

    The user application has told us to eject the device from the bus.
    In a real situation the driver gets notified by an interrupt when the
    user presses the Eject button on the device.

Arguments:


Returns:

    STATUS_SUCCESS upon successful removal from the list
    STATUS_INVALID_PARAMETER if the ejection was unsuccessful

--*/

{
    WDFDEVICE        hChild;
    NTSTATUS         status = STATUS_INVALID_PARAMETER;
    WDFCHILDLIST     list;

    PAGED_CODE ();

    list = WdfFdoGetDefaultChildList(Device);

    //
    // A zero serial number means eject all children
    //
    if (0 == SerialNo) {
        WDF_CHILD_LIST_ITERATOR     iterator;

        WDF_CHILD_LIST_ITERATOR_INIT( &iterator,
                                      WdfRetrievePresentChildren );

        WdfChildListBeginIteration(list, &iterator);

        for ( ; ; ) {
            WDF_CHILD_RETRIEVE_INFO         childInfo;
            PDO_IDENTIFICATION_DESCRIPTION  description;
            BOOLEAN                         ret;

            //
            // Init the structures.
            //
            WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
            WDF_CHILD_RETRIEVE_INFO_INIT(&childInfo, &description.Header);

            WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(
                                    &description.Header,
                                    sizeof(description)
                                    );
            //
            // Get the device identification description
            //
            status = WdfChildListRetrieveNextDevice(list,
                                                &iterator,
                                                &hChild,
                                                &childInfo);

            if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES) {
                break;
            }

            ASSERT(childInfo.Status == WdfChildListRetrieveDeviceSuccess);

            //
            // Use that description to request an eject.
            //
            ret = WdfChildListRequestChildEject(list, &description.Header);
            if(!ret) {
                WDFVERIFY(ret);
            }

        }

        WdfChildListEndIteration(list, &iterator);

        if (status == STATUS_NO_MORE_ENTRIES) {
            status = STATUS_SUCCESS;
        }

    }
    else {

        PDO_IDENTIFICATION_DESCRIPTION description;

        WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(
            &description.Header,
            sizeof(description)
            );

        description.SerialNo = SerialNo;

        if (WdfChildListRequestChildEject(list, &description.Header)) {
            status = STATUS_SUCCESS;
        }
    }

    return status;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
NTSTATUS
VIOSerialEvtDeviceD0ExitPreInterruptsDisabled(
    IN WDFDEVICE WdfDevice,
    IN WDF_POWER_DEVICE_STATE TargetState
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    WDFCHILDLIST portList;
    WDF_CHILD_LIST_ITERATOR portIterator;

    UNREFERENCED_PARAMETER(TargetState);

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

    PAGED_CODE();

    portList = WdfFdoGetDefaultChildList(WdfDevice);
    WDF_CHILD_LIST_ITERATOR_INIT(&portIterator, WdfRetrievePresentChildren);

    WdfChildListBeginIteration(portList, &portIterator);

    for (;;)
    {
        WDF_CHILD_RETRIEVE_INFO childInfo;
        WDFDEVICE hChild;
        VIOSERIAL_PORT port;
        PRAWPDO_VIOSERIAL_PORT pdoData;

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

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

        pdoData = RawPdoSerialPortGetData(hChild);

        if (pdoData->port->GuestConnected && !pdoData->port->Removed)
        {
            VIOSerialSendCtrlMsg(pdoData->port->BusDevice, pdoData->port->PortId,
                VIRTIO_CONSOLE_PORT_OPEN, 0);
            pdoData->port->GuestConnected = FALSE;
        }
        pdoData->port->Removed = TRUE;
    }

    WdfChildListEndIteration(portList, &portIterator);

    if (status == STATUS_NO_MORE_ENTRIES)
    {
        status = STATUS_SUCCESS;
    }

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s: 0x%x\n",
        __FUNCTION__, status);

    return status;
}