summaryrefslogtreecommitdiff
path: root/spb/SpbTestTool/sys/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'spb/SpbTestTool/sys/device.cpp')
-rw-r--r--spb/SpbTestTool/sys/device.cpp848
1 files changed, 0 insertions, 848 deletions
diff --git a/spb/SpbTestTool/sys/device.cpp b/spb/SpbTestTool/sys/device.cpp
deleted file mode 100644
index 28455aa6..00000000
--- a/spb/SpbTestTool/sys/device.cpp
+++ /dev/null
@@ -1,848 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-Module Name:
-
- device.cpp
-
-Abstract:
-
- This module contains WDF device initialization
- functions for the peripheral driver.
-
-Environment:
-
- kernel-mode only
-
-Revision History:
-
---*/
-
-#include "internal.h"
-#include "peripheral.h"
-#include "device.h"
-
-#include "device.tmh"
-
-
-/////////////////////////////////////////////////
-//
-// WDF callbacks.
-//
-/////////////////////////////////////////////////
-
-NTSTATUS
-OnPrepareHardware(
- _In_ WDFDEVICE FxDevice,
- _In_ WDFCMRESLIST FxResourcesRaw,
- _In_ WDFCMRESLIST FxResourcesTranslated
- )
-/*++
-
- Routine Description:
-
- This routine caches the SPB resource connection ID.
-
- Arguments:
-
- FxDevice - a handle to the framework device object
- FxResourcesRaw - list of translated hardware resources that
- the PnP manager has assigned to the device
- FxResourcesTranslated - list of raw hardware resources that
- the PnP manager has assigned to the device
-
- Return Value:
-
- Status
-
---*/
-{
- FuncEntry(TRACE_FLAG_WDFLOADING);
-
- PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);
- BOOLEAN fSpbResourceFound = FALSE;
- BOOLEAN fInterruptResourceFound = FALSE;
- ULONG interruptIndex = 0;
- NTSTATUS status = STATUS_SUCCESS;
-
- UNREFERENCED_PARAMETER(FxResourcesRaw);
-
- //
- // Parse the peripheral's resources.
- //
-
- ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated);
-
- for(ULONG i = 0; i < resourceCount; i++)
- {
- PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
- UCHAR Class;
- UCHAR Type;
-
- pDescriptor = WdfCmResourceListGetDescriptor(
- FxResourcesTranslated, i);
-
- switch (pDescriptor->Type)
- {
- case CmResourceTypeConnection:
-
- //
- // Look for I2C or SPI resource and save connection ID.
- //
-
- Class = pDescriptor->u.Connection.Class;
- Type = pDescriptor->u.Connection.Type;
-
- if ((Class == CM_RESOURCE_CONNECTION_CLASS_SERIAL) &&
- ((Type == CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C) ||
- (Type == CM_RESOURCE_CONNECTION_TYPE_SERIAL_SPI)))
- {
- if (fSpbResourceFound == FALSE)
- {
- pDevice->PeripheralId.LowPart =
- pDescriptor->u.Connection.IdLowPart;
- pDevice->PeripheralId.HighPart =
- pDescriptor->u.Connection.IdHighPart;
-
- fSpbResourceFound = TRUE;
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_WDFLOADING,
- "SPB resource found with ID=0x%llx",
- pDevice->PeripheralId.QuadPart);
- }
- else
- {
- Trace(
- TRACE_LEVEL_WARNING,
- TRACE_FLAG_WDFLOADING,
- "Duplicate SPB resource found with ID=0x%llx",
- pDevice->PeripheralId.QuadPart);
- }
- }
-
- break;
-
- case CmResourceTypeInterrupt:
-
- if (fInterruptResourceFound == FALSE)
- {
- fInterruptResourceFound = TRUE;
- interruptIndex = i;
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_WDFLOADING,
- "Interrupt resource found");
- }
- else
- {
- Trace(
- TRACE_LEVEL_WARNING,
- TRACE_FLAG_WDFLOADING,
- "Duplicate interrupt resource found");
- }
-
- break;
-
- default:
-
- //
- // Ignoring all other resource types.
- //
-
- break;
- }
- }
-
- //
- // An SPB resource is required.
- //
-
- if (fSpbResourceFound == FALSE)
- {
- status = STATUS_NOT_FOUND;
- Trace(
- TRACE_LEVEL_ERROR,
- TRACE_FLAG_WDFLOADING,
- "SPB resource not found - %!STATUS!",
- status);
- }
-
- //
- // Create the interrupt if an interrupt
- // resource was found.
- //
-
- if (NT_SUCCESS(status))
- {
- if ((pDevice->ConnectInterrupt == TRUE) &&
- (fInterruptResourceFound == TRUE))
- {
- WDF_INTERRUPT_CONFIG interruptConfig;
- WDF_INTERRUPT_CONFIG_INIT(
- &interruptConfig,
- OnInterruptIsr,
- NULL);
-
- interruptConfig.PassiveHandling = TRUE;
- interruptConfig.InterruptTranslated = WdfCmResourceListGetDescriptor(
- FxResourcesTranslated,
- interruptIndex);
- interruptConfig.InterruptRaw = WdfCmResourceListGetDescriptor(
- FxResourcesRaw,
- interruptIndex);
-
- status = WdfInterruptCreate(
- pDevice->FxDevice,
- &interruptConfig,
- WDF_NO_OBJECT_ATTRIBUTES,
- &pDevice->Interrupt);
-
- if (!NT_SUCCESS(status))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- TRACE_FLAG_WDFLOADING,
- "WdfInterruptCreate failed - %!STATUS!",
- status);
- }
-
- if (NT_SUCCESS(status))
- {
- KeInitializeEvent(
- &pDevice->IsrWaitEvent,
- SynchronizationEvent,
- FALSE);
- }
- }
- }
-
- FuncExit(TRACE_FLAG_WDFLOADING);
-
- return status;
-}
-
-NTSTATUS
-OnReleaseHardware(
- _In_ WDFDEVICE FxDevice,
- _In_ WDFCMRESLIST FxResourcesTranslated
- )
-/*++
-
- Routine Description:
-
- Arguments:
-
- FxDevice - a handle to the framework device object
- FxResourcesTranslated - list of raw hardware resources that
- the PnP manager has assigned to the device
-
- Return Value:
-
- Status
-
---*/
-{
- FuncEntry(TRACE_FLAG_WDFLOADING);
-
- PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);
- NTSTATUS status = STATUS_SUCCESS;
-
- UNREFERENCED_PARAMETER(FxResourcesTranslated);
-
- if (pDevice->Interrupt != nullptr)
- {
- WdfObjectDelete(pDevice->Interrupt);
- }
-
- FuncExit(TRACE_FLAG_WDFLOADING);
-
- return status;
-}
-
-NTSTATUS
-OnD0Entry(
- _In_ WDFDEVICE FxDevice,
- _In_ WDF_POWER_DEVICE_STATE FxPreviousState
- )
-/*++
-
- Routine Description:
-
- This routine allocates objects needed by the driver.
-
- Arguments:
-
- FxDevice - a handle to the framework device object
- FxPreviousState - previous power state
-
- Return Value:
-
- Status
-
---*/
-{
- FuncEntry(TRACE_FLAG_WDFLOADING);
-
- UNREFERENCED_PARAMETER(FxPreviousState);
-
- PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);
- NTSTATUS status;
-
- //
- // Create the SPB target.
- //
-
- WDF_OBJECT_ATTRIBUTES targetAttributes;
- WDF_OBJECT_ATTRIBUTES_INIT(&targetAttributes);
-
- status = WdfIoTargetCreate(
- pDevice->FxDevice,
- &targetAttributes,
- &pDevice->SpbController);
-
- if (!NT_SUCCESS(status))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- TRACE_FLAG_WDFLOADING,
- "Failed to create IO target - %!STATUS!",
- status);
- }
-
- //
- // InputMemory will be created when an SPB request is about to be
- // sent. Indicate that it is not yet initialized.
- //
-
- pDevice->InputMemory = WDF_NO_HANDLE;
-
- //
- // Create the SPB request.
- //
-
- if (NT_SUCCESS(status))
- {
- WDF_OBJECT_ATTRIBUTES requestAttributes;
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&requestAttributes, REQUEST_CONTEXT);
-
- status = WdfRequestCreate(
- &requestAttributes,
- nullptr,
- &pDevice->SpbRequest);
-
- if (!NT_SUCCESS(status))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- TRACE_FLAG_WDFLOADING,
- "Failed to create IO request - %!STATUS!",
- status);
- }
-
- if (NT_SUCCESS(status))
- {
- PREQUEST_CONTEXT pRequest = GetRequestContext(
- pDevice->SpbRequest);
-
- pRequest->FxDevice = pDevice->FxDevice;
- pRequest->IsSpbSequenceRequest = FALSE;
- pRequest->SequenceWriteLength = 0;
- }
- }
-
- FuncExit(TRACE_FLAG_WDFLOADING);
-
- return status;
-}
-
-NTSTATUS
-OnD0Exit(
- _In_ WDFDEVICE FxDevice,
- _In_ WDF_POWER_DEVICE_STATE FxPreviousState
- )
-/*++
-
- Routine Description:
-
- This routine destroys objects needed by the driver.
-
- Arguments:
-
- FxDevice - a handle to the framework device object
- FxPreviousState - previous power state
-
- Return Value:
-
- Status
-
---*/
-{
- FuncEntry(TRACE_FLAG_WDFLOADING);
-
- UNREFERENCED_PARAMETER(FxPreviousState);
-
- PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);
-
- if (pDevice->SpbController != WDF_NO_HANDLE)
- {
- WdfObjectDelete(pDevice->SpbController);
- pDevice->SpbController = WDF_NO_HANDLE;
- }
-
- if (pDevice->SpbRequest != WDF_NO_HANDLE)
- {
- WdfObjectDelete(pDevice->SpbRequest);
- pDevice->SpbRequest = WDF_NO_HANDLE;
- }
-
- if (pDevice->InputMemory != WDF_NO_HANDLE)
- {
- WdfObjectDelete(pDevice->InputMemory);
- pDevice->InputMemory = WDF_NO_HANDLE;
- }
-
- FuncExit(TRACE_FLAG_WDFLOADING);
-
- return STATUS_SUCCESS;
-}
-
-VOID
-OnFileCleanup(
- _In_ WDFFILEOBJECT FileObject
- )
-/*++
-
- Routine Description:
-
- This routine is called before a device is stopped.
-
- Arguments:
-
- FileObject - a handle to the framework file object
-
- Return Value:
-
- None
-
---*/
-{
- FuncEntry(TRACE_FLAG_WDFLOADING);
-
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
-
- device = WdfFileObjectGetDevice(FileObject);
- pDevice = GetDeviceContext(device);
-
- //
- // The client app has closed the device handle,
- // make sure the SPB target is closed.
- //
-
- SpbPeripheralClose(pDevice);
-
- //
- // Signal the ISR wait event just
- // in case the callback is stalled.
- //
-
- if (pDevice->Interrupt != nullptr)
- {
- KeSetEvent(
- &pDevice->IsrWaitEvent,
- IO_NO_INCREMENT,
- FALSE);
- }
-
- FuncExit(TRACE_FLAG_WDFLOADING);
-}
-
-VOID
-OnTopLevelIoDefault(
- _In_ WDFQUEUE FxQueue,
- _In_ WDFREQUEST FxRequest
- )
-/*++
-
- Routine Description:
-
- Accepts all incoming requests and pends or forwards appropriately.
-
- Arguments:
-
- FxQueue - Handle to the framework queue object that is associated with the
- I/O request.
- FxRequest - Handle to a framework request object.
-
- Return Value:
-
- None.
-
---*/
-{
- FuncEntry(TRACE_FLAG_SPBAPI);
-
- UNREFERENCED_PARAMETER(FxQueue);
-
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
- WDF_REQUEST_PARAMETERS params;
- NTSTATUS status;
-
- device = WdfIoQueueGetDevice(FxQueue);
- pDevice = GetDeviceContext(device);
-
- WDF_REQUEST_PARAMETERS_INIT(&params);
-
- WdfRequestGetParameters(FxRequest, &params);
-
- if ((params.Type == WdfRequestTypeDeviceControl) &&
- (params.Parameters.DeviceIoControl.IoControlCode ==
- IOCTL_SPBTESTTOOL_WAIT_ON_INTERRUPT))
- {
- SpbPeripheralWaitOnInterrupt(pDevice, FxRequest);
- }
- else
- {
- status = WdfRequestForwardToIoQueue(FxRequest, pDevice->SpbQueue);
-
- if (!NT_SUCCESS(status))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- TRACE_FLAG_SPBAPI,
- "Failed to forward WDFREQUEST %p to SPB queue %p - %!STATUS!",
- FxRequest,
- pDevice->SpbQueue,
- status);
-
- WdfRequestComplete(FxRequest, status);
- }
- }
-
- FuncExit(TRACE_FLAG_SPBAPI);
-}
-
-VOID
-OnIoRead (
- _In_ WDFQUEUE FxQueue,
- _In_ WDFREQUEST FxRequest,
- _In_ size_t Length
- )
-/*++
-
- Routine Description:
-
- Performs read from the toaster device. This event is called when the
- framework receives IRP_MJ_READ requests.
-
- Arguments:
-
- FxQueue - Handle to the framework queue object that is associated with the
- I/O request.
- FxRequest - Handle to a framework request object.
- Length - Length of the data buffer associated with the request.
- By default, the queue does not dispatch zero length read & write
- requests to the driver and instead to complete such requests with
- status success. So we will never get a zero length request.
-
- Return Value:
-
- None.
-
---*/
-{
- FuncEntry(TRACE_FLAG_SPBAPI);
-
- UNREFERENCED_PARAMETER(Length);
-
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_SPBAPI,
- "Read request %p received",
- FxRequest);
-
- device = WdfIoQueueGetDevice(FxQueue);
- pDevice = GetDeviceContext(device);
-
- //
- // Send the read request.
- //
-
- SpbPeripheralRead(pDevice,FxRequest);
-
- FuncExit(TRACE_FLAG_SPBAPI);
-}
-
-VOID
-OnIoWrite (
- _In_ WDFQUEUE FxQueue,
- _In_ WDFREQUEST FxRequest,
- _In_ size_t Length
- )
-/*++
-
-Routine Description:
-
- Performs write to the toaster device. This event is called when the
- framework receives IRP_MJ_WRITE requests.
-
-Arguments:
-
- Queue - Handle to the framework queue object that is associated
- with the I/O request.
- Request - Handle to a framework request object.
- Lenght - Length of the data buffer associated with the request.
- The default property of the queue is to not dispatch
- zero lenght read & write requests to the driver and
- complete is with status success. So we will never get
- a zero length request.
-
-Return Value:
-
- None
---*/
-{
- FuncEntry(TRACE_FLAG_SPBAPI);
-
- UNREFERENCED_PARAMETER(Length);
-
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_SPBAPI,
- "Write request %p received",
- FxRequest);
-
- device = WdfIoQueueGetDevice(FxQueue);
- pDevice = GetDeviceContext(device);
-
- //
- // Send the write request.
- //
-
- SpbPeripheralWrite(pDevice,FxRequest);
-
- FuncExit(TRACE_FLAG_SPBAPI);
-}
-
-VOID
-OnIoDeviceControl(
- _In_ WDFQUEUE FxQueue,
- _In_ WDFREQUEST FxRequest,
- _In_ size_t OutputBufferLength,
- _In_ size_t InputBufferLength,
- _In_ ULONG IoControlCode
- )
-/*++
-Routine Description:
-
- This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
- requests from the system.
-
-Arguments:
-
- FxQueue - Handle to the framework queue object that is associated
- with the I/O request.
- FxRequest - Handle to a framework request object.
- OutputBufferLength - length of the request's output buffer,
- if an output buffer is available.
- InputBufferLength - length of the request's input buffer,
- if an input buffer is available.
- IoControlCode - the driver-defined or system-defined I/O control code
- (IOCTL) that is associated with the request.
-
-Return Value:
-
- VOID
-
---*/
-{
- FuncEntry(TRACE_FLAG_SPBAPI);
-
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
- BOOLEAN fSync = FALSE;
- NTSTATUS status = STATUS_SUCCESS;
-
- UNREFERENCED_PARAMETER(OutputBufferLength);
- UNREFERENCED_PARAMETER(InputBufferLength);
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_SPBAPI,
- "DeviceIoControl request %p received with IOCTL=%lu",
- FxRequest,
- IoControlCode);
-
- device = WdfIoQueueGetDevice(FxQueue);
- pDevice = GetDeviceContext(device);
-
- //
- // Translate the test IOCTL into the appropriate
- // SPB API method. Open and close are completed
- // synchronously.
- //
-
- switch (IoControlCode)
- {
- case IOCTL_SPBTESTTOOL_OPEN:
- fSync = TRUE;
- status = SpbPeripheralOpen(pDevice);
- break;
-
- case IOCTL_SPBTESTTOOL_CLOSE:
- fSync = TRUE;
- status = SpbPeripheralClose(pDevice);
- break;
-
- case IOCTL_SPBTESTTOOL_LOCK:
- SpbPeripheralLock(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_UNLOCK:
- SpbPeripheralUnlock(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_LOCK_CONNECTION:
- SpbPeripheralLockConnection(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_UNLOCK_CONNECTION:
- SpbPeripheralUnlockConnection(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_WRITEREAD:
- SpbPeripheralWriteRead(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_FULL_DUPLEX:
- SpbPeripheralFullDuplex(pDevice, FxRequest);
- break;
-
- case IOCTL_SPBTESTTOOL_SIGNAL_INTERRUPT:
- SpbPeripheralSignalInterrupt(pDevice, FxRequest);
- break;
-
- default:
- fSync = TRUE;
- status = STATUS_INVALID_DEVICE_REQUEST;
- Trace(
- TRACE_LEVEL_WARNING,
- TRACE_FLAG_SPBAPI,
- "Request %p received with unexpected IOCTL=%lu",
- FxRequest,
- IoControlCode);
- }
-
- //
- // Complete the request if necessary.
- //
-
- if (fSync)
- {
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_SPBAPI,
- "Completing request %p with %!STATUS!",
- FxRequest,
- status);
-
- WdfRequestComplete(FxRequest, status);
- }
-
- FuncExit(TRACE_FLAG_SPBAPI);
-}
-
-BOOLEAN
-OnInterruptIsr(
- _In_ WDFINTERRUPT FxInterrupt,
- _In_ ULONG MessageID
- )
-/*++
-
- Routine Description:
-
- This routine responds to interrupts generated by the H/W.
- It then waits indefinitely for the user to signal that
- the interrupt has been acknowledged, allowing the ISR to
- return. This ISR is called at PASSIVE_LEVEL.
-
- Arguments:
-
- Interrupt - a handle to a framework interrupt object
- MessageID - message number identifying the device's
- hardware interrupt message (if using MSI)
-
- Return Value:
-
- TRUE if interrupt recognized.
-
---*/
-{
- FuncEntry(TRACE_FLAG_SPBAPI);
-
- BOOLEAN fInterruptRecognized = TRUE;
- BOOLEAN fNotificationSent;
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevice;
-
- UNREFERENCED_PARAMETER(MessageID);
-
- device = WdfInterruptGetDevice(FxInterrupt);
- pDevice = GetDeviceContext(device);
-
- //
- // Notify the app that an interrupt has occurred.
- //
-
- fNotificationSent = SpbPeripheralInterruptNotify(pDevice);
-
- if (fNotificationSent)
- {
- //
- // Stall in ISR until acknowledged by user.
- //
- // Note: In a 'real' driver, the ISR should directly
- // acknowledge the interrupt and then queue
- // a workitem to carry out any additional
- // processing. The ISR should never call
- // KeWaitForSingleObject as done below.
- //
-
- Trace(
- TRACE_LEVEL_INFORMATION,
- TRACE_FLAG_SPBAPI,
- "Stalling in ISR until continue command received");
-
- KeClearEvent(&pDevice->IsrWaitEvent);
-
- KeWaitForSingleObject(
- &pDevice->IsrWaitEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
- }
- else
- {
- Trace(
- TRACE_LEVEL_WARNING,
- TRACE_FLAG_SPBAPI,
- "Interrupt detected, but failed to send notification, ignoring");
- }
-
- FuncExit(TRACE_FLAG_SPBAPI);
-
- return fInterruptRecognized;
-}