diff options
Diffstat (limited to 'spb/SpbTestTool/sys/device.cpp')
| -rw-r--r-- | spb/SpbTestTool/sys/device.cpp | 848 |
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(¶ms); - - WdfRequestGetParameters(FxRequest, ¶ms); - - 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; -} |
