diff options
| author | Wei Mao <[email protected]> | 2017-03-17 19:47:04 -0700 |
|---|---|---|
| committer | Wei Mao <[email protected]> | 2017-03-17 19:47:04 -0700 |
| commit | 1a3e0d580380e58bf336a242d2affc8a1e2d1ddf (patch) | |
| tree | bf5d9c5b0b4cba1b81726b9f78c4d5ff5c636fea /spb/SkeletonI2C/controller.cpp | |
| parent | da21c8784c83c5fd614f3030323e229d6a5fb10e (diff) | |
Fix cases
Diffstat (limited to 'spb/SkeletonI2C/controller.cpp')
| -rw-r--r-- | spb/SkeletonI2C/controller.cpp | 851 |
1 files changed, 0 insertions, 851 deletions
diff --git a/spb/SkeletonI2C/controller.cpp b/spb/SkeletonI2C/controller.cpp deleted file mode 100644 index f867fb62..00000000 --- a/spb/SkeletonI2C/controller.cpp +++ /dev/null @@ -1,851 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - controller.cpp - -Abstract: - - This module contains the controller-specific functions - for handling transfers and implementing interrupts. - -Environment: - - kernel-mode only - -Revision History: - ---*/ - -#include "internal.h" -#include "controller.h" -#include "device.h" - -#include "controller.tmh" - -const PBC_TRANSFER_SETTINGS g_TransferSettings[] = -{ - // TODO: Update this array to reflect changes - // made to the PBC_TRANSFER_SETTINGS - // structure in internal.h. - - // Bus condition IsStart IsEnd - {BusConditionDontCare, FALSE, FALSE}, // SpbRequestTypeInvalid - {BusConditionFree, TRUE, TRUE}, // SpbRequestTypeSingle - {BusConditionFree, TRUE, FALSE}, // SpbRequestTypeFirst - {BusConditionBusy, FALSE, FALSE}, // SpbRequestTypeContinue - {BusConditionBusy, FALSE, TRUE} // SpbRequestTypeLast -}; - -VOID -ControllerInitialize( - _In_ PPBC_DEVICE pDevice - ) -/*++ - - Routine Description: - - This routine initializes the controller hardware. - - Arguments: - - pDevice - a pointer to the PBC device context - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_PBCLOADING); - - NT_ASSERT(pDevice != NULL); - - // TODO: Initialize controller hardware via the - // pDevice->pRegisters->* register interface. - // Work may include configuring operating modes, - // FIFOs, clock, interrupts, etc. - - UNREFERENCED_PARAMETER(pDevice); - - FuncExit(TRACE_FLAG_PBCLOADING); -} - -VOID -ControllerUninitialize( - _In_ PPBC_DEVICE pDevice - ) -/*++ - - Routine Description: - - This routine uninitializes the controller hardware. - - Arguments: - - pDevice - a pointer to the PBC device context - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_PBCLOADING); - - NT_ASSERT(pDevice != NULL); - - // TODO: Uninitialize controller hardware via the - // pDevice->pRegisters->* register interface - // if necessary. Work may include disabling - // interrupts, etc. - - UNREFERENCED_PARAMETER(pDevice); - - FuncExit(TRACE_FLAG_PBCLOADING); -} - -VOID -ControllerConfigureForTransfer( - _In_ PPBC_DEVICE pDevice, - _In_ PPBC_REQUEST pRequest - ) -/*++ - - Routine Description: - - This routine configures and starts the controller - for a transfer. - - Arguments: - - pDevice - a pointer to the PBC device context - pRequest - a pointer to the PBC request context - - Return Value: - - None. The request is completed asynchronously. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NT_ASSERT(pDevice != NULL); - NT_ASSERT(pRequest != NULL); - - // - // Initialize request context for transfer. - // - - pRequest->Settings = g_TransferSettings[pRequest->SequencePosition]; - pRequest->Status = STATUS_SUCCESS; - - // - // Configure hardware for transfer. - // - - // TODO: Initialize controller hardware for a general - // transfer via the pDevice->pRegisters->* register - // interface. Work may include setting up transfer, - // configuring FIFOs, selecting address, etc. - - if (pRequest->Settings.IsStart) - { - // TODO: Perform any action to program a start bit. - } - else if (pRequest->Settings.IsEnd) - { - // TODO: Perform any action to program a stop bit. - } - - if (pRequest->Direction == SpbTransferDirectionToDevice) - { - // TODO: Perform write-specific configuration, - // i.e. pRequest->DataReadyFlag = ... - } - else if (pRequest->Direction == SpbTransferDirectionFromDevice) - { - // TODO: Perform read-specific configuration, - // i.e. pRequest->DataReadyFlag = ... - } - - // - // Synchronize access to device context with ISR. - // - - // TODO: Uncomment when using interrupts. - //WdfInterruptAcquireLock(pDevice->InterruptObject); - - // - // Set interrupt mask and clear current status. - // - - // TODO: Save desired interrupt mask. - // PbcDeviceSetInterruptMask(pDevice, mask) - - pDevice->InterruptStatus = 0; - - Trace( - TRACE_LEVEL_VERBOSE, - TRACE_FLAG_TRANSFER, - "Controller configured for %s of %Iu bytes to address 0x%lx " - "(SPBREQUEST %p, WDFDEVICE %p)", - pRequest->Direction == SpbTransferDirectionFromDevice ? "read" : "write", - pRequest->Length, - pDevice->pCurrentTarget->Settings.Address, - pRequest->SpbRequest, - pDevice->FxDevice); - - // TODO: Perform necessary action to begin transfer. - - ControllerEnableInterrupts( - pDevice, - PbcDeviceGetInterruptMask(pDevice)); - - // TODO: Uncomment when using interrupts. - //WdfInterruptReleaseLock(pDevice->InterruptObject); - - // TODO: For the purpose of this skeleton sample, - // simply complete the request synchronously. - - ControllerCompleteTransfer(pDevice, pRequest, FALSE); - - FuncExit(TRACE_FLAG_TRANSFER); -} - -VOID -ControllerProcessInterrupts( - _In_ PPBC_DEVICE pDevice, - _In_ PPBC_REQUEST pRequest, - _In_ ULONG InterruptStatus - ) -/*++ - - Routine Description: - - This routine processes a hardware interrupt. Activities - include checking for errors and transferring data. - - Arguments: - - pDevice - a pointer to the PBC device context - pRequest - a pointer to the PBC request context - InterruptStatus - saved interrupt status bits from the ISR. - These have already been acknowledged and disabled - - Return Value: - - None. The request is completed asynchronously. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NTSTATUS status; - - NT_ASSERT(pDevice != NULL); - NT_ASSERT(pRequest != NULL); - - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Ready to process interrupts with status 0x%lx for WDFDEVICE %p", - InterruptStatus, - pDevice->FxDevice); - - // - // Check for address NACK. - // - - if (TestAnyBits(InterruptStatus, SI2C_STATUS_ADDRESS_NACK /*update with nack flag*/)) - { - // - // An address NACK indicates that a device is - // not present at that address or is not responding. - // Set the error status accordingly. - // - - pRequest->Status = STATUS_NO_SUCH_DEVICE; - pRequest->Information = 0; - - // TODO: Perform any additional action needed to handle NACK. - - Trace( - TRACE_LEVEL_ERROR, - TRACE_FLAG_TRANSFER, - "NACK on address 0x%lx (WDFDEVICE %p) - %!STATUS!", - pDevice->pCurrentTarget->Settings.Address, - pDevice->FxDevice, - pRequest->Status); - - // - // Complete the transfer and stop processing - // interrupts. - // - - ControllerCompleteTransfer(pDevice, pRequest, TRUE); - goto exit; - } - - // - // Check for data NACK. - // - - if (TestAnyBits(InterruptStatus, SI2C_STATUS_DATA_NACK /*update with nack flag*/)) - { - // - // A data NACK is not necessarily an error. - // Set the error status to STATUS_SUCCESS and - // indicate the number of bytes successfully - // transferred in the information field. The - // client will determine success or failure of - // the IO based on this length. - // - - pRequest->Status = STATUS_SUCCESS; - - // TODO: Assuming this info is available, set - // information to the actual number of - // bytes successfully transferred. - //pRequest->Information = 0; - - // TODO: Perform any additional action needed to handle NACK. - - Trace( - TRACE_LEVEL_WARNING, - TRACE_FLAG_TRANSFER, - "NACK after %Iu bytes transferred for address 0x%lx " - "(WDFDEVICE %p)- %!STATUS!", - pRequest->Information, - pDevice->pCurrentTarget->Settings.Address, - pDevice->FxDevice, - pRequest->Status); - - // - // Complete the transfer and stop processing - // interrupts. - // - - ControllerCompleteTransfer(pDevice, pRequest, TRUE); - goto exit; - } - - // TODO: Check for other errors. - - if (TestAnyBits(InterruptStatus, SI2C_STATUS_GENERIC_ERROR /*update with error flag*/)) - { - // TODO: Perform any action needed to handle error, - // i.e. set status or bytes transferred accordingly. - - pRequest->Status = STATUS_UNSUCCESSFUL; - pRequest->Information = 0; - - Trace( - TRACE_LEVEL_WARNING, - TRACE_FLAG_TRANSFER, - "Error after %Iu bytes transferred for address 0x%lx " - "(WDFDEVICE %p)- %!STATUS!", - pRequest->Information, - pDevice->pCurrentTarget->Settings.Address, - pDevice->FxDevice, - pRequest->Status); - - // - // Complete the transfer and stop processing - // interrupts. - // - - ControllerCompleteTransfer(pDevice, pRequest, TRUE); - goto exit; - } - - // - // Check if controller is ready to transfer more data. - // - - if (TestAnyBits(InterruptStatus, pRequest->DataReadyFlag)) - { - // - // Transfer data. - // - - status = ControllerTransferData(pDevice, pRequest); - - if (!NT_SUCCESS(status)) - { - pRequest->Status = status; - - Trace( - TRACE_LEVEL_ERROR, - TRACE_FLAG_TRANSFER, - "Unexpected error while transferring data for address 0x%lx, " - "completing transfer and resetting controller - %!STATUS!", - pDevice->pCurrentTarget->Settings.Address, - pRequest->Status); - - // - // Complete the transfer and stop processing - // interrupts. - // - - ControllerCompleteTransfer(pDevice, pRequest, TRUE); - goto exit; - } - - // - // If finished transferring data, stop listening for - // data ready interrupt. Do not complete transfer - // until transfer complete interrupt occurs. - // - - if (PbcRequestGetInfoRemaining(pRequest) == 0) - { - Trace( - TRACE_LEVEL_VERBOSE, - TRACE_FLAG_TRANSFER, - "No bytes remaining in transfer for address 0x%lx, wait for " - "transfer complete interrupt", - pDevice->pCurrentTarget->Settings.Address); - - PbcDeviceAndInterruptMask(pDevice, ~pRequest->DataReadyFlag); - } - } - - // - // Check if transfer is complete. - // - - if (TestAnyBits(InterruptStatus, 0 /*update with transfer complete flag*/)) - { - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Transfer complete for address 0x%lx with %Iu bytes remaining", - pDevice->pCurrentTarget->Settings.Address, - PbcRequestGetInfoRemaining(pRequest)); - - // - // If transfer complete interrupt occured and there - // are still bytes remaining, transfer data. This occurs - // when the number of bytes remaining is less than - // the FIFO transfer level to trigger a data ready interrupt. - // - - if (PbcRequestGetInfoRemaining(pRequest) > 0) - { - status = ControllerTransferData(pDevice, pRequest); - - if (!NT_SUCCESS(status)) - { - pRequest->Status = status; - - Trace( - TRACE_LEVEL_ERROR, - TRACE_FLAG_TRANSFER, - "Unexpected error while transferring data for address 0x%lx, " - "completing transfer and resetting controller " - "(WDFDEVICE %p) - %!STATUS!", - pDevice->pCurrentTarget->Settings.Address, - pDevice->FxDevice, - pRequest->Status); - - // - // Complete the transfer and stop processing - // interrupts. - // - - ControllerCompleteTransfer(pDevice, pRequest, TRUE); - goto exit; - } - } - - // - // Complete the transfer. - // - - ControllerCompleteTransfer(pDevice, pRequest, FALSE); - } - -exit: - - FuncExit(TRACE_FLAG_TRANSFER); -} - -NTSTATUS -ControllerTransferData( - _In_ PPBC_DEVICE pDevice, - _In_ PPBC_REQUEST pRequest - ) -/*++ - - Routine Description: - - This routine transfers data to or from the device. - - Arguments: - - pDevice - a pointer to the PBC device context - pRequest - a pointer to the PBC request context - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - UNREFERENCED_PARAMETER(pDevice); - - size_t bytesToTransfer = 0; - NTSTATUS status = STATUS_SUCCESS; - - // - // Write - // - - if (pRequest->Direction == SpbTransferDirectionToDevice) - { - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Ready to write %Iu byte(s) for address 0x%lx", - bytesToTransfer, - pDevice->pCurrentTarget->Settings.Address); - - // TODO: Perform write. May need to use - // PbcRequestGetByte() or some variation. - } - - // - // Read - // - - else - { - - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Ready to read %Iu byte(s) for address 0x%lx", - bytesToTransfer, - pDevice->pCurrentTarget->Settings.Address); - - // TODO: Perform read. May need to use - // PbcRequestSetByte() or some variation. - } - - // - // Update request context with bytes transferred. - // - - pRequest->Information += bytesToTransfer; - - FuncExit(TRACE_FLAG_TRANSFER); - - return status; -} - -VOID -ControllerCompleteTransfer( - _In_ PPBC_DEVICE pDevice, - _In_ PPBC_REQUEST pRequest, - _In_ BOOLEAN AbortSequence - ) -/*++ - - Routine Description: - - This routine completes a data transfer. Unless there are - more transfers remaining in the sequence, the request is - completed. - - Arguments: - - pDevice - a pointer to the PBC device context - pRequest - a pointer to the PBC request context - AbortSequence - specifies whether the driver should abort the - ongoing sequence or begin the next transfer - - Return Value: - - None. The request is completed asynchronously. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NT_ASSERT(pDevice != NULL); - NT_ASSERT(pRequest != NULL); - - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Transfer (index %lu) %s with %Iu bytes for address 0x%lx " - "(SPBREQUEST %p)", - pRequest->TransferIndex, - NT_SUCCESS(pRequest->Status) ? "complete" : "error", - pRequest->Information, - pDevice->pCurrentTarget->Settings.Address, - pRequest->SpbRequest); - - // - // Update request context with information from this transfer. - // - - pRequest->TotalInformation += pRequest->Information; - pRequest->Information = 0; - - // - // Check if there are more transfers - // in the sequence. - // - - if (!AbortSequence) - { - pRequest->TransferIndex++; - - if (pRequest->TransferIndex < pRequest->TransferCount) - { - // - // Configure the request for the next transfer. - // - - pRequest->Status = PbcRequestConfigureForIndex( - pRequest, - pRequest->TransferIndex); - - if (NT_SUCCESS(pRequest->Status)) - { - // - // Configure controller and kick-off read. - // Request will be completed asynchronously. - // - - PbcRequestDoTransfer(pDevice,pRequest); - goto exit; - } - } - } - - // - // If not already cancelled, unmark request cancellable. - // - - if (pRequest->Status != STATUS_CANCELLED) - { - NTSTATUS cancelStatus; - cancelStatus = WdfRequestUnmarkCancelable(pRequest->SpbRequest); - - if (!NT_SUCCESS(cancelStatus)) - { - // - // WdfRequestUnmarkCancelable should only fail if the request - // has already been or is about to be cancelled. If it does fail - // the request must NOT be completed - the cancel callback will do - // this. - // - - NT_ASSERTMSG("WdfRequestUnmarkCancelable should only fail if the request has already been or is about to be cancelled", - cancelStatus == STATUS_CANCELLED); - - Trace( - TRACE_LEVEL_INFORMATION, - TRACE_FLAG_TRANSFER, - "Failed to unmark SPBREQUEST %p as cancelable - %!STATUS!", - pRequest->SpbRequest, - cancelStatus); - - goto exit; - } - } - - // - // Done or error occurred. Set interrupt mask to 0. - // Doing this keeps the DPC from re-enabling interrupts. - // - - PbcDeviceSetInterruptMask(pDevice, 0); - - // - // Clear the target's current request. This will prevent - // the request context from being accessed once the request - // is completed (and the context is invalid). - // - - pDevice->pCurrentTarget->pCurrentRequest = NULL; - - // - // Clear the controller's current target if any of - // 1. request is type sequence - // 2. request position is single - // (did not come between lock/unlock) - // Otherwise wait until unlock. - // - - if ((pRequest->Type == SpbRequestTypeSequence) || - (pRequest->SequencePosition == SpbRequestSequencePositionSingle)) - { - pDevice->pCurrentTarget = NULL; - } - - // - // Mark the IO complete. Request not - // completed here. - // - - pRequest->bIoComplete = TRUE; - -exit: - - FuncExit(TRACE_FLAG_TRANSFER); -} - -VOID -ControllerEnableInterrupts( - _In_ PPBC_DEVICE pDevice, - _In_ ULONG InterruptMask - ) -/*++ - - Routine Description: - - This routine enables the hardware interrupts for the - specificed mask. - - Arguments: - - pDevice - a pointer to the PBC device context - InterruptMask - interrupt bits to enable - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NT_ASSERT(pDevice != NULL); - - Trace( - TRACE_LEVEL_VERBOSE, - TRACE_FLAG_TRANSFER, - "Enable interrupts with mask 0x%lx (WDFDEVICE %p)", - InterruptMask, - pDevice->FxDevice); - - // TODO: Enable interrupts as requested. - - UNREFERENCED_PARAMETER(pDevice); - - FuncExit(TRACE_FLAG_TRANSFER); -} - -VOID -ControllerDisableInterrupts( - _In_ PPBC_DEVICE pDevice - ) -/*++ - - Routine Description: - - This routine disables all controller interrupts. - - Arguments: - - pDevice - a pointer to the PBC device context - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NT_ASSERT(pDevice != NULL); - - // TODO: Disable all interrupts. - - UNREFERENCED_PARAMETER(pDevice); - - FuncExit(TRACE_FLAG_TRANSFER); -} - -ULONG -ControllerGetInterruptStatus( - _In_ PPBC_DEVICE pDevice, - _In_ ULONG InterruptMask - ) -/*++ - - Routine Description: - - This routine gets the interrupt status of the - specificed interrupt bits. - - Arguments: - - pDevice - a pointer to the PBC device context - InterruptMask - interrupt bits to check - - Return Value: - - A bitmap indicating which interrupts are set. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - ULONG interruptStatus = 0; - - NT_ASSERT(pDevice != NULL); - - // TODO: Check if any of the interrupt mask - // bits have triggered an interrupt. - - UNREFERENCED_PARAMETER(pDevice); - UNREFERENCED_PARAMETER(InterruptMask); - - FuncExit(TRACE_FLAG_TRANSFER); - - return interruptStatus; -} - -VOID -ControllerAcknowledgeInterrupts( - _In_ PPBC_DEVICE pDevice, - _In_ ULONG InterruptMask - ) -/*++ - - Routine Description: - - This routine acknowledges the - specificed interrupt bits. - - Arguments: - - pDevice - a pointer to the PBC device context - InterruptMask - interrupt bits to acknowledge - - Return Value: - - None. - ---*/ -{ - FuncEntry(TRACE_FLAG_TRANSFER); - - NT_ASSERT(pDevice != NULL); - - // TODO: Acknowledge requested interrupts. - - UNREFERENCED_PARAMETER(pDevice); - UNREFERENCED_PARAMETER(InterruptMask); - - FuncExit(TRACE_FLAG_TRANSFER); -} |
