Example #1
0
File: Uart.c Project: levic/dektec
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaUartIntDpc -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
void  DtaUartIntDpc(DtDpcArgs* pArgs)
{
    DtaUartPort*  pUart = (DtaUartPort*)pArgs->m_pContext;
    UInt32 IntReason = pArgs->m_Data1.m_UInt32_1;

    // Check for TX interrupt
    if ((IntReason&DTA_UART_INT_TX_EMPTY)!=0 || (IntReason&DTA_UART_INT_TX_HALFEMPTY)!=0)
        DtEventSet(&pUart->m_TxEvent);

    // Check for RX interrupt
    if ((IntReason&DTA_UART_INT_RX_IDLE)!=0 || (IntReason&DTA_UART_INT_RX_HALFFULL)!=0)
        DtEventSet(&pUart->m_RxEvent);
}
Example #2
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGetCancel -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
// This functions cancels the DtuEventGetWait function if that function was waiting
// for an event to happen
//
DtStatus  DtuEventsGetCancel(DtuDeviceData* pDvcData, DtFileObject* pFile)
{
    DtuEvents*  pDtuEvents;

    if (pFile == NULL)
        return DT_STATUS_INVALID_PARAMETER;

    DtDbgOut(MAX, EVENTS, "Start");

    // We force the Pending event to be signaled.
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents == NULL)
    {
        DtDbgOut(MAX, EVENTS, "Exit");
        return DT_STATUS_NOT_FOUND;
    }

    pDtuEvents->m_CancelInProgress = TRUE;

#ifdef WINBUILD
    // Dequeue pending events
    DtuEventsDequeue(pDvcData, pFile);
#endif

    // Trigger event
    DtEventSet(&pDtuEvents->m_PendingEvent);

    // Decrement refcount
    DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);

    DtDbgOut(MAX, EVENTS, "Exit");

    return DT_STATUS_OK;
}
Example #3
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtStatus  DtuEventsSetEvent(
    DtuEvents*  pDtuEvents,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtuEvent*  pDtuEvent;

    // Skip unregistered events
    if ((EventType & pDtuEvents->m_EventTypeMask) != 0)
    {
        DtSpinLockAcquire(&pDtuEvents->m_Lock);

        if (EventType == DTU_EVENT_TYPE_IOCONFIG)
        {
            UInt i;
            for (i=0; i<pDtuEvents->m_NumPendingEvents; i++)
            {
                if (pDtuEvents->m_PendingEvents[i].m_EventType==DTU_EVENT_TYPE_IOCONFIG
                                  && pDtuEvents->m_PendingEvents[i].m_EventValue1==Value1)
                {
                    // Event is already pending, don't create a duplicate
                    DtSpinLockRelease(&pDtuEvents->m_Lock);
                    return DT_STATUS_OK;
                }
            }
        }

        // Add new events
        if (pDtuEvents->m_NumPendingEvents == MAX_PENDING_EVENTS)
        {
            // Remove oldest event
            DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event");
            DtMemMove(&pDtuEvents->m_PendingEvents[0],
                                         &pDtuEvents->m_PendingEvents[1],
                                         sizeof(DtuEvent) * (MAX_PENDING_EVENTS - 1));
            pDtuEvent = &pDtuEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1];
        } else {
            pDtuEvent = &pDtuEvents->m_PendingEvents[pDtuEvents->m_NumPendingEvents];
            pDtuEvents->m_NumPendingEvents++;
        }

        DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", 
                           pDtuEvents->m_NumPendingEvents, EventType, Value1, Value2);
        
        pDtuEvent->m_EventType = EventType;
        pDtuEvent->m_EventValue1 = Value1;
        pDtuEvent->m_EventValue2 = Value2;

        // Trigger wait function if it was waiting
        DtEventSet(&pDtuEvents->m_PendingEvent);
        DtSpinLockRelease(&pDtuEvents->m_Lock);
    }
    return DT_STATUS_OK;
}
Example #4
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtStatus  DtaEventsSetEvent(
    DtaEvents*  pDtaEvents,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    DtaEvent*  pDtaEvent;

    // Skip unregistered events
    if ((EventType & pDtaEvents->m_EventTypeMask) != 0)
    {
        DtSpinLockAcquire(&pDtaEvents->m_Lock);

        // Add new events
        if (pDtaEvents->m_NumPendingEvents == MAX_PENDING_EVENTS)
        {
            // Remove oldest event
            DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event");
            DtMemMove(&pDtaEvents->m_PendingEvents[0],
                                         &pDtaEvents->m_PendingEvents[1],
                                         sizeof(DtaEvent) * (MAX_PENDING_EVENTS - 1));
            pDtaEvent = &pDtaEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1];
        } else {
            pDtaEvent = &pDtaEvents->m_PendingEvents[pDtaEvents->m_NumPendingEvents];
            pDtaEvents->m_NumPendingEvents++;
        }

        DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", 
                           pDtaEvents->m_NumPendingEvents, EventType, Value1, Value2);
        
        pDtaEvent->m_EventType = EventType;
        pDtaEvent->m_EventValue1 = Value1;
        pDtaEvent->m_EventValue2 = Value2;

        // Trigger wait function if it was waiting
        DtEventSet(&pDtaEvents->m_PendingEvent);
        DtSpinLockRelease(&pDtaEvents->m_Lock);
    }
    return Result;
}
Example #5
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuShBufferIoctl -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtuShBufferIoctl(
    DtuDeviceData*  pDvcData, 
    DtFileObject*  pFile, 
    DtIoctlObject*  pIoctl)
{
    DtStatus  Status = DT_STATUS_OK;
    char*  pIoctlStr;           // Mnemonic string for Command
    UInt  InReqSize = 0;        // Required length of input buffer
    UInt  OutReqSize = 0;       // Required length of output buffer
    Int  Index;
    DtuShBuffer*  pShBuffer = NULL;
    DtuIoctlShBufCmdInput*  pShBufCmdInput = 
                                           (DtuIoctlShBufCmdInput*)pIoctl->m_pInputBuffer;
    
    InReqSize = OFFSETOF(DtuIoctlShBufCmdInput, m_Data);
    
    
    // Check if we can read m_Cmd
    if (pIoctl->m_InputBufferSize < OFFSETOF(DtuIoctlShBufCmdInput, m_Data))
        return DT_STATUS_INVALID_PARAMETER;

    switch (pShBufCmdInput->m_Cmd)
    {
    case DTU_SH_BUF_CMD_INIT:
        pIoctlStr = "DTU_SH_BUF_CMD_INIT";
        InReqSize += sizeof(DtuIoctlShBufCmdInitInput);
        // We expect an output buffer size, but will be checked later
        OutReqSize = 0;
        break;

    case DTU_SH_BUF_CMD_CLOSE:
        pIoctlStr = "DTU_HP_BUF_CMD_CLOSE";
        // We expect no output buffer
        OutReqSize = 0;
        break;

    default:
        pIoctlStr = "??UNKNOWN VPDCMD CODE??";
        Status = DT_STATUS_NOT_SUPPORTED;
    }

    if (DT_SUCCESS(Status))
    {
        // Check buffer sizes
        if (pIoctl->m_InputBufferSize < InReqSize)
        {
            DtDbgOut(ERR, SHBUF, "%s: INPUT BUFFER TOO SMALL Size=%d Req=%d", pIoctlStr, 
                                                        pIoctl->m_InputBufferSize, InReqSize);
            return DT_STATUS_INVALID_PARAMETER;
        }
        if (pIoctl->m_OutputBufferSize < OutReqSize)
        {
            DtDbgOut(ERR, SHBUF, "%s: OUTPUT BUFFER TOO SMALL Size=%d Req=%d", pIoctlStr, 
                                                      pIoctl->m_OutputBufferSize, OutReqSize);
            return DT_STATUS_INVALID_PARAMETER;
        }

        DtDbgOut(MAX, SHBUF, "%s: In=%d (Rq=%d), Out=%d (Rq=%d)", pIoctlStr,
                pIoctl->m_InputBufferSize, InReqSize, pIoctl->m_OutputBufferSize, OutReqSize);
    }

    if (pShBufCmdInput->m_BufferIndex != 0)
    {
        DtDbgOut(ERR, SHBUF, "%s: OUTPUT BUFFER TOO SMALL Size=%d Req=%d", pIoctlStr, 
                                                      pIoctl->m_OutputBufferSize, OutReqSize);
        return DT_STATUS_INVALID_PARAMETER;
    }
    
    // The bytes written will be updated if needed. Set the default value here.
    pIoctl->m_OutputBufferBytesWritten = OutReqSize;

    // Lookup the shared buffer structure
    // Check if the PortIndex is from the NonIpPort
    Status = DtuGetNonIpPortIndex(pDvcData, pShBufCmdInput->m_PortIndex, &Index);
    if (!DT_SUCCESS(Status))
        return DT_STATUS_NOT_FOUND;
    pShBuffer = &pDvcData->m_pNonIpPorts[Index].m_SharedBuffer;

    if (DT_SUCCESS(Status))
    {
        switch (pShBufCmdInput->m_Cmd)
        {
        case DTU_SH_BUF_CMD_INIT:
            {
                char*  pBuffer;
                UInt  Size;
                DtPageList*  pPageList = NULL;
#if defined(WINBUILD)
                DtPageList  PageList;
                PMDL  pMdl;
                NTSTATUS  NtStatus;
                // Retrieve MDL and virtual buffer from request object
                NtStatus = WdfRequestRetrieveOutputWdmMdl(pIoctl->m_WdfRequest, &pMdl);
                if (NtStatus != STATUS_SUCCESS)
                {
                    DtDbgOut(ERR, SHBUF, "WdfRequestRetrieveOutputWdmMdl error: %08x", 
                                                                                NtStatus);
                    Status = DT_STATUS_OUT_OF_RESOURCES;
                }
                if (DT_SUCCESS(Status))
                {
                    pBuffer = MmGetMdlVirtualAddress(pMdl);
                    if (pBuffer == NULL)
                    {
                        DtDbgOut(ERR, SHBUF, "DTU_SH_BUF_CMD_INIT: DT_STATUS_OUT_OF_MEMORY");
                        Status = DT_STATUS_OUT_OF_MEMORY;
                    }
                    Size = MmGetMdlByteCount(pMdl);

                    // Build pagelist object for user space buffer
                    pPageList = &PageList;
                    pPageList->m_BufType = DT_BUFTYPE_USER;
                    pPageList->m_OwnedByOs = TRUE;
                    pPageList->m_pMdl = pMdl;
                    pPageList->m_pVirtualKernel = NULL;
                }
#else // LINBUILD
                Size = (UInt)pShBufCmdInput->m_Data.m_Init.m_BufferSize;
#if defined(LIN32)
                pBuffer = (char*)(UInt32)pShBufCmdInput->m_Data.m_Init.m_BufferAddr;
#else
                pBuffer = (char*)(UInt64)pShBufCmdInput->m_Data.m_Init.m_BufferAddr;
#endif
#endif
                if (DT_SUCCESS(Status))
                {
                    Status = DtuShBufferInit(pShBufCmdInput, pFile, pPageList, pBuffer, 
                                                        Size, DT_BUFTYPE_USER, pShBuffer);
                    if (!DT_SUCCESS(Status))
                        DtDbgOut(ERR, SHBUF, "DtuShBufferInit failed");
                }
            }
            break;
        case DTU_SH_BUF_CMD_CLOSE:
            if (pDvcData->m_pNonIpPorts!=NULL && 
                                   pDvcData->m_pNonIpPorts[0].m_State==DTU3_STATE_READ351)
            {
                pDvcData->m_pNonIpPorts[0].m_NextState = DTU3_STATE_DET_VIDSTD;
                DtEventSet(&pDvcData->m_pNonIpPorts[0].m_StateChanged);
                DtEventWait(&pDvcData->m_pNonIpPorts[0].m_StateChangeCmpl, -1);
            }
            else  if (pDvcData->m_pNonIpPorts!=NULL && 
                                  pDvcData->m_pNonIpPorts[0].m_State==DTU3_STATE_WRITE315)
            {
                pDvcData->m_pNonIpPorts[0].m_NextState = DTU3_STATE_IDLE;
                DtEventSet(&pDvcData->m_pNonIpPorts[0].m_StateChanged);
                DtEventWait(&pDvcData->m_pNonIpPorts[0].m_StateChangeCmpl, -1);
            }
            Status = DtuShBufferClose(pShBuffer);
            break;
        default:
            Status = DT_STATUS_NOT_SUPPORTED;
        }
    }

    // If we failed, no data has te be copied to user space
    if (!DT_SUCCESS(Status))
    {
        pIoctl->m_OutputBufferBytesWritten = 0;
        if (Status == DT_STATUS_NOT_SUPPORTED)
            DtDbgOut(MIN, SHBUF, "ShBufCmd=0x%x: NOT SUPPORTED", pShBufCmdInput->m_Cmd);
    }
    return Status;
}