Esempio n. 1
0
NTSTATUS
SampleDrvEvtDeviceD0Entry (
    _In_ WDFDEVICE Device,
    _In_ WDF_POWER_DEVICE_STATE PreviousPowerState
    )

/*++

Routine Description:

    This routine is invoked by the framework to program the device to goto
    D0, which is the working state. The framework invokes callback every
    time the hardware needs to be (re-)initialized.  This includes after
    IRP_MN_START_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE,
    and IRP_MN_SET_POWER-D0.

    N.B. This function is not marked pageable because this function is in
         the device power up path. When a function is marked pagable and the
         code section is paged out, it will generate a page fault which could
         impact the fast resume behavior because the client driver will have
         to wait until the system drivers can service this page fault.

Arguments:

    Device - Supplies a handle to the framework device object.

    PreviousPowerState - WDF_POWER_DEVICE_STATE-typed enumerator that identifies
        the device power state that the device was in before this transition
        to D0.

Return Value:

    NTSTATUS code. A failure here will indicate a fatal error and cause the
    framework to tear down the stack.

--*/

{

    BYTE Data;
    NTSTATUS Status;
    WDFIOTARGET ReadTarget;
    WDFIOTARGET WriteTarget;
    PSAMPLE_DRV_DEVICE_EXTENSION SampleDrvExtension;
    UNICODE_STRING ReadString;
    WCHAR ReadStringBuffer[100];
    UNICODE_STRING WriteString;
    WCHAR WriteStringBuffer[100];

    UNREFERENCED_PARAMETER(PreviousPowerState);

    ReadTarget = NULL;
    WriteTarget = NULL;

    SampleDrvExtension = SampleDrvGetDeviceExtension(Device);

    //
    //  For demonstration purporses, the sample device consumes two IO resources,
    //  the first of which will be used for input, and the second for output.
    //

    RtlInitEmptyUnicodeString(&ReadString,
                              ReadStringBuffer,
                              sizeof(ReadStringBuffer));

    RtlInitEmptyUnicodeString(&WriteString,
                              WriteStringBuffer,
                              sizeof(WriteStringBuffer));


    //
    //  Construct full-path string for GPIO read operation
    //

    Status = RESOURCE_HUB_CREATE_PATH_FROM_ID(&ReadString,
                                              SampleDrvExtension->ConnectionIds[0].LowPart,
                                              SampleDrvExtension->ConnectionIds[0].HighPart);

    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    //  Construct full-path string for GPIO write operation
    //

    Status = RESOURCE_HUB_CREATE_PATH_FROM_ID(&WriteString,
                                              SampleDrvExtension->ConnectionIds[1].LowPart,
                                              SampleDrvExtension->ConnectionIds[1].HighPart);

    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    // Perform the read operation
    //

    Data = 0x0;
    Status = TestReadWrite(Device, &ReadString, TRUE, &Data, sizeof(Data), &ReadTarget);
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    //  Perform the write operation
    //

    Status = TestReadWrite(Device, &WriteString, FALSE, &Data, sizeof(Data), &WriteTarget);
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

Cleanup:

    if (ReadTarget != NULL) {
        WdfIoTargetClose(ReadTarget);
        WdfObjectDelete(ReadTarget);
    }

    if (WriteTarget != NULL) {
        WdfIoTargetClose(WriteTarget);
        WdfObjectDelete(WriteTarget);
    }

    return Status;
}
Esempio n. 2
0
NTSTATUS
I2COpen(
    _In_ PDEVICE_CONTEXT DeviceContext
)
/*++

Routine Description:

    This routine opens a handle to the I2C controller.

Arguments:

    DeviceContext - a pointer to the device context

Return Value:

    NTSTATUS

--*/
{
    TRACE_FUNC_ENTRY(TRACE_I2C);

    PAGED_CODE();

    NTSTATUS status;
    WDF_IO_TARGET_OPEN_PARAMS openParams;
    WDF_OBJECT_ATTRIBUTES requestAttributes;
    WDF_OBJECT_ATTRIBUTES workitemAttributes;
    WDF_WORKITEM_CONFIG workitemConfig;

    // Create the device path using the connection ID.
    DECLARE_UNICODE_STRING_SIZE(DevicePath, RESOURCE_HUB_PATH_SIZE);

    RESOURCE_HUB_CREATE_PATH_FROM_ID(
        &DevicePath,
        DeviceContext->I2CConnectionId.LowPart,
        DeviceContext->I2CConnectionId.HighPart);

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_I2C,
        "Opening handle to I2C target via %wZ", &DevicePath);

    status = WdfIoTargetCreate(DeviceContext->Device, WDF_NO_OBJECT_ATTRIBUTES, &DeviceContext->I2CIoTarget);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfIoTargetCreate failed - %!STATUS!", status);
        goto Exit;
    }

    // Open a handle to the I2C controller.
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
        &openParams,
        &DevicePath,
        (GENERIC_READ | GENERIC_WRITE));

    openParams.ShareAccess = 0;
    openParams.CreateDisposition = FILE_OPEN;
    openParams.FileAttributes = FILE_ATTRIBUTE_NORMAL;

    status = WdfIoTargetOpen(DeviceContext->I2CIoTarget, &openParams);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "Failed to open I2C I/O target - %!STATUS!", status);
        goto Exit;
    }

    // Create a WDFMEMORY object. Do call WdfMemoryAssignBuffer before use it,
    status = WdfMemoryCreatePreallocated(
        WDF_NO_OBJECT_ATTRIBUTES,
        static_cast<PVOID>(&status), // initial value does not matter
        sizeof(status),
        &DeviceContext->I2CMemory);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfMemoryCreatePreallocated failed with status %!STATUS!", status);
        goto Exit;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&requestAttributes);
    requestAttributes.ParentObject = DeviceContext->I2CIoTarget;

    for (ULONG i = 0; i < I2CRequestSourceMax; i++)
    {
        status = WdfRequestCreate(&requestAttributes, DeviceContext->I2CIoTarget, &DeviceContext->OutgoingRequests[i]);
        if (!NT_SUCCESS(status))
        {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
                "WdfRequestCreate failed with status %!STATUS!", status);
            goto Exit;
        }
    }

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&workitemAttributes, WORKITEM_CONTEXT);
    workitemAttributes.ParentObject = DeviceContext->I2CIoTarget;

    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, EvtWorkItemGetStatus);
    status = WdfWorkItemCreate(&workitemConfig, &workitemAttributes, &DeviceContext->I2CWorkItemGetStatus);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfWorkItemCreate failed with status %!STATUS!", status);
        goto Exit;
    }

    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, EvtWorkItemGetControl);
    status = WdfWorkItemCreate(&workitemConfig, &workitemAttributes, &DeviceContext->I2CWorkItemGetControl);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfWorkItemCreate failed with status %!STATUS!", status);
        goto Exit;
    }

Exit:
    TRACE_FUNC_EXIT(TRACE_I2C);
    return status;
}