9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2012 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "VBoxMPWddm.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/semaphore.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* SHGSMI */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxSHGSMICommandRetain (PVBOXSHGSMIHEADER pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ASMAtomicIncU32(&pCmd->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid vboxSHGSMICommandFree (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxSHGSMIHeapFree(pHeap, pCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(void) vboxSHGSMICommandRelease (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cRefs < UINT32_MAX / 2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(!cRefs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandFree (pHeap, pCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLCALLBACK(void) vboxSHGSMICompletionSetEvent(PVBOXSHGSMI pHeap, void *pvCmd, void *pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventSignal((RTSEMEVENT)pvContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLCALLBACK(void) vboxSHGSMICompletionCommandRelease(PVBOXSHGSMI pHeap, void *pvCmd, void *pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease (pHeap, VBoxSHGSMIBufferHeader(pvCmd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* do not wait for completion */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(const VBOXSHGSMIHEADER*) vboxSHGSMICommandPrepAsynch (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* ensure the command is not removed until we're processing it */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRetain(pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pHeader;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(void) vboxSHGSMICommandDoneAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(!(ASMAtomicReadU32((volatile uint32_t *)&pHeader->fFlags) & VBOXSHGSMI_FLAG_HG_ASYNCH))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCompletion = (PFNVBOXSHGSMICMDCOMPLETION)pHeader->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pfnCompletion)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCompletion(pHeap, VBoxSHGSMIBufferData (pHeader), (PVOID)pHeader->u64Info2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease(pHeap, (PVBOXSHGSMIHEADER)pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchEvent (PVBOXSHGSMI pHeap, PVOID pvBuff, RTSEMEVENT hEventSem)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info1 = (uint64_t)vboxSHGSMICompletionSetEvent;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info2 = (uint64_t)hEventSem;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->fFlags = VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepSynch (PVBOXSHGSMI pHeap, PVOID pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTSemEventCreate(&hEventSem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(RT_SUCCESS(rc));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBoxSHGSMICommandPrepAsynchEvent (pHeap, pCmd, hEventSem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandDoneAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER * pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandDoneAsynch(pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandDoneSynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBoxSHGSMICommandDoneAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem = (RTSEMEVENT)pHeader->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTSemEventWait(hEventSem, RT_INDEFINITE_WAIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventDestroy(hEventSem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return rc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandCancelAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease(pHeap, (PVBOXSHGSMIHEADER)pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandCancelSynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBoxSHGSMICommandCancelAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem = (RTSEMEVENT)pHeader->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventDestroy(hEventSem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynch (PVBOXSHGSMI pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fFlags &= ~VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info1 = (uint64_t)pfnCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info2 = (uint64_t)pvCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->fFlags = fFlags;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchIrq (PVBOXSHGSMI pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fFlags |= VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ | VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info1 = (uint64_t)pfnCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info2 = (uint64_t)pvCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* we must assign rather than or because flags field does not get zeroed on command creation */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->fFlags = fFlags;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid* VBoxSHGSMIHeapAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KIRQL OldIrql;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync void* pvData;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KeAcquireSpinLock(&pHeap->HeapLock, &OldIrql);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pvData = HGSMIHeapAlloc(&pHeap->Heap, cbData, u8Channel, u16ChannelInfo);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KeReleaseSpinLock(&pHeap->HeapLock, OldIrql);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync if (!pvData)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync WARN(("HGSMIHeapAlloc failed!"));
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync return pvData;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync}
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMIHeapFree(PVBOXSHGSMI pHeap, void *pvBuffer)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KIRQL OldIrql;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KeAcquireSpinLock(&pHeap->HeapLock, &OldIrql);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync HGSMIHeapFree(&pHeap->Heap, pvBuffer);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KeReleaseSpinLock(&pHeap->HeapLock, OldIrql);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync}
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsyncvoid* VBoxSHGSMIHeapBufferAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData)
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync{
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KIRQL OldIrql;
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync void* pvData;
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KeAcquireSpinLock(&pHeap->HeapLock, &OldIrql);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync pvData = HGSMIHeapBufferAlloc(&pHeap->Heap, cbData);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KeReleaseSpinLock(&pHeap->HeapLock, OldIrql);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync if (!pvData)
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync WARN(("HGSMIHeapAlloc failed!"));
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync return pvData;
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync}
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsyncvoid VBoxSHGSMIHeapBufferFree(PVBOXSHGSMI pHeap, void *pvBuffer)
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync{
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KIRQL OldIrql;
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KeAcquireSpinLock(&pHeap->HeapLock, &OldIrql);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync HGSMIHeapBufferFree(&pHeap->Heap, pvBuffer);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync KeReleaseSpinLock(&pHeap->HeapLock, OldIrql);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync}
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync
32b1164f35483be483177be7b5235002a4a5afbevboxsyncint VBoxSHGSMIInit(PVBOXSHGSMI pHeap, uint32_t u32HeapType, void *pvBase, HGSMISIZE cbArea, HGSMIOFFSET offBase,
32b1164f35483be483177be7b5235002a4a5afbevboxsync const HGSMIENV *pEnv)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync KeInitializeSpinLock(&pHeap->HeapLock);
32b1164f35483be483177be7b5235002a4a5afbevboxsync return HGSMIHeapSetup(&pHeap->Heap, u32HeapType, pvBase, cbArea, offBase, pEnv);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync}
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMITerm(PVBOXSHGSMI pHeap)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync HGSMIHeapDestroy(&pHeap->Heap);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync}
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid* VBoxSHGSMICommandAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Issue the flush command. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync PVBOXSHGSMIHEADER pHeader = (PVBOXSHGSMIHEADER)VBoxSHGSMIHeapAlloc(pHeap, cbData + sizeof (VBOXSHGSMIHEADER), u8Channel, u16ChannelInfo);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->cRefs = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBoxSHGSMIBufferData(pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandFree(PVBOXSHGSMI pHeap, void *pvBuffer)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader(pvBuffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync#define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXVTLIST_ENTRY)&(_pCmd)->pvNext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSHGSMI_LISTENTRY2CMD(_pEntry) ( (PVBOXSHGSMIHEADER)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXSHGSMIHEADER, pvNext)) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandProcessCompletion (PVBOXSHGSMI pHeap, VBOXSHGSMIHEADER* pCur, bool bIrq, PVBOXVTLIST pPostProcessList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCur->fFlags & VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(bIrq);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCompletion = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void *pvCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION_IRQ)pCur->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void *pvCallback = (void*)pCur->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
d9fec6d329252f6e5eb8f564690e582b2aea6624vboxsync pfnCompletion = pfnCallback(pHeap, VBoxSHGSMIBufferData(pCur), pvCallback, &pvCompletion);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pfnCompletion)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCur->u64Info1 = (uint64_t)pfnCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCur->u64Info2 = (uint64_t)pvCompletion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCur->fFlags &= ~VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* nothing to do with this command */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!bIrq)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCur->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void *pvCallback = (void*)pCur->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCallback(pHeap, VBoxSHGSMIBufferData(pCur), pvCallback);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
e6ad2e18e663b076aeabfec994947514566a7accvboxsync vboxVtListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return rc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandPostprocessCompletion (PVBOXSHGSMI pHeap, PVBOXVTLIST pPostProcessList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync PVBOXVTLIST_ENTRY pNext, pCur;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (pCur = pPostProcessList->pFirst; pCur; pCur = pNext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* need to save next since the command may be released in a pfnCallback and thus its data might be invalid */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pNext = pCur->pNext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pCmd = VBOXSHGSMI_LISTENTRY2CMD(pCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCmd->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void *pvCallback = (void*)pCmd->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCallback(pHeap, VBoxSHGSMIBufferData(pCmd), pvCallback);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}