Example #1
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGetEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtuEvents* DtuEventsGetEventsObject(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFile)
{
    Int  i;
    DtuEvents*  pDtuEvents = NULL;

    for (i=0; i<MAX_NUM_FILE_HANDLES; i++)
    {
        DtSpinLockAcquire(&pDvcData->m_Events[i].m_Lock);
        if (pDvcData->m_Events[i].m_RefCount > 0)
        {
            if (DtFileCompare(&pDvcData->m_Events[i].m_File, pFile))
            {
                pDtuEvents = &pDvcData->m_Events[i];

                // Increment refcount
                pDtuEvents->m_RefCount++;
            }
        }
        DtSpinLockRelease(&pDvcData->m_Events[i].m_Lock);

        if (pDtuEvents != NULL)
            break;
    }

    return pDtuEvents;
}
Example #2
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsUnrefEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static void  DtuEventsUnrefEventsObject(DtuDeviceData* pDvcData, DtuEvents* pDtuEvents)
{
    DtSpinLockAcquire(&pDtuEvents->m_Lock);
    if (pDtuEvents->m_RefCount > 0)
        pDtuEvents->m_RefCount--;
    DtSpinLockRelease(&pDtuEvents->m_Lock);
}
Example #3
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsAllocEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static DtuEvents* DtuEventsAllocEventsObject(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFileHandle,
    UInt  EventTypeMask)
{
    Int  i;
    DtuEvents*  pDtuEvents = NULL;
    
    for (i=0; i<MAX_NUM_FILE_HANDLES; i++)
    {
        DtSpinLockAcquire(&pDvcData->m_Events[i].m_Lock);
        if (pDvcData->m_Events[i].m_RefCount == 0)
        {
            pDtuEvents = &pDvcData->m_Events[i];

            pDtuEvents->m_RefCount = 2;
                                // Start with 2 to prevent removal after first unref
            pDtuEvents->m_File = *pFileHandle;
            pDtuEvents->m_EventTypeMask = EventTypeMask;
            pDtuEvents->m_CancelInProgress = FALSE;
            pDtuEvents->m_NumPendingEvents = 0;
            memset(&pDtuEvents->m_PendingEvents, 0, sizeof(pDtuEvents->m_PendingEvents));
        }
        DtSpinLockRelease(&pDvcData->m_Events[i].m_Lock);

        if (pDtuEvents != NULL)
            break;
    }

    return pDtuEvents;
}
Example #4
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsSet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// This function adds new events to the pending events.
//
DtStatus  DtaEventsSet(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    DtaEvents*  pDtaEvents = NULL;
    
    DtDbgOut(MAX, EVENTS, "Start");
    DtDbgOut(AVG, EVENTS, "EventType: %i, Value1: %i, Value2: %i", EventType, Value1, 
                                                                                  Value2);
    if (pFile != NULL)
    {
        // Get corresponding events object
        pDtaEvents = DtaEventsGetEventsObject(pDvcData, pFile);
        if (pDtaEvents == NULL)
            Result = DT_STATUS_NOT_FOUND;
        else {
            Result = DtaEventsSetEvent(pDtaEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtaEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                pFile = &pDtaEvents->m_File;
                DtaEventsDequeue(pDvcData, pFile, pDtaEvents);
            }
#endif
            DtaEventsUnrefEventsObject(pDvcData, pDtaEvents);
        }
    } else {
        // Set event for all file handles
        DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);

        pDtaEvents = pDvcData->m_pEvents;
        while (pDtaEvents != NULL)
        {
            // Set event
            Result = DtaEventsSetEvent(pDtaEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtaEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                pFile = &pDtaEvents->m_File;
                DtaEventsDequeue(pDvcData, pFile, pDtaEvents);
            }
#endif
            pDtaEvents = pDtaEvents->m_pNext;
        }
        DtSpinLockRelease(&pDvcData->m_EventsSpinlock);
    }
    
    DtDbgOut(MAX, EVENTS, "Exit");

    return Result;
}
Example #5
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 #6
0
File: EnDec.c Project: levic/dektec
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEncD7ProExclusiveAccess -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtaEnDecExclusiveAccess(
    DtaNonIpPort*  pNonIpPort,
    DtFileObject*  pFile,
    Int  Cmd)
{
    DtStatus  Result = DT_STATUS_OK;
    DtaEnDecPort*  pEnDec = &pNonIpPort->m_EnDec;

    DtSpinLockAcquire(&pEnDec->m_ExclAccessLock);

    if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_ACQUIRE)
    {
        if (!pEnDec->m_ExclAccess)
        {
            pEnDec->m_ExclAccess = TRUE;
            pEnDec->m_ExclAccessOwner = *pFile;
        } else
            Result = DT_STATUS_IN_USE;
    } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_RELEASE)
    {
        if (pEnDec->m_ExclAccess)
        {
            if (DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile))
            {
                pEnDec->m_ExclAccess = FALSE;
            }
            else
                Result = DT_STATUS_IN_USE;
        }
    } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_PROBE)
    {
        if (pEnDec->m_ExclAccess)
            Result = DT_STATUS_IN_USE;
    } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_CHECK)
    {
        if (!pNonIpPort->m_ExclAccess)
            Result = DT_STATUS_EXCL_ACCESS_REQD;
        else if (!DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile))
            Result = DT_STATUS_IN_USE;
    } else
        Result = DT_STATUS_NOT_SUPPORTED;
    
    DtSpinLockRelease(&pEnDec->m_ExclAccessLock);

    return Result;
}
Example #7
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxGetFlags -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtaNonIpTxGetFlags(DtaNonIpPort* pNonIpPort, Int* pStatus, Int* pLatched)
{
    // Update flags
    DtaNonIpTxProcessFlagsFromUser(pNonIpPort);

    // Update DMA pending status
    //if (NonIpTxIsDmaPending(pNonIpPort))
    //    pNonIpPort->m_Flags |= DTA_TX_DMA_PENDING;

    DtSpinLockAcquire(&pNonIpPort->m_FlagsSpinLock);

    // Return flags
    *pStatus = pNonIpPort->m_Flags;
    *pLatched = pNonIpPort->m_FlagsLatched;

    DtSpinLockRelease(&pNonIpPort->m_FlagsSpinLock);

    return DT_STATUS_OK;
}
Example #8
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsUnregister -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtaEventsUnregister(DtaDeviceData* pDvcData, DtFileObject* pFile)
{
    DtaEvents*  pDtaEvents = NULL;

    DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);
    pDtaEvents = pDvcData->m_pEvents;

    while (pDtaEvents != NULL)
    {
        if (DtFileCompare(&pDtaEvents->m_File, pFile))
            break;
        pDtaEvents = pDtaEvents->m_pNext;
    }
    if (pDtaEvents == NULL)
    {
        DtSpinLockRelease(&pDvcData->m_EventsSpinlock);
        return;
    }
    // Remove events struct from linked list while holding the spinlock
    if (pDtaEvents->m_pPrev != NULL)
        pDtaEvents->m_pPrev->m_pNext = pDtaEvents->m_pNext;
    else
        pDvcData->m_pEvents = pDtaEvents->m_pNext;
    if (pDtaEvents->m_pNext != NULL)
        pDtaEvents->m_pNext->m_pPrev = pDtaEvents->m_pPrev;

    pDtaEvents->m_pPrev = NULL;
    pDtaEvents->m_pNext = NULL;

    DtSpinLockRelease(&pDvcData->m_EventsSpinlock);
    
    // Even if two threads call DtaEventsUnregister at the same time we'll only come here
    // once. We remove the DtaEvents object from the linked-list while holding the
    // spinlock, so the second thread won't find the object and return immediately.

    // Signal pending event (will remove object if event was pending)
    DtaEventsGetCancel(pDvcData, pFile);

    // Decrement refcount to free object as soon as it's no longer in use
    DtaEventsUnrefEventsObject(pDvcData, pDtaEvents);
}
Example #9
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 #10
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsUnregister -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtuEventsUnregister(DtuDeviceData* pDvcData, DtFileObject* pFile)
{
    DtuEvents*  pDtuEvents;

    // We force the Pending event to be signaled.
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents == NULL)
        return;

    // Decrement initial refcount to mark unused after last unreference
    DtSpinLockAcquire(&pDtuEvents->m_Lock);
    if (pDtuEvents->m_RefCount > 0)
        pDtuEvents->m_RefCount--;
    DtSpinLockRelease(&pDtuEvents->m_Lock);

    // Decrement refcount
    DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);

    // Signal pending event (will remove object if event was pending)
    DtuEventsGetCancel(pDvcData, pFile);
}
Example #11
0
File: EnDec.c Project: levic/dektec
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEnDecClose -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtaEnDecClose(DtaNonIpPort* pNonIpPort, DtFileObject* pFile)
{
    DtaEnDecPort*  pEnDec = &pNonIpPort->m_EnDec;

    DtSpinLockAcquire(&pEnDec->m_ExclAccessLock);

    if (!pEnDec->m_ExclAccess || !DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile))
    {
        DtSpinLockRelease(&pEnDec->m_ExclAccessLock);
        return DT_STATUS_OK;
    }
    
    if (pNonIpPort->m_pDvcData->m_DevInfo.m_TypeNumber == 2180 ||
                                   pNonIpPort->m_pDvcData->m_DevInfo.m_TypeNumber == 2182)
        DtaEncD7ProUncleanDetach(pNonIpPort);

    pEnDec->m_ExclAccess = FALSE;

    DtSpinLockRelease(&pEnDec->m_ExclAccessLock);

    return DT_STATUS_OK;
}
Example #12
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsGetEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtaEvents*  DtaEventsGetEventsObject(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile)
{
    DtaEvents*  pDtaEvents = NULL;

    DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);
    pDtaEvents = pDvcData->m_pEvents;

    while (pDtaEvents != NULL)
    {
        if (DtFileCompare(&pDtaEvents->m_File, pFile))
        {
            // Increment refcount
            DtAtomicIncrement(&pDtaEvents->m_RefCount);
            break;
        }
        pDtaEvents = pDtaEvents->m_pNext;
    }
    DtSpinLockRelease(&pDvcData->m_EventsSpinlock);
    return pDtaEvents;
}
Example #13
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsAllocEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static DtaEvents*  DtaEventsAllocEventsObject(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFileHandle,
    UInt  EventTypeMask)
{
    DtaEvents*  pDtaEvents;

    pDtaEvents = (DtaEvents*)DtMemAllocPool(DtPoolNonPaged, sizeof(DtaEvents), DTA_TAG);
    if (pDtaEvents == NULL)
    {
        DtDbgOut(ERR, EVENTS, "Out of memory allocating DtaEvents struct");
        return NULL;
    }

    DtAtomicSet(&pDtaEvents->m_RefCount, 1);
    pDtaEvents->m_File = *pFileHandle;
    pDtaEvents->m_EventTypeMask = EventTypeMask;
    pDtaEvents->m_CancelInProgress = FALSE;
    pDtaEvents->m_NumPendingEvents = 0;
    DtEventInit(&pDtaEvents->m_PendingEvent, FALSE);
    DtSpinLockInit(&pDtaEvents->m_Lock);
    memset(&pDtaEvents->m_PendingEvents, 0, sizeof(pDtaEvents->m_PendingEvents));

    // Insert at start of list
    DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);
    pDtaEvents->m_pPrev = NULL;
    pDtaEvents->m_pNext = NULL;
    if (pDvcData->m_pEvents != NULL)
    {
        pDtaEvents->m_pNext = pDvcData->m_pEvents;
        pDtaEvents->m_pNext->m_pPrev = pDtaEvents;
    }
    pDvcData->m_pEvents = pDtaEvents;
    DtSpinLockRelease(&pDvcData->m_EventsSpinlock);

    return pDtaEvents;
}
Example #14
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxClearFlags -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtaNonIpTxClearFlags(DtaNonIpPort* pNonIpPort, Int FlagsToClear)
{
    DtSpinLockAcquire(&pNonIpPort->m_FlagsSpinLock);

    // Clear latched flags
    pNonIpPort->m_Flags &= ~FlagsToClear;
    pNonIpPort->m_FlagsLatched &= ~FlagsToClear;

    // Also clear flags in Transmit Status register, to avoid that flags in
    // m_Latched are set again in next periodic interrupt.
    if (!pNonIpPort->m_CapMatrix)
    {
        if ((FlagsToClear&DTA_TX_FIFO_UFL) == DTA_TX_FIFO_UFL)
            DtaRegTxStatClrUflInt(pNonIpPort->m_pTxRegs);
        if ((FlagsToClear&DTA_TX_SYNC_ERR) == DTA_TX_SYNC_ERR)
            DtaRegTxStatClrSyncInt(pNonIpPort->m_pTxRegs);
    }
    else
    {
        if ((FlagsToClear&DTA_TX_FIFO_UFL) == DTA_TX_FIFO_UFL)
            DtaRegHdStatClrTxUflErrInt(pNonIpPort->m_pTxRegs);
        if ((FlagsToClear&DTA_TX_SYNC_ERR) == DTA_TX_SYNC_ERR)
            DtaRegHdStatClrTxSyncErrInt(pNonIpPort->m_pTxRegs);
    }

    // Special case for DTA-102
    if (pNonIpPort->m_pDvcData->m_DevInfo.m_TypeNumber == 102)
    {
        if ((FlagsToClear&DTA_TX_READBACK_ERR) == DTA_TX_READBACK_ERR)
            DtaRegTxStatClrShortInt(pNonIpPort->m_pTxRegs);
    }

    DtSpinLockRelease(&pNonIpPort->m_FlagsSpinLock);

    return DT_STATUS_OK;
}
Example #15
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsSet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// This function adds new events to the pending events. If the Events argument is 0, 
// this function does nothing.
//
DtStatus  DtuEventsSet(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFile,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    Int  i;
    DtuEvents*  pDtuEvents = NULL;
    Bool  InUse;
    
    DtDbgOut(MAX, EVENTS, "Start");
    DtDbgOut(AVG, EVENTS, "EventType: %i, Value1: %i, Value2: %i", EventType, Value1, 
                                                                                  Value2);
    if (pFile != NULL)
    {
        // Get corresponding events object
        pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
        if (pDtuEvents == NULL)
            Result = DT_STATUS_NOT_FOUND;
        else {
            Result = DtuEventsSetEvent(pDtuEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtuEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                DtuEventsDequeue(pDvcData, pFile);
            }
#endif
            DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
        }
    } else {
        // Set event for all file handles
        for (i=0; i<MAX_NUM_FILE_HANDLES; i++)
        {
            pDtuEvents = &pDvcData->m_Events[i];

            // Increment refcount
            InUse = FALSE;
            DtSpinLockAcquire(&pDtuEvents->m_Lock);
            if (pDtuEvents->m_RefCount > 0)
            {
                pDtuEvents->m_RefCount++;
                InUse = TRUE;
            }
            DtSpinLockRelease(&pDtuEvents->m_Lock);
            
            if (InUse)
            {
                // Set event
                Result = DtuEventsSetEvent(pDtuEvents, EventType, Value1, Value2);
#ifdef WINBUILD
                if (pDtuEvents->m_NumPendingEvents != 0)
                {
                    // Dequeue pending events
                    pFile = &pDtuEvents->m_File;
                    DtuEventsDequeue(pDvcData, pFile);
                }
#endif
                // Decrement refcount
                DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
            }
        }
    }
    
    DtDbgOut(MAX, EVENTS, "Exit");

    return Result;
}
Example #16
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// Return a pending event. This functions blocks if no events are pending.
//
DtStatus  DtuEventsGet(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFile, 
    UInt*  pEventType, 
    UInt*  pValue1,
    UInt*  pValue2,
    Bool  Wait)
{
    DtStatus  Result = DT_STATUS_OK;
    DtuEvents*  pDtuEvents;

    if (pFile==NULL || pEventType==NULL || pValue1==NULL || pValue2==NULL)
        return DT_STATUS_INVALID_PARAMETER;

    // Get corresponding events object
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents == NULL)
        Result = DT_STATUS_NOT_FOUND;

    if (DT_SUCCESS(Result))
    {
        DtEventReset(&pDtuEvents->m_PendingEvent);

        if (Wait && pDtuEvents->m_NumPendingEvents==0 && !pDtuEvents->m_CancelInProgress) 
        {
            DtDbgOut(MAX, EVENTS, "Waiting for event");
        
            // Wait for event to be triggered
            DtEventWait(&pDtuEvents->m_PendingEvent, -1);
        }

        // The next request will be rejected by the IoCtl function, so we can reset
        // the Cancel state here.
        if (pDtuEvents->m_CancelInProgress)
            Result = DT_STATUS_CANCELLED;
        pDtuEvents->m_CancelInProgress = FALSE;

        DtSpinLockAcquire(&pDtuEvents->m_Lock);
        
        // Return pending events
        if (pDtuEvents->m_NumPendingEvents != 0)
        {  
            *pEventType = pDtuEvents->m_PendingEvents[0].m_EventType;
            *pValue1 = pDtuEvents->m_PendingEvents[0].m_EventValue1;
            *pValue2 =  pDtuEvents->m_PendingEvents[0].m_EventValue2;
            DtDbgOut(MAX, EVENTS, "Event #%d. Type: %d, Value1: %d, Value2: %d", 
                         pDtuEvents->m_NumPendingEvents, *pEventType, *pValue1, *pValue2);
            pDtuEvents->m_NumPendingEvents--;

            if (pDtuEvents->m_NumPendingEvents != 0)
            {   
                // Remove the old event
                DtMemMove(&pDtuEvents->m_PendingEvents[0],
                                       &pDtuEvents->m_PendingEvents[1],
                                       sizeof(DtuEvent) * pDtuEvents->m_NumPendingEvents);
            }
        } else {
            *pEventType = 0;
            *pValue1 = 0;
            *pValue2 = 0;
            if (Result == DT_STATUS_OK)
                Result = DT_STATUS_REQUEUE; // No pending events
            DtDbgOut(MAX, EVENTS, "Event #%d. No event", pDtuEvents->m_NumPendingEvents);
        }
    
        DtSpinLockRelease(&pDtuEvents->m_Lock);

        // Decrement refcount
        DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
    }
    
    return Result;
}
Example #17
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxProcessFlagsFromUser -.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtaNonIpTxProcessFlagsFromUser(DtaNonIpPort* pNonIpPort)
{
    DtSpinLockAcquire(&pNonIpPort->m_FlagsSpinLock);
    DtaNonIpTxProcessFlags(pNonIpPort);
    DtSpinLockRelease(&pNonIpPort->m_FlagsSpinLock);
}