]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - ubuntu/vbox/r0drv/powernotification-r0drv.c
UBUNTU: ubuntu: vbox -- update to 5.2.0-dfsg-2
[mirror_ubuntu-bionic-kernel.git] / ubuntu / vbox / r0drv / powernotification-r0drv.c
diff --git a/ubuntu/vbox/r0drv/powernotification-r0drv.c b/ubuntu/vbox/r0drv/powernotification-r0drv.c
deleted file mode 100644 (file)
index 92acef3..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/* $Id: powernotification-r0drv.c $ */
-/** @file
- * IPRT - Power Management, Ring-0 Driver, Event Notifications.
- */
-
-/*
- * Copyright (C) 2008-2016 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#include <iprt/power.h>
-#include "internal/iprt.h"
-
-#include <iprt/asm.h>
-#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
-# include <iprt/asm-amd64-x86.h>
-#endif
-#include <iprt/assert.h>
-#include <iprt/err.h>
-#include <iprt/mem.h>
-#include <iprt/spinlock.h>
-#include <iprt/string.h>
-#include <iprt/thread.h>
-#include "r0drv/mp-r0drv.h"
-#include "r0drv/power-r0drv.h"
-
-
-/*********************************************************************************************************************************
-*   Structures and Typedefs                                                                                                      *
-*********************************************************************************************************************************/
-/**
- * Notification registration record tracking
- * RTPowerRegisterNotification() calls.
- */
-typedef struct RTPOWERNOTIFYREG
-{
-    /** Pointer to the next record. */
-    struct RTPOWERNOTIFYREG * volatile pNext;
-    /** The callback. */
-    PFNRTPOWERNOTIFICATION pfnCallback;
-    /** The user argument. */
-    void *pvUser;
-    /** Bit mask indicating whether we've done this callback or not. */
-    uint8_t bmDone[sizeof(void *)];
-} RTPOWERNOTIFYREG;
-/** Pointer to a registration record. */
-typedef RTPOWERNOTIFYREG *PRTPOWERNOTIFYREG;
-
-
-/*********************************************************************************************************************************
-*   Global Variables                                                                                                             *
-*********************************************************************************************************************************/
-/** The spinlock protecting the list. */
-static RTSPINLOCK volatile g_hRTPowerNotifySpinLock = NIL_RTSPINLOCK;
-/** List of callbacks, in registration order. */
-static PRTPOWERNOTIFYREG volatile g_pRTPowerCallbackHead = NULL;
-/** The current done bit. */
-static uint32_t volatile g_iRTPowerDoneBit;
-/** The list generation.
- * This is increased whenever the list has been modified. The callback routine
- * make use of this to avoid having restart at the list head after each callback. */
-static uint32_t volatile g_iRTPowerGeneration;
-
-
-
-
-RTDECL(int) RTPowerSignalEvent(RTPOWEREVENT enmEvent)
-{
-    PRTPOWERNOTIFYREG pCur;
-    RTSPINLOCK        hSpinlock;
-
-    /*
-     * This is a little bit tricky as we cannot be holding the spinlock
-     * while calling the callback. This means that the list might change
-     * while we're walking it, and that multiple events might be running
-     * concurrently (depending on the OS).
-     *
-     * So, the first measure is to employ a 32-bitmask for each
-     * record where we'll use a bit that rotates for each call to
-     * this function to indicate which records that has been
-     * processed. This will take care of both changes to the list
-     * and a reasonable amount of concurrent events.
-     *
-     * In order to avoid having to restart the list walks for every
-     * callback we make, we'll make use a list generation number that is
-     * incremented everytime the list is changed. So, if it remains
-     * unchanged over a callback we can safely continue the iteration.
-     */
-    uint32_t iDone = ASMAtomicIncU32(&g_iRTPowerDoneBit);
-    iDone %= RT_SIZEOFMEMB(RTPOWERNOTIFYREG, bmDone) * 8;
-
-    hSpinlock = g_hRTPowerNotifySpinLock;
-    if (hSpinlock == NIL_RTSPINLOCK)
-        return VERR_ACCESS_DENIED;
-    RTSpinlockAcquire(hSpinlock);
-
-    /* Clear the bit. */
-    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
-        ASMAtomicBitClear(&pCur->bmDone[0], iDone);
-
-    /* Iterate the records and perform the callbacks. */
-    do
-    {
-        uint32_t const iGeneration = ASMAtomicUoReadU32(&g_iRTPowerGeneration);
-
-        pCur = g_pRTPowerCallbackHead;
-        while (pCur)
-        {
-            if (!ASMAtomicBitTestAndSet(&pCur->bmDone[0], iDone))
-            {
-                PFNRTPOWERNOTIFICATION pfnCallback = pCur->pfnCallback;
-                void *pvUser = pCur->pvUser;
-                pCur = pCur->pNext;
-                RTSpinlockRelease(g_hRTPowerNotifySpinLock);
-
-                pfnCallback(enmEvent, pvUser);
-
-                /* carefully require the lock here, see RTR0MpNotificationTerm(). */
-                hSpinlock = g_hRTPowerNotifySpinLock;
-                if (hSpinlock == NIL_RTSPINLOCK)
-                    return VERR_ACCESS_DENIED;
-                RTSpinlockAcquire(hSpinlock);
-                if (ASMAtomicUoReadU32(&g_iRTPowerGeneration) != iGeneration)
-                    break;
-            }
-            else
-                pCur = pCur->pNext;
-        }
-    } while (pCur);
-
-    RTSpinlockRelease(hSpinlock);
-    return VINF_SUCCESS;
-}
-RT_EXPORT_SYMBOL(RTPowerSignalEvent);
-
-
-RTDECL(int) RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
-{
-    PRTPOWERNOTIFYREG   pCur;
-    PRTPOWERNOTIFYREG   pNew;
-
-    /*
-     * Validation.
-     */
-    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
-    AssertReturn(g_hRTPowerNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
-    RT_ASSERT_PREEMPTIBLE();
-
-    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
-    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
-        if (    pCur->pvUser == pvUser
-            &&  pCur->pfnCallback == pfnCallback)
-            break;
-    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
-    AssertMsgReturn(!pCur, ("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
-
-    /*
-     * Allocate a new record and attempt to insert it.
-     */
-    pNew = (PRTPOWERNOTIFYREG)RTMemAlloc(sizeof(*pNew));
-    if (!pNew)
-        return VERR_NO_MEMORY;
-
-    pNew->pNext = NULL;
-    pNew->pfnCallback = pfnCallback;
-    pNew->pvUser = pvUser;
-    memset(&pNew->bmDone[0], 0xff, sizeof(pNew->bmDone));
-
-    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
-
-    pCur = g_pRTPowerCallbackHead;
-    if (!pCur)
-        g_pRTPowerCallbackHead = pNew;
-    else
-    {
-        for (pCur = g_pRTPowerCallbackHead; ; pCur = pCur->pNext)
-            if (    pCur->pvUser == pvUser
-                &&  pCur->pfnCallback == pfnCallback)
-                break;
-            else if (!pCur->pNext)
-            {
-                pCur->pNext = pNew;
-                pCur = NULL;
-                break;
-            }
-    }
-
-    ASMAtomicIncU32(&g_iRTPowerGeneration);
-
-    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
-
-    /* duplicate? */
-    if (pCur)
-    {
-        RTMemFree(pCur);
-        AssertMsgFailedReturn(("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
-    }
-
-    return VINF_SUCCESS;
-}
-RT_EXPORT_SYMBOL(RTPowerNotificationRegister);
-
-
-RTDECL(int) RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
-{
-    PRTPOWERNOTIFYREG   pPrev;
-    PRTPOWERNOTIFYREG   pCur;
-
-    /*
-     * Validation.
-     */
-    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
-    AssertReturn(g_hRTPowerNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
-    RT_ASSERT_INTS_ON();
-
-    /*
-     * Find and unlink the record from the list.
-     */
-    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
-    pPrev = NULL;
-    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
-    {
-        if (    pCur->pvUser == pvUser
-            &&  pCur->pfnCallback == pfnCallback)
-            break;
-        pPrev = pCur;
-    }
-    if (pCur)
-    {
-        if (pPrev)
-            pPrev->pNext = pCur->pNext;
-        else
-            g_pRTPowerCallbackHead = pCur->pNext;
-        ASMAtomicIncU32(&g_iRTPowerGeneration);
-    }
-    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
-
-    if (!pCur)
-        return VERR_NOT_FOUND;
-
-    /*
-     * Invalidate and free the record.
-     */
-    pCur->pNext = NULL;
-    pCur->pfnCallback = NULL;
-    RTMemFree(pCur);
-
-    return VINF_SUCCESS;
-}
-RT_EXPORT_SYMBOL(RTPowerNotificationDeregister);
-
-
-DECLHIDDEN(int) rtR0PowerNotificationInit(void)
-{
-    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTPowerNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0Power");
-    if (RT_SUCCESS(rc))
-    {
-        /** @todo OS specific init here */
-        return rc;
-#if 0
-        RTSpinlockDestroy(g_hRTPowerNotifySpinLock);
-        g_hRTPowerNotifySpinLock = NIL_RTSPINLOCK;
-#endif
-    }
-    return rc;
-}
-
-
-DECLHIDDEN(void) rtR0PowerNotificationTerm(void)
-{
-    PRTPOWERNOTIFYREG   pHead;
-    RTSPINLOCK          hSpinlock = g_hRTPowerNotifySpinLock;
-    AssertReturnVoid(hSpinlock != NIL_RTSPINLOCK);
-
-    /** @todo OS specific term here */
-
-    /* pick up the list and the spinlock. */
-    RTSpinlockAcquire(hSpinlock);
-    ASMAtomicWriteHandle(&g_hRTPowerNotifySpinLock, NIL_RTSPINLOCK);
-    pHead = g_pRTPowerCallbackHead;
-    g_pRTPowerCallbackHead = NULL;
-    ASMAtomicIncU32(&g_iRTPowerGeneration);
-    RTSpinlockRelease(hSpinlock);
-
-    /* free the list. */
-    while (pHead)
-    {
-        PRTPOWERNOTIFYREG pFree = pHead;
-        pHead = pHead->pNext;
-
-        pFree->pNext = NULL;
-        pFree->pfnCallback = NULL;
-        RTMemFree(pFree);
-    }
-
-    RTSpinlockDestroy(hSpinlock);
-}
-