Exemplo n.º 1
0
VOID
otLwfEventProcessingIndicateNewWaitTime(
    _In_ PMS_FILTER             pFilter,
    _In_ ULONG                  waitTime
    )
{
    BOOLEAN FireUpdateEvent = TRUE;
    
    // Cancel previous timer
    if (ExCancelTimer(pFilter->EventHighPrecisionTimer, NULL))
    {
        pFilter->EventTimerState = OT_EVENT_TIMER_NOT_RUNNING;
    }

    if (waitTime == (ULONG)(-1))
    {
        // Ignore if we are already stopped
        if (pFilter->NextAlarmTickCount.QuadPart == 0) return;
        pFilter->NextAlarmTickCount.QuadPart = 0;
    }
    else
    {
        if (waitTime == 0)
        {
#ifdef DEBUG_TIMING
            LogInfo(DRIVER_DEFAULT, "Event processing updating to fire timer immediately.");
#endif
            pFilter->EventTimerState = OT_EVENT_TIMER_FIRED;
            pFilter->NextAlarmTickCount.QuadPart = 0;
        }
        else if (waitTime * 10000ll < (KeQueryTimeIncrement() - 30000))
        {
#ifdef DEBUG_TIMING
            LogInfo(DRIVER_DEFAULT, "Event processing starting high precision timer for %u ms.", waitTime);
#endif
            pFilter->EventTimerState = OT_EVENT_TIMER_RUNNING;
            pFilter->NextAlarmTickCount.QuadPart = 0;
            FireUpdateEvent = FALSE;
            ExSetTimer(pFilter->EventHighPrecisionTimer, waitTime * -10000ll, 0, NULL);
        }
        else
        {

            ULONG TickWaitTime = (waitTime * 10000ll) / KeQueryTimeIncrement();
            if (TickWaitTime == 0) TickWaitTime = 1;
#ifdef DEBUG_TIMING
            LogInfo(DRIVER_DEFAULT, "Event processing updating wait ticks to %u.", TickWaitTime);
#endif

            // Update the time to be 'waitTime' ms from 'now', saved in TickCounts
            KeQueryTickCount(&pFilter->NextAlarmTickCount);
            pFilter->NextAlarmTickCount.QuadPart += TickWaitTime;
        }
    }
    
    // Indicate event to worker thread to update the wait time
    KeSetEvent(&pFilter->EventWorkerThreadWaitTimeUpdated, 0, FALSE);
}
Exemplo n.º 2
0
//
// How long has the system been up, in seconds.
//
LONGLONG Uptime()
{
    LARGE_INTEGER Ticks;
    ULONG Increment = KeQueryTimeIncrement();
    KeQueryTickCount(&Ticks);
    return (Ticks.QuadPart * Increment)/10000000L;
}
Exemplo n.º 3
0
//
// Exported functions.
//
int
CTEInitialize(
    VOID
    )

/*++

Routine Description:

    Initializes the Common Tranport Environment (CTE).

Arguments:

    None.

Return Value:

    0 if initialization fails. Nonzero otherwise.

--*/

{
    CTEpTimeIncrement = KeQueryTimeIncrement();

    return(1);
}
Exemplo n.º 4
0
VOID
DokanUpdateTimeout(
	__out PLARGE_INTEGER TickCount,
	__in ULONG	Timeout
	)
{
	KeQueryTickCount(TickCount);
	TickCount->QuadPart += Timeout * 1000 * 10 / KeQueryTimeIncrement();
}
Exemplo n.º 5
0
VOID
DokanCheckKeepAlive(
	PDEVICE_EXTENSION	DeviceExtension)
{
	LARGE_INTEGER		tickCount;
	ULONG				eventLength;
	PEVENT_CONTEXT		eventContext;
	ULONG				mounted;

	//DDbgPrint("==> DokanCheckKeepAlive\n");

	KeQueryTickCount(&tickCount);
	ExAcquireResourceSharedLite(&DeviceExtension->Resource, TRUE);

	if ( (tickCount.QuadPart - DeviceExtension->TickCount.QuadPart) * KeQueryTimeIncrement()
		> DOKAN_KEEPALIVE_TIMEOUT * 10000 * 1000) {
	

		mounted = DeviceExtension->Mounted;

		ExReleaseResourceLite(&DeviceExtension->Resource);


		DDbgPrint("  Force to umount\n");

		if (!mounted) {
			// not mounted
			return;
		}

		eventLength = sizeof(EVENT_CONTEXT);
		eventContext = ExAllocatePool(eventLength);
				
		if (eventContext == NULL) {
			;//STATUS_INSUFFICIENT_RESOURCES;
			DokanEventRelease(DeviceExtension->DeviceObject);
			return;
		}

		RtlZeroMemory(eventContext, eventLength);
		eventContext->Length = eventLength;

		// set drive letter
		eventContext->Flags = mounted;

		DokanEventNotification(&DeviceExtension->Global->NotifyService, eventContext);

		DokanEventRelease(DeviceExtension->DeviceObject);

	} else {
		ExReleaseResourceLite(&DeviceExtension->Resource);
	}

	//DDbgPrint("<== DokanCheckKeepAlive\n");
}
Exemplo n.º 6
0
static
__inline
VOID
LsuCurrentTime(
	PLARGE_INTEGER	CurrentTime
){
	ULONG    	Tick;

	KeQueryTickCount(CurrentTime);
	Tick = KeQueryTimeIncrement();
	CurrentTime->QuadPart = CurrentTime->QuadPart * Tick;
}
Exemplo n.º 7
0
//
//	get the current system clock
//
static
__inline
LARGE_INTEGER
CurrentTime(VOID){
	LARGE_INTEGER Time;
	ULONG		Tick;

	KeQueryTickCount(&Time);
	Tick = KeQueryTimeIncrement();
	Time.QuadPart = Time.QuadPart * Tick;

	return Time;
}
Exemplo n.º 8
0
uint32_t systime(void)
{
        LARGE_INTEGER time;
        uint32_t timeIncrement100ns;
        uint32_t time0_1ms;
        uint32_t result;

        timeIncrement100ns = KeQueryTimeIncrement ();
        time0_1ms = timeIncrement100ns / 1000;
        KeQueryTickCount(&time);
        result = time.LowPart * time0_1ms;

//            dbgpl(NULL, "chantara systime = 0x%x \n", result); 
        return (result); // the unit must be 0.1ms

}
Exemplo n.º 9
0
static
__inline 
LARGE_INTEGER 
LMCurrentTime (VOID)
{
	LARGE_INTEGER	currentCount;
	ULONG			interval;
	LARGE_INTEGER	time;

	KeQueryTickCount(&currentCount);

	interval = KeQueryTimeIncrement();

	time.QuadPart = currentCount.QuadPart * interval;

	return time;
}
RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
{
    /*
     * Get the default/max timer increment value, return it if ExSetTimerResolution
     * isn't available. According to the sysinternals guys NtQueryTimerResolution
     * is only available in userland and they find it equally annoying.
     */
    ULONG ulTimeInc = KeQueryTimeIncrement();
    if (!g_pfnrtNtExSetTimerResolution)
        return ulTimeInc * 100; /* The value is in 100ns, the funny NT unit. */

    /*
     * Use the value returned by ExSetTimerResolution. Since the kernel is keeping
     * count of these calls, we have to do two calls that cancel each other out.
     */
    g_pfnrtNtExSetTimerResolution(ulTimeInc, TRUE);
    ULONG ulResolution = g_pfnrtNtExSetTimerResolution(0 /*ignored*/, FALSE);
    return ulResolution * 100; /* NT -> ns */
}
Exemplo n.º 11
0
/*
 * @implemented
 */
VOID
NTAPI
IoInitializeRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
                         IN ULONG AllocateTag,
                         IN ULONG MaxLockedMinutes,
                         IN ULONG HighWatermark,
                         IN ULONG RemlockSize)
{
    PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
    PAGED_CODE();

    ASSERT(HighWatermark < MAXLONG);

    /* If no lock given, nothing to do */
    if (!Lock)
    {
        return;
    }

    switch (RemlockSize)
    {
        /* Check if this is a debug lock */
        case (sizeof(IO_REMOVE_LOCK_DBG_BLOCK) + sizeof(IO_REMOVE_LOCK_COMMON_BLOCK)):
            /* Setup debug parameters */
            Lock->Dbg.Signature = 'COLR';
            Lock->Dbg.HighWatermark = HighWatermark;
            Lock->Dbg.MaxLockedTicks = KeQueryTimeIncrement() * MaxLockedMinutes * 600000000;
            Lock->Dbg.AllocateTag = AllocateTag;
            KeInitializeSpinLock(&(Lock->Dbg.Spin));
            Lock->Dbg.LowMemoryCount = 0;
            Lock->Dbg.Blocks = NULL;

        case sizeof(IO_REMOVE_LOCK_COMMON_BLOCK):
            /* Setup a free block */
            Lock->Common.Removed = FALSE;
            Lock->Common.IoCount = 1;
            KeInitializeEvent(&Lock->Common.RemoveEvent,
                              SynchronizationEvent,
                              FALSE);
    }
}
Exemplo n.º 12
0
Arquivo: Uart.c Projeto: levic/dektec
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaUartWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtaUartRead(
    DtaUartPort*  pUart,
    UInt8*  pBuf,
    Int  BytesToRead,
    Int  Timeout,
    Int*  pNumBytesRead)
{
    DtStatus  Status = DT_STATUS_OK; 
    Int  NumBytesAvail, NumCanRead, FifoSize, i;
    Int Idx = 0;
    volatile UInt8* pFwbRegs = pUart->m_pFwbRegs;
#ifdef WINBUILD
    LARGE_INTEGER  StartTime, CurTime;
#else
    struct timespec  StartTime, CurTime;
#endif
    Int  TimeElapsed;
    Int  OrigTimeout = Timeout;

    *pNumBytesRead = 0;
    
    // Check timeout
    if (Timeout < -1)
        return DT_STATUS_INVALID_PARAMETER;


#ifdef WINBUILD
    KeQueryTickCount(&StartTime);
#else
    getnstimeofday(&StartTime);
#endif

    FifoSize = DtaFwbRegRead(pFwbRegs,  &pUart->m_pFwbUart->Config_RxFifoSize);
    NumBytesAvail = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxStat_FifoLoad);
    do
    {
        NumCanRead = (BytesToRead < NumBytesAvail) ? BytesToRead : NumBytesAvail;
        // Read available data from FIFO
        for (i=0; i<NumCanRead; i++)
            pBuf[Idx++] = (UInt8)DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxData);

        BytesToRead -= NumCanRead;
        *pNumBytesRead += NumCanRead;

        // Ready?
        if (BytesToRead==0 || Timeout==0)
            break;

        // Wait for data available event
        DtEventReset(&pUart->m_RxEvent);
        if (BytesToRead < FifoSize/2)
            DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_DataIdleIntEnable, 1);
        else
            DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_HalfFullIntEnable, 1);
        Status = DtEventWait(&pUart->m_RxEvent, Timeout);
        if (!DT_SUCCESS(Status))
            break;

        // Check how much is availble now
        NumBytesAvail = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxStat_FifoLoad);

        if (Timeout == -1)
            continue;

#ifdef WINBUILD
        KeQueryTickCount(&CurTime);
        TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement()
                                                                                 / 10000);
#else
        getnstimeofday(&CurTime);
        TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL
                                   + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL);
#endif

        Timeout = OrigTimeout - TimeElapsed;
    } while (Timeout > 0);
    
    // Reception ready
    DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_DataIdleIntEnable, 0);
    DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_HalfFullIntEnable, 0);

    // A timeout is not an error in this case. Let userspace deal with the fact that
    // the read operation is not complete.
    if (Status == DT_STATUS_TIMEOUT)
        Status = DT_STATUS_OK;

    return Status;
}
Exemplo n.º 13
0
NTSTATUS
LMInitialize(
	IN PLURELATION_NODE		Lurn,
	IN PBUFFLOCK_CONTROL	BuffLockCtl,
	IN BOOLEAN				InitialState
){

	RtlZeroMemory(BuffLockCtl, sizeof(PBUFFLOCK_CONTROL));

	//
	// Timer resolution data:
	//
	// Windows Vista Business x86 with Xeon SMP: 1/64 second per tick. ( 15.6250 msec )
	// Windows Vista Enterprise x86_64 with AMD Sempron 2600+: 1/64
	// Windows XP Professional x86 with VMWare 5.5: 1/64
	// Windows XP Professional x86 with Xeon SMP: 1/64
	// Windows XP Professional x86 with Dell Latitude D520 note book: 15.6001 msec per tick.
	//
	BuffLockCtl->TimerResolution = KeQueryTimeIncrement();
	KDPrintM(DBG_OTHER_ERROR, ("KeQueryTickCount()'s 100nano per tick = %u, LOCKMGMT_QUANTUM = %u\n", 
								BuffLockCtl->TimerResolution, LOCKMGMT_QUANTUM));

	BuffLockCtl->Quantum.QuadPart = LOCKMGMT_QUANTUM;
	BuffLockCtl->PriorityWaitTime.QuadPart = LOCKMGMT_PRIORITYWAITTIME;
	BuffLockCtl->AcquisitionMaxTime.QuadPart = LOCKMGMT_MAX_ACQUISITION_TIME;
	BuffLockCtl->AcquisitionExpireTime.QuadPart = 0;
	BuffLockCtl->MaxIOBytes = LOCKMGMT_MAX_ACQUISITION_BYTES;
	BuffLockCtl->IoIdleTimeOut.QuadPart = LOCKMGMT_IOIDLE_TIMEOUT;
	BuffLockCtl->IoIdle = TRUE;
	BuffLockCtl->ConnectedHosts = 1; // add myself.
	BuffLockCtl->CurrentLockCount = 0;
	BuffLockCtl->RequestCountWhenReleased = 0;
	BuffLockCtl->Priority = 0;
	KeInitializeTimer(&BuffLockCtl->IoIdleTimer);
	BuffLockCtl->AccumulatedIOBytes = 0;
	BuffLockCtl->BufferLockConrol = InitialState;

#if __NDAS_SCSI_DISABLE_LOCK_RELEASE_DELAY__
	if (LURN_IS_ROOT_NODE(Lurn)) {

		BuffLockCtl->BufferLockParent = FALSE;
	
	} else {

		BuffLockCtl->BufferLockParent = TRUE;
		// Must be off when the parent controls the buffer lock.
		BuffLockCtl->BufferLockConrol = FALSE;
	}
#else
	BuffLockCtl->BufferLockParent = FALSE;
#endif

#if DBG
	if(BuffLockCtl->BufferLockParent)
		ASSERT(BuffLockCtl->BufferLockConrol == FALSE);
	KDPrintM(DBG_LURN_ERROR, ("Buffer lock control:%x Controlled by parent:%x\n",
		BuffLockCtl->BufferLockConrol,
		BuffLockCtl->BufferLockParent));
#endif

	return STATUS_SUCCESS;
}
Exemplo n.º 14
0
/*++////////////////////////////////////////////////////////////////////////////

ClassReleaseRemoveLock()

Routine Description:

    This routine is called to release the remove lock on the device object.  It
    must be called when finished using a previously locked reference to the
    device object.  If an Tag was specified when acquiring the lock then the
    same Tag must be specified when releasing the lock.

    When the lock count reduces to zero, this routine will signal the waiting
    remove Tag to delete the device object.  As a result the DeviceObject
    pointer should not be used again once the lock has been released.

Arguments:

    DeviceObject - the device object to lock

    Tag - The irp (if any) specified when acquiring the lock.  This is used
          for lock tracking purposes

Return Value:

    none

--*/
VOID
NTAPI
ClassReleaseRemoveLock(
    IN PDEVICE_OBJECT DeviceObject,
    IN OPTIONAL PIRP Tag
    )
{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    LONG lockValue;

    #if DBG
        PREMOVE_TRACKING_BLOCK *listEntry =
            (PREMOVE_TRACKING_BLOCK*)&commonExtension->RemoveTrackingList;

        BOOLEAN found = FALSE;

        LONGLONG maxCount;

        BOOLEAN isRemoved = (commonExtension->IsRemoved == REMOVE_COMPLETE);

        KIRQL oldIrql;

        if(isRemoved) {
            DBGTRAP(("ClassReleaseRemoveLock: REMOVE_COMPLETE set; this should never happen"));
            InterlockedDecrement(&(commonExtension->RemoveLock));
            return;
        }

        //
        // Check the tick count and make sure this thing hasn't been locked
        // for more than MaxLockedMinutes.
        //

        maxCount = KeQueryTimeIncrement() * 10;     // microseconds
        maxCount *= 1000;                           // milliseconds
        maxCount *= 1000;                           // seconds
        maxCount *= 60;                             // minutes
        maxCount *= MaxLockedMinutes;

        DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
                    "maxCount = %0I64x\n", maxCount));

        KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
                          &oldIrql);

        while(*listEntry != NULL) {

            PREMOVE_TRACKING_BLOCK block;
            LARGE_INTEGER difference;

            block = *listEntry;

            KeQueryTickCount((&difference));

            difference.QuadPart -= block->TimeLocked.QuadPart;

            DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
                        "Object %p (tag %p) locked for %I64d ticks\n",
                        DeviceObject, block->Tag, difference.QuadPart));

            if(difference.QuadPart >= maxCount) {

                DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
                            "Object %p (tag %p) locked for %I64d ticks - TOO LONG\n",
                            DeviceObject, block->Tag, difference.QuadPart));
                DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
                            "Lock acquired in file %s on line %d\n",
                            block->File, block->Line));
                ASSERT(FALSE);
            }

            if((found == FALSE) && ((*listEntry)->Tag == Tag)) {

                *listEntry = block->NextBlock;
                ExFreePool(block);
                found = TRUE;

            } else {

                listEntry = &((*listEntry)->NextBlock);

            }
        }

        if(!found) {
            if(commonExtension->RemoveTrackingUntrackedCount == 0) {
                DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
                            "Couldn't find Tag %p in the lock tracking list\n",
                            Tag));
                ASSERT(FALSE);
            } else {
                DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
                            "Couldn't find Tag %p in the lock tracking list - "
                            "may be one of the %d untracked requests still "
                            "outstanding\n",
                            Tag,
                            commonExtension->RemoveTrackingUntrackedCount));

                commonExtension->RemoveTrackingUntrackedCount--;
                ASSERT(commonExtension->RemoveTrackingUntrackedCount >= 0);
            }
        }

        KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock,
                          oldIrql);

    #endif

    lockValue = InterlockedDecrement(&commonExtension->RemoveLock);

    DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
                "Released for Object %p & irp %p - count is %d\n",
                DeviceObject, Tag, lockValue));

    ASSERT(lockValue >= 0);

    ASSERTMSG("RemoveLock decreased to meet LockLowWatermark",
              ((LockLowWatermark == 0) || !(lockValue == LockLowWatermark)));

    if(lockValue == 0) {

        ASSERT(commonExtension->IsRemoved);

        //
        // The device needs to be removed.  Signal the remove event
        // that it's safe to go ahead.
        //

        DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
                    "Release for object %p & irp %p caused lock to go to zero\n",
                    DeviceObject, Tag));

        KeSetEvent(&commonExtension->RemoveEvent,
                   IO_NO_INCREMENT,
                   FALSE);

    }
    return;
}
Exemplo n.º 15
0
NTSTATUS
ReleaseTimeoutPendingIrp(
   PDEVICE_EXTENSION	DeviceExtension
   )
{
	KIRQL				oldIrql;
    PLIST_ENTRY			thisEntry, nextEntry, listHead;
	PIRP_ENTRY			irpEntry;
	LARGE_INTEGER		tickCount;
	LIST_ENTRY			completeList;
	PIRP				irp;

	DDbgPrint("==> ReleaseTimeoutPendingIRP\n");
	InitializeListHead(&completeList);

	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
	KeAcquireSpinLock(&DeviceExtension->PendingIrp.ListLock, &oldIrql);

	// when IRP queue is empty, there is nothing to do
	if (IsListEmpty(&DeviceExtension->PendingIrp.ListHead)) {
		KeReleaseSpinLock(&DeviceExtension->PendingIrp.ListLock, oldIrql);
		DDbgPrint("  IrpQueue is Empty\n");
		return STATUS_SUCCESS;
	}

	KeQueryTickCount(&tickCount);

	// search timeout IRP through pending IRP list
	listHead = &DeviceExtension->PendingIrp.ListHead;

    for (thisEntry = listHead->Flink;
		thisEntry != listHead;
		thisEntry = nextEntry) {

        nextEntry = thisEntry->Flink;

        irpEntry = CONTAINING_RECORD(thisEntry, IRP_ENTRY, ListEntry);

		// this IRP is NOT timeout yet
		if ( (tickCount.QuadPart - irpEntry->TickCount.QuadPart) * KeQueryTimeIncrement()
			< DOKAN_IPR_PENDING_TIMEOUT * 10000 * 1000) {
			break;
		}

		RemoveEntryList(thisEntry);

		DDbgPrint(" timeout Irp #%X\n", irpEntry->SerialNumber);

		irp = irpEntry->Irp;

		if (irp == NULL) {
			// this IRP has already been canceled
			ASSERT(irpEntry->CancelRoutineFreeMemory == FALSE);
			ExFreePool(irpEntry);
			continue;
		}

		// this IRP is not canceled yet
		if (IoSetCancelRoutine(irp, NULL) == NULL) {
			// Cancel routine will run as soon as we release the lock
			InitializeListHead(&irpEntry->ListEntry);
			irpEntry->CancelRoutineFreeMemory = TRUE;
			continue;
		}
		// IrpEntry is saved here for CancelRoutine
		// Clear it to prevent to be completed by CancelRoutine twice
		irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_IRP_ENTRY] = NULL;
		InsertTailList(&completeList, &irpEntry->ListEntry);
	}

	if (IsListEmpty(&DeviceExtension->PendingIrp.ListHead)) {
		KeClearEvent(&DeviceExtension->PendingIrp.NotEmpty);
	}
	KeReleaseSpinLock(&DeviceExtension->PendingIrp.ListLock, oldIrql);
	
	while (!IsListEmpty(&completeList)) {
		listHead = RemoveHeadList(&completeList);
		irpEntry = CONTAINING_RECORD(listHead, IRP_ENTRY, ListEntry);
		irp = irpEntry->Irp;
		irp->IoStatus.Information = 0;
		irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		ExFreePool(irpEntry);
		IoCompleteRequest(irp, IO_NO_INCREMENT);
	}

	DDbgPrint("<== ReleaseTimeoutPendingIRP\n");
	return STATUS_SUCCESS;
}
Exemplo n.º 16
0
VOID
FASTCALL
SpReleaseRemoveLock(
    IN PDEVICE_OBJECT DeviceObject,
    IN OPTIONAL PIRP Tag
)

/*++

Routine Description:

    This routine is called to release the remove lock on the device object.  It
    must be called when finished using a previously locked reference to the
    device object.  If an Tag was specified when acquiring the lock then the
    same Tag must be specified when releasing the lock.

    When the lock count reduces to zero, this routine will signal the waiting
    remove Tag to delete the device object.  As a result the DeviceObject
    pointer should not be used again once the lock has been released.

Arguments:

    DeviceObject - the device object to lock

    Tag - The irp (if any) specified when acquiring the lock.  This is used
          for lock tracking purposes

Return Value:

    none

--*/

{
    PCOMMON_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    LONG lockValue;

#if DBG
    PREMOVE_TRACKING_BLOCK *listEntry =
        &((PREMOVE_TRACKING_BLOCK) commonExtension->RemoveTrackingList);

    BOOLEAN found = FALSE;

    LONGLONG maxCount;

    KIRQL oldIrql;

    if(commonExtension->IsRemoved == REMOVE_COMPLETE) {
        return;
    }

    //
    // Check the tick count and make sure this thing hasn't been locked
    // for more than MaxLockedMinutes.
    //

    maxCount = KeQueryTimeIncrement() * 10;     // microseconds
    maxCount *= 1000;                           // milliseconds
    maxCount *= 1000;                           // seconds
    maxCount *= 60;                             // minutes
    maxCount *= MaxLockedMinutes;

    DebugPrint((4, "SpReleaseRemoveLock: maxCount = %0I64x\n", maxCount));

    KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
                      &oldIrql);

    while(*listEntry != NULL) {

        PREMOVE_TRACKING_BLOCK block;
        LARGE_INTEGER difference;

        block = *listEntry;

        KeQueryTickCount((&difference));

        difference.QuadPart -= block->TimeLocked.QuadPart;

        DebugPrint((4, "SpReleaseRemoveLock: Object %#p (tag %#p) locked "
                    "for %I64d ticks\n", DeviceObject, block->Tag, difference.QuadPart));

        if(difference.QuadPart >= maxCount) {

            DebugPrint((0, ">>>>SpReleaseRemoveLock: Object %#p (tag %#p) locked "
                        "for %I64d ticks - TOO LONG\n", DeviceObject, block->Tag, difference.QuadPart));
            DebugPrint((0, ">>>>SpReleaseRemoveLock: Lock acquired in file "
                        "%s on line %d\n", block->File, block->Line));
            ASSERT(FALSE);
        }

        if((found == FALSE) && ((*listEntry)->Tag == Tag)) {

            *listEntry = block->NextBlock;
            ExFreeToNPagedLookasideList(
                &(commonExtension->RemoveTrackingLookasideList),
                block);
            found = TRUE;

        } else {

            listEntry = &((*listEntry)->NextBlock);

        }
    }

    if(!found) {

        if(commonExtension->RemoveTrackingUntrackedCount == 0) {
            DebugPrint((0, ">>>>SpReleaseRemoveLock: Couldn't find Tag %#p "
                        "in the lock tracking list\n",
                        Tag));
            ASSERT(FALSE);
        } else {

            DebugPrint((0, ">>>>SpReleaseRemoveLock: Couldn't find Tag %#p "
                        "in the lock tracking list - may be one of the "
                        "%d untracked requests still outstanding\n",
                        Tag,
                        commonExtension->RemoveTrackingUntrackedCount));

            commonExtension->RemoveTrackingUntrackedCount--;
            ASSERT(commonExtension->RemoveTrackingUntrackedCount >= 0);
        }
    }

    KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);

#endif

    lockValue = InterlockedDecrement(&commonExtension->RemoveLock);

    DebugPrint((4, "SpReleaseRemoveLock: Released for Object %#p & irp "
                "%#p - count is %d\n",
                DeviceObject,
                Tag,
                lockValue));

    ASSERT(lockValue >= 0);

    ASSERTMSG("RemoveLock decreased to meet LockLowWatermark",
              ((LockLowWatermark == 0) || !(lockValue == LockLowWatermark)));

    if(lockValue == 0) {

        ASSERT(commonExtension->IsRemoved);

        //
        // The device needs to be removed.  Signal the remove event
        // that it's safe to go ahead.
        //

        DebugPrint((3, "SpReleaseRemoveLock: Release for object %#p & "
                    "irp %#p caused lock to go to zero\n",
                    DeviceObject,
                    Tag));

        KeSetEvent(&commonExtension->RemoveEvent,
                   IO_NO_INCREMENT,
                   FALSE);

    }
    return;
}
Exemplo n.º 17
0
NTSTATUS
NTAPI
PciStallForPowerChange(IN PPCI_PDO_EXTENSION PdoExtension,
                       IN DEVICE_POWER_STATE PowerState,
                       IN ULONG_PTR CapOffset)
{
    ULONG PciState, TimeoutEntry, PmcsrOffset, TryCount;
    PPCI_VERIFIER_DATA VerifierData;
    LARGE_INTEGER Interval;
    PCI_PMCSR Pmcsr;
    KIRQL Irql;

    /* Make sure the power state is valid, and the device can support it */
    ASSERT((PdoExtension->PowerState.CurrentDeviceState >= PowerDeviceD0) &&
           (PdoExtension->PowerState.CurrentDeviceState <= PowerDeviceD3));
    ASSERT((PowerState >= PowerDeviceD0) && (PowerState <= PowerDeviceD3));
    ASSERT(!(PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS));

    /* Save the current IRQL */
    Irql = KeGetCurrentIrql();

    /* Pick the expected timeout for this transition */
    TimeoutEntry = PciPowerDelayTable[PowerState * PdoExtension->PowerState.CurrentDeviceState];

    /* PCI power states are one less than NT power states */
    PciState = PowerState - 1;

    /* The state status is stored in the PMCSR offset */
    PmcsrOffset = CapOffset + FIELD_OFFSET(PCI_PM_CAPABILITY, PMCSR);

    /* Try changing the power state up to 100 times */
    TryCount = 100;
    while (--TryCount)
    {
        /* Check if this state transition will take time */
        if (TimeoutEntry > 0)
        {
            /* Check if this is happening at high IRQL */
            if (Irql >= DISPATCH_LEVEL)
            {
                /* Can't wait at high IRQL, stall the processor */
                KeStallExecutionProcessor(TimeoutEntry);
            }
            else
            {
                /* Do a wait for the timeout specified instead */
                Interval.QuadPart = -10 * TimeoutEntry;
                Interval.QuadPart -= KeQueryTimeIncrement() - 1;
                KeDelayExecutionThread(0, 0, &Interval);
            }
        }

        /* Read the PMCSR and see if the state has changed */
        PciReadDeviceConfig(PdoExtension, &Pmcsr, PmcsrOffset, sizeof(PCI_PMCSR));
        if (Pmcsr.PowerState == PciState) return STATUS_SUCCESS;

        /* Try again, forcing a timeout of 1ms */
        TimeoutEntry = 1000;
    }

    /* Call verifier with this error */
    VerifierData = PciVerifierRetrieveFailureData(2);
    ASSERT(VerifierData);
    VfFailDeviceNode(PdoExtension->PhysicalDeviceObject,
                     PCI_VERIFIER_DETECTED_VIOLATION,
                     2, // The PMCSR register was not updated within the spec-mandated time.
                     VerifierData->FailureClass,
                     &VerifierData->AssertionControl,
                     VerifierData->DebuggerMessageText,
                     "%DevObj%Ulong",
                     PdoExtension->PhysicalDeviceObject,
                     PciState);

    return STATUS_DEVICE_PROTOCOL_ERROR;
}
Exemplo n.º 18
0
void launch_rb_tree_testing()
{
	//Creating structure for RB-tree information
	RB_TREE* tree = (RB_TREE*) YtAlloc(NonPagedPool, sizeof(RB_TREE)); 

	init_rb_tree(tree);

#ifdef USER_MODE

	DWORD t = GetTickCount();

#else
	
	PLARGE_INTEGER t1 = (PLARGE_INTEGER) YtAlloc(NonPagedPool, sizeof(LARGE_INTEGER)); 
	PLARGE_INTEGER t2 = (PLARGE_INTEGER) YtAlloc(NonPagedPool, sizeof(LARGE_INTEGER)); 

	LARGE_INTEGER time;

	KeQueryTickCount(t1);

#endif

	//Random-generating sector's adresses and inserting its to tree
	const int N = 250000;

	const int M = 2000;
	const int MAX_COUNT = 256;

	//Seting up random seed.
	srand(N);

	INT32 original_sector, target_sector, sectors_count;

	DebugPrint(("RB-tree test: Inserting random nodes to tree... "));

	for (int i = 0; i < N; i++)
	{
		original_sector = (rand() + 1)*(rand() + 1);
		target_sector = (rand() + 1)*(rand() + 1);
		insert_to_rb_tree(tree, original_sector, target_sector);
	}

	DebugPrint(("ok\n"));

#ifdef USER_MODE

	DebugPrint(("RB-tree test: Total time of inserting %d values to tree is %d msecs\n", N, GetTickCount() - t));
	t = GetTickCount();

#else
	
	KeQueryTickCount(t2);
	time.QuadPart = ((t2->QuadPart - t1->QuadPart) * KeQueryTimeIncrement()) / 10000;
	DebugPrint(("RB-tree test: Total time of inserting %d values to tree is %d msecs\n", N, time.QuadPart));
	KeQueryTickCount(t1);

#endif

	DebugPrint(("RB-tree test: Inserting random chains of nodes to tree... "));

	for (int i = 0; i < M; i++)
	{
		original_sector = (rand() + 1)*(rand() + 1);
		target_sector = (rand() + 1)*(rand() + 1);
		sectors_count = (rand() + 1) % MAX_COUNT + 1;

		insert_to_rb_tree(tree, original_sector, target_sector, sectors_count);
	}

	//Manual tests
	insert_to_rb_tree(tree, 64, 12, 1);
	insert_to_rb_tree(tree, 64, 12, 8);
	insert_to_rb_tree(tree, 64, 12, 0);
	insert_to_rb_tree(tree, 63, 12, 1);
	insert_to_rb_tree(tree, 63, 12, 2);
	insert_to_rb_tree(tree, 63, 12, 9);
	insert_to_rb_tree(tree, 63, 12, 14);

	DebugPrint(("ok\n"));

#ifdef USER_MODE

	DebugPrint(("RB-tree test: Total time of inserting %d chains values average with %d nodes to tree is %d msecs\n", M,
		MAX_COUNT / 2, GetTickCount() - t));
	t = GetTickCount();

#else
	
	KeQueryTickCount(t2);
	time.QuadPart = ((t2->QuadPart - t1->QuadPart) * KeQueryTimeIncrement()) / 10000;
	DebugPrint(("RB-tree test: Total time of inserting %d chains values average with %d nodes to tree is %d msecs\n", M,
		MAX_COUNT / 2, time.QuadPart));
	KeQueryTickCount(t1);

#endif

	DebugPrint(("RB-tree test: Searching random nodes in tree... "));

	for (int i = 0; i < N; i++)
		search_in_rb_tree(tree, (rand() + 1)*(rand() + 1));

	DebugPrint(("ok\n"));

#ifdef USER_MODE

	DebugPrint(("RB-tree test: Total time of seaching %d values in tree is %d msecs\n", N, GetTickCount() - t));
	t = GetTickCount();

#else
	
	KeQueryTickCount(t2);
	time.QuadPart = ((t2->QuadPart - t1->QuadPart) * KeQueryTimeIncrement()) / 10000;
	DebugPrint(("RB-tree test: Total time of seaching %d values in tree is %d msecs\n", N, time.QuadPart));
	KeQueryTickCount(t1);

#endif

	DebugPrint(("RB-tree test: Testing tree... "));

	if (test_rb_tree(tree->root, 0, 0))
		DebugPrint(("ok\n"));
	else
		DebugPrint(("FAIL\n"));

#ifdef USER_MODE

	DebugPrint(("RB-tree test: Total time of testing %d tree is %d msecs\n", N, GetTickCount() - t));

#else
	
	KeQueryTickCount(t2);
	time.QuadPart = ((t2->QuadPart - t1->QuadPart) * KeQueryTimeIncrement()) / 10000;
	DebugPrint(("RB-tree test: Total time of testing %d tree is %d msecs\n", N, time.QuadPart));
	KeQueryTickCount(t1);

#endif

	DebugPrint(("RB-tree test: Max level of tree is %d\n", max_level));

	DebugPrint(("RB-tree test: Freeing memory... "));

	//Frees memory of RB-tree
	free_rb_tree(tree->root);

	DebugPrint(("ok\n"));
}
Exemplo n.º 19
0
/*
 *  RetryTransferPacket
 *
 *      Retry sending a TRANSFER_PACKET.
 *
 *      Return TRUE iff the packet is complete.
 *          (if so the status in pkt->irp is the final status).
 */
BOOLEAN NTAPI RetryTransferPacket(PTRANSFER_PACKET Pkt)
{
    BOOLEAN packetDone;

    DBGTRACE(ClassDebugTrace, ("retrying failed transfer (pkt=%ph, op=%s)", Pkt, DBGGETSCSIOPSTR(&Pkt->Srb)));

    ASSERT(Pkt->NumRetries > 0);
    Pkt->NumRetries--;

    /*
     *  Tone down performance on the retry.  
     *  This increases the chance for success on the retry.
     *  We've seen instances of drives that fail consistently but then start working
     *  once this scale-down is applied.
     */
    SET_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_DISABLE_DISCONNECT);
    SET_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
    CLEAR_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_QUEUE_ACTION_ENABLE);
    Pkt->Srb.QueueTag = SP_UNTAGGED;

    if (Pkt->Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES){
        PCDB pCdb = (PCDB)Pkt->Srb.Cdb;
        BOOLEAN isReadWrite = ((pCdb->CDB10.OperationCode == SCSIOP_READ) ||
                                                (pCdb->CDB10.OperationCode == SCSIOP_WRITE));
    
        if (Pkt->InLowMemRetry || !isReadWrite){
            /*
             *  This should never happen.
             *  The memory manager guarantees that at least four pages will
             *  be available to allow forward progress in the port driver.
             *  So a one-page transfer should never fail with insufficient resources.
             */
            ASSERT(isReadWrite && !Pkt->InLowMemRetry);
            packetDone = TRUE;
        }
        else {
            /*
             *  We are in low-memory stress.  
             *  Start the low-memory retry state machine, which tries to
             *  resend the packet in little one-page chunks.
             */
            InitLowMemRetry(  Pkt, 
                                        Pkt->BufPtrCopy, 
                                        Pkt->BufLenCopy, 
                                        Pkt->TargetLocationCopy); 
            StepLowMemRetry(Pkt);
            packetDone = FALSE;
        }
    }
    else {      
        /*
         *  Retry the packet by simply resending it after a delay.
         *  Put the packet back in the pending queue and
         *  schedule a timer to retry the transfer.
         *
         *  Do not call SetupReadWriteTransferPacket again because:
         *  (1)  The minidriver may have set some bits 
         *       in the SRB that it needs again and
         *  (2)  doing so would reset numRetries.
         *
         *  BECAUSE we do not call SetupReadWriteTransferPacket again,
         *  we have to reset a couple fields in the SRB that
         *  some miniports overwrite when they fail an SRB.
         */
         
        Pkt->Srb.DataBuffer = Pkt->BufPtrCopy;
        Pkt->Srb.DataTransferLength = Pkt->BufLenCopy;
        
        if (Pkt->RetryIntervalSec == 0){
            /*
             *  Always delay by at least a little when retrying.
             *  Some problems (e.g. CRC errors) are not recoverable without a slight delay.
             */
            LARGE_INTEGER timerPeriod;

            timerPeriod.HighPart = -1;
            timerPeriod.LowPart = -(LONG)((ULONG)MINIMUM_RETRY_UNITS*KeQueryTimeIncrement());
            KeInitializeTimer(&Pkt->RetryTimer);
            KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt);
            KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC);            
        }
        else {
            LARGE_INTEGER timerPeriod;

            ASSERT(Pkt->RetryIntervalSec < 100);    // sanity check
            timerPeriod.HighPart = -1;
            timerPeriod.LowPart = Pkt->RetryIntervalSec*-10000000;
            KeInitializeTimer(&Pkt->RetryTimer);
            KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt);
            KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC);
        }
        packetDone = FALSE;
    }

    return packetDone;
}
Exemplo n.º 20
0
NTSTATUS
otLwfEventProcessingStart(
    _In_ PMS_FILTER             pFilter
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    HANDLE   threadHandle = NULL;

    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p, TimeIncrement = %u", pFilter, KeQueryTimeIncrement());
    
    pFilter->NextAlarmTickCount.QuadPart = 0;

    NT_ASSERT(pFilter->EventWorkerThread == NULL);
    if (pFilter->EventWorkerThread != NULL)
    {
        status = STATUS_ALREADY_REGISTERED;
        goto error;
    }

    // Make sure to reset the necessary events
    KeResetEvent(&pFilter->EventWorkerThreadStopEvent);
    KeResetEvent(&pFilter->SendNetBufferListComplete);
    KeResetEvent(&pFilter->EventWorkerThreadEnergyScanComplete);

    // Start the worker thread
    status = PsCreateSystemThread(
                &threadHandle,                  // ThreadHandle
                THREAD_ALL_ACCESS,              // DesiredAccess
                NULL,                           // ObjectAttributes
                NULL,                           // ProcessHandle
                NULL,                           // ClientId
                otLwfEventWorkerThread,         // StartRoutine
                pFilter                         // StartContext
                );
    if (!NT_SUCCESS(status))
    {
        LogError(DRIVER_DEFAULT, "PsCreateSystemThread failed, %!STATUS!", status);
        goto error;
    }

    // Grab the object reference to the worker thread
    status = ObReferenceObjectByHandle(
                threadHandle,
                THREAD_ALL_ACCESS,
                *PsThreadType,
                KernelMode,
                &pFilter->EventWorkerThread,
                NULL
                );
    if (!NT_VERIFYMSG("ObReferenceObjectByHandle can't fail with a valid kernel handle", NT_SUCCESS(status)))
    {
        LogError(DRIVER_DEFAULT, "ObReferenceObjectByHandle failed, %!STATUS!", status);
        KeSetEvent(&pFilter->EventWorkerThreadStopEvent, IO_NO_INCREMENT, FALSE);
    }

    ZwClose(threadHandle);

error:

    if (!NT_SUCCESS(status))
    {
        ExSetTimerResolution(0, FALSE);
    }

    LogFuncExitNT(DRIVER_DEFAULT, status);

    return status;
}
Exemplo n.º 21
0
--*/

{
    LARGE_INTEGER nowTick, nowTime, time;
    ULONG maxInc = 0;
    TIME_FIELDS timeFields = {0};
    WCHAR outDateTime[TIME_STRING_LENGTH + 1];

    nowTick.QuadPart = 0;
    nowTime.QuadPart = 0;
    //
    // Translate the tick count to a system time
    //
    KeQueryTickCount(&nowTick);
    maxInc = KeQueryTimeIncrement();
    KeQuerySystemTime(&nowTime);
    time.QuadPart = nowTime.QuadPart - ((nowTick.QuadPart - Tick.QuadPart) * maxInc);

    RtlTimeToTimeFields(&time, &timeFields);

    //
    // The buffer String is of size MAX_PATH. Use that to specify the buffer size.
    //
    //yyyymmddhhmmss.mmmmmmsutc
    RtlStringCbPrintfW(outDateTime, sizeof(outDateTime), L"%04d%02d%02d%02d%02d%02d.%03d***+000", timeFields.Year, timeFields.Month, timeFields.Day, timeFields.Hour, timeFields.Minute, timeFields.Second, timeFields.Milliseconds);
    RtlMoveMemory(String, outDateTime, sizeof(WCHAR) * TIME_STRING_LENGTH);
    return  String;
}

/*++////////////////////////////////////////////////////////////////////////////
Exemplo n.º 22
0
Arquivo: Uart.c Projeto: levic/dektec
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaUartWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtaUartWrite(
    DtaUartPort*  pUart,
    UInt8*  pBuf,
    Int  NumBytes,
    Int*  pTimeout)
{
    DtStatus  Status = DT_STATUS_OK;
    Int  FifoSize, FifoFree;
    volatile UInt8* pFwbRegs = pUart->m_pFwbRegs;
#ifdef WINBUILD
    LARGE_INTEGER  StartTime, CurTime;
#else
    struct timespec  StartTime, CurTime;
#endif
    Int  TimeElapsed = 0;

#ifdef WINBUILD
    KeQueryTickCount(&StartTime);
#else
    getnstimeofday(&StartTime);
#endif

    if (pTimeout==NULL || *pTimeout<=0)
        return DT_STATUS_INVALID_PARAMETER;
    
    // Get current space in FIFO
    FifoSize = DtaFwbRegRead(pFwbRegs,  &pUart->m_pFwbUart->Config_TxFifoSize);
    FifoFree = FifoSize - DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->TxStat_FifoLoad);

    while (NumBytes > FifoFree)
    {
        // Write as many bytes as fit in the buffer
        while (FifoFree-- > 0)
        {
            DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxData, *pBuf++);
            NumBytes--;
        }
        DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxCtrl_HalfEmptyIntEnable, 1);
        Status = DtEventWaitUnInt(&pUart->m_TxEvent, *pTimeout - TimeElapsed);
#ifdef WINBUILD
        KeQueryTickCount(&CurTime);
        TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement()
                                                                                 / 10000);
#else
        getnstimeofday(&CurTime);
        TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL
                                   + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL);
#endif
        if (TimeElapsed > *pTimeout)
            return DT_STATUS_TIMEOUT;

        FifoFree = FifoSize - DtaFwbRegRead(pFwbRegs,&pUart->m_pFwbUart->TxStat_FifoLoad);
    }
    DT_ASSERT(NumBytes <= FifoFree);
    while (NumBytes-- > 0)
    {
        DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxData, *pBuf++);
    }
    
#ifdef WINBUILD
        KeQueryTickCount(&CurTime);
        TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement()
                                                                                 / 10000);
#else
        getnstimeofday(&CurTime);
        TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL
                                   + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL);
#endif
    if (TimeElapsed > *pTimeout)
        return DT_STATUS_TIMEOUT;

    // Wait for completion
    DtEventReset(&pUart->m_TxEvent);
    DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxCtrl_EmptyIntEnable, 1);
    Status = DtEventWaitUnInt(&pUart->m_TxEvent, *pTimeout - TimeElapsed);

    if (!DT_SUCCESS(Status))
    {
#ifdef WINBUILD
        KeQueryTickCount(&CurTime);
        TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement()
                                                                                 / 10000);
#else
        getnstimeofday(&CurTime);
        TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL
                                   + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL);
#endif
        *pTimeout -= TimeElapsed;
        return Status;
    }
    return DT_STATUS_OK;
}
Exemplo n.º 23
0
NTSTATUS
FPFilterAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS                status;
    PDEVICE_OBJECT          filterDeviceObject;
    ULONG                   registrationFlag = 0;
    PDEVICE_EXTENSION       pDevExtFilter;
    PDEVICE_OBJECT          controlDeviceObject;
    PDEVICE_EXTENSION2      pDevExtControl;
	WCHAR					deviceNamestr[32];
	WCHAR					linkNamestr[32];
	UNICODE_STRING			deviceName;
	UNICODE_STRING			linkName;
	ULONG					n;
    PDEVICE_OBJECT          TempDeviceObject;
	ULONG					DeviceType = FILE_DEVICE_UNKNOWN;


    KdPrint(("LPCFILTER: FPFilterAddDevice: Driver %p Device %p\n", DriverObject, PhysicalDeviceObject));


	//
	//  Create a single control device object. This can be opened by user mode apps to do usefull things with
	//

	if(gCtlDevNum == 0)
	{

		RtlStringCbPrintfW(deviceNamestr,   64, L"\\Device\\SFltrl%d", gCtlDevNum);  // the symbollic link that can be opened by CreateFile() in user mode.
		RtlStringCbPrintfW(linkNamestr,   64, L"\\DosDevices\\SFltrl%d", gCtlDevNum);

		RtlInitUnicodeString(&deviceName,	deviceNamestr);

		RtlInitUnicodeString(&linkName,	linkNamestr);

		gStatus = IoCreateDevice(DriverObject,
								sizeof(DEVICE_EXTENSION2), // this allocates a chunk of memory in the device obhect of this size
								&deviceName,
								FILE_DEVICE_UNKNOWN,
								0,
								FALSE,
								&controlDeviceObject);

		if (!NT_SUCCESS(gStatus))
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create control DeviceObject\n"));
			goto EndCONTROLdeviceCreate;
		}


		// point our device extension to the chunk of memory allocated for us
		pDevExtControl					= (PDEVICE_EXTENSION2) controlDeviceObject->DeviceExtension;

		// and set up some usefull values in it...
		RtlZeroMemory(pDevExtControl, sizeof(PDEVICE_EXTENSION2));

		pDevExtControl->DeviceObject	= controlDeviceObject;

		pDevExtControl->Type			= CONTROL;

		pDevExtControl->DeviceObject->Flags |= DO_DIRECT_IO;

		pDevExtControl->DeviceObject->Flags  &= ~DO_POWER_PAGABLE;



		status = IoCreateSymbolicLink(&linkName, &deviceName);

		if (!NT_SUCCESS(status)) 
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create symbolic link\n"));
			IoDeleteDevice(pDevExtControl->DeviceObject);
			goto EndCONTROLdeviceCreate;
		}


		RtlStringCbCopyW(pDevExtControl->linkNamestr, 64, linkNamestr);
		
		RtlInitUnicodeString(&pDevExtControl->linkName, pDevExtControl->linkNamestr);

		KeInitializeSpinLock(&pDevExtControl->AppLock);


		//
		// set some default values
		//

		pDevExtControl->Config.StayAliveFailureLimit	= 50;

		pDevExtControl->Config.ThreadDelay				= 20;

		pDevExtControl->Config.StatsSampleRate			= 1;  // basic sampling rate

		// KeQueryTimeIncrement returns the number of 100 nano seconds intervals per tick,
		// Convert it to milliseconds (normally about 15 ms per tick, but this can be adjusted)
		pDevExtControl->MillisPerTick =  KeQueryTimeIncrement() / 10000;
		

		KdPrint(("LPCFILTER: FPFilterAddDevice: control Device Object: 0x%X \n		Created device %S \n", controlDeviceObject, deviceNamestr));

		// Clear the DO_DEVICE_INITIALIZING flag, if you dont, you cant open the device from user mode.
		// Yep, how many times have I forgotten to do that.... :)
		CLEAR_FLAG(controlDeviceObject->Flags, DO_DEVICE_INITIALIZING);
	}
EndCONTROLdeviceCreate:

	


    //
    // Create a filter device object for this device.
	// This is the device that actually sits in the CPU stack.
	// Because declared this device as a lower filter to the normal CPU driver, 
	// ie, we are above acpi and below intelppmm when we cal IoAttachDeviceToDeviceStack() 
	// we get attached to acpi and get a pointer to its device object for the CPU (actually called a Physical Device Object) 
    //

	// get a temp ref to the lower device so we can copy the device type
	TempDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
    DeviceType = TempDeviceObject->DeviceType;
    ObDereferenceObject(TempDeviceObject);

	KdPrint(("LPCFILTER: FPFilterAddDevice: device type is %d\n", DeviceType));

    status = IoCreateDevice(DriverObject,
                            sizeof(DEVICE_EXTENSION),
                            NULL,
                            DeviceType,
                            0,
                            FALSE,
                            &filterDeviceObject);

    if (!NT_SUCCESS(status)) {
        KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create filterDeviceObject\n"));
		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        return status;
    }

    pDevExtFilter = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension;

    RtlZeroMemory(pDevExtFilter, sizeof(DEVICE_EXTENSION));



    //
    // Attach the device object to the highest device object in the chain and
    // return the previously highest device object, which is passed to
    // IoCallDriver when we pass IRPs down the device stack
    //

	// we use TargetDeviceObject to send IOCTLs to  to get information on ACPI objects
    pDevExtFilter->TargetDeviceObject = IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject);

    if (pDevExtFilter->TargetDeviceObject == NULL) 
	{
 		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        IoDeleteDevice(filterDeviceObject);
        KdPrint(("LPCFILTER: FPFilterAddDevice: Unable to attach %X to target %X\n", filterDeviceObject, PhysicalDeviceObject));
        return STATUS_NO_SUCH_DEVICE;
    }

    // Save the filter device object in the device extension
    pDevExtFilter->DeviceObject = filterDeviceObject;

	pDevExtFilter->Type			= FILTER;

	// copy the flags and other stuff off the lower device 
	pDevExtFilter->DeviceObject->Flags |= 
					pDevExtFilter->TargetDeviceObject->Flags &
					(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE );

	pDevExtFilter->DeviceObject->Characteristics	= pDevExtFilter->TargetDeviceObject->Characteristics;
	pDevExtFilter->DeviceObject->DeviceType			= pDevExtFilter->TargetDeviceObject->DeviceType;

	KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo type is %d\n", pDevExtFilter->DeviceObject->DeviceType));
    KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo flags are: 0x%X\n",  pDevExtFilter->DeviceObject->Flags));

    // if it is the first FILTER device we created and we sucessfully created a CONTROL device...
	if((gCtlDevNum == 0) && (NT_SUCCESS(gStatus)))
	{
		// reference each other device extensions
		// we do this so when the CONTROL device object gets caled frodm user mode we can interact with the acpi PhsicalDevice Object
		pDevExtControl->pOtherExt = pDevExtFilter;
		pDevExtFilter->pOtherExt = pDevExtControl;
	}
		
    //
    // Initialize the remove lock
    //
    IoInitializeRemoveLock(&pDevExtFilter->RemoveLock,
                           0,
                           0,
                           0);

    // Clear the DO_DEVICE_INITIALIZING flag
    CLEAR_FLAG(filterDeviceObject->Flags, DO_DEVICE_INITIALIZING);

	gCtlDevNum = 1; // we created our control device object, so even though AddDevice 
	// gets called again on a multi processor system, we set this so we dont create any more

    return STATUS_SUCCESS;
} 
Exemplo n.º 24
0
static NDIS_STATUS
OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
{
    int i;
    NTSTATUS status;

    OVS_LOG_TRACE("Enter: switchContext: %p", switchContext);

    switchContext->dispatchLock =
        NdisAllocateRWLock(switchContext->NdisFilterHandle);

    switchContext->portNoHashArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
        sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
    switchContext->ovsPortNameHashArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
        sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
    switchContext->portIdHashArray= (PLIST_ENTRY)OvsAllocateMemoryWithTag(
        sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
    switchContext->pidHashArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
        sizeof(LIST_ENTRY) * OVS_MAX_PID_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
    status = OvsAllocateFlowTable(&switchContext->datapath, switchContext);

    if (status == NDIS_STATUS_SUCCESS) {
        status = OvsInitBufferPool(switchContext);
    }
    if (status != NDIS_STATUS_SUCCESS ||
        switchContext->dispatchLock == NULL ||
        switchContext->portNoHashArray == NULL ||
        switchContext->ovsPortNameHashArray == NULL ||
        switchContext->portIdHashArray== NULL ||
        switchContext->pidHashArray == NULL) {
        if (switchContext->dispatchLock) {
            NdisFreeRWLock(switchContext->dispatchLock);
        }
        if (switchContext->portNoHashArray) {
            OvsFreeMemoryWithTag(switchContext->portNoHashArray,
                                 OVS_SWITCH_POOL_TAG);
        }
        if (switchContext->ovsPortNameHashArray) {
            OvsFreeMemoryWithTag(switchContext->ovsPortNameHashArray,
                                 OVS_SWITCH_POOL_TAG);
        }
        if (switchContext->portIdHashArray) {
            OvsFreeMemoryWithTag(switchContext->portIdHashArray,
                                 OVS_SWITCH_POOL_TAG);
        }
        if (switchContext->pidHashArray) {
            OvsFreeMemoryWithTag(switchContext->pidHashArray,
                                 OVS_SWITCH_POOL_TAG);
        }

        OvsDeleteFlowTable(&switchContext->datapath);
        OvsCleanupBufferPool(switchContext);

        OVS_LOG_TRACE("Exit: Failed to init switchContext");
        return NDIS_STATUS_RESOURCES;
    }

    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
        InitializeListHead(&switchContext->ovsPortNameHashArray[i]);
    }
    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
        InitializeListHead(&switchContext->portIdHashArray[i]);
    }
    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
        InitializeListHead(&switchContext->portNoHashArray[i]);
    }

    for (i = 0; i < OVS_MAX_PID_ARRAY_SIZE; i++) {
        InitializeListHead(&switchContext->pidHashArray[i]);
    }

    NdisAllocateSpinLock(&(switchContext->pidHashLock));
    switchContext->isActivated = FALSE;
    switchContext->isActivateFailed = FALSE;
    switchContext->dpNo = OVS_DP_NUMBER;
    ovsTimeIncrementPerTick = KeQueryTimeIncrement() / 10000;
    OVS_LOG_TRACE("Exit: Succesfully initialized switchContext: %p",
                  switchContext);
    return NDIS_STATUS_SUCCESS;
}